Chart (Chart.js)
Simple yet flexible JavaScript charting for designers & developers.
Chart.js documentationHow 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);
By using code splitting and dynamic import techniques you don't need to worry about the size of the JavaScript file. Dashly will only import the necessary files when they are needed.
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-muted 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.
Income
Expense
<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);
}
}