摆脱 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/

如果放大,您可以更好地看到差异。


最上面的是扩展图