图表JS - 条件水平行背景颜色

时间:2017-12-13 01:44:26

标签: javascript charts chart.js

基于垂直轴上的数字,我有点不习惯在ChartJS的行中添加条件背景颜色。

例如

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

以前有人做过这样的事吗?

我附上了一张大致描述功能的图片。

enter image description here

干杯!

2 个答案:

答案 0 :(得分:1)

使用chartjs无法做到这一点。但是,您可以编写自己的plugin并在beforeDraw挂钩中自己绘制背景。

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

您可以从图表参数中获取所有信息以计算y轴段的高度。 我已经在下面列出了如何实现这一点的代码段。但请注意,这更像是一个概念证明而不是正确的实现:



        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++;
                            }
                        }
                    }
                }]
            });
&#13;
<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>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

Shiffty的答案是正确的,但是只有在yAxis上存在背景值时,它才有效,但情况并非总是如此……取决于适合的条件。一种更通用的解决方案是计算实际值:

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