Javascript Chart.js — 绘制任意垂直线

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30256695/
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 04:52:20  来源:igfitidea点击:

Chart.js — drawing an arbitrary vertical line

javascriptchart.js

提问by Fredrik

How can I draw an vertical line at a particular point on the x-axis using Chart.js?

如何使用 Chart.js 在 x 轴上的特定点绘制一条垂直线?

In particular, I want to draw a line to indicate the current day on a LineChart. Here's a mockup of the chart: http://i.stack.imgur.com/VQDWR.png

特别是,我想画一条线来指示 LineChart 上的当前日期。这是图表的模型:http: //i.stack.imgur.com/VQDWR.png

enter image description here

在此处输入图片说明

回答by potatopeelings

Update- this answer is for Chart.js 1.x, if you are looking for a 2.x answer check the comments and other answers.

更新- 此答案适用于 Chart.js 1.x,如果您正在寻找 2.x 答案,请查看评论和其他答案。

You extend the line chart and include logic for drawing the line in the draw function.

您扩展折线图并在 draw 函数中包含用于绘制线条的逻辑。



Preview

预览

enter image description here

在此处输入图片说明



HTML

HTML

<div>
    <canvas id="LineWithLine" width="600" height="400"></canvas>
</div>

Script

脚本

var data = {
    labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
    datasets: [{
        data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1]
    }]
};

var ctx = document.getElementById("LineWithLine").getContext("2d");

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

        var point = this.datasets[0].points[this.options.lineAtIndex]
        var scale = this.scale

        // draw line
        this.chart.ctx.beginPath();
        this.chart.ctx.moveTo(point.x, scale.startPoint + 24);
        this.chart.ctx.strokeStyle = '#ff0000';
        this.chart.ctx.lineTo(point.x, scale.endPoint);
        this.chart.ctx.stroke();

        // write TODAY
        this.chart.ctx.textAlign = 'center';
        this.chart.ctx.fillText("TODAY", point.x, scale.startPoint + 12);
    }
});

new Chart(ctx).LineWithLine(data, {
    datasetFill : false,
    lineAtIndex: 2
});

The option property lineAtIndex controls which point to draw the line at.

选项属性 lineAtIndex 控制在哪个点绘制线。

Fiddle - http://jsfiddle.net/dbyze2ga/14/

小提琴 - http://jsfiddle.net/dbyze2ga/14/

回答by Tomá? Dvo?ák

Sharing my solution for chartjs.org version 2.5. I wanted to use a plugin, to make the implementation reusable.

分享我的 chartjs.org 2.5 版解决方案。我想使用一个插件,使实现可重用。

const verticalLinePlugin = {
  getLinePosition: function (chart, pointIndex) {
      const meta = chart.getDatasetMeta(0); // first dataset is used to discover X coordinate of a point
      const data = meta.data;
      return data[pointIndex]._model.x;
  },
  renderVerticalLine: function (chartInstance, pointIndex) {
      const lineLeftOffset = this.getLinePosition(chartInstance, pointIndex);
      const scale = chartInstance.scales['y-axis-0'];
      const context = chartInstance.chart.ctx;

      // render vertical line
      context.beginPath();
      context.strokeStyle = '#ff0000';
      context.moveTo(lineLeftOffset, scale.top);
      context.lineTo(lineLeftOffset, scale.bottom);
      context.stroke();

      // write label
      context.fillStyle = "#ff0000";
      context.textAlign = 'center';
      context.fillText('MY TEXT', lineLeftOffset, (scale.bottom - scale.top) / 2 + scale.top);
  },

  afterDatasetsDraw: function (chart, easing) {
      if (chart.config.lineAtIndex) {
          chart.config.lineAtIndex.forEach(pointIndex => this.renderVerticalLine(chart, pointIndex));
      }
  }
  };

  Chart.plugins.register(verticalLinePlugin);

Usage is simple then:

用法很简单:

 new Chart(ctx, {
     type: 'line',
     data: data,
     label: 'Progress',
     options: options,
     lineAtIndex: [2,4,8],
 })

The code above inserts red vertical lines at positions 2,4 and 8, running through points of first dataset at those positions.

上面的代码在位置 2,4 和 8 处插入红色垂直线,穿过这些位置的第一个数据集的点。

回答by Brandon Johnson

I had to go through the trouble of figuring out how to do something similar with ChartJS 2.0 so I thought I would share.

我不得不经历弄清楚如何用 ChartJS 2.0 做类似事情的麻烦,所以我想我会分享。

This is based on the new way of overriding a chart prototype as explained here: https://github.com/chartjs/Chart.js/issues/2321

这是基于覆盖图表原型的新方法,如下所述:https: //github.com/chartjs/Chart.js/issues/2321

var ctx = document.getElementById('income-chart');

var originalDraw = Chart.controllers.line.prototype.draw;
Chart.controllers.line.prototype.draw = function (ease) {
    originalDraw.call(this, ease);

    var point = dataValues[vm.incomeCentile];
    var scale = this.chart.scales['x-axis-0'];

    // calculate the portion of the axis and multiply by total axis width
    var left = (point.x / scale.end * (scale.right - scale.left));
                
    // draw line
    this.chart.chart.ctx.beginPath();
    this.chart.chart.ctx.strokeStyle = '#ff0000';
    this.chart.chart.ctx.moveTo(scale.left + left, 0);
    this.chart.chart.ctx.lineTo(scale.left + left, 1000000);
    this.chart.chart.ctx.stroke();

    // write label
    this.chart.chart.ctx.textAlign = 'center';
    this.chart.chart.ctx.fillText('YOU', scale.left + left, 200);
};

回答by phifi

I'd highly recommend to use the Chartjs-Plugin-Annotation.

我强烈建议使用Chartjs-Plugin-Annotation

An example can be found at CodePen

可以在CodePen上找到一个示例

var chartData = {
  labels: ["JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"],
  datasets: [
    {
      data: [12, 3, 2, 1, 8, 8, 2, 2, 3, 5, 7, 1]
    }
  ]
};

window.onload = function() {
  var ctx = document.getElementById("canvas").getContext("2d");
  new Chart(ctx, {
    type: "line",
    data: chartData,
    options: {
      annotation: {
        annotations: [
          {
            type: "line",
            mode: "vertical",
            scaleID: "x-axis-0",
            value: "MAR",
            borderColor: "red",
            label: {
              content: "TODAY",
              enabled: true,
              position: "top"
            }
          }
        ]
      }
    }
  });
};

Have a look here for more Details: https://stackoverflow.com/a/36431041

在这里查看更多详细信息:https: //stackoverflow.com/a/36431041

回答by Gray Kemmey

Here's a pen that achieves a similar effect without the chartjs-plugin-annotation, or hacking how Chart.js renders, or any other plugins: https://codepen.io/gkemmey/pen/qBWZbYM

这是一个无需chartjs-plugin-annotation,或hacking Chart.js渲染方式或任何其他插件即可实现类似效果的笔:https://codepen.io/gkemmey/pen/qBWZbYM

Approach

方法

  1. Use a combo bar / line chart, and use the bar chart to draw the vertical lines.
  2. Use two y-axes: one for the bar chart (which we don't display), and one for all your other line chart datasets.
  3. Force the bar chart y-axes to min: 0and max: 1. Anytime you want to draw a vertical line, add a data object like { x: where_the_line_goes, y: 1 }to your bar chart dataset.
  4. The pen also adds some custom data to the bar chart dataset and a legend filter and label callback to exclude the bar chart dataset from the legend, and control the label on the vertical line.
  1. 使用组合条形图/折线图,并使用条形图绘制垂直线。
  2. 使用两个 y 轴:一个用于条形图(我们不显示),另一个用于所有其他折线图数据集。
  3. 将条形图 y 轴强制为min: 0max: 1。任何时候您想绘制一条垂直线,都可以{ x: where_the_line_goes, y: 1 }向条形图数据集添加一个数据对象。
  4. 笔还在条形图数据集中添加了一些自定义数据和图例过滤器和标签回调,以从图例中排除条形图数据集,并控制垂直线上的标签。

Pros

优点

  1. No other dependencies. No custom monkey patching / extending.
  2. The annotations plugin doesn't seem to be actively maintained. For instance, atm, their event handlers throw an error about "preventing default on passive events"
  3. Maybe a pro: The annotations plugin always shows the labels of lines drawn, and you have to use their event callbacks to get a show-on-hover effect. Chart.js tooltips show on hover by default.
  1. 没有其他依赖。没有自定义猴子修补/扩展。
  2. 注释插件似乎没有得到积极维护。例如,atm,他们的事件处理程序会抛出关于“防止被动事件默认”的错误
  3. 也许专业人士:注释插件总是显示绘制的线条的标签,你必须使用它们的事件回调来获得悬停显示效果。Chart.js 工具提示默认显示在悬停时。

Cons

缺点

  1. We're adding custom data in the dataset config, and hoping it doesn't conflict with anything Chart.js is doing. It's data Chart.js doesn't expect to be there, but as of 2.8, also doesn't break it.
  1. 我们在数据集配置中添加自定义数据,并希望它不会与 Chart.js 正在做的任何事情发生冲突。这是 Chart.js 不希望存在的数据,但从 2.8 开始,也不会破坏它。