Search code examples
javascriptchartschart.js

Chartjs 4 - Fill area between stacked line and bar chart


I'm in the process of migrating over to chart.js 4.4.1 and in the prior version (2.9.4) I was able to fill the gap with a color as in the attached image.

2.9.4 sample img

In the newest version, I'm able to get close by using an opacity, but it's not quite the same: 4.4.1 sample img

Any ideas on how to make that happen? I'm using the non-module JavaScript chartjs file.

See my test code below.

<canvas id="my-chart"></canvas>


    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script>
    <script>
        
        let labels = [];
        for (let year=2000; year <= 2010; year++) {
            labels.push(year);
        }

        const config = {
            data: {
                labels: labels,
                datasets: [
                    {
                        type: "bar",
                        label: "Product",
                        data: [1331320,2851137,5952127,6607851,11068289,12059067,12117998,11827962,16582836,20184478,23915606],
                        backgroundColor: "#bec38f",
                        order: 1
                    },
                    {
                        backgroundColor: "rgba(151,156,106,0.5)",// "#979c6a",
                        borderColor: "#826f68",
                        borderWidth: 3,
                        data: [1242306,2442693,5070218,5502960,8572948,7722718,6916448,7196356,10429229,12544283,15149568],
                        label: "Benchmark",
                        type: "line",
                        fill: true,
                        pointBackgroundColor: "#ffffff",
                        pointRadius: 5,
                        order: 0
                    }
                ]
            },
            options: {
                scales: {
                    x: {
                        grid: {
                            display: false
                        }
                    },
                    y: {
                        stacked: true,
                        scaleLabel: {
                            display: false
                        },
                        ticks: {
                            callback: function(value, index, ticks) {
                                return ("$" + (value/1000000));
                            }
                        }
                    }
                },
                plugins: {
                    tooltip: {
                        intersect: true,
                        callbacks: {
                            label: function(context) {
                                return ("$" + context.parsed.y.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
                            }
                        }
                    }
                }
            }
        };

        new Chart(document.getElementById("my-chart"), config);

    </script>

Solution

  • You can set the drawTime of the filler plugin to beforeDatasetsDraw by adding the following config to the plugins section of the config object:

    filler: {
      drawTime: 'beforeDatasetsDraw'
    },
    

    Live example:

    let labels = [];
    for (let year = 2000; year <= 2010; year++) {
      labels.push(year);
    }
    
    const config = {
      data: {
        labels: labels,
        datasets: [{
            type: "bar",
            label: "Product",
            data: [1331320, 2851137, 5952127, 6607851, 11068289, 12059067, 12117998, 11827962, 16582836, 20184478, 23915606],
            backgroundColor: "#bec38f",
            order: 1
          },
          {
            backgroundColor: "#979c6a",
            borderColor: "#826f68",
            borderWidth: 3,
            data: [1242306, 2442693, 5070218, 5502960, 8572948, 7722718, 6916448, 7196356, 10429229, 12544283, 15149568],
            label: "Benchmark",
            type: "line",
            fill: true,
            pointBackgroundColor: "#ffffff",
            pointRadius: 5,
            order: 0
          }
        ]
      },
      options: {
        scales: {
          x: {
            grid: {
              display: false
            }
          },
          y: {
            stacked: true,
            scaleLabel: {
              display: false
            },
            ticks: {
              callback: function(value, index, ticks) {
                return ("$" + (value / 1000000));
              }
            }
          }
        },
        plugins: {
          filler: {
            drawTime: 'beforeDatasetsDraw'
          },
          tooltip: {
            intersect: true,
            callbacks: {
              label: function(context) {
                return ("$" + context.parsed.y.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","));
              }
            }
          }
        }
      }
    };
    
    new Chart(document.getElementById("my-chart"), config);
    <canvas id="my-chart"></canvas>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js"></script>

    Documentation