我正在 JavaScript 循环中绘制带有一些系列值的条形图。尽管绘制系列值的代码位于绘制条形的代码下方,但在循环的下一次迭代中,刚刚绘制的文本会被覆盖。
当警报框出现时,您可以在下面的代码中看到这种效果的发生。
为什么在 Canvas 的另一部分上进行的绘制操作会覆盖之前在完全不同的位置绘制的内容?
更新:有人有用地指出使用 fillRect()
隐藏了这个问题,但我的问题是:为什么它首先发生?
var exampleData = {
"Series 1": 10,
"Series 2": 14,
"Series 3": 2,
"Series 4": 12
};
var BarChart = function(options) {
this.options = options;
this.canvas = options.canvas;
this.ctx = this.canvas.getContext("2d");
this.colors = options.colors;
this.plot = function() {
var maxValue = 0;
for (var categ in this.options.data) {
maxValue = Math.max(maxValue, this.options.data[categ]);
}
var noBars = Object.keys(this.options.data).length;
var barWidth = (this.canvas.height) / noBars;
var barIdx = 0;
for (categ in this.options.data) {
var barLength = Math.round(this.canvas.width * this.options.data[categ] / maxValue);
this.ctx.save();
alert("plotting series line " + categ);
this.ctx.fillStyle = this.colors[barIdx % this.colors.length];
this.ctx.rect(30, barIdx * barWidth, barLength, barWidth);
this.ctx.fill();
alert("plotting series value " + categ);
this.ctx.fillStyle = "#000000";
this.ctx.font = "24px Georgia";
this.ctx.textBaseline = "middle";
this.ctx.fillText(this.options.data[categ], 25, barIdx * barWidth + barWidth / 2); //will be covered in the loop's next iteration. Why?
this.ctx.restore();
barIdx++;
}
}
}
function init() {
var myCanvas = document.getElementById("myCanvas");
myCanvas.width = 800;
myCanvas.height = 300;
var ctx = myCanvas.getContext("2d");
var myBarChart = new BarChart({
canvas: myCanvas,
seriesName: "Example Series",
padding: 40,
data: exampleData,
colors: ["#D1E3F3", "#D1E3F3", "#D1E3F3", "#D1E3F3"]
});
myBarChart.plot();
}
document.addEventListener("DOMContentLoaded", init, false);
<canvas id="myCanvas"></canvas>
最佳答案
改变:
this.ctx.rect(30, barIdx * barWidth, barLength, barWidth);
this.ctx.fill();
改为使用fillRect()
解决问题:
this.ctx.fillRect(30, barIdx * barWidth, barLength, barWidth);
Working example here (与原始示例 here 相比)
关于Javascript Canvas 绘制顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51143526/