javascriptchartschart.js

combo-bar-line with differest number of element


I would like to make a graphic design showing the trend of amounts. Specifically a bar graph with the monthly delta and a graph with the cumulative total so far. In my situation, the starting amount is 9,218.06 and the ending amount is 3,336.55. In the graph, however, I cannot show the initial amount.

I would like to have the points in the line graph to be horizontally in the middle between the 2 bar graphs and the line graph to have an extra point, the initial amount as first element.

const comboChart_all = new Chart(document.getElementById('canvas-balances-all'), {
  type: 'bar', // Tipo di grafico principale (bar)
  data: {
    labels: ['2022-08', '2022-09', '2022-10', '2022-11', '2022-12', '2023-01', '2023-02', '2023-03', '2023-04', '2023-05', '2023-06', '2023-07', '2023-08', '2023-09', '2023-10', '2023-11', '2023-12', '2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06', '2024-07', '2024-08'],
    datasets: [
      { 
        label: 'Total for Month',
        type: 'bar', // Tipo di dataset
        data: [-2858.18, 2014.21, 3060.16, -5606.27, 7070.87, -208.27, -5702.15, -244.05, 754.22, 375.52, -1002.45, -1145.54, 1118.56, -5210.75, -215.21, -3383.08, 1570.59, 2394.53, -1864.91, -146.8, 62.89, 1354.87, -4995.44, 4563.65, -2638.48],
        backgroundColor: 'rgba(180, 180, 180, 0.5)',
        borderColor: 'rgba(180, 180, 180, 0.8)',
        borderWidth: 1
      },
      {
        label: 'Cumulative Total',
        type: 'line', // Tipo di dataset
        data: [11359.88, 13374.09, 16434.25, 10827.98, 17898.85, 17690.58, 11988.43, 11744.38, 12498.6, 12874.12, 11871.67, 10726.13, 11844.69, 6633.94, 6418.73, 3035.65, 4606.24, 7000.77, 5135.86, 4989.06, 5051.95, 6406.82, 1411.38, 5975.03, 3336.55],
        backgroundColor: 'rgba(151, 187, 205, 0.2)',
        borderColor: 'rgba(151, 187, 205, 1)',
        fill: false, // La linea non deve essere riempita sotto
        borderWidth: 2
      }
    ]
  },
  options: {
    responsive: true
  }
});
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<div class="c-chart-wrapper">
  <canvas id="canvas-balances-all"></canvas>
</div>

https://jsfiddle.net/unxp03dv/

how can I do it?


Solution

  • You may set a secondary, invisible (display: false) x axis for the line dataset, with an additional label in front of the regular labels, and with option offset: false to set the new x positions between those of the regular x labels.

    This way, you'll have to set the first value of the data array of the line dataset to be your initial value. This dataset will have one additional data value, as it has one additional label (as compared to the bar dataset).

    If the regular labels are set separately in an array, the scales setup could be this:

    options:{
       scales:{
          x: {},
          x2: {
             labels: ['initial'].concat(labels),
             offset: false,
             display: false
          }
       }
    }
    

    Original snippet, with these modifications:

    const labels = ['2022-08', '2022-09', '2022-10', '2022-11', '2022-12', '2023-01', '2023-02', '2023-03', '2023-04', '2023-05', '2023-06', '2023-07', '2023-08', '2023-09', '2023-10', '2023-11', '2023-12', '2024-01', '2024-02', '2024-03', '2024-04', '2024-05', '2024-06', '2024-07', '2024-08'];
    
    const comboChart_all = new Chart(document.getElementById('canvas-balances-all'), {
      type: 'bar', // Tipo di grafico principale (bar)
      data: {
        labels,
        datasets: [
          { 
            label: 'Total for Month',
            type: 'bar', // Tipo di dataset
            data: [-2858.18, 2014.21, 3060.16, -5606.27, 7070.87, -208.27, -5702.15, -244.05, 754.22, 375.52, -1002.45, -1145.54, 1118.56, -5210.75, -215.21, -3383.08, 1570.59, 2394.53, -1864.91, -146.8, 62.89, 1354.87, -4995.44, 4563.65, -2638.48],
            backgroundColor: 'rgba(180, 180, 180, 0.5)',
            borderColor: 'rgba(180, 180, 180, 0.8)',
            borderWidth: 1
          },
          {
            label: 'Cumulative Total',
            xAxisID: 'x2',
            type: 'line', // Tipo di dataset
            data: [ 9218.06, 11359.88, 13374.09, 16434.25, 10827.98, 17898.85, 17690.58, 11988.43, 11744.38, 12498.6, 12874.12, 11871.67, 10726.13, 11844.69, 6633.94, 6418.73, 3035.65, 4606.24, 7000.77, 5135.86, 4989.06, 5051.95, 6406.82, 1411.38, 5975.03, 3336.55],
            backgroundColor: 'rgba(151, 187, 205, 0.2)',
            borderColor: 'rgba(151, 187, 205, 1)',
            fill: false, // La linea non deve essere riempita sotto
            borderWidth: 2
          }
        ]
      },
      options: {
        responsive: true,
        scales: {
           x: {},
           x2:{
             labels: ['initial'].concat(labels),
             offset: false,
             display: false
           }
        }
      }
    });
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <div class="c-chart-wrapper">
      <canvas id="canvas-balances-all"></canvas>
    </div>