I want to create a chart.js plugin to create waterfall charts.
I am new to working with chart.js. I was thinking to extend the bar-chart to create a waterfall chart.
You can use the plugin recommented by Chart.JS https://github.com/everestate/chartjs-plugin-waterfall (Ref: https://www.chartjs.org/docs/2.7.2/notes/extensions.html)
Installation
npm install --save chartjs-plugin-waterfall
Usage
import waterFallPlugin from 'chartjs-plugin-waterfall';
var chart = new Chart(ctx, {
plugins: [waterFallPlugin]
});
I created a chartjs plugin for waterfall charts.
See https://github.com/MartinDawson/chartjs-plugin-waterfall
This plugin works by checking if any of your datasets contain a property called dummyStack that is set to true. The stack property must be used in conjunction with dummyStack for this plugin to work properly. If dummyStack is true then it hides the label, tooltip and sets the color invisible. When you use stacking with this it creates the affect of a floating bar as shown in the image above that we can use for waterfall charts as chartjs-2 doesn't support waterfall charts by default.
import waterFallPlugin from 'chartjs-plugin-waterfall';
var chart = new Chart(ctx, {
plugins: [waterFallPlugin]
});
const data = {
datasets: [
{
label: 'Closing Costs',
data: [50],
backgroundColor: '#e8cdd7',
stack: 'stack 1',
},
{
label: 'Purchase Price',
data: [700],
backgroundColor: '#d29baf',
stack: 'stack 1',
},
{
data: [200],
dummyStack: true,
stack: 'stack 2',
},
{
label: 'Opening Loan Balance',
data: [550],
backgroundColor: '#bb6987',
stack: 'stack 2',
},
{
label: 'Initial Cash Investment',
data: [200],
backgroundColor: '#a53860',
stack: 'stack 3',
},
],
};
It also has line steps from bar to bar.
Since Chart.js v2.9.0., we can use floating bars to easily create waterfall charts. Individual bars may since be specified with the syntax [min, max]
.
Given an array of values [3, 5, 4, 2, 6]
, we need to produce the following data (last entry being the computed value for the 'Total' bar):
[[0, 3], [3, 8], [8, 12], [12, 14], [14, 20], 20]
The only additional thing left to do is defining a tooltips.callback
function that computes the correct value to be shown in the tooltips.
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
const v = data.datasets[0].data[tooltipItem.index];
return Array.isArray(v) ? v[1] - v[0] : v;
}
}
},
Please have a look at the following code sample that produces a waterfall chart out of the baseData
array.
let baseData = [
{ label: 'A', value: 3 },
{ label: 'B', value: 5 },
{ label: 'C', value: 4 },
{ label: 'D', value: 2 },
{ label: 'E', value: 6 }
];
const labels = baseData.map(o => o.label).concat('Total');
const data = [];
let total = 0;
for (let i = 0; i < baseData.length; i++) {
const vStart = total;
total += baseData[i].value;
data.push([vStart, total]);
}
data.push(total);
const backgroundColors = data.map((o, i) => 'rgba(255, 99, 132, ' + (i + (11 - data.length)) * 0.1 + ')');
new Chart('waterfall', {
type: 'bar',
data: {
labels: labels,
datasets: [{
data: data,
backgroundColor: backgroundColors,
barPercentage: 1
}]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
display: false
},
tooltips: {
callbacks: {
label: (tooltipItem, data) => {
const v = data.datasets[0].data[tooltipItem.index];
return Array.isArray(v) ? v[1] - v[0] : v;
}
}
},
scales: {
yAxes: [{
ticks: {
beginAtZero: true
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="waterfall" height="200"></canvas>
If the chart should start with the 'Total' bar, simply reverse
labels
,data
andbackgroundColors
arrays as follows.
data: {
labels: labels.reverse(),
datasets: [{
data: data.reverse(),
backgroundColor: backgroundColors.reverse(),
...