摆脱 Chart.js canvas 子像素
Getting rid of Chart.js canvas subpixels
我正在开发一个非常小的小部件,它显示一个简单的条形图:
我正在使用 Chart.js 来完成该特定任务。
var canvas = this.$(".chart-canvas")[0];
if (canvas) {
var ctx = canvas.getContext("2d");
ctx.translate(0.5, 0.5);
window.barChart = new Chart(ctx).Bar(barChartData, {
responsive: true,
maintainAspectRatio: false,
showScale: false,
scaleShowGridLines: false,
scaleGridLineWidth: 0,
barValueSpacing: 1,
barDatasetSpacing: 0,
showXAxisLabel: false,
barShowStroke: false,
showTooltips: false,
animation: false
});
如你所见,我试过了
ctx.translate(0.5, 0.5);
但这并没有真正帮助。
有什么办法可以去掉亚像素渲染吗?
我读过 Bresenham 的线算法,但不知道如何在那里实现它。
任何ideas/suggestions赞赏。
提前致谢!
假设您只有一种颜色,您可以通过扩展图表并覆盖绘图来执行 getImageData,"rounding"(如果像素具有 R、G 或 B 值,将其设置为颜色)像素颜色和 putImageData。
您也可以对多种颜色执行此操作,但是当附近有两种颜色时,它会变得有点复杂。
但是,您看到的条形值间距的差异是由于 Chart.js 计算条形的 x 位置的方式 - 发生了四舍五入。
您可以扩展图表并覆盖计算 x 位置的方法以消除舍入
Chart.types.Bar.extend({
// Passing in a name registers this chart in the Chart namespace in the same way
name: "BarAlt",
initialize: function (data) {
Chart.types.Bar.prototype.initialize.apply(this, arguments);
// copy paste from library code with only 1 line changed
this.scale.calculateX = function (index) {
var isRotated = (this.xLabelRotation > 0),
innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
valueWidth = innerWidth / Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),
valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
if (this.offsetGridLines) {
valueOffset += (valueWidth / 2);
}
// the library code rounds this off - we don't
return valueOffset;
}
// render again because the original initialize call does a render
// when animation is off this is the only render that happens
this.render();
}
});
你可以这样称呼它
var ctx = document.getElementById('canvas').getContext('2d');
var myBarChart = new Chart(ctx).BarAlt(data, {
...
Fiddle - http://jsfiddle.net/gf2c4ue4/
如果放大,您可以更好地看到差异。
最上面的是扩展图
我正在开发一个非常小的小部件,它显示一个简单的条形图:
我正在使用 Chart.js 来完成该特定任务。
var canvas = this.$(".chart-canvas")[0];
if (canvas) {
var ctx = canvas.getContext("2d");
ctx.translate(0.5, 0.5);
window.barChart = new Chart(ctx).Bar(barChartData, {
responsive: true,
maintainAspectRatio: false,
showScale: false,
scaleShowGridLines: false,
scaleGridLineWidth: 0,
barValueSpacing: 1,
barDatasetSpacing: 0,
showXAxisLabel: false,
barShowStroke: false,
showTooltips: false,
animation: false
});
如你所见,我试过了
ctx.translate(0.5, 0.5);
但这并没有真正帮助。
有什么办法可以去掉亚像素渲染吗? 我读过 Bresenham 的线算法,但不知道如何在那里实现它。
任何ideas/suggestions赞赏。
提前致谢!
假设您只有一种颜色,您可以通过扩展图表并覆盖绘图来执行 getImageData,"rounding"(如果像素具有 R、G 或 B 值,将其设置为颜色)像素颜色和 putImageData。
您也可以对多种颜色执行此操作,但是当附近有两种颜色时,它会变得有点复杂。
但是,您看到的条形值间距的差异是由于 Chart.js 计算条形的 x 位置的方式 - 发生了四舍五入。
您可以扩展图表并覆盖计算 x 位置的方法以消除舍入
Chart.types.Bar.extend({
// Passing in a name registers this chart in the Chart namespace in the same way
name: "BarAlt",
initialize: function (data) {
Chart.types.Bar.prototype.initialize.apply(this, arguments);
// copy paste from library code with only 1 line changed
this.scale.calculateX = function (index) {
var isRotated = (this.xLabelRotation > 0),
innerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),
valueWidth = innerWidth / Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),
valueOffset = (valueWidth * index) + this.xScalePaddingLeft;
if (this.offsetGridLines) {
valueOffset += (valueWidth / 2);
}
// the library code rounds this off - we don't
return valueOffset;
}
// render again because the original initialize call does a render
// when animation is off this is the only render that happens
this.render();
}
});
你可以这样称呼它
var ctx = document.getElementById('canvas').getContext('2d');
var myBarChart = new Chart(ctx).BarAlt(data, {
...
Fiddle - http://jsfiddle.net/gf2c4ue4/
如果放大,您可以更好地看到差异。
最上面的是扩展图