gentelella
Version:
Gentelella Admin is a free to use Bootstrap admin template
1,468 lines (1,349 loc) • 109 kB
JavaScript
(function($) {
/**
* This file contains all the component initialization logic.
* It is loaded after all vendor and custom libraries, so it has access to everything.
*/
// Get security utilities from window if available
const sanitizeHtml = window.sanitizeHtml || function(html) { return html; };
$(window).on('load', function() {
// NProgress (we start it on document ready, but stop it on window load)
if (typeof NProgress !== 'undefined') {
NProgress.done();
}
// Panel Toolbox
$('.collapse-link').on('click', function() {
var $BOX_PANEL = $(this).closest('.x_panel');
var $ICON = $(this).find('i');
var $BOX_CONTENT = $BOX_PANEL.find('.x_content');
if ($BOX_PANEL.attr('style')) {
$BOX_CONTENT.slideToggle(200, function() {
$BOX_PANEL.removeAttr('style');
});
} else {
$BOX_CONTENT.slideToggle(200);
$BOX_PANEL.css('height', 'auto');
}
$ICON.toggleClass('fa-chevron-up fa-chevron-down');
});
$('.close-link').click(function() {
var $BOX_PANEL = $(this).closest('.x_panel');
$BOX_PANEL.remove();
});
// Tooltip
if ($.fn.tooltip) {
$('[data-toggle="tooltip"]').tooltip({
container: 'body'
});
}
// Popover
if ($.fn.popover) {
$('body').popover({
selector: '[data-popover]',
trigger: 'click hover',
delay: {
show: 50,
hide: 400
}
});
}
// Switchery
if (typeof Switchery !== 'undefined') {
var elems = Array.prototype.slice.call(document.querySelectorAll('.js-switch'));
elems.forEach(function(html) {
var switchery = new Switchery(html, {
size: 'small'
});
});
}
// Bootstrap 5 Native Progress Bars
initializeProgressBars();
// Initialize all chart components
initializeCharts();
initializeNetworkCharts();
initializeECharts();
initializeOtherCharts();
initializeIndex2();
initializeIndex4();
initializeIndex3();
initializeSidebarGauges();
initializeSkycons();
initializeGeneralElements();
initializeMaps();
// World Map (for Visitors Location) - Using Leaflet
if ($('#world-map-gdp').length) {
try {
var mapContainer = document.getElementById('world-map-gdp');
mapContainer.style.height = '400px'; // Set a specific height for the map
// Initialize Leaflet map
var visitorsMap = L.map('world-map-gdp').setView([40, 0], 2);
// Add OpenStreetMap tiles
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
}).addTo(visitorsMap);
// Add markers for visitor locations with popups showing percentages
var visitorData = [
{ coords: [39.8283, -98.5795], country: 'United States', percentage: '33%' },
{ coords: [46.2276, 2.2137], country: 'France', percentage: '27%' },
{ coords: [51.1657, 10.4515], country: 'Germany', percentage: '16%' },
{ coords: [40.4637, -3.7492], country: 'Spain', percentage: '11%' },
{ coords: [55.3781, -3.4360], country: 'United Kingdom', percentage: '10%' }
];
visitorData.forEach(function(location) {
L.marker(location.coords)
.addTo(visitorsMap)
.bindPopup(`<b>${location.country}</b><br/>Visitors: ${location.percentage}`)
.openPopup();
});
} catch (error) {
console.error('❌ Map initialization failed:', error);
}
}
// Chart.js initialization - Main Dashboard Chart
const Chart = window.Chart || globalThis.Chart;
if (typeof Chart !== 'undefined') {
// Main chart in dashboard (chart_plot_01 is a div, so we create canvas inside)
if ($('#chart_plot_01').length) {
var chartDiv = document.getElementById('chart_plot_01');
// Clear any existing content and create canvas
chartDiv.innerHTML = sanitizeHtml('');
var canvas = document.createElement('canvas');
canvas.id = 'mainChart';
canvas.width = chartDiv.offsetWidth || 800;
canvas.height = 300;
chartDiv.appendChild(canvas);
var ctx = canvas.getContext('2d');
var lineChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgba(38, 185, 154, 0.31)',
borderColor: 'rgba(38, 185, 154, 0.7)',
pointBorderColor: 'rgba(38, 185, 154, 0.7)',
pointBackgroundColor: 'rgba(38, 185, 154, 0.7)',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(220,220,220,1)',
pointBorderWidth: 1,
data: [31, 74, 6, 39, 20, 85, 7, 45, 38, 62, 29, 41],
fill: true,
tension: 0.4
}, {
label: 'My Second dataset',
backgroundColor: 'rgba(3, 88, 106, 0.3)',
borderColor: 'rgba(3, 88, 106, 0.70)',
pointBorderColor: 'rgba(3, 88, 106, 0.70)',
pointBackgroundColor: 'rgba(3, 88, 106, 0.70)',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(151,187,205,1)',
pointBorderWidth: 1,
data: [82, 23, 66, 9, 99, 4, 2, 25, 67, 44, 55, 33],
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
} else {
}
// Doughnut Chart (using class selector since DOM shows class="canvasDoughnut")
if ($('.canvasDoughnut').length) {
var originalCanvas = document.querySelector('.canvasDoughnut');
var xContent = originalCanvas.closest('.x_content');
var panel = originalCanvas.closest('.x_panel');
// Make the widget taller to fit the chart and legend
if (panel) {
panel.style.height = 'auto';
panel.style.minHeight = '320px';
}
if (xContent) {
// 1. Clear the problematic table layout
xContent.innerHTML = sanitizeHtml('');
// 2. Create a new, simple container for the chart
var chartContainer = document.createElement('div');
chartContainer.style.height = '250px'; // Adjust container height
chartContainer.style.position = 'relative';
var newCanvas = document.createElement('canvas');
chartContainer.appendChild(newCanvas);
xContent.appendChild(chartContainer);
// 3. Initialize the chart in the new clean container
var ctx_doughnut = newCanvas.getContext('2d');
var data = {
labels: ['IOS', 'Android', 'Blackberry', 'Symbian', 'Others'],
datasets: [{
data: [30, 10, 20, 15, 30],
backgroundColor: ['#3498DB', '#2ECC71', '#9B59B6', '#1ABC9C', '#E74C3C'],
hoverBackgroundColor: ['#5DADE2', '#58D68D', '#BB8FCE', '#52C9B4', '#EC7063']
}]
};
new Chart(ctx_doughnut, {
type: 'doughnut',
data: data,
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: 'bottom',
labels: {
padding: 15,
boxWidth: 12
}
}
}
}
});
} else {
console.error("Doughnut chart's .x_content container not found.");
}
} else {
}
// Chart.js pages - Line Chart
if ($('#lineChart').length) {
var canvas = document.getElementById('lineChart');
canvas.style.height = '400px'; // Set explicit height
var ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgba(38, 185, 154, 0.31)',
borderColor: 'rgba(38, 185, 154, 0.7)',
pointBorderColor: 'rgba(38, 185, 154, 0.7)',
pointBackgroundColor: 'rgba(38, 185, 154, 0.7)',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(220,220,220,1)',
pointBorderWidth: 1,
data: [31, 74, 6, 39, 20, 85, 7],
tension: 0.4
}, {
label: 'My Second dataset',
backgroundColor: 'rgba(3, 88, 106, 0.3)',
borderColor: 'rgba(3, 88, 106, 0.70)',
pointBorderColor: 'rgba(3, 88, 106, 0.70)',
pointBackgroundColor: 'rgba(3, 88, 106, 0.70)',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(151,187,205,1)',
pointBorderWidth: 1,
data: [82, 23, 66, 9, 99, 4, 2],
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
// Chart.js pages - Bar Chart
if ($('#mybarChart').length) {
var canvas = document.getElementById('mybarChart');
canvas.style.height = '400px'; // Set explicit height
var ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [{
label: '# of Votes',
data: [51, 30, 40, 28, 92, 50, 45],
backgroundColor: [
'rgba(38, 185, 154, 0.31)',
'rgba(3, 88, 106, 0.3)',
'rgba(38, 185, 154, 0.31)',
'rgba(3, 88, 106, 0.3)',
'rgba(38, 185, 154, 0.31)',
'rgba(3, 88, 106, 0.3)',
'rgba(38, 185, 154, 0.31)'
],
borderColor: [
'rgba(38, 185, 154, 0.7)',
'rgba(3, 88, 106, 0.70)',
'rgba(38, 185, 154, 0.7)',
'rgba(3, 88, 106, 0.70)',
'rgba(38, 185, 154, 0.7)',
'rgba(3, 88, 106, 0.70)',
'rgba(38, 185, 154, 0.7)'
],
borderWidth: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
// Chart.js pages - Radar Chart
if ($('#canvasRadar').length) {
var canvas = document.getElementById('canvasRadar');
canvas.style.height = '400px'; // Set explicit height
var ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'radar',
data: {
labels: ['Eating', 'Drinking', 'Sleeping', 'Designing', 'Coding', 'Cycling', 'Running'],
datasets: [{
label: 'My First dataset',
backgroundColor: 'rgba(38, 185, 154, 0.2)',
borderColor: 'rgba(38, 185, 154, 0.85)',
pointBackgroundColor: 'rgba(38, 185, 154, 0.85)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(38, 185, 154, 0.85)',
data: [65, 59, 90, 81, 56, 55, 40]
}, {
label: 'My Second dataset',
backgroundColor: 'rgba(3, 88, 106, 0.2)',
borderColor: 'rgba(3, 88, 106, 0.85)',
pointBackgroundColor: 'rgba(3, 88, 106, 0.85)',
pointBorderColor: '#fff',
pointHoverBackgroundColor: '#fff',
pointHoverBorderColor: 'rgba(3, 88, 106, 0.85)',
data: [28, 48, 40, 19, 96, 27, 100]
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
// Chart.js pages - Doughnut Chart (ID version)
if ($('#canvasDoughnut').length) {
var canvas = document.getElementById('canvasDoughnut');
canvas.style.height = '400px'; // Set explicit height
var ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'doughnut',
data: {
labels: ['Dark Grey', 'Purple', 'Blue', 'Grey', 'Green'],
datasets: [{
data: [15, 20, 30, 10, 30],
backgroundColor: [
'#455C73',
'#9B59B6',
'#26B99A',
'#3498DB',
'#BDC3C7'
],
hoverBackgroundColor: [
'#34495E',
'#B370CF',
'#36CAAB',
'#49A9EA',
'#CFD4D8'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
// Chart.js pages - Pie Chart
if ($('#pieChart').length) {
var canvas = document.getElementById('pieChart');
canvas.style.height = '400px'; // Set explicit height
var ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'pie',
data: {
labels: ['Dark Grey', 'Purple', 'Blue', 'Grey', 'Green'],
datasets: [{
data: [20, 50, 30, 25, 40],
backgroundColor: [
'#455C73',
'#9B59B6',
'#26B99A',
'#3498DB',
'#BDC3C7'
],
hoverBackgroundColor: [
'#34495E',
'#B370CF',
'#36CAAB',
'#49A9EA',
'#CFD4D8'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
// Chart.js pages - Polar Area Chart
if ($('#polarArea').length) {
var canvas = document.getElementById('polarArea');
canvas.style.height = '400px'; // Set explicit height
var ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'polarArea',
data: {
labels: ['Dark Grey', 'Purple', 'Blue', 'Grey', 'Green'],
datasets: [{
data: [20, 50, 30, 25, 40],
backgroundColor: [
'#455C73',
'#9B59B6',
'#26B99A',
'#3498DB',
'#BDC3C7'
],
hoverBackgroundColor: [
'#34495E',
'#B370CF',
'#36CAAB',
'#49A9EA',
'#CFD4D8'
]
}]
},
options: {
responsive: true,
maintainAspectRatio: false
}
});
}
} else {
}
});
// We still want NProgress to start early, so we'll keep this separate.
$(document).ready(function() {
if (typeof NProgress !== 'undefined') {
NProgress.start();
}
// Skycons initialization moved to initializeSkycons() function
// Top Campaign Performance Progress Bars (handled by initializeProgressBars)
// Chart initialization moved to main window.on('load') event
});
/**
* Initializes Bootstrap 5 native progress bars with animations
* Replaces the old bootstrap-progressbar library
*/
function initializeProgressBars() {
// Animate all progress bars with data-transitiongoal
const progressBars = document.querySelectorAll('.progress-bar[data-transitiongoal]');
progressBars.forEach(bar => {
const targetPercent = parseInt(bar.getAttribute('data-transitiongoal'), 10);
const displayText = bar.getAttribute('data-display-text') !== 'false';
// Remove any inline width styles to allow animation
bar.style.removeProperty('width');
// Set initial state with !important to override any CSS
bar.style.setProperty('width', '0%', 'important');
bar.setAttribute('aria-valuenow', '0');
// Animate to target value
setTimeout(() => {
bar.style.setProperty('transition', 'width 1s ease-in-out', 'important');
bar.style.setProperty('width', targetPercent + '%', 'important');
bar.setAttribute('aria-valuenow', targetPercent);
if (displayText) {
bar.textContent = targetPercent + '%';
}
}, 100);
});
// Handle App Versions progress bars (widget_summary containers)
const appVersionBars = document.querySelectorAll('.widget_summary .progress-bar');
appVersionBars.forEach(bar => {
// Skip if already processed with data-transitiongoal
if (bar.getAttribute('data-transitiongoal')) {
return;
}
// Extract target percentage from inline style
const inlineWidth = bar.style.width;
if (inlineWidth && inlineWidth.includes('%')) {
const targetPercent = parseInt(inlineWidth.replace('%', ''), 10);
// Remove inline width and animate
bar.style.removeProperty('width');
bar.style.setProperty('width', '0%', 'important');
bar.setAttribute('aria-valuenow', '0');
// Animate to target value with delay for staggered effect
const delay = Array.from(appVersionBars).indexOf(bar) * 100 + 200;
setTimeout(() => {
bar.style.setProperty('transition', 'width 1s ease-in-out', 'important');
bar.style.setProperty('width', targetPercent + '%', 'important');
bar.setAttribute('aria-valuenow', targetPercent);
}, delay);
}
});
// For other progress bars without data-transitiongoal, just show them immediately
const staticProgressBars = document.querySelectorAll('.progress-bar:not([data-transitiongoal])');
staticProgressBars.forEach(bar => {
// Skip App Versions bars as they're handled above
if (bar.closest('.widget_summary')) {
return;
}
const currentPercent = bar.style.width || bar.getAttribute('aria-valuenow') + '%' || '0%';
bar.style.width = currentPercent;
});
}
/**
* Initializes all Chart.js instances on a page.
*
* This function discovers all canvas elements with a `data-chart` attribute
* and initializes a chart of the specified type.
*/
function initializeCharts() {
if (typeof Chart === 'undefined') {
console.error('Chart.js not loaded.');
return;
}
const isChartJs1 = document.body.classList.contains('page-chartjs1');
const isChartJs2 = document.body.classList.contains('page-chartjs2');
const isChart3 = document.body.classList.contains('page-chart3');
if (!isChartJs1 && !isChartJs2 && !isChart3) {
return;
}
const chartCanvases = document.querySelectorAll('[data-chart]');
chartCanvases.forEach((canvas, index) => {
let type = canvas.dataset.chart;
const ctx = canvas.getContext('2d');
if (!type || !ctx) {return;}
let chartType = type; // Use separate variable for Chart.js type
let data, options = {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
position: 'top',
labels: {
boxWidth: 12,
padding: 8
}
},
title: {
display: true,
padding: {
top: 5,
bottom: 8
}
}
}
};
if (isChartJs1) {
// Data and options for chartjs.html
options.plugins.title.text = `Chart.js ${type.charAt(0).toUpperCase() + type.slice(1)} Chart`;
if (type === 'line' || type === 'bar' || type === 'radar') {
data = {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [{
label: 'Primary Sales',
backgroundColor: 'rgba(38, 185, 154, 0.31)',
borderColor: 'rgba(38, 185, 154, 0.7)',
data: [65, 59, 80, 81, 56, 55, 40, 58, 70, 60, 75, 68]
}, {
label: 'Secondary Sales',
backgroundColor: 'rgba(3, 88, 106, 0.3)',
borderColor: 'rgba(3, 88, 106, 0.70)',
data: [28, 48, 40, 19, 86, 27, 90, 75, 88, 70, 80, 72]
}]
};
if (type === 'line') {data.datasets.forEach(d => d.tension = 0.4);}
} else {
data = {
labels: ['Green', 'Blue', 'Gray', 'Purple', 'Red'],
datasets: [{
data: [120, 50, 140, 180, 100],
backgroundColor: ['#26B99A', '#3498DB', '#BDC3C7', '#9B59B6', '#E74C3C']
}]
};
}
} else if (isChartJs2) {
// Data and options for chartjs2.html
options.plugins.title.text = `Chart.js ${type.charAt(0).toUpperCase() + type.slice(1)} Chart`;
if (type === 'line' || type === 'bar' || type === 'radar') {
data = {
labels: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
datasets: [{
label: 'Online Orders',
backgroundColor: 'rgba(243, 156, 18, 0.3)',
borderColor: 'rgba(243, 156, 18, 0.7)',
data: [45, 62, 55, 78, 58, 65, 80]
}, {
label: 'In-Store Pickups',
backgroundColor: 'rgba(231, 76, 60, 0.3)',
borderColor: 'rgba(231, 76, 60, 0.7)',
data: [33, 40, 32, 51, 44, 48, 55]
}]
};
if (type === 'line') {data.datasets.forEach(d => d.stepped = true);}
} else {
data = {
labels: ['Laptops', 'Monitors', 'Keyboards', 'Mice', 'Webcams'],
datasets: [{
data: [350, 250, 180, 220, 150],
backgroundColor: ['#F39C12', '#E74C3C', '#8E44AD', '#3498DB', '#16A085']
}]
};
}
} else if (isChart3) {
// Data and options for chart3.html (Chart.js implementation)
options.plugins.title.text = `${type.charAt(0).toUpperCase() + type.slice(1)} Chart`;
// Make charts fill more space and be visually appealing
options.aspectRatio = 2.2; // Make charts even taller
options.layout = {
padding: {
top: 5, // Minimal top padding
bottom: 10,
left: 10,
right: 10
}
};
options.plugins.legend.labels = {
padding: 10 // Reduce legend padding
};
options.plugins.title.padding = {
top: 5,
bottom: 10
};
options.elements = {
bar: {
borderWidth: 2,
borderRadius: 4
},
line: {
tension: 0.4
},
point: {
radius: 4,
hoverRadius: 6
}
};
switch (index) {
case 0: // Bar
data = {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [
{
label: 'Licensed Vehicles (thousands)',
data: [3407, 3551, 3269, 3846, 4171, 4387, 4625, 4891, 5156, 5423, 5678, 5945, 6201],
backgroundColor: '#26B99A',
borderColor: '#1e8e7a',
borderWidth: 1
},
{
label: 'SORN (Off Road)',
data: [660, 729, 818, 761, 681, 645, 598, 567, 534, 501, 468, 435, 402],
backgroundColor: '#34495E',
borderColor: '#2c3e50',
borderWidth: 1
}
]
};
break;
case 1: // Grouped Bar
data = {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [
{
label: 'Cloud Services (millions)',
data: [2407, 2851, 3469, 4246, 5057, 5687, 6225, 6891, 7456, 8123, 8678, 9245, 9801],
backgroundColor: '#26B99A',
borderColor: '#1e8e7a',
borderWidth: 1
},
{
label: 'AI/ML Adoption (millions)',
data: [360, 529, 718, 961, 1281, 1645, 2098, 2567, 3034, 3501, 3968, 4435, 4902],
backgroundColor: '#3498DB',
borderColor: '#2980b9',
borderWidth: 1
}
]
};
break;
case 2: // Line
data = {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [
{
label: 'Revenue (millions)',
data: [100, 125, 95, 138, 164, 195, 226, 258, 291, 325, 360, 396, 433],
borderColor: '#26B99A',
backgroundColor: 'rgba(38, 185, 154, 0.1)',
tension: 0.4,
pointBackgroundColor: '#26B99A',
pointBorderColor: '#1e8e7a',
pointRadius: 4
},
{
label: 'Profit (millions)',
data: [25, 35, 18, 42, 58, 72, 89, 108, 127, 147, 168, 190, 213],
borderColor: '#3498DB',
backgroundColor: 'rgba(52, 152, 219, 0.1)',
tension: 0.4,
pointBackgroundColor: '#3498DB',
pointBorderColor: '#2980b9',
pointRadius: 4
},
{
label: 'Expenses (millions)',
data: [75, 90, 77, 96, 106, 123, 137, 150, 164, 178, 192, 206, 220],
borderColor: '#E74C3C',
backgroundColor: 'rgba(231, 76, 60, 0.1)',
tension: 0.4,
pointBackgroundColor: '#E74C3C',
pointBorderColor: '#c0392b',
pointRadius: 4
}
]
};
break;
case 3: // Area
options.plugins.title.text = 'Area Chart';
data = {
labels: ['2018 Q1', '2018 Q2', '2018 Q3', '2018 Q4', '2019 Q1', '2019 Q2', '2019 Q3', '2019 Q4', '2020 Q1', '2020 Q2', '2020 Q3', '2020 Q4', '2021 Q1', '2021 Q2', '2021 Q3', '2021 Q4', '2022 Q1', '2022 Q2', '2022 Q3', '2022 Q4', '2023 Q1', '2023 Q2', '2023 Q3', '2023 Q4', '2024 Q1'],
datasets: [
{
label: 'Mobile Revenue (millions)',
data: [2666, 2778, 4912, 3767, 6810, 7234, 8156, 9023, 8567, 9234, 10456, 11789, 12345, 13567, 14890, 16123, 17456, 18789, 20123, 21456, 22789, 24123, 25456, 26789, 28123],
fill: true,
backgroundColor: 'rgba(38, 185, 154, 0.3)',
borderColor: '#26B99A',
tension: 0.4,
pointBackgroundColor: '#26B99A',
pointBorderColor: '#1e8e7a',
pointRadius: 3
},
{
label: 'Web Revenue (millions)',
data: [1890, 2294, 1969, 3597, 1914, 2456, 2789, 3123, 3456, 3789, 4123, 4456, 4789, 5123, 5456, 5789, 6123, 6456, 6789, 7123, 7456, 7789, 8123, 8456, 8789],
fill: true,
backgroundColor: 'rgba(52, 152, 219, 0.3)',
borderColor: '#3498DB',
tension: 0.4,
pointBackgroundColor: '#3498DB',
pointBorderColor: '#2980b9',
pointRadius: 3
}
]
};
chartType = 'line'; // Area chart is a line chart with fill
break;
case 4: // Donut
data = {
labels: ['Mobile Apps', 'Web Applications', 'Desktop Software', 'IoT Solutions', 'AI Services', 'Cloud Platforms', 'Data Analytics'],
datasets: [
{
data: [32, 28, 18, 12, 7, 5, 3],
backgroundColor: ['#26B99A', '#3498DB', '#E74C3C', '#F39C12', '#9B59B6', '#1ABC9C', '#34495E'],
borderColor: ['#1e8e7a', '#2980b9', '#c0392b', '#d68910', '#7d3c98', '#16a085', '#2c3e50'],
borderWidth: 2,
hoverOffset: 10
}
]
};
break;
case 5: // Line 2
data = {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [
{
label: 'Performance Score (%)',
data: [72, 68, 58, 65, 78, 85, 89, 92, 95, 97, 98, 99, 100],
borderColor: '#3498DB',
backgroundColor: 'rgba(52, 152, 219, 0.1)',
fill: false,
tension: 0.4,
pointBackgroundColor: '#3498DB',
pointBorderColor: '#2980b9',
pointRadius: 5,
pointHoverRadius: 7
},
{
label: 'User Satisfaction (%)',
data: [78, 82, 75, 80, 85, 88, 91, 93, 96, 97, 98, 99, 99],
borderColor: '#26B99A',
backgroundColor: 'rgba(38, 185, 154, 0.1)',
fill: false,
tension: 0.4,
pointBackgroundColor: '#26B99A',
pointBorderColor: '#1e8e7a',
pointRadius: 5,
pointHoverRadius: 7
}
]
};
break;
}
}
new Chart(ctx, { type: chartType, data, options });
});
}
// Network Activity Charts (Chart.js replacement for Flot)
function initializeNetworkCharts() {
// Network Activity Chart 1 (index.html)
if (document.getElementById('chart_plot_01')) {
const netCtx1 = document.getElementById('chart_plot_01');
const canvas1 = document.createElement('canvas');
canvas1.id = 'networkChart1';
canvas1.width = netCtx1.offsetWidth;
canvas1.height = 250;
netCtx1.appendChild(canvas1);
new Chart(canvas1, {
type: 'line',
data: {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [{
label: 'Network Requests (millions)',
data: [128, 148, 140, 119, 186, 227, 290, 360, 430, 480, 550, 620, 700],
backgroundColor: 'rgba(38, 185, 154, 0.3)',
borderColor: 'rgba(38, 185, 154, 0.7)',
borderWidth: 2,
fill: true,
tension: 0.4
}, {
label: 'Data Transfer (TB)',
data: [65, 89, 120, 181, 256, 355, 440, 545, 660, 770, 855, 950, 1050],
backgroundColor: 'rgba(3, 88, 106, 0.3)',
borderColor: 'rgba(3, 88, 106, 0.7)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: 'top'
}
},
scales: {
y: {
beginAtZero: true,
grid: {
color: '#E4E7ED'
}
},
x: {
grid: {
color: '#E4E7ED'
}
}
}
}
});
}
// Network Activity Chart 2 (index2.html)
if (document.getElementById('chart_plot_02')) {
const netCtx2 = document.getElementById('chart_plot_02');
const canvas2 = document.createElement('canvas');
canvas2.id = 'networkChart2';
canvas2.width = netCtx2.offsetWidth;
canvas2.height = 250;
netCtx2.appendChild(canvas2);
new Chart(canvas2, {
type: 'line',
data: {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [{
label: 'Email Campaigns (thousands)',
data: [1120, 1490, 1800, 2200, 2650, 3100, 3580, 4090, 4620, 5180, 5760, 6360, 7000],
backgroundColor: 'rgba(150, 202, 89, 0.3)',
borderColor: 'rgba(150, 202, 89, 0.7)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: 'top'
}
},
scales: {
y: {
beginAtZero: true,
grid: {
color: '#E4E7ED'
}
},
x: {
grid: {
color: '#E4E7ED'
}
}
}
}
});
}
// Network Activity Chart 3 (index3.html)
if (document.getElementById('chart_plot_03')) {
const netCtx3 = document.getElementById('chart_plot_03');
const canvas3 = document.createElement('canvas');
canvas3.id = 'networkChart3';
canvas3.width = netCtx3.offsetWidth;
canvas3.height = 250;
netCtx3.appendChild(canvas3);
new Chart(canvas3, {
type: 'line',
data: {
labels: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030'],
datasets: [{
label: 'User Registrations (thousands)',
data: [450, 650, 580, 720, 890, 1050, 1230, 1420, 1620, 1830, 2050, 2280, 2520],
backgroundColor: 'rgba(150, 202, 89, 0.3)',
borderColor: 'rgba(150, 202, 89, 0.7)',
borderWidth: 2,
fill: true,
tension: 0.4
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
plugins: {
legend: {
display: true,
position: 'top'
}
},
scales: {
y: {
beginAtZero: true,
grid: {
color: '#E4E7ED'
}
},
x: {
grid: {
color: '#E4E7ED'
}
}
}
}
});
}
}
// ECharts initialization function
function initializeECharts() {
const echarts = window.echarts || globalThis.echarts;
if (typeof echarts === 'undefined') {
console.warn('⚠️ ECharts library not available');
return;
}
// Check if there are any ECharts elements on the page
const echartElements = document.querySelectorAll('[id^="echart"]');
if (echartElements.length === 0) {
return;
}
try {
// 1. Bar Chart (mainb)
if (document.getElementById('mainb')) {
const mainbChart = echarts.init(document.getElementById('mainb'));
const mainbOption = {
title: {
text: 'Revenue by Technology Stack',
left: 'center',
textStyle: { fontSize: 16 }
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
legend: {
data: ['2023', '2024', '2025'],
top: 30
},
xAxis: {
type: 'category',
data: ['React', 'Vue.js', 'Angular', 'Node.js', 'Python', 'Java', 'Go', '.NET']
},
yAxis: {
type: 'value',
name: 'Revenue (millions)'
},
series: [
{
name: '2023',
type: 'bar',
data: [120, 90, 85, 110, 95, 105, 70, 80],
itemStyle: { color: '#26B99A' }
},
{
name: '2024',
type: 'bar',
data: [140, 105, 95, 130, 115, 125, 85, 95],
itemStyle: { color: '#3498DB' }
},
{
name: '2025',
type: 'bar',
data: [165, 125, 110, 155, 140, 150, 105, 115],
itemStyle: { color: '#E74C3C' }
}
]
};
mainbChart.setOption(mainbOption);
}
// 2. Mini Pie Chart (echart_mini_pie)
if (document.getElementById('echart_mini_pie')) {
const miniPieChart = echarts.init(document.getElementById('echart_mini_pie'));
const miniPieOption = {
title: {
text: 'User Devices',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c} ({d}%)'
},
series: [
{
name: 'Devices',
type: 'pie',
radius: '60%',
data: [
{ value: 45, name: 'Mobile', itemStyle: { color: '#26B99A' } },
{ value: 35, name: 'Desktop', itemStyle: { color: '#3498DB' } },
{ value: 20, name: 'Tablet', itemStyle: { color: '#E74C3C' } }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
miniPieChart.setOption(miniPieOption);
}
// 3. Regular Pie Chart (echart_pie)
if (document.getElementById('echart_pie')) {
const pieChart = echarts.init(document.getElementById('echart_pie'));
const pieOption = {
title: {
text: 'Market Share 2024',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b}: {c}% ({d}%)'
},
legend: {
orient: 'vertical',
left: 'left',
data: ['React', 'Vue', 'Angular', 'Svelte', 'Others']
},
series: [
{
name: 'Framework Usage',
type: 'pie',
radius: '50%',
data: [
{ value: 42, name: 'React', itemStyle: { color: '#61DAFB' } },
{ value: 28, name: 'Vue', itemStyle: { color: '#4FC08D' } },
{ value: 18, name: 'Angular', itemStyle: { color: '#DD0031' } },
{ value: 8, name: 'Svelte', itemStyle: { color: '#FF3E00' } },
{ value: 4, name: 'Others', itemStyle: { color: '#34495E' } }
]
}
]
};
pieChart.setOption(pieOption);
}
// 4. Pie Area Chart (echart_pie2)
if (document.getElementById('echart_pie2')) {
const pie2Chart = echarts.init(document.getElementById('echart_pie2'));
const pie2Option = {
title: {
text: 'Cloud Services',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'item'
},
series: [
{
name: 'Cloud Services',
type: 'pie',
radius: ['40%', '70%'],
avoidLabelOverlap: false,
data: [
{ value: 35, name: 'AWS', itemStyle: { color: '#FF9900' } },
{ value: 28, name: 'Azure', itemStyle: { color: '#0078D4' } },
{ value: 22, name: 'Google Cloud', itemStyle: { color: '#4285F4' } },
{ value: 10, name: 'Digital Ocean', itemStyle: { color: '#0080FF' } },
{ value: 5, name: 'Others', itemStyle: { color: '#34495E' } }
],
label: {
show: false,
position: 'center'
},
emphasis: {
label: {
show: true,
fontSize: '16',
fontWeight: 'bold'
}
},
labelLine: {
show: false
}
}
]
};
pie2Chart.setOption(pie2Option);
}
// 5. Donut Chart (echart_donut)
if (document.getElementById('echart_donut')) {
const donutChart = echarts.init(document.getElementById('echart_donut'));
const donutOption = {
title: {
text: 'Revenue Sources',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'item'
},
series: [
{
name: 'Revenue',
type: 'pie',
radius: ['40%', '70%'],
data: [
{ value: 45, name: 'Subscriptions', itemStyle: { color: '#26B99A' } },
{ value: 30, name: 'Consulting', itemStyle: { color: '#3498DB' } },
{ value: 15, name: 'Training', itemStyle: { color: '#F39C12' } },
{ value: 10, name: 'Support', itemStyle: { color: '#9B59B6' } }
],
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
donutChart.setOption(donutOption);
}
// 6. Scatter Chart (echart_scatter)
if (document.getElementById('echart_scatter')) {
const scatterChart = echarts.init(document.getElementById('echart_scatter'));
const scatterOption = {
title: {
text: 'Performance vs Experience',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'item',
formatter: function (params) {
return `${params.seriesName}<br/>Performance: ${params.value[0]}<br/>Experience: ${params.value[1]} years<br/>Salary: $${params.value[2]}k`;
}
},
xAxis: {
type: 'value',
name: 'Performance Score',
min: 60,
max: 100
},
yAxis: {
type: 'value',
name: 'Years of Experience'
},
series: [
{
name: 'Developers',
type: 'scatter',
data: [
[85, 3, 75], [92, 5, 95], [78, 2, 65], [88, 4, 85], [95, 7, 120],
[82, 3, 70], [90, 6, 110], [75, 1, 55], [87, 4, 80], [93, 8, 135],
[80, 2, 60], [89, 5, 90], [91, 6, 105], [86, 3, 75], [94, 9, 150]
],
symbolSize: function (data) {
return Math.sqrt(data[2]) * 2;
},
itemStyle: {
color: '#26B99A',
opacity: 0.7
}
}
]
};
scatterChart.setOption(scatterOption);
}
// 7. Line Chart (echart_line)
if (document.getElementById('echart_line')) {
const lineChart = echarts.init(document.getElementById('echart_line'));
const lineOption = {
title: {
text: 'Growth Trends 2018-2030',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'axis'
},
legend: {
data: ['Users', 'Revenue', 'Profit'],
top: 30
},
xAxis: {
type: 'category',
data: ['2018', '2019', '2020', '2021', '2022', '2023', '2024', '2025', '2026', '2027', '2028', '2029', '2030']
},
yAxis: {
type: 'value'
},
series: [
{
name: 'Users',
type: 'line',
data: [1200, 1450, 1300, 1680, 1950, 2200, 2500, 2850, 3200, 3600, 4000, 4450, 4900],
smooth: true,
itemStyle: { color: '#26B99A' }
},
{
name: 'Revenue',
type: 'line',
data: [100, 125, 95, 138, 164, 195, 226, 258, 291, 325, 360, 396, 433],
smooth: true,
itemStyle: { color: '#3498DB' }
},
{
name: 'Profit',
type: 'line',
data: [25, 35, 18, 42, 58, 72, 89, 108, 127, 147, 168, 190, 213],
smooth: true,
itemStyle: { color: '#E74C3C' }
}
]
};
lineChart.setOption(lineOption);
}
// 8. Horizontal Bar Chart (echart_bar_horizontal)
if (document.getElementById('echart_bar_horizontal')) {
const hBarChart = echarts.init(document.getElementById('echart_bar_horizontal'));
const hBarOption = {
title: {
text: 'Top Programming Languages',
left: 'center',
textStyle: { fontSize: 14 }
},
tooltip: {
trigger: 'axis',
axisPointer: { type: 'shadow' }
},
yAxis: {
type: 'category',
data: ['JavaScript', 'Python', 'Java', 'TypeScript', 'C#', 'Go', 'Rust', 'Swift']
},
xAxis: {
type: 'value',
name: 'Popularity %'
},
series: [
{
name: 'Popularity',
type: 'bar',
data: [68, 62, 58, 45, 38, 28, 18, 15],
itemStyle: {
color: function(params) {
const colors = ['#26B99A', '#3498DB', '#E74C3C', '#F39C12', '#9B59B6', '#1ABC9C', '#E67E22', '#34495E'];
return colors[params.dataIndex];
}
}
}
]
};
hBarChart.setOption(hBarOption);
}
// 9. World Map (echart_world_map) - Interactive scatter plot with geographic visualization
if (document.getElementById('echart_world_map')) {
const worldMapChart = echarts.init(document.getElementById('echart_world_map'));
// Global user distribution data with coordinates
const globalData = [
{name: 'United States', value: [2300, -95.7129, 37.0902], users: 2300},
{name: 'China', value: [1800, 104.1954, 35.8617], users: 1800},
{name: 'Japan', value: [1200, 138.2529, 36.2048], users: 1200},
{name: 'Germany', value: [1000, 10.4515, 51.1657], users: 1000},
{name: 'United Kingdom', value: [800, -3.4360, 55.3781], users: 800},
{name: 'France', value: [750, 2.2137, 46.2276], users: 750},
{name: 'India', value: [700, 78.9629, 20.5937], users: 700},
{name: 'Canada', value: [650, -106.3468, 56.1304], users: 650},
{name: 'Brazil', value: [600, -51.9253, -14.2350], users: 600},
{name: 'Australia', value: [550, 133.7751, -25.2744], users: 550},
{name: 'South Korea', value: [500, 127.7669, 35.9078], users: 500},
{name: 'Italy', value: [450, 12.5674, 41.8719], users: 450},
{name: 'Spain', value: [400, -3.7492, 40.4637], users: 400},
{name: 'Netherlands', value: [350, 5.2913, 52.1326], users: 350},
{name: 'Sweden', value: [300, 18.6435, 60.1282], users: 300},
{name: 'Russia', value: [275, 105.3188, 61.5240], users: 275},
{name: 'Mexico', value: [250, -102.5528, 23.6345], users: 250},
{name: 'Switzerland', value: [225, 8.2275, 46.8182], users: 225},
{name: 'Singapore', value: [200, 103.8198, 1.3521], users: 200},
{name: 'Norway', value: [175, 8.4689, 60.4720], users: 175}
];
const worldMapOption = {
backgroundColor: '#f5f5f5',
title: {
text: 'Global User Distribution',
left: 'center',
top: 20,
textStyle: {
fontSize: 18,
color: '#333',
fontWeight: 'bold'
}
},
tooltip: {
trigger: 'item',
formatter: function(params) {
if (params.data) {
return `<div style="padding: 8px;">
<div style="font-weight: bold; color: #333; margin-bottom: 4px;">${params.data.name}</div>
<div style="color: #666;">Active Users: <span style="color: #26B99A; font-weight: bold;">${params.data.users}k</span></div>
<div style="color: #999; font-size: 11px;">Coordinates: ${params.data.value[1].toFixed(2)}°, ${params.data.value[2].toFixed(2)}°</div>
</div>`;
}
return params.name;
},
backgroundColor: 'rgba(255, 255, 255, 0.95)',
borderColor: '#ccc',
borderWidth: 1,
textStyle: {
color: '#333'
}
},
legend: {
data: ['Global Users'],
left: 'left',
top: 60,
textStyle: {
color: '#333'
}