chart.js plugin for making waterfall charts

后端 未结 3 1055
隐瞒了意图╮
隐瞒了意图╮ 2021-01-19 21:37

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.

3条回答
  •  深忆病人
    2021-01-19 22:20

    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
            }
          }]
        }
      }
    });
    
    

    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(),
        ...
    

提交回复
热议问题