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);
};
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, label, color, alignment, xOffset, yOffset) {
const lineLeftOffset = this.getLinePosition(chartInstance, pointIndex);
const scale = chartInstance.scales['y-axis-0'];
const context = chartInstance.chart.ctx;
if (xOffset == undefined) xOffset = 0;
if (yOffset == undefined) yOffset = 0;
// render vertical line
context.beginPath();
context.strokeStyle = color;
context.moveTo(lineLeftOffset, scale.top);
context.lineTo(lineLeftOffset, scale.bottom);
context.stroke();
// write label
context.fillStyle = color;
context.textAlign = alignment;
context.fillText(label, lineLeftOffset + xOffset, (scale.bottom - scale.top) / 2 + scale.top + yOffset);
},
afterDatasetsDraw: function (chart, easing) {
if (chart.config.lineAtIndex) {
labelIndex = 0;
chart.config.lineAtIndex.forEach((pointIndex) => {
if (chart.config.verticalLinesLabels != undefined) { // if array of labels exists...
label = chart.config.verticalLinesLabels[labelIndex]; // chart.config.verticalLinesLabels must contain all elements; use elements ="" for lines not requiring labels
color = chart.config.verticalLinesColors[labelIndex]; // chart.config.verticalLinesColors must contain all elements
alignment = chart.config.verticalLinesAlignments[labelIndex]; // chart.config.verticalLinesAlignments must contain all elements
xOff = chart.config.verticalLinesX[labelIndex]; // chart.config.verticalLinesX must contain all elements
yOff = chart.config.verticalLinesY[labelIndex]; // chart.config.verticalLinesY must contain all elements
} else {
label = "";
}
this.renderVerticalLine(chart, pointIndex, label, color, alignment, xOff, yOff)
labelIndex++;
});
}
}
};
Chart.plugins.register(verticalLinePlugin);
用法:
myChart.config.verticalLinesLabels = ["aaa", "bbb", "ddd"];
myChart.config.verticalLinesColors = ["#FF0000", 'rgb(0,255,0)', 'rgba(0,0,255,0.5)'];
myChart.config.verticalLinesAlignments = ["left", "center", "right"]; // Set label aligment (note: it is inverted because referred to line, not to label)
myChart.config.verticalLinesX = [10,5,0]; // Set label X offset
myChart.config.verticalLinesY = [10,5,0]; // Set label Y offset
myChart.config.lineAtIndex = [10,30,50]; // Mandatory to enable all previous ones
myChart.update()
7条答案
按热度按时间oxosxuxt1#
更新-此答案适用于Chart.js 1.x,如果您正在寻找2.x版本的答案,请查看评论和其他答案。
您可以扩展折线图,并在draw函数中包含用于绘制折线的逻辑。
预览
HTML格式
脚本
选项属性lineAtIndex控制要在哪一点绘制直线。
小提琴-http://jsfiddle.net/dbyze2ga/14/
ogq8wdun2#
分享我的chartjs.org版本2.5的解决方案。我想使用一个插件,使实现可重用。
用法很简单:
上面的代码在位置2、4和8处插入红色垂直线,穿过这些位置处的第一个数据集的点。
mbskvtky3#
我强烈推荐使用Chartjs-Plugin-Annotation。
可在CodePen中找到示例
请点击此处了解更多详情:https://stackoverflow.com/a/36431041
0md85ypi4#
我不得不经历麻烦,弄清楚如何用ChartJS 2. 0做类似的事情,所以我想我会分享。
这是基于重写图表原型的新方法,如下所述:https://github.com/chartjs/Chart.js/issues/2321
xytpbqjk5#
下面是一个实现类似效果的笔,它不需要chartjs-plugin-annotation,也不需要破解Chart.js的渲染方式,或者任何其他插件:https://codepen.io/gkemmey/pen/qBWZbYM
方法
1.使用组合条形/折线图,并使用条形图绘制垂直线。
1.使用两个y轴:一个用于条形图(我们不显示条形图),一个用于所有其他折线图数据集。
1.将条形图的y轴强制为
min: 0
和max: 1
。无论何时要绘制垂直线,都可以向条形图数据集中添加一个数据对象(如{ x: where_the_line_goes, y: 1 }
)。1.画笔还向条形图数据集添加一些自定义数据,并添加图例筛选器和标签回调以从图例中排除条形图数据集,并控制垂直线上的标签。
职业玩家
1.没有其他依赖项。没有自定义的monkey修补/扩展。
1.注解插件似乎没有被主动维护。例如,atm,他们的事件处理程序抛出一个关于“防止默认被动事件”的错误。
1.也许是专业人士:注解插件总是显示所画线条的标签,您必须使用它们的事件回调来获得悬停时显示的效果。Chart.js工具提示默认显示悬停时显示。
缺点
1.我们在dataset config中添加了自定义数据,希望它不会与Chart.js正在做的任何事情相冲突。这是Chart.js不希望出现的数据,但从2.8开始,也没有破坏它。
ekqde3dh6#
在chart.js3.8.0中,我使用了带有时间轴(x轴)和百分比(y轴)的折线图/条形图组合。请参见docs
数据集配置提供了一个选项,用于设置
maxBarThickness
(我应用了2),然后在条形图的每个数据条目上应用y轴的最大值。数据集配置示例:
输出示例:
xxe27gdn7#
@托马斯·德沃夏克答案的增强版
支持:
用法: