簡體   English   中英

Chart.js — 繪制任意垂直線

[英]Chart.js — drawing an arbitrary vertical line

如何使用 Chart.js 在 x 軸上的特定點繪制垂直線?

特別是,我想在 LineChart 上畫一條線來表示當天。 這是圖表的模型:http: //i.stack.imgur.com/VQDWR.png

在此處輸入圖像描述

更新- 此答案適用於 Chart.js 1.x,如果您正在尋找 2.x 答案,請查看評論和其他答案。

您擴展折線圖並在 draw 函數中包含用於繪制線條的邏輯。


預覽

在此處輸入圖片說明


HTML

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

腳本

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
});

選項屬性 lineAtIndex 控制在哪個點繪制線。

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

分享我的 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);

用法很簡單:

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

上面的代碼在位置 2,4 和 8 處插入紅色垂直線,穿過這些位置的第一個數據集的點。

我不得不經歷弄清楚如何用 ChartJS 2.0 做類似事情的麻煩,所以我想我會分享。

這是基於覆蓋圖表原型的新方法,如下所述: 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); };

我強烈建議使用Chartjs-Plugin-Annotation

可以在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"
            }
          }
        ]
      }
    }
  });
};

在這里查看更多詳細信息: https : //stackoverflow.com/a/36431041

這是一個無需chartjs-plugin-annotation,或hacking Chart.js渲染方式,或任何其他插件即可實現類似效果的筆: https ://codepen.io/gkemmey/pen/qBWZbYM

方法

  1. 使用組合條形圖/折線圖,並使用條形圖繪制垂直線。
  2. 使用兩個 y 軸:一個用於條形圖(我們不顯示),另一個用於所有其他折線圖數據集。
  3. 強制條形圖 y 軸為min: 0max: 1 任何時候你想畫一條垂直線,添加一個像{ x: where_the_line_goes, y: 1 }這樣的數據對象到你的條形圖數據集。
  4. 筆還在條形圖數據集中添加了一些自定義數據和圖例過濾器和標簽回調,以從圖例中排除條形圖數據集,並控制垂直線上的標簽。

優點

  1. 沒有其他依賴。 沒有自定義猴子修補/擴展。
  2. 注釋插件似乎沒有得到積極維護。 例如,atm,他們的事件處理程序會拋出關於“防止被動事件默認”的錯誤
  3. 也許專業人士:注釋插件總是顯示繪制的線條的標簽,你必須使用它們的事件回調來獲得懸停顯示效果。 Chart.js 工具提示默認顯示在懸停時。

缺點

  1. 我們在數據集配置中添加自定義數據,並希望它不會與 Chart.js 正在做的任何事情發生沖突。 這是 Chart.js 不希望存在的數據,但從 2.8 開始,也不會破壞它。

在 chart.js 3.8.0中,我使用了帶有時間線 (xAxis) 和百分比 (yAxis) 的折線圖/條形圖的組合。 查看文檔

數據集配置提供了一個選項來設置maxBarThickness (我已經應用了 2),然后在條形圖的每個數據條目上應用 y 軸的最大值。

數據集配置示例:

datasets: [
  {
    type: 'line'
    data: [
      {x: "2022-07-18", y: 10},
      {x: "2022-07-19", y: 60},
      {x: "2022-07-20", y: 30}
    ],
    ....
  },
  {
    type: 'bar',
    data: [
      {x: "2022-07-19", y: 100}
    ],
    maxBarThickness: 2,
    ...
  }
]

輸出示例:

在此處輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM