Skip to content

Commit 4ff71d9

Browse files
committed
WIP: fix: chart jumping and wobbling on window.devicePixelRatio !== 1
1 parent e22ba7e commit 4ff71d9

File tree

2 files changed

+31
-6
lines changed

2 files changed

+31
-6
lines changed

examples/example1.html

+7-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,13 @@
1111
}, 500);
1212

1313
function createTimeline() {
14-
var chart = new SmoothieChart();
15-
chart.addTimeSeries(random, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 4 });
14+
var chart = new SmoothieChart({
15+
millisPerPixel: 1000 / (74.6 / 3),
16+
interpolation: 'step',
17+
maxValue: 10000,
18+
minValue: 0,
19+
});
20+
chart.addTimeSeries(random, { strokeStyle: 'rgba(0, 255, 0, 1)', fillStyle: 'rgba(0, 255, 0, 0.2)', lineWidth: 2 * 1 / window.devicePixelRatio });
1621
chart.streamTo(document.getElementById("chart"), 500);
1722
}
1823
</script>

smoothie.js

+24-4
Original file line numberDiff line numberDiff line change
@@ -141,12 +141,30 @@
141141
},
142142
// So lines (especially vertical and horizontal) look a) consistent along their length and b) sharp.
143143
pixelSnap: function(position, lineWidth) {
144-
if (lineWidth % 2 === 0) {
144+
// TODO grid lines and bezier lines still (occasionally) wobble. But it's still better than it was.
145+
146+
var dpr = window.devicePixelRatio
147+
coordinatesPerPixel = 1 / dpr;
148+
149+
// return position - position % window.devicePixelRatio;
150+
// return position - position % coordinatesPerPixel;
151+
152+
// if (lineWidth % (2 * dpr) === 0) {
153+
154+
// TODO may need to replace the strict comparison with `<= coordinatesPerPixel / 2` (or something
155+
// like this), that will minimize smudging instead of only removing it when it's strictly divisible.
156+
// Not only because of truncation error that comes with `dpr !== 1` but because it also makes sense for
157+
// `dpr === 1`.
158+
if (lineWidth % (2 * coordinatesPerPixel) === 0) {
145159
// Closest pixel edge.
146-
return Math.round(position);
160+
// return Math.round(position);
161+
162+
// TODO It's not the closest, it's round down.
163+
return position - position % coordinatesPerPixel;
147164
} else {
148165
// Closest pixel center.
149-
return Math.floor(position) + 0.5;
166+
// return Math.floor(position) + 0.5;
167+
return position - position % coordinatesPerPixel + coordinatesPerPixel / 2;
150168
}
151169
},
152170
};
@@ -797,7 +815,9 @@
797815
time = time || nowMillis - (this.delay || 0);
798816

799817
// Round time down to pixel granularity, so motion appears smoother.
800-
time -= time % this.options.millisPerPixel;
818+
// time -= time % this.options.millisPerPixel;
819+
// time -= time % (this.options.millisPerPixel / window.devicePixelRatio);
820+
time -= time % (this.options.millisPerPixel / window.devicePixelRatio);
801821

802822
if (!this.isAnimatingScale) {
803823
// We're not animating. We can use the last render time and the scroll speed to work out whether

0 commit comments

Comments
 (0)