// All imports for the Marketing Dashboard import ApexCharts from '../thirdparty/apexchartsWrapper.js'; import { SmartTables } from '../optional/smartTables/smartTables.bundle.js'; import { PeityAPI } from './../thirdparty/peity.es6.js'; document.addEventListener('DOMContentLoaded', function () { 'use strict'; /***************************************************************/ /* Marketing Performance Chart */ /***************************************************************/ const marketingPerformanceChart = new ApexCharts(document.querySelector('#marketing-profits-chart'), { chart: { height: 350, type: 'line', stacked: false, toolbar: { show: false }, zoom: { enabled: false }, animations: { enabled: true, easing: 'easeinout', speed: 800 }, parentHeightOffset: 0, fontFamily: 'inherit' }, colors: [ window.colorMap.primary[300].hex, window.colorMap.warning[300].hex, window.colorMap.success[300].hex ], stroke: { width: [0, 3, 3], curve: 'smooth' }, fill: { type: ['gradient', 'solid', 'solid'], gradient: { shade: 'light', type: 'vertical', shadeIntensity: 0.5, gradientToColors: [window.colorMap.primary[200].hex], inverseColors: false, opacityFrom: 1, opacityTo: 0.3 } }, grid: { show: true, borderColor: window.colorMap.bootstrapVars.bodyColor.rgba(0.08), strokeDashArray: 5, position: 'back', padding: { left: -5, right: 0, top: -20, bottom: -5 }, xaxis: { lines: { show: false } }, yaxis: { lines: { show: true } } }, plotOptions: { bar: { columnWidth: '50%', endingShape: 'rounded', borderRadius: 5, } }, dataLabels: { enabled: false }, markers: { size: 4, strokeWidth: 0, hover: { size: 6 } }, xaxis: { type: 'category', categories: ['Jan 2013', 'Apr 2013', 'Jul 2013', 'Oct 2013', 'Jan 2014', 'Apr 2014', 'Jul 2014', 'Oct 2014', 'Jan 2015', 'Apr 2015', 'Jul 2015', 'Oct 2015', 'Jan 2016', 'Apr 2016'], labels: { style: { colors: window.colorMap.bootstrapVars.bodyColor.rgba(0.7), fontSize: '10px' } }, axisBorder: { show: false }, axisTicks: { show: false } }, yaxis: { min: 0, max: 1200, tickAmount: 6, labels: { style: { colors: window.colorMap.bootstrapVars.bodyColor.rgba(0.7), fontSize: '10px' }, formatter: function (val) { return val.toFixed(0); } } }, tooltip: { shared: true, intersect: false, y: { formatter: function (y) { if (typeof y !== "undefined") { return y.toFixed(0); } return y; } } }, legend: { show: false }, series: [ { name: 'Target Profit', type: 'column', data: [150, 650, 200, 650, 800, 1050, 350, 750, 500, 250, 650, 250, 350, 350] }, { name: 'Actual Profit', type: 'line', data: [50, 70, 90, 80, 300, 950, 800, 700, 650, 30, 100, 80, 30, 30] }, { name: 'User Signups', type: 'line', data: [650, 430, 800, 350, 450, 450, 450, 470, 250, 830, 650, 250, 350, 350] } ] }); marketingPerformanceChart.render(); /***************************************************************/ /* Returning Target Chart */ /***************************************************************/ const returningTargetChart = new ApexCharts(document.querySelector('#returning-target-chart'), { chart: { height: 350, type: 'area', stacked: false, toolbar: { show: false }, zoom: { enabled: false }, animations: { enabled: true, easing: 'easeinout', speed: 800 }, parentHeightOffset: 0, fontFamily: 'inherit' }, colors: [ window.colorMap.success[200].hex, // New Customer (darker blue) window.colorMap.primary[200].hex, // Returning Customer (lighter teal) ], stroke: { width: 2, curve: 'straight' }, fill: { type: 'gradient', gradient: { shade: 'light', type: 'vertical', shadeIntensity: 0.4, opacityFrom: 0.8, opacityTo: 0.1, stops: [0, 90, 100] } }, grid: { show: true, borderColor: window.colorMap.bootstrapVars.bodyColor.rgba(0.07), strokeDashArray: 0, position: 'back', padding: { left: 5 }, xaxis: { lines: { show: false } }, yaxis: { lines: { show: false } } }, dataLabels: { enabled: false }, markers: { size: 4, strokeWidth: 0, hover: { size: 6 } }, xaxis: { type: 'numeric', categories: [0, 100, 200, 300, 400, 500, 600, 700], tickAmount: 8, labels: { style: { colors: window.colorMap.bootstrapVars.bodyColor.rgba(0.7), fontSize: '10px' } }, axisBorder: { show: false }, axisTicks: { show: false } }, yaxis: { show: false, max: 180, tickAmount: 10, }, tooltip: { shared: true, intersect: false, y: { formatter: function (y) { if (typeof y !== "undefined") { return y.toFixed(0); } return y; } } }, legend: { show: true, position: 'top', horizontalAlign: 'left', fontSize: '12px', fontFamily: 'inherit', offsetY: 10, offsetX: -35, itemMargin: { horizontal: 10, vertical: 0 }, markers: { width: 8, height: 8, radius: 0, } }, series: [ { name: 'Returning Customer', data: [140, 120, 95, 80, 60, 95, 70, 50] }, { name: 'New Customer', data: [110, 90, 70, 55, 50, 75, 50, 30] }, ] }); returningTargetChart.render(); /***************************************************************/ /* Efficiency Metrics Chart */ /***************************************************************/ const efficiencyMetricsChart = new ApexCharts(document.querySelector('#efficiency-metrics-chart'), { chart: { height: 259, type: 'area', stacked: false, toolbar: { show: false }, zoom: { enabled: false }, animations: { enabled: true, easing: 'easeinout', speed: 800 }, parentHeightOffset: 0, fontFamily: 'inherit' }, colors: [ window.colorMap.primary[300].hex, // Sessions (blue) window.colorMap.success[300].hex, // New Sessions (teal) window.colorMap.warning[300].hex, // Bounce Rate (yellow) window.colorMap.info[300].hex // Clickthrough (cyan) ], stroke: { width: 2, curve: 'straight' }, fill: { type: 'gradient', gradient: { shade: 'light', type: 'vertical', shadeIntensity: 0.4, opacityFrom: 0.8, opacityTo: 0.1, stops: [0, 90, 100] } }, grid: { show: true, borderColor: window.colorMap.bootstrapVars.bodyColor.rgba(0.08), strokeDashArray: 5, position: 'back', padding: { top: -25, }, xaxis: { lines: { show: true } }, yaxis: { lines: { show: true } } }, dataLabels: { enabled: false }, markers: { size: 3, strokeWidth: 0, hover: { size: 5 } }, xaxis: { type: 'category', categories: ['2am', '3am', '4am', '5am', '6am', '7am', '8am', '9am', '1pm', '2pm', '3pm', '4pm'], labels: { style: { colors: window.colorMap.bootstrapVars.bodyColor.rgba(0.7), fontSize: '10px' } }, axisBorder: { show: false }, axisTicks: { show: false } }, yaxis: { min: 0, max: 300000, tickAmount: 3, labels: { style: { colors: window.colorMap.bootstrapVars.bodyColor.rgba(0.7), fontSize: '10px' }, formatter: function (val) { if (val >= 1000) { return (val / 1000) + 'K'; } return val; } } }, tooltip: { shared: true, intersect: false, y: { formatter: function (y) { if (typeof y !== "undefined") { if (y >= 1000) { return Math.round(y).toLocaleString(); } return y.toFixed(0); } return y; } } }, legend: { show: false }, series: [ { name: 'Sessions', data: [20000, 25000, 40000, 50000, 60000, 150000, 190000, 180000, 200000, 100000, 100000, 90000] }, { name: 'New Sessions', data: [15000, 30000, 35000, 60000, 80000, 110000, 230000, 200000, 180000, 230000, 160000, 100000] }, { name: 'Bounce Rate', data: [10000, 15000, 20000, 25000, 30000, 40000, 60000, 80000, 100000, 120000, 140000, 160000] }, { name: 'Clickthrough', data: [5000, 10000, 15000, 20000, 25000, 30000, 40000, 50000, 60000, 70000, 80000, 90000] } ] }); efficiencyMetricsChart.render(); /***************************************************************/ /* Peity Charts */ /***************************************************************/ // Global default settings for charts const defaults = { // Default background color for donut and pie charts (replaces the gray) donutBackground: 'var(--bs-border-color)', // Light purple background instead of gray pieBackground: 'var(--bs-border-color)' // Same for pie charts }; // Helper to create peity charts (similar to jQuery plugin style) function createPeity(selector, type, customOptions = {}) { document.querySelectorAll(selector).forEach(element => { // Parse data-peity attribute for options let options = { ...customOptions }; const dataAttr = element.getAttribute('data-peity'); if (dataAttr) { try { options = { ...options, ...JSON.parse(dataAttr) }; } catch (e) { console.warn('Invalid data-peity format for', selector); } } // Apply defaults for donut and pie charts background colors if (type === 'donut' || type === 'pie') { // If fill is not defined or is an empty array, set default colors if (!options.fill || options.fill.length === 0) { options.fill = type === 'donut' ? ['var(--primary-500)', defaults.donutBackground] : ['var(--primary-500)', defaults.pieBackground]; } // If fill is defined but doesn't include a background color (for fractions like "1/4") else if (Array.isArray(options.fill) && options.fill.length === 1) { options.fill.push(type === 'donut' ? defaults.donutBackground : defaults.pieBackground); } // If data contains multiple values (e.g., "10,4,4,6"), don't add background } PeityAPI.create(element, type, options); }); } try { // Simple chart initializations with default settings createPeity('.peity-pie', 'pie'); createPeity('.peity-donut', 'donut'); createPeity('.peity-line', 'line'); createPeity('.peity-bar', 'bar'); // Updating chart with animation const updatingChart = document.querySelector('.updating-chart'); if (updatingChart) { const values = updatingChart.textContent.split(',').map(Number); const chart = PeityAPI.create(updatingChart, 'line', { width: 200, height: 40, stroke: 'var(--info-500)', fill: 'var(--info-200)', min: 0, max: 10 }); setInterval(function () { values.shift(); values.push(Math.floor(Math.random() * 10)); updatingChart.textContent = values.join(','); chart.draw(); }, 500); } // Bar charts with negative values (red/green coloring) document.querySelectorAll('.bar-negative').forEach(element => { const values = element.textContent.split(',').map(Number); PeityAPI.create(element, 'bar', { height: 40, width: 110, fill: values.map(value => value > 0 ? 'var(--success-500)' : 'var(--danger-500)') }); }); // Bar charts with color transitions document.querySelectorAll('.bar-transition').forEach(element => { const values = element.textContent.split(',').map(Number); PeityAPI.create(element, 'bar', { height: 40, width: 110, fill: values.map((_, i, all) => { const g = parseInt((i / all.length) * 255); return `rgb(255, ${g}, ${g})`; }) }); }); // Process all remaining elements with data-peity attribute document.querySelectorAll('[data-peity]').forEach(element => { // Skip elements already handled by specific selectors if (element.classList.contains('peity-pie') || element.classList.contains('peity-donut') || element.classList.contains('peity-line') || element.classList.contains('peity-bar') || element.classList.contains('updating-chart') || element.classList.contains('bar-negative') || element.classList.contains('bar-transition')) { return; } // Auto-detect chart type based on content const content = element.textContent.trim(); let type; if (content.includes('/')) { type = 'donut'; // Fraction data is best for donut } else if (content.includes(',')) { // If it has commas, it's likely a series const hasNegative = content.split(',').some(val => parseFloat(val) < 0); type = hasNegative ? 'bar' : 'line'; // Bars handle negative values better visually } else { type = 'pie'; // Default fallback } // Get options from data attribute let options = {}; const dataAttr = element.getAttribute('data-peity'); if (dataAttr) { try { options = JSON.parse(dataAttr); } catch (e) { console.warn('Invalid data-peity format for element', element); } } // Apply global background color for donut/pie charts if ((type === 'donut' || type === 'pie') && content.includes('/')) { // For fraction notation (e.g. "1/4"), make sure we have a background color if (!options.fill || !Array.isArray(options.fill) || options.fill.length < 2) { options.fill = options.fill || []; // If we have one color already, keep it and add the background if (options.fill.length === 1) { options.fill.push(type === 'donut' ? defaults.donutBackground : defaults.pieBackground); } else { // No colors defined yet, set defaults options.fill = [ type === 'donut' ? 'var(--primary-500)' : 'var(--success-500)', type === 'donut' ? defaults.donutBackground : defaults.pieBackground ]; } } } // Create chart PeityAPI.create(element, type, options); }); } catch (error) { console.error('Error initializing Peity charts:', error); } /***************************************************************/ /* Sales Performance Table */ /***************************************************************/ // Initialize SmartTables with the table ID and options const table = new SmartTables('sales-performance-table', { data: { type: "json", source: "json/MOCK_DATA_SALES_PERF.json", columns: [ { data: "CustomerID", title: "ID" }, { data: "Name", title: "Full Name", render: function (data) { // Assuming data is in format "LastName, FirstName" if (!data) return ''; const nameParts = data.split(','); if (nameParts.length === 2) { const lastName = nameParts[0].trim(); const firstName = nameParts[1].trim(); return firstName + ' ' + lastName; } return data; } }, { data: "PurchaseDate", title: "Purchase Date", render: function (data) { if (!data) return ''; try { const date = new Date(data); if (isNaN(date.getTime())) return data; const day = date.getDate().toString().padStart(2, '0'); const month = (date.getMonth() + 1).toString().padStart(2, '0'); const year = date.getFullYear(); return `${day}-${month}-${year}`; } catch (e) { return data; } } }, { data: "CustomerCVV", title: "CVV", render: function (data) { if (!data) return ''; const cvvId = 'cvv-' + Math.random().toString(36).substring(2, 10); return `