chart.js 制作瀑布图的插件

chart.js plugin for making waterfall charts

我想创建一个 chart.js 插件来创建瀑布图。

我刚开始使用 chart.js。我正在考虑扩展条形图以创建瀑布图。

条形图控制器中的绘制函数如下:

draw: function(ease) {
            var me = this;
            var easingDecimal = ease || 1;
            helpers.each(me.getMeta().data, function(rectangle, index) {
                var d = me.getDataset().data[index];
                if (d !== null && d !== undefined && !isNaN(d)) {
                    rectangle.transition(easingDecimal).draw();
                }
            }, me);
        },

可以在此处找到完整的条形图控制器 js 文件: https://github.com/chartjs/Chart.js/tree/master/src/controllers

我为瀑布图创建了一个 chartjs 插件。

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',
    },
  ],
};

它还有从小节到小节的线条步骤。

Since Chart.js v2.9.0., we can use floating bars 轻松创建瀑布图。单独的柱可以用语法 [min, max] 指定。

给定值数组 [3, 5, 4, 2, 6],我们需要生成以下数据(最后一个条目是 'Total' 柱的计算值):

[[0, 3], [3, 8], [8, 12], [12, 14], [14, 20], 20]

唯一剩下要做的事情是定义一个 tooltips.callback 函数来计算要在工具提示中显示的正确值。

tooltips: {
  callbacks: {
    label: (tooltipItem, data) => {
      const v = data.datasets[0].data[tooltipItem.index];
      return Array.isArray(v) ? v[1] - v[0] : v;
    }
  }
},

请查看以下从 baseData 数组生成瀑布图的代码示例。

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 and backgroundColors arrays as follows.

data: {
  labels: labels.reverse(),
  datasets: [{
    data: data.reverse(),
    backgroundColor: backgroundColors.reverse(),
    ...

可以使用Chart.JS https://github.com/everestate/chartjs-plugin-waterfall (Ref: https://www.chartjs.org/docs/2.7.2/notes/extensions.html)

推荐的插件

安装

npm install --save chartjs-plugin-waterfall

用法

import waterFallPlugin from 'chartjs-plugin-waterfall';

var chart = new Chart(ctx, {
    plugins: [waterFallPlugin]
});