最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Chart JS — Conditional horizontal row background colours - Stack Overflow

programmeradmin0浏览0评论

I'm a bit stuck on adding conditional background colours to a row in ChartJS, based on numbers on the vertical axis.

Eg.

If the vertical axis is between 0 - 6, background colour for those rows is green.
If the vertical axis is between 6 - 12 background colour for those rows is grey
If the vertical axis is > 12 background colour for those rows is red

Has anyone done something like this before?

I've attached a picture that roughly describes the functionality.

Cheers!

I'm a bit stuck on adding conditional background colours to a row in ChartJS, based on numbers on the vertical axis.

Eg.

If the vertical axis is between 0 - 6, background colour for those rows is green.
If the vertical axis is between 6 - 12 background colour for those rows is grey
If the vertical axis is > 12 background colour for those rows is red

Has anyone done something like this before?

I've attached a picture that roughly describes the functionality.

Cheers!

Share Improve this question asked Dec 13, 2017 at 1:44 Joshua RussellJoshua Russell 7005 silver badges14 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 4

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./ajax/libs/Chart.js/2.7.1/Chart.min.js"></script>
<canvas id="myChart" width="400" height="250"></canvas>

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);
                    }
                }
            }]
        });
发布评论

评论列表(0)

  1. 暂无评论