Accounting
Highcharts.setOptions({ chart: { styledMode: true }, lang: { locale: 'en-us' } }); const currentMonth = Date.UTC(2023, 9); const revTarget = 105; const costTarget = 89; const currentYear = new Date(currentMonth).getFullYear(); const commonGaugeOptions = { chart: { type: 'gauge', className: 'highcharts-gauge-chart', marginBottom: 0 }, pane: { startAngle: -90, endAngle: 89.9, background: null, center: ['50%', '64%'], size: '110%' }, yAxis: { visible: true, min: 0, minorTickInterval: null, labels: { distance: 12, allowOverlap: true } }, tooltip: { enabled: false }, plotOptions: { series: { dial: { baseWidth: 12, baseLength: 0, rearLength: 0 }, pivot: { radius: 5 }, dataLabels: { format: '${y}M' } } } }; const commonColumnOptions = { accessibility: { point: { valuePrefix: '$' } }, chart: { type: 'column', className: 'highcharts-column-chart' }, credits: { enabled: false }, xAxis: { type: 'datetime', min: Date.UTC(currentYear), max: Date.UTC(currentYear, 11) }, yAxis: { tickInterval: 2e6 }, series: [{ name: 'Budget', id: 'budget-series', colorIndex: 1 }], tooltip: { format: `<span style="font-size: 10px">{x:%B %Y}</span><br> <span class="highcharts-color-{colorIndex}">●</span> {series.name}: {(divide y 1000000):.2f}M ` } }; const board = Dashboards.board('container', { dataPool: { connectors: [{ type: 'CSV', id: 'data', options: { csv: document.getElementById('csv').innerHTML, dataModifier: { type: 'Math', columnFormulas: [{ column: 'Result', // I formula: 'D1-C1' }, { column: 'AccResult', // J formula: 'SUM(I$1:I1)' }, { column: 'CostPredA', // K formula: 'AVERAGE(E1,G1)' }, { column: 'RevPredA', // L formula: 'AVERAGE(F1, H1)' }, { column: 'AccResPredP', // M formula: 'J1+SUM(F$1:F1)-SUM(E$1:E1)' }, { column: 'AccResPredO', // N formula: 'J1+SUM(H$1:H1)-SUM(G$1:G1)' }, { column: 'ResPredA', // O formula: 'L1-K1' }, { column: 'AccResPredA', // P formula: 'J1+SUM(O$1:O1)' }] } } }] }, gui: { layouts: [{ id: 'layout-1', rows: [{ cells: [{ id: 'kpi-layout-cell', layout: { rows: [{ cells: [{ id: 'rev-chart-kpi' }, { id: 'rev-forecast-kpi' }, { id: 'rev-goal-forecast-kpi' }] }, { cells: [{ id: 'cost-chart-kpi' }, { id: 'cost-forecast-kpi' }, { id: 'cost-goal-forecast-kpi' }] }, { cells: [{ id: 'res-chart-kpi' }, { id: 'res-forecast-kpi' }, { id: 'res-goal-forecast-kpi' }] }] } }, { id: 'stock-cell' }] }, { cells: [{ id: 'rev-chart' }, { id: 'cost-chart' }] }] }] }, components: [{ renderTo: 'rev-chart-kpi', type: 'KPI', chartOptions: Highcharts.merge(commonGaugeOptions, { title: { text: 'Revenue (YTD)' }, accessibility: { point: { valueDescriptionFormat: 'YTD revenue is {value} million $.' } }, yAxis: { max: 102, tickPositions: [73, 83, 92, 102], plotBands: [{ from: 0, to: 73, className: 'null-band' }, { from: 73, to: 83, className: 'warn-band' }, { from: 83, to: 92, className: 'opt-band' }, { from: 92, to: 102, className: 'high-band' }] } }) }, { renderTo: 'rev-forecast-kpi', type: 'KPI', title: `Revenue forecast for ${currentYear}:`, valueFormat: '${value}M' }, { renderTo: 'rev-goal-forecast-kpi', type: 'KPI', title: 'Revenue goal will be achieved at:', valueFormat: '{value}%' }, { renderTo: 'cost-chart-kpi', type: 'KPI', chartOptions: Highcharts.merge(commonGaugeOptions, { title: { text: 'Cost (YTD)' }, accessibility: { point: { valueDescriptionFormat: 'YTD cost is {value} million $.' } }, yAxis: { max: 86, tickPositions: [61, 70, 78, 86], plotBands: [{ from: 0, to: 61, className: 'null-band' }, { from: 61, to: 70, className: 'warn-band' }, { from: 70, to: 78, className: 'opt-band' }, { from: 78, to: 86, className: 'warn-band' }] } }) }, { renderTo: 'cost-forecast-kpi', type: 'KPI', title: `Cost forecast for ${currentYear}:`, valueFormat: '${value}M' }, { renderTo: 'cost-goal-forecast-kpi', type: 'KPI', title: 'Cost goal will be achieved at:', valueFormat: '{value}%' }, { renderTo: 'res-chart-kpi', type: 'KPI', chartOptions: Highcharts.merge(commonGaugeOptions, { title: { text: 'Result (YTD)' }, accessibility: { point: { valueDescriptionFormat: 'YTD result is {value} million $.' } }, yAxis: { max: 21, tickPositions: [6, 10, 16, 21], plotBands: [{ from: 0, to: 6, className: 'null-band' }, { from: 6, to: 10, className: 'warn-band' }, { from: 10, to: 16, className: 'opt-band' }, { from: 16, to: 21, className: 'high-band' }] } }) }, { renderTo: 'res-forecast-kpi', type: 'KPI', title: `Result forecast for ${currentYear}:`, valueFormat: '${value}M' }, { renderTo: 'res-goal-forecast-kpi', type: 'KPI', title: 'Result goal will be achieved at:', valueFormat: '{value}%' }, { renderTo: 'rev-chart', type: 'Highcharts', connector: { id: 'data', columnAssignment: [{ seriesId: 'budget-series', data: ['Date', 'Budget'] }, { seriesId: 'Revenue', data: ['Date', 'Revenue'] }] }, sync: { highlight: true }, chartOptions: { ...commonColumnOptions, title: { text: 'Revenue' } } }, { renderTo: 'cost-chart', type: 'Highcharts', connector: { id: 'data', columnAssignment: [{ seriesId: 'budget-series', data: ['Date', 'Budget'] }, { seriesId: 'Cost', data: ['Date', 'Cost'] }] }, sync: { highlight: true }, chartOptions: { ...commonColumnOptions, title: { text: 'Cost' } } }, { renderTo: 'stock-cell', type: 'Highcharts', chartConstructor: 'stockChart', connector: { id: 'data', columnAssignment: [{ seriesId: 'result', data: ['Date', 'AccResPredA'] }, { seriesId: 'pessimistically', data: ['Date', 'AccResPredP'] }, { seriesId: 'optimistically', data: ['Date', 'AccResPredO'] }] }, sync: { highlight: true }, tooltip: { useHTML: true }, chartOptions: { chart: { className: 'highcharts-stock-chart' }, title: { text: 'Accumulated Result with Forecast' }, subtitle: { text: 'From January 2019 to December 2024' }, accessibility: { point: { valuePrefix: '$' } }, xAxis: { plotLines: [{ value: currentMonth, label: { text: 'current month' } }, { value: Date.UTC(currentYear, 0), className: 'year-plotline' }, { value: Date.UTC(currentYear, 11), className: 'year-plotline' }] }, rangeSelector: { buttons: [{ type: 'month', count: 6, text: '6m', title: 'View 6 months' }, { type: 'year', count: 1, text: '1y', title: 'View 1 year' }, { type: 'year', count: 3, text: '3y', title: 'View 3 years' }, { type: 'ytd', text: 'YTD', title: 'View year to date' }, { type: 'all', text: 'All', title: 'View all' }], selected: 2 }, tooltip: { formatter: function () { const { x, points } = this; const format = v => '$' + (v / 1e6).toFixed(2) + 'M'; const color = (s, color) => ` <span class="highcharts-color-${color}">${s}</span> `; const date = Highcharts.dateFormat('%B %Y', x); if (x <= currentMonth) { return `<span style="font-size: 10px">${date}</span><br> ${color('●', 0)} Result: ${color(format(points[0].y), 0)} `; } return `<span style="font-size: 10px"> Forecast for ${date} </span><br> ${color('➚', 2)} Optimistically: ${color(format(points[2].y), 2)}<br> ${color('●', 0)} Average: ${color(format(points[0].y), 0)}<br> ${color('➘', 1)} Pessimistically: ${color(format(points[1].y), 1)} `; } }, credits: { enabled: false }, series: [{ name: 'Result', id: 'result', zIndex: 2 }, { name: 'Pessimistically', id: 'pessimistically' }, { name: 'Optimistically', id: 'optimistically' }] } }] }, true); board.then(res => { const table = res.dataPool.connectors.data.table.modified.columns; const revKPI = res.mountedComponents[0].component; const revForecast = res.mountedComponents[1].component; const revGoalForecast = res.mountedComponents[2].component; const costKPI = res.mountedComponents[3].component; const costForecast = res.mountedComponents[4].component; const costGoalForecast = res.mountedComponents[5].component; const resKPI = res.mountedComponents[6].component; const resForecast = res.mountedComponents[7].component; const resGoalForecast = res.mountedComponents[8].component; const firstRowID = table.Date.findIndex(d => d === Date.UTC(currentYear)); const lastRowID = table.Date.findIndex(d => d === currentMonth); const forecastRowID = table.Date.findIndex(d => d === Date.UTC(currentYear, 11)); let revYTD = 0, costYTD = 0; for (let i = firstRowID; i <= lastRowID; i++) { revYTD += table.Revenue[i] / 1e6; costYTD += table.Cost[i] / 1e6; } let revYearlyForecast = revYTD, costYearlyForecast = costYTD; for (let i = lastRowID + 1; i <= forecastRowID; i++) { revYearlyForecast += table.RevPredA[i] / 1e6; costYearlyForecast += table.CostPredA[i] / 1e6; } revKPI.update({ caption: `${Math.round(revYTD / revTarget * 100)}% of annual target` }); revKPI.chart.addSeries({ data: [revYTD] }); costKPI.update({ caption: `${Math.round(costYTD / costTarget * 100)}% of annual target` }); costKPI.chart.addSeries({ data: [costYTD] }); resKPI.update({ caption: `${Math.round( (revYTD - costYTD) / (revTarget - costTarget) * 100 )}% of annual target` }); resKPI.chart.addSeries({ data: [Math.round((revYTD - costYTD) * 10) / 10] }); revForecast.update({ value: revYearlyForecast.toFixed(2) }); revGoalForecast.update({ value: Math.round(revYearlyForecast / revTarget * 100) }); costForecast.update({ value: costYearlyForecast.toFixed(2) }); costGoalForecast.update({ value: Math.round(costYearlyForecast / costTarget * 100) }); resForecast.update({ value: (revYearlyForecast - costYearlyForecast).toFixed(2) }); resGoalForecast.update({ value: Math.round(( revYearlyForecast - costYearlyForecast ) / (revTarget - costTarget) * 100) }); });
DashboardsAdvanced
Install with NPM
The official Highcharts Dashboards NPM package comes with support for CommonJS. Read more about how to install Highcharts Dashboards with NPM.
npm install @highcharts/dashboards
See more installation optionsDownload our library
The zip archive contains Javascript files and examples. Unzip the zip package and open index.html in your browser to see the examples.
DownloadBuy a license
You can download and try out all Highcharts products for free. Once your project/product is ready for launch, purchase a commercial license.
See License Pricing