【问题标题】:How to set gradient in legend box color in Chart,js如何在图表,js中的图例框颜色中设置渐变
【发布时间】:2021-07-31 06:47:42
【问题描述】:

我正在尝试用不同颜色的利润和损失制作利润图表,到目前为止,我扩展了默认折线图

Chart.defaults.ProfitLossLine = Chart.helpers.clone(Chart.defaults.line);
Chart.controllers.ProfitLossLine = Chart.controllers.line.extend({
    update: function () {
        // get the min and max values
        const dataset = this.chart.data.datasets[0];
        const min = Math.min.apply(null, dataset.data);
        const max = Math.max.apply(null, dataset.data);
        const yScale = this.getScaleForId(this.getMeta(0).yAxisID);
        // figure out the pixels for these and the value 0
        const top = yScale.getPixelForValue(max);
        const zero = yScale.getPixelForValue(0);
        const bottom = yScale.getPixelForValue(min);
        // build a gradient that switches color at the 0 point
        const ctx = this.chart.chart.ctx;
        const gradient = ctx.createLinearGradient(0, top, 0, bottom);
        const ratio = Math.min((zero - top) / (bottom - top), 1);
        gradient.addColorStop(0, dataset.positiveBorderColor);
        gradient.addColorStop(ratio, dataset.positiveBackgroundColor);
        gradient.addColorStop(ratio, dataset.negativeBackgroundColor);
        gradient.addColorStop(1, dataset.negativeBorderColor);
        dataset.borderColor = gradient;
        dataset.backgroundColor = gradient;
        dataset.pointBorderColor = gradient;
        dataset.pointBackgroundColor = gradient;
        dataset.pointHoverBorderColor = gradient;
        dataset.pointHoverBackgroundColor = gradient;
        this.chart.options.legend.labels.generateLabels = (chart) => {
            const labels = Chart.defaults.global.legend.labels.generateLabels(chart);
            for (const key in labels) {
                labels[key].fillStyle  = gradient;
                labels[key].strokeStyle = gradient; 
              }
            return labels;
        }
        return Chart.controllers.line.prototype.update.apply(this, arguments);
    }
});

得到了

但我想在“利润”的图例框中应用相同的绿-红渐变,它实际上是灰色的。

【问题讨论】:

    标签: javascript charts chart.js


    【解决方案1】:

    看看这个:Chart.js Legend Item interface

    你可以这样实现:

    let maxLeft = 0;
    let maxWidth = 0;
    function generateLabelsNew(chart) {
        const datasets = chart.data.datasets;
        const {labels: {usePointStyle, pointStyle, textAlign, color}} = chart.legend.options;
        
        return chart._getSortedDatasetMetas().map((meta) => {
            const style = meta.controller.getStyle(usePointStyle ? 0 : undefined);
            const borderWidth = style.borderWidth;
            
            const box = meta?.controller?.chart?.legend?.legendHitBoxes[meta.index];
    
            if (box?.left > maxLeft) {
                maxLeft = box.left;
            }
            if (box?.width > maxWidth) {
                maxWidth = box.width;
            }
            const gradient = chart.ctx.createLinearGradient(maxLeft, 0, maxLeft + maxWidth, 0);
            gradient.addColorStop(0, 'green');
            gradient.addColorStop(1, 'red');
            
            return {
                text: datasets[meta.index].label,
                fillStyle: gradient,//style.backgroundColor,
                fontColor: color,
                hidden: !meta.visible,
                lineCap: style.borderCapStyle,
                lineDash: style.borderDash,
                lineDashOffset: style.borderDashOffset,
                lineJoin: style.borderJoinStyle,
                lineWidth: (borderWidth.width + borderWidth.height) / 4,
                strokeStyle: style.borderColor,
                pointStyle: pointStyle || style.pointStyle,
                rotation: style.rotation,
                textAlign: textAlign || style.textAlign,
                borderRadius: 0,
                datasetIndex: meta.index
            };
        }, this);
    }
    

    然后,在您的配置中,您需要将 generateLabel 函数设置为您刚刚生成的函数,如下所示:

    const options = {
        plugins: {
            legend: {
                labels: {
                    generateLabels: generateLabelsNew,
                },
            },
        },
    };
    

    这实际上覆盖了默认的标签生成函数并将框的填充样式设置为渐变。您使用 maxWidth 和 maxLeft 来获取每个图例项的边界框的位置。

    【讨论】:

      猜你喜欢
      • 2016-10-01
      • 1970-01-01
      • 2017-09-17
      • 2019-09-04
      • 2020-08-04
      • 1970-01-01
      • 2020-04-01
      • 2019-08-09
      • 1970-01-01
      相关资源
      最近更新 更多