score:3

Accepted answer

There is no option to do this with chartjs. However you can write your own plugin and draw the background by yourself in the beforeDraw hook for example.

var chart = new Chart(ctx, {
    plugins: [{
        beforeDraw: function(chart) {
            //..
        }
    }]
});

You can get all the information to calculate the height of an y-axis-segment from the chart parameter. I've included a snippet below how this could be implemented. Note however that this is more a proof of concept than a proper implementation:

        var canvas = document.getElementById('myChart');
        window.chartColors = {
            red: 'rgb(255, 99, 132)',
            orange: 'rgb(255, 159, 64)',
            yellow: 'rgb(255, 205, 86)',
            green: 'rgb(51, 204, 51)',
            blue: 'rgb(54, 162, 235)',
            purple: 'rgb(153, 102, 255)',
            grey: 'rgb(201, 203, 207)'
        };

        var myLineChart = new Chart(canvas,
            {
                type: 'line',
                data: {
                    labels: ['1', '2', '3', '4', '5'],
                    datasets: [
                        {
                            label: '# of Votes',
                            fill: false,
                            backgroundColor: window.chartColors.blue,
                            borderColor: window.chartColors.blue,
                            data: [2, 5, 12.5, 9, 6.3]
                        }
                    ]
                },
                options: {
                    responsive: true,
                    title: {
                        display: true,
                        text: 'Conditional Background'
                    },
                    backgroundRules: [{
                        backgroundColor: window.chartColors.green, 
                        yAxisSegement: 6
                    }, {
                        backgroundColor: window.chartColors.grey,
                        yAxisSegement: 12
                    }, {
                        backgroundColor: window.chartColors.red,
                        yAxisSegement: Infinity
                    }],
                    scales: {
                        yAxes: [{
                            ticks: {
                                beginAtZero: true,
                                stepSize: 1
                            }
                        }]
                    }
                },
                plugins: [{
                    beforeDraw: function (chart) {
                        var ctx = chart.chart.ctx;
                        var ruleIndex = 0;
                        var rules = chart.chart.options.backgroundRules;
                        var yaxis = chart.chart.scales["y-axis-0"];
                        var xaxis = chart.chart.scales["x-axis-0"];
                        var partPercentage = 1 / (yaxis.ticksAsNumbers.length - 1);
                        for (var i = yaxis.ticksAsNumbers.length - 1; i > 0; i--) {
                            if (yaxis.ticksAsNumbers[i] < rules[ruleIndex].yAxisSegement) {
                                ctx.fillStyle = rules[ruleIndex].backgroundColor;
                                ctx.fillRect(xaxis.left, yaxis.top + ((i - 1) * (yaxis.height * partPercentage)), xaxis.width, yaxis.height * partPercentage);
                            } else {
                                ruleIndex++;
                                i++;
                            }
                        }
                    }
                }]
            });
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<canvas id="myChart" width="400" height="250"></canvas>

score:1

Shiffty's answer is right on point, however it only works if the background values are present on the yAxis, which is not always the case... depends on what fits. A more generic solution is to calculate the actual values:

    var canvas = document.getElementById('myChart');
    window.chartColors = {
        red: 'rgb(255, 99, 132)',
        orange: 'rgb(255, 159, 64)',
        yellow: 'rgb(255, 205, 86)',
        green: 'rgb(51, 204, 51)',
        blue: 'rgb(54, 162, 235)',
        purple: 'rgb(153, 102, 255)',
        grey: 'rgb(201, 203, 207)'
    };

    var myLineChart = new Chart(canvas,
        {
            type: 'line',
            data: {
                labels: ['1', '2', '3', '4', '5'],
                datasets: [
                    {
                        label: '# of Votes',
                        fill: false,
                        backgroundColor: window.chartColors.blue,
                        borderColor: window.chartColors.blue,
                        data: [2, 5, 12.5, 9, 6.3]
                    }
                ]
            },
            options: {
                responsive: true,
                title: {
                    display: true,
                    text: 'Conditional Background'
                },
                backgroundRules: [{
                    backgroundColor: window.chartColors.green, 
                    yAxisSegement: 6
                }, {
                    backgroundColor: window.chartColors.grey,
                    yAxisSegement: 12
                }, {
                    backgroundColor: window.chartColors.red,
                    yAxisSegement: 999999
                }],
                scales: {
                    yAxes: [{
                        ticks: {
                            beginAtZero: true,
                            stepSize: 1
                        }
                    }]
                }
            },
            plugins: [{
                beforeDraw: function (chart) {
                    var rules = chart.chart.options.backgroundRules;
                    var ctx = chart.chart.ctx;
                    var yAxis = chart.chart.scales["y-axis-0"];
                    var xaxis = chart.chart.scales["x-axis-0"];
                    for (var i = 0; i < rules.length; ++i) {
                        var yAxisSegement = (rules[i].yAxisSegement > yAxis.ticksAsNumbers[0] ? yAxis.ticksAsNumbers[0] : rules[i].yAxisSegement);
                        var yAxisPosStart = yAxis.height - ((yAxisSegement * yAxis.height) / yAxis.ticksAsNumbers[0]) + chart.chart.controller.chartArea.top;
                        var yAxisPosEnd = (i === 0 ? yAxis.height : yAxis.height - ((rules[i - 1].yAxisSegement * yAxis.height) / yAxis.ticksAsNumbers[0]));
                        ctx.fillStyle = rules[i].backgroundColor;
                        ctx.fillRect(xaxis.left, yAxisPosStart, xaxis.width, yAxisPosEnd - yAxisPosStart + chart.chart.controller.chartArea.top);
                    }
                }
            }]
        });

Related Query

More Query from same tag