使用Chart.js样式化条形图和折线图

8
我们已经使用Chart.js几个月了,非常喜欢它给我们带来的易编程性和强大功能。我们想要开始为从Chart.js生成的图表添加一些更好的样式。我们使用的大部分图表是条形图,还有一些折线图。
当我使用“样式”这个词时,我真正想说的是让条形和折线看起来更加好看。具体而言,我想在条形和折线图后面添加一个投影,并可能甚至给条形添加斜角。
我查看了许多问题,似乎找不到我要找的内容。我也进行了一些尝试,通过修改Chart.js文件向JavaScript中添加阴影和模糊效果,但我没有在正确的位置添加。我将这些更改放在了Chart.Element.extend绘制函数内部:
ctx.shadowColor = '#000';
ctx.shadowBlur = 10;
ctx.shadowOffsetX = 8;
ctx.shadowOffsetY = 8;

我将它放在 ctx.fill() 之前,这样几乎可以达到我想要的效果。结果是我得到了一个很好看的投影,既适用于我正在绘制的柱状图和折线图,但同时也在 x 和 y 轴标签上产生了一个投影,这看起来不好。我希望投影只出现在条形和线条上,而不是标签上。
如果您能提供任何帮助,我将非常感激。虽然我没有 JavaScript 经验,但在 Stack Overflow 的帮助下,我已经成功完成了许多其他我本来无法完成的编码工作。

尝试过 https://dev59.com/k5Dea4cB1Zd3GeqPWQtq#33124653 吗? - potatopeelings
3个回答

11

为折线图添加阴影效果

您可以扩展折线图类型来实现此功能。


预览

图片描述


脚本

Chart.types.Line.extend({
    name: "LineAlt",
    initialize: function () {
        Chart.types.Line.prototype.initialize.apply(this, arguments);

        var ctx = this.chart.ctx;
        var originalStroke = ctx.stroke;
        ctx.stroke = function () {
            ctx.save();
            ctx.shadowColor = '#000';
            ctx.shadowBlur = 10;
            ctx.shadowOffsetX = 8;
            ctx.shadowOffsetY = 8;
            originalStroke.apply(this, arguments)
            ctx.restore();
        }
    }
});

然后

...
var myChart = new Chart(ctx).LineAlt(data, {
    datasetFill: false
});

Fiddle - https://jsfiddle.net/7kbz1L4t/



土豆皮,谢谢!这个没有被评价的事实让我感到惊讶。在10个投影答案中,这是唯一一个最简单但更重要的是唯一一个真正有效的答案。谢谢! - Nolan
1
你能扩展到饼图吗? - Paul Fitzgerald
你介意解释一下你在 ctx.stroke 中做了什么吗?文档中说它可以接收一个 Path2D,但是你传递了一个自定义函数。感谢你的回答! - Miguel Péres
@MiguelPéres - 我进行了猴子补丁 - 基本上用自己的实现替换了实际实现,这个实现在调用我存储在originalStroke中的原始实际实现之前会执行一些其他操作。 - potatopeelings
当我尝试使用Chart.js 4.4.0时,该扩展会产生错误Chart.types is undefined,这表明自发布以来,该库已经删除了Chart.types命名空间。这个解决方案是否仅限于特定的Chart.js版本? - undefined

7

..

预览

enter image description here


脚本 覆盖绘制函数

let draw = Chart.controllers.line.prototype.draw;
Chart.controllers.line.prototype.draw = function() {
    draw.apply(this, arguments);
    let ctx = this.chart.chart.ctx;
    let _stroke = ctx.stroke;
    ctx.stroke = function() {
        ctx.save();
        ctx.shadowColor = '#07C';
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 4;
        _stroke.apply(this, arguments);
        ctx.restore();
    }
};

let draw = Chart.controllers.line.prototype.draw;
Chart.controllers.line.prototype.draw = function() {
    draw.apply(this, arguments);
    let ctx = this.chart.chart.ctx;
    let _stroke = ctx.stroke;
    ctx.stroke = function() {
        ctx.save();
        ctx.shadowColor = '#07C';
        ctx.shadowBlur = 10;
        ctx.shadowOffsetX = 0;
        ctx.shadowOffsetY = 4;
        _stroke.apply(this, arguments);
        ctx.restore();
    }
};

let ctx = document.querySelector("#canvas").getContext('2d');
let myChart = new Chart(ctx, {
    type: 'line',
    data: {
        labels: ["January", "February", "March", "April", "May", "June", "July"],
        datasets: [{
            data: [65, 59, 75, 64, 70, 30, 40],
            borderColor: '#07C',
            pointBackgroundColor: "#FFF",
            pointBorderColor: "#07C",
            pointHoverBackgroundColor: "#07C",
            pointHoverBorderColor: "#FFF",
            pointRadius: 4,
            pointHoverRadius: 4,
            fill: false,
            tension: 0.15
        }]
    },
    options: {
        responsive: false,
        tooltips: {
            displayColors: false,
            callbacks: {
                label: function(e, d) {
                    return `${e.xLabel} : ${e.yLabel}`
                },
                title: function() {
                    return;
                }
            }
        },
        legend: {
            display: false
        },
        scales: {
            yAxes: [{
                ticks: {
                    max: 90
                }
            }]
        }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.min.js"></script>
<canvas id="canvas" width="400" height="210" style="background-color: #E4E8F0"></canvas>


我尝试了这个解决方案,它有效,但是网格上也出现了蓝色的阴影...我做错了什么? - angry kiwi
当我尝试使用Chart.js 4.4.0时,draw覆盖会产生错误this.chart.chart未定义,这表明2.x和4.x之间存在命名空间的更改。你(或任何阅读此信息的人)知道如何更新这个答案以适应Chart.js v4吗? - undefined

0

这适用于新版本的Chart JS。我们可以创建一个插件对象并注册到Chart JS中,插件是开发人员在创建图表时修改图表的一种方式,请参考

https://riptutorial.com/chart-js/example/22332/plugins-introduction

示例插件,可向任何图表添加阴影

var simpleplugin = {
beforeDraw : function(chartInstance)
{

    let _stroke = chartInstance.ctx.stroke;
    chartInstance.ctx.stroke = function () {

        chartInstance.ctx.save();
        chartInstance.ctx.shadowColor = 'gray';
        chartInstance.ctx.shadowBlur = 10;
        chartInstance.ctx.shadowOffsetX = 2;
        chartInstance.ctx.shadowOffsetY = 2;
        _stroke.apply(this, arguments)
        chartInstance.ctx.restore();
    }

    let _fill = chartInstance.ctx.fill;
    ctx.fill = function () {

        chartInstance.ctx.save();
        chartInstance.ctx.shadowColor = 'gray';
        chartInstance.ctx.shadowBlur = 10;
        chartInstance.ctx.shadowOffsetX = 2;
        chartInstance.ctx.shadowOffsetY = 2;
        _fill.apply(this, arguments)
        chartInstance.ctx.restore();
    }
}

}

$(function()
{
    Chart.pluginService.register(simpleplugin);
});

当我尝试在Chart.js 4.4.0中运行此代码时,控制台会记录错误信息Chart.pluginService is undefined,这可能是版本不匹配导致的。请问这个解决方案是针对哪个版本的Chart.js? - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接