Chart (Chart.js)

Simple yet flexible JavaScript charting for designers & developers.

Chart.js documentation share-external-link-1

How to use

Import helper file to access all Dashly helper functions.

import * as helper from './helpers';

Define a cssPrefix variable to be able to use CSS variables within JavaScript

const cssPrefix = helper.getCSSVariable('--prefix');

Import chart vendor file which imports all the necessary files from Chart.js and contains the default settings.

import(/* webpackChunkName: 'chart.js' */ './vendors/chart')
.then(() => {
// furter code
})
.catch(console.warn);

Bar chart

<div class="chart-container flex-grow-1 h-275px">
<canvas id="salesChart"></canvas>
</div>
// dashly/theme/src/js/user.js
const salesChart = document.getElementById('salesChart');
if(salesChart) {
import(/* webpackChunkName: 'chart.js' */ './vendors/chart')
.then(() => {
new Chart(salesChart, {
// The type of chart we want to create
type: 'bar',
// The data for our dataset
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'Projections',
data: [12440, 15021, 10081, 10984, 8409, 12532, 13986, 19227, 12636, 10171, 6753, 15589],
backgroundColor: helper.getCSSVariable(`${cssPrefix}primary`)
},
{
label: 'Actual',
data: [12357, 13665, 9071, 9914, 5115, 12291, 10010, 19092, 11976, 9174, 5189, 14523],
backgroundColor: helper.getCSSVariable(`${cssPrefix}light`),
borderRadius: 30
}
]
},
// Configuration options
options: {
scales: {
x: {
stacked: true,
gridLines: {
display: false
}
},
y: {
stacked: true,
ticks: {
callback: (value, index, values) => {
return value > 0 ? '$' + Math.floor(value / 1000) + 'k' : value;
}
}
}
},
plugins: {
tooltip: {
callbacks: {
label: context => {
return new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'}).format(context.parsed.y);
},
labelColor: context => {
return {
backgroundColor: context.dataset.backgroundColor
};
}
}
}
}
}
});
})
.catch(console.warn);
}

Line chart

<div class="chart-container h-150px">
<canvas id="incomeChart"></canvas>
</div>
// dashly/theme/src/js/user.js
const incomeChart = document.getElementById('incomeChart');
if(incomeChart) {
import(/* webpackChunkName: 'chart.js' */ './vendors/chart')
.then(() => {
new Chart(incomeChart, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
backgroundColor: (context) => {
const chart = context.chart;
const {ctx, chartArea} = chart;
if (!chartArea) {
return null;
}
return helper.getGradient(
ctx,
chartArea,
`rgba(${helper.getCSSVariable(`${cssPrefix}primary-rgb`)}, 0.5)`,
`rgba(${helper.getCSSVariable(`${cssPrefix}primary-rgb`)}, 0.2)`,
`rgba(${helper.getCSSVariable(`${cssPrefix}primary-rgb`)}, 0)`
);
},
data: [400, 1000, 1000, 2500, 3000, 1500, 4000, 5000, 8000, 6000, 5500, 6500]
}
]
},
// Configuration options
options: {
layout: {
padding: {
top: 2,
bottom: -10
}
},
scales: {
x: {
ticks: {
display: false
},
grid: {
drawOnChartArea: true
}
},
y: {
display: false
}
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
return new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'}).format(context.parsed.y);
}
}
}
}
}
});
})
.catch(console.warn);
}

Doughnut chart (rounded)Exclusive

ordered products

329

<div class="chart-container flex-grow-1">
<canvas id="orderStatusChart"></canvas>
<!-- Labels -->
<div class="position-absolute top-50 start-50 translate-middle text-center">
<p class="fs-5 mb-0 text-body-secondary lh-sm">ordered products</p>
<h3 class="display-2 fw-bold mb-0">329</h3>
</div>
</div>
// dashly/theme/src/js/user.js
const orderStatusChart = document.getElementById('orderStatusChart');
if(orderStatusChart){
import(/* webpackChunkName: 'chart.js' */ './vendors/chart')
.then(() => {
new Chart(orderStatusChart, {
// The type of chart we want to create
type: 'roundedDoughnut',
// The data for our dataset
data: {
labels: [
'Delivered',
'In progress',
'To-do'
],
datasets: [
{
label: 'Order status',
data: [29, 45, 26],
backgroundColor: [
helper.getCSSVariable(`${cssPrefix}primary`),
helper.getCSSVariable(`${cssPrefix}dark`),
helper.getCSSVariable(`${cssPrefix}gray-300`)
]
}
]
},
// Configuration options
options: {
plugins: {
tooltip: {
callbacks: {
label: (context) => {
return context.parsed + '%';
}
}
}
}
}
});
})
.catch(console.warn);
}

Line chart (toggle)

Use data-toggle="chart" attribute with data-target="#idOfTheChartElement" and data-dataset="indexOfTheDataset" attribute to switch between datasets. data-action="toggle" atrribute is optional, toggle is the default value.

<div class="d-flex justify-content-end mb-5">
<!-- Label -->
<h5 class="d-flex align-items-center text-uppercase link-secondary fw-semibold mb-0 cursor-pointer" data-toggle="chart" data-target="#salesReportChart" data-dataset="0">
<span class="legend-circle-lg bg-primary"></span>
Income
</h5>
<!-- Label -->
<h5 class="d-flex align-items-center text-uppercase link-secondary fw-semibold mb-0 ms-4 cursor-pointer" data-toggle="chart" data-target="#salesReportChart" data-dataset="1">
<span class="legend-circle-lg bg-dark"></span>
Expense
</h5>
</div>
<div class="chart-container flex-grow-1 h-275px">
<canvas id="salesReportChart"></canvas>
</div>
// dashly/theme/src/js/user.js
const salesReportChart = document.getElementById('salesReportChart');
if(salesReportChart) {
import(/* webpackChunkName: 'chart.js' */ './vendors/chart')
.then(() => {
new Chart(salesReportChart, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'Income',
data: [28, 70, 68, 77, 35, 24, 18, 73, 29, 43, 19, 24],
borderWidth: 4,
borderColor: helper.getCSSVariable(`${cssPrefix}primary`)
},
{
label: 'Expense',
data: [18, 23, 79, 37, 19, 45, 55, 72, 79, 57, 32, 59],
borderWidth: 4,
borderColor: helper.getCSSVariable(`${cssPrefix}dark`),
hidden: true
}
]
},
// Configuration options
options: {
scales: {
y: {
ticks: {
callback: (value, index, values) => {
return value > 0 ? '$' + value + 'k' : value;
}
}
}
},
plugins: {
tooltip: {
callbacks: {
label: (context) => {
return new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'}).format(context.parsed.y);
}
}
}
}
}
});
})
.catch(console.warn);
}

Show/hide datasets

Use data-toggle="chart" attribute with data-target="#idOfTheChartElement" and data-dataset="indexOfTheDataset" with data-action="visibility" atrribute to show/hide datasets in the chart.

<div class="d-flex justify-content-end mb-5">
<ul class="nav">
<li class="nav-item" data-toggle="chart" data-action="visibility" data-target="#overviewChart" data-dataset="0">
<a class="nav-link chart-legend" href="#">
<span class="legend-circle-lg bg-white border border-2 border-primary"></span>
Expected revenue
</a>
</li>
<li class="nav-item" data-toggle="chart" data-action="visibility" data-target="#overviewChart" data-dataset="1">
<a class="nav-link chart-legend" href="#">
<span class="legend-circle-lg rounded-0 h-4px bg-blue"></span>
Actual revenue
</a>
</li>
</ul>
</div>
<div class="chart-container h-250px">
<canvas id="overviewChart"></canvas>
</div>
// dashly/theme/src/js/user.js
const overviewChart = document.getElementById('overviewChart');
if(overviewChart) {
import(/* webpackChunkName: 'chart.js' */ './vendors/chart')
.then(() => {
new Chart(overviewChart, {
// The type of chart we want to create
type: 'line',
// The data for our dataset
data: {
labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
datasets: [
{
label: 'Expected',
data: [9440, 18021, 34081, 43804, 30409, 22532, 21986, 27227, 32636, 30171, 32753, 19589],
borderColor: helper.getCSSVariable(`${cssPrefix}primary`),
pointRadius: 4,
pointBorderWidth: 3,
pointBorderColor: helper.getCSSVariable(`${cssPrefix}primary`),
pointBackgroundColor: helper.getCSSVariable(`${cssPrefix}white`),
pointHoverRadius: 4,
pointHoverBorderWidth: 3,
pointHoverBorderColor: helper.getCSSVariable(`${cssPrefix}primary`),
pointHoverBackgroundColor: helper.getCSSVariable(`${cssPrefix}primary`),
tension: 0
},
{
label: 'Actual',
data: [2440, 9247, 23081, 30839, 39923, 36532, 28386, 34227, 38636, 37171, 25753, 25589],
borderWidth: 2,
borderDash: [5, 5],
borderColor: `rgba(${helper.getCSSVariable(`${cssPrefix}blue-rgb`)}, 0.75)`,
pointBackgroundColor: helper.getCSSVariable(`${cssPrefix}blue`),
tension: 0
}
]
},
// Configuration options
options: {
scales: {
x: {
gridLines: {
display: false
}
},
y: {
ticks: {
callback: (value, index, values) => {
return value > 0 ? '$' + ((value < 1000000) ? Math.floor(value / 1000) + 'k' : Math.floor(value / 1000000) + 'M') : value;
}
}
}
},
plugins: {
tooltip: {
mode: 'index',
callbacks: {
label: context => {
return new Intl.NumberFormat('en-US', {style: 'currency', currency: 'USD'}).format(context.parsed.y);
},
labelColor: context => {
return {
backgroundColor: context.dataset.borderColor
}
}
}
},
mouseLine: {
enabled: true
}
}
}
});
})
.catch(console.warn);
}
}