我经常使用 Chart.js 生成图表,无它,名字好记+免费+持续更新。现在主要基于 Vue 开发项目,所以经常使用 vue-chart.js。前阵子遇到一个需求:
- 把一组数据画成线图
- 用户可以任意点击时间
- 用数据生成饼图
那么就需要在线图中画一条竖线,标识出当前时间点。本以为这个需求不复杂,没想到不仅 Chart.js 不支持,包含这个功能的插件因为 Chart.js 升级的关系,暂时没法用。所以只好自己实现。
经过一番 Google,在别人的基础上(链接忘记了)改出了这个版本:
import {generateChart, mixins} from 'vue-chartjs';
import Chart from 'chart.js';
const {reactiveProp} = mixins;
Chart.defaults.LineWithLine = Chart.defaults.line;
Chart.controllers.LineWithLine = Chart.controllers.line.extend({
draw(ease) {
Chart.controllers.line.prototype.draw.call(this, ease);
let x;
if (this.chart.tooltip._active && this.chart.tooltip._active.length) {
const [activePoint] = this.chart.tooltip._active;
x = activePoint.tooltipPosition().x;
} else {
const index = this.chart.lastClickIndex;
if (index === undefined || index === null) {
return;
}
const meta = this.chart.getDatasetMeta(0);
x = meta.data[index]._model.x;
}
const ctx = this.chart.ctx;
const topY = this.chart.scales['y-axis-0'].top;
const bottomY = this.chart.scales['y-axis-0'].bottom;
// draw line
ctx.save();
ctx.beginPath();
ctx.moveTo(x, topY);
ctx.lineTo(x, bottomY);
ctx.lineWidth = 2;
ctx.strokeStyle = '#1C57A3';
ctx.stroke();
ctx.restore();
}
});
const Line = generateChart('line-chart', 'LineWithLine');
export default {
extends: Line,
mixins: [reactiveProp],
props: {
chartData: {
type: Object,
default: null,
},
options: {
type: Object,
default: null,
},
},
mounted() {
this.renderChart(this.chartData, this.options);
},
};
这个组件基于 vue-chart.js,用法也跟 vue-chart.js 一致。主要利用 draw
回调,在线图绘制完成后,找到特定的位置,画一条宽度为 2 的竖线。实际使用效果良好。
回头有空提个 PR 去。
欢迎吐槽,共同进步