Javascript 如何在 Chart.js 上显示数据值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31631354/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:56:39  来源:igfitidea点击:

how to display data values on Chart.js

javascriptchart.js

提问by FuSsA

I would like to ask if it's possible using Chart.js to display data values? I want to print the graph.

我想问一下是否可以使用 Chart.js 显示数据值?我想打印图表。

Thanks for any advice.

感谢您的任何建议。

回答by potatopeelings

Late edit:there is an official plugin for Chart.js 2.7.0+to do this: https://github.com/chartjs/chartjs-plugin-datalabels

后期编辑:Chart.js 有一个官方插件2.7.0+可以做到这一点:https: //github.com/chartjs/chartjs-plugin-datalabels

Original answer:

原答案:

You can loop through the points / bars onAnimationComplete and display the values

您可以遍历点/条 onAnimationComplete 并显示值



Preview

预览

enter image description here

在此处输入图片说明



HTML

HTML

<canvas id="myChart1" height="300" width="500"></canvas>
<canvas id="myChart2" height="300" width="500"></canvas>

Script

脚本

var chartData = {
    labels: ["January", "February", "March", "April", "May", "June"],
    datasets: [
        {
            fillColor: "#79D1CF",
            strokeColor: "#79D1CF",
            data: [60, 80, 81, 56, 55, 40]
        }
    ]
};

var ctx = document.getElementById("myChart1").getContext("2d");
var myLine = new Chart(ctx).Line(chartData, {
    showTooltips: false,
    onAnimationComplete: function () {

        var ctx = this.chart.ctx;
        ctx.font = this.scale.font;
        ctx.fillStyle = this.scale.textColor
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";

        this.datasets.forEach(function (dataset) {
            dataset.points.forEach(function (points) {
                ctx.fillText(points.value, points.x, points.y - 10);
            });
        })
    }
});

var ctx = document.getElementById("myChart2").getContext("2d");
var myBar = new Chart(ctx).Bar(chartData, {
    showTooltips: false,
    onAnimationComplete: function () {

        var ctx = this.chart.ctx;
        ctx.font = this.scale.font;
        ctx.fillStyle = this.scale.textColor
        ctx.textAlign = "center";
        ctx.textBaseline = "bottom";

        this.datasets.forEach(function (dataset) {
            dataset.bars.forEach(function (bar) {
                ctx.fillText(bar.value, bar.x, bar.y - 5);
            });
        })
    }
});


Fiddle - http://jsfiddle.net/uh9vw0ao/

小提琴 - http://jsfiddle.net/uh9vw0ao/

回答by Ross

Here is an updated version for Chart.js 2.3

这是 Chart.js 2.3 的更新版本

Sep 23, 2016: Edited my code to work with v2.3 for both line/bar type.

2016 年 9 月 23 日:编辑了我的代码以使用 v2.3 的线条/条形类型。

Important:Even if you don't need the animation, don't change the duration option to 0, otherwise you will get chartInstance.controller is undefinederror.

重要提示:即使您不需要动画,也不要将持续时间选项更改为 0,否则您会得到chartInstance.controller is undefined错误。

var chartData = {
    labels: ["January", "February", "March", "April", "May", "June"],
        datasets: [
            {
                fillColor: "#79D1CF",
                strokeColor: "#79D1CF",
                data: [60, 80, 81, 56, 55, 40]
            }
        ]
    };

var opt = {
    events: false,
    tooltips: {
        enabled: false
    },
    hover: {
        animationDuration: 0
    },
    animation: {
        duration: 1,
        onComplete: function () {
            var chartInstance = this.chart,
                ctx = chartInstance.ctx;
            ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
            ctx.textAlign = 'center';
            ctx.textBaseline = 'bottom';

            this.data.datasets.forEach(function (dataset, i) {
                var meta = chartInstance.controller.getDatasetMeta(i);
                meta.data.forEach(function (bar, index) {
                    var data = dataset.data[index];                            
                    ctx.fillText(data, bar._model.x, bar._model.y - 5);
                });
            });
        }
    }
};
 var ctx = document.getElementById("Chart1"),
     myLineChart = new Chart(ctx, {
        type: 'bar',
        data: chartData,
        options: opt
     });
<canvas id="myChart1" height="300" width="500"></canvas>

回答by Aaron Hudon

This animation option works for 2.1.3 on a bar chart.

此动画选项适用于条形图上的 2.1.3。

Slightly modified @Ross answer

稍微修改@Ross 答案

animation: {
duration: 0,
onComplete: function () {
    // render the value of the chart above the bar
    var ctx = this.chart.ctx;
    ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
    ctx.fillStyle = this.chart.config.options.defaultFontColor;
    ctx.textAlign = 'center';
    ctx.textBaseline = 'bottom';
    this.data.datasets.forEach(function (dataset) {
        for (var i = 0; i < dataset.data.length; i++) {
            var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
            ctx.fillText(dataset.data[i], model.x, model.y - 5);
        }
    });
}}

回答by David

I think the nicest option to do this in chartJS v2.x is by using a plugin, so you don't have a large block of code in the options. In addition, it prevents the data from disappearing when hovering over a bar.

我认为在 chartJS v2.x 中执行此操作的最佳选择是使用插件,因此选项中没有大量代码。此外,它可以防止将鼠标悬停在条形上时数据消失。

I.e. simply use this code, which registers a plugin that adds the text after the chart is drawn.

即简单地使用这段代码,它注册了一个插件,在绘制图表后添加文本。

Chart.pluginService.register({
    afterDraw: function(chartInstance) {
        var ctx = chartInstance.chart.ctx;

        // render the value of the chart above the bar
        ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
        ctx.textAlign = 'center';
        ctx.textBaseline = 'bottom';

        chartInstance.data.datasets.forEach(function (dataset) {
            for (var i = 0; i < dataset.data.length; i++) {
                var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
                ctx.fillText(dataset.data[i], model.x, model.y - 2);
            }
        });
  }
});

回答by Hung Tran

Based on @Ross's answer answer for Chart.js 2.0 and up, I had to include a little tweak to guard against the case when the bar's heights comes too chose to the scale boundary.

根据@Ross 对 Chart.js 2.0 及更高版本的回答,我必须进行一些调整,以防止当条的高度选择到比例边界时出现这种情况。

Example

例子

The animationattribute of the bar chart's option:

animation条形图选项的属性:

animation: {
            duration: 500,
            easing: "easeOutQuart",
            onComplete: function () {
                var ctx = this.chart.ctx;
                ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontFamily, 'normal', Chart.defaults.global.defaultFontFamily);
                ctx.textAlign = 'center';
                ctx.textBaseline = 'bottom';

                this.data.datasets.forEach(function (dataset) {
                    for (var i = 0; i < dataset.data.length; i++) {
                        var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model,
                            scale_max = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._yScale.maxHeight;
                        ctx.fillStyle = '#444';
                        var y_pos = model.y - 5;
                        // Make sure data value does not get overflown and hidden
                        // when the bar's value is too close to max value of scale
                        // Note: The y value is reverse, it counts from top down
                        if ((scale_max - model.y) / scale_max >= 0.93)
                            y_pos = model.y + 20; 
                        ctx.fillText(dataset.data[i], model.x, y_pos);
                    }
                });               
            }
        }

回答by Karthik

If you are using the plugin chartjs-plugin-datalabelsthen the following code options object will help

如果您使用插件chartjs-plugin-datalabels那么以下代码选项对象将有所帮助

Make sure you import import 'chartjs-plugin-datalabels';in your typescript file or add reference to <script src="chartjs-plugin-datalabels.js"></script>in your javascript file.

确保import 'chartjs-plugin-datalabels';在打字稿文件中导入或<script src="chartjs-plugin-datalabels.js"></script>在 javascript 文件中添加引用。

options: {
    maintainAspectRatio: false,
    responsive: true,
    scales: {
      yAxes: [{
        ticks: {
          beginAtZero: true,
        }
      }]
    },
    plugins: {
      datalabels: {
        anchor: 'end',
        align: 'top',
        formatter: Math.round,
        font: {
          weight: 'bold'
        }
      }
    }
  }

回答by Pierre de LESPINAY

Following this good answer, I'd use these options for a bar chart:

按照这个好的答案,我将这些选项用于条形图:

var chartOptions = {
    animation: false,
    responsive : true,
    tooltipTemplate: "<%= value %>",
    tooltipFillColor: "rgba(0,0,0,0)",
    tooltipFontColor: "#444",
    tooltipEvents: [],
    tooltipCaretSize: 0,
    onAnimationComplete: function()
    {
        this.showTooltip(this.datasets[0].bars, true);
    }
};

window.myBar = new Chart(ctx1).Bar(chartData, chartOptions);

Bar Chart

条形图

This still uses the tooltip system and his advantages (automatic positionning, templating, ...) but hiding the decorations (background color, caret, ...)

这仍然使用工具提示系统和他的优势(自动定位,模板,...),但隐藏了装饰(背景颜色,插入符号,...)

回答by Radek Dest

From chart.js samples (file Chart.js-2.4.0/samples/data_labelling.html) :

来自 chart.js 示例(文件 Chart.js-2.4.0/samples/data_labelling.html):

``` // Define a plugin to provide data labels

``` // 定义一个插件来提供数据标签

    Chart.plugins.register({
        afterDatasetsDraw: function(chartInstance, easing) {
            // To only draw at the end of animation, check for easing === 1
            var ctx = chartInstance.chart.ctx;

            chartInstance.data.datasets.forEach(function (dataset, i) {
                var meta = chartInstance.getDatasetMeta(i);
                if (!meta.hidden) {
                    meta.data.forEach(function(element, index) {
                        // Draw the text in black, with the specified font
                        ctx.fillStyle = 'rgb(0, 0, 0)';

                        var fontSize = 16;
                        var fontStyle = 'normal';
                        var fontFamily = 'Helvetica Neue';
                        ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);

                        // Just naively convert to string for now
                        var dataString = dataset.data[index].toString();

                        // Make sure alignment settings are correct
                        ctx.textAlign = 'center';
                        ctx.textBaseline = 'middle';

                        var padding = 5;
                        var position = element.tooltipPosition();
                        ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
                    });
                }
            });
        }
    });

```

``

回答by DavidX

I'd recommend using this plugin: https://github.com/chartjs/chartjs-plugin-datalabels

我建议使用这个插件:https: //github.com/chartjs/chartjs-plugin-datalabels

Labels can be added to your charts simply by importing the plugin to the js file e.g.:

只需将插件导入 js 文件,即可将标签添加到图表中,例如:

import 'chartjs-plugin-datalabels'

And can be fine tuned using these docs: https://chartjs-plugin-datalabels.netlify.com/options.html

并且可以使用这些文档进行微调:https: //chartjs-plugin-datalabels.netlify.com/options.html

回答by Janne Annala

Edited @ajhuddy's answer a little. Only for bar charts. My version adds:

稍微编辑了@ajhuddy 的回答。仅用于条形图。我的版本增加了:

  • Fade in animation for the values.
  • Prevent clipping by positioning the value inside the bar if the bar is too high.
  • No blinking.
  • 淡入动画值。
  • 如果条形太高,则通过将值定位在条形内来防止剪裁。
  • 没有眨眼。

Example

例子

Downside: When hovering over a bar that has value inside it the value might look a little jagged. I have not found a solution do disable hover effects. It might also need tweaking depending on your own settings.

缺点:当将鼠标悬停在内部有值的条形上时,该值可能看起来有点参差不齐。我还没有找到禁用悬停效果的解决方案。它可能还需要根据您自己的设置进行调整。

Configuration:

配置:

bar: {
  tooltips: {
    enabled: false
  },
  hover: {
    animationDuration: 0
  },
  animation: {
    onComplete: function() {
      this.chart.controller.draw();
      drawValue(this, 1);
    },
    onProgress: function(state) {
      var animation = state.animationObject;
      drawValue(this, animation.currentStep / animation.numSteps);
    }
  }
}

Helpers:

帮手:

// Font color for values inside the bar
var insideFontColor = '255,255,255';
// Font color for values above the bar
var outsideFontColor = '0,0,0';
// How close to the top edge bar can be before the value is put inside it
var topThreshold = 20;

var modifyCtx = function(ctx) {
  ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, 'normal', Chart.defaults.global.defaultFontFamily);
  ctx.textAlign = 'center';
  ctx.textBaseline = 'bottom';
  return ctx;
};

var fadeIn = function(ctx, obj, x, y, black, step) {
  var ctx = modifyCtx(ctx);
  var alpha = 0;
  ctx.fillStyle = black ? 'rgba(' + outsideFontColor + ',' + step + ')' : 'rgba(' + insideFontColor + ',' + step + ')';
  ctx.fillText(obj, x, y);
};

var drawValue = function(context, step) {
  var ctx = context.chart.ctx;

  context.data.datasets.forEach(function (dataset) {
    for (var i = 0; i < dataset.data.length; i++) {
      var model = dataset._meta[Object.keys(dataset._meta)[0]].data[i]._model;
      var textY = (model.y > topThreshold) ? model.y - 3 : model.y + 20;
      fadeIn(ctx, dataset.data[i], model.x, textY, model.y > topThreshold, step);
    }
  });
};