自定义 Chart.js 疑难解答

Customizing Chart.js troubleshoot

使用 Chart.js

时遇到一些问题

1) 是否可以将底部标签移动到图表顶部? 2)是否可以用第一条灰线隐藏左侧标签? 3) 是否可以在每个点上设置永久工具提示(显示温度)而不是悬停工具提示?

这是我的图表http://jsfiddle.net/JohnnyJuarez/ojc09hv4/:

<canvas id="weeksChart" width="651" height="335"></canvas>


var dayTemperatureArray = [-5, 14, 15, 15, 17, 18, 19, 21, 22, 25, 24, 20, 19, 16];
var nightTemperatureArray = [-10, 4, 5, 6, 8, 11, 12, 15, 17, 15, 13, 12, 11, 9];

var dataWeeks = {
    labels: ["16.02", "17.02", "18.02", "19.02", "20.02", "21.02", "22.02", "23.02", "24.02", "25.02", "26.02", "27.02", "28.02", "01.03"],
    datasets: [
        {
            label: "Days temperature chart",
            fillColor: "transparent",
            strokeColor: "rgba(244, 6, 6, 1)",
            data: dayTemperatureArray
        },
        {
            label: "Nights temperature chart",
            strokeColor: "#3f6bf5",
            data: nightTemperatureArray
        }
    ]
    };

var ctx = document.getElementById("weeksChart").getContext("2d");
window.weeksChart = new Chart(ctx).Line(dataWeeks, {
    responsive: true,
    pointDot: true,
    datasetStrokeWidth: 0.5,
    scaleSteps: 2,
    scaleLabel: "<%=value + '°'%>",
    tooltipTemplate: "<%= value %>",
    showTooltips: true

});

提前致谢!

p.s。如果可能的话,请避免 jquery:-)

先从最简单的开始吧

2) 是否可以用第一条灰线隐藏左边的标签?

我假设你指的是 y 轴标签。您可以在图表选项中将 scaleShowLabels 选项设置为 false 以隐藏 y 轴标签

window.weeksChart = new Chart(ctx).Line(dataWeeks, {
    scaleShowLabels: false,
    ...

1) 是否可以将底部标签移动到图表顶部?

我假设你指的是 x 轴标签。 Chart.js 没有执行此操作的直接选项。但是你可以隐藏实际的x轴标签,自己在图表顶部绘制x轴标签。

同样,Chart.js 没有隐藏 x 轴标签的选项,但幸运的是有一个选项可以控制比例字体颜色。只需将其设置为透明,您原来的 x 轴标签现在就被隐藏了!

window.weeksChart = new Chart(ctx).Line(dataWeeks, {
    scaleFontColor: "transparent",
    ...

现在绘制图表顶部的 x 轴标签。为了省去扩展图表的麻烦,我们可以添加一个 post 动画事件处理程序并在其中执行此操作,例如

window.weeksChart = new Chart(ctx).Line(dataWeeks, {
     onAnimationComplete: function () {
          animationComplete.apply(this)
     }
     ...

var animationComplete = function () {
    var self = this;

    Chart.helpers.each(self.datasets[0].points, function (point, index) {
        self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
        self.chart.ctx.textAlign = 'center';
        self.chart.ctx.textBaseline = "middle";
        self.chart.ctx.fillStyle = "#666";
        self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
    });
};

我们只是遍历其中一个数据集中的所有点并添加标签(scale.startPoint 是图表区域的上边缘)

注意 - 为什么我们每次迭代都设置字体、对齐方式等?这是我们添加工具提示的时候。


3) 是否可以在每个点上设置永久工具提示(以显示温度)而不是悬停工具提示?

第一步是实际显示工具提示。这相当简单,尽管有点乏味。我们遍历所有 x 轴点,构建标签(通过遍历每个数据集),然后构造一个工具提示(幸运的是,我们可以为此使用 Chart.MultiTooltip 函数。

我们将其添加到我们用于构建新的 x 轴标签的同一个循环中。由于我们需要为工具提示着色,因此我们需要获取颜色集并将其存储在一个数组中(我们将其传递给 MultiTooltip 函数 - 我们只需要执行一次,因此我们将其从循环中取出。

修改后的animationComplete函数现在是这个

var animationComplete = function () {
    var self = this;

    var tooltipColors = []
    Chart.helpers.each(self.datasets, function (dataset) {
        tooltipColors.push({
            fill: dataset.strokeColor,
            stroke: dataset.strokeColor
        })
    });

    Chart.helpers.each(self.datasets[0].points, function (point, index) {
        var labels = []
        var total = 0;
        Chart.helpers.each(self.datasets, function (dataset) {
            labels.push(dataset.points[index].value)
            total += Number(dataset.points[index].y);
        });

        new Chart.MultiTooltip({
            x: point.x,
            y: total / 2,
            xPadding: self.options.tooltipXPadding,
            yPadding: self.options.tooltipYPadding,
            xOffset: self.options.tooltipXOffset,
            fillColor: self.options.tooltipFillColor,
            textColor: self.options.tooltipFontColor,
            fontFamily: self.options.tooltipFontFamily,
            fontStyle: self.options.tooltipFontStyle,
            fontSize: self.options.tooltipFontSize,
            titleTextColor: self.options.tooltipTitleFontColor,
            titleFontFamily: self.options.tooltipTitleFontFamily,
            titleFontStyle: self.options.tooltipTitleFontStyle,
            titleFontSize: self.options.tooltipTitleFontSize,
            cornerRadius: self.options.tooltipCornerRadius,
            labels: labels,
            legendColors: tooltipColors,
            legendColorBackground: self.options.multiTooltipKeyBackground,
            title: point.label,
            chart: self.chart,
            ctx: self.chart.ctx,
            custom: self.options.customTooltips
        }).draw()

        self.chart.ctx.font = Chart.helpers.fontString(self.fontSize, self.fontStyle, self.fontFamily)
        self.chart.ctx.textAlign = 'center';
        self.chart.ctx.textBaseline = "middle";
        self.chart.ctx.fillStyle = "#666";
        self.chart.ctx.fillText(point.label, point.x, self.scale.startPoint);
    });
};

它看起来很复杂,但我们所做的只是将我们从图表实例选项复制的选项传递给 MultiTooltip 函数。

工具提示会在动画完成时全部显示。但是,一旦您将鼠标移到图表上,它们就会全部消失!那是因为图表实例监听多个事件来决定是否开始检查是否应该显示工具提示——其中之一是 mousemove(这会导致它重绘图表,清除我们所有硬绘制的工具提示,如果幸运的话,它根据鼠标悬停的点绘制工具提示)

这是一个可配置的选项。所以,我们所要做的就是删除所有此类事件。

window.weeksChart = new Chart(ctx).Line(dataWeeks, {
    tooltipEvents: []
    ...

工作 fiddle - http://jsfiddle.net/fuodxsfv/


除非你的图表足够宽,否则你会有工具提示(主要是中间的 2 个)重叠(当然你可以将逻辑合并到上面的循环中来处理),但是无论如何,那些实际上是工具提示!