在ChartJS或D3中为简单折线图绘制多条水平线和标签的最佳方法是什么?我知道我可以将它们作为单独的线条绘制,然后进行文本覆盖,但我想知道是否有更简单的解决方案。理想情况下,我可以将下面的每个标签创建为一个单元并将其移动到任何位置。
如果这在另一个JS图库中更简单,那么请随意提示。
以下示例
答案 0 :(得分:2)
要使用Chart.js,您必须扩展折线图
Chart.types.Line.extend({
name: "LineAlt",
initialize: function (data) {
// it's easier to programmatically update if you store the raw data in the object (vs. storing the geometric data)
this.marks = data.marks;
this.marks.xStart = Number(data.labels[0]);
this.marks.xStep = data.labels[1] - data.labels[0];
// make sure all our x labels are uniformly apart
if (!data.labels.every(function (e, i, arr) { return !i || ((e - arr[i - 1]) === this.marks.xStep); }, this))
throw "labels must be uniformly spaced";
Chart.types.Line.prototype.initialize.apply(this, arguments);
},
draw: function () {
Chart.types.Line.prototype.draw.apply(this, arguments);
// save existing context properties
var self = this;
var ctx = self.chart.ctx;
var scale = self.scale;
ctx.save();
// line properties
ctx.lineWidth = 1;
ctx.fillStyle = "#666";
ctx.strokeStyle = "#666";
ctx.textAlign = "center";
ctx.textBaseline = "bottom";
ctx.font = scale.font;
// draw marks
self.marks.forEach(function (mark) {
// assuming that the marks are always within the data range
var y = scale.calculateY(mark.y);
var x1 = scale.calculateX((mark.x1 - self.marks.xStart) / self.marks.xStep);
var x2 = scale.calculateX((mark.x2 - self.marks.xStart) / self.marks.xStep);
// draw line
ctx.beginPath();
ctx.moveTo(x1, y);
ctx.lineTo(x2, y);
// draw edges
ctx.moveTo(x1, y + 10);
ctx.lineTo(x1, y - 10);
ctx.moveTo(x2, y + 10);
ctx.lineTo(x2, y - 10);
ctx.stroke();
// draw text
ctx.fillText(mark.label, (x1 + x2) / 2, y + scale.fontSize * 1.5);
})
ctx.restore();
},
});
您传递的数据用于绘制像这样的行
var data = {
...
marks: [
{
x1: 1.5,
x2: 3.5,
y: 50,
label: 'Label1'
},
{
x1: 5,
x2: 7,
y: 60,
label: 'Label2'
}
]
};
并使用此扩展图表类型
创建图表var myLineChart = new Chart(ctx).LineAlt(data);
您可以像这样更新
myLineChart.marks[0].y = 80;
myLineChart.marks[0].x1 = 9;
myLineChart.marks[0].x2 = 10;
然后致电
myLineChart.update();
在画布上反映这些变化
<强>注意事项强>