chartjs / Chart.js

Simple HTML5 Charts using the <canvas> tag
https://www.chartjs.org/
MIT License
64.58k stars 11.9k forks source link

Chrome doesn't render dataset lines when dataset contains values that extrapolate max yAxes tick value by a large margin #7776

Closed gfrn closed 4 years ago

gfrn commented 4 years ago

Expected Behavior

It should work like Firefox, where the relevant points (those that are >=scales.yAxes.ticks.min and <=scales.yAxes.ticks.max) are displayed, and the line follows all points in a coherent manner, going out of bounds when the values extrapolate the maximum and minimum yAxis tick values.

Firefox Behavior

Current Behavior

While it works on Firefox just fine, Chrome fails to render any lines when a dataset contains values way above those set as the max in yAxes.ticks.max

Chrome Behavior

Steps to Reproduce

Use incredibly high values in one dataset, along with a few values that fit inside the min/max intervals, while setting scales.yAxes.ticks min and max values vastly inferior values to those present in the dataset, and then open the Chart utilizing Chrome.

Example: https://codepen.io/gfrancisco/pen/BaKrovx

Context

This error was detected in an application that displays values gathered from external sources, that sometimes due to abnormal conditions contains datasets with insanely high and sudden peaks/value ranges(0 to 5*10³⁴, for example, where this was detected)

Environment

etimberg commented 4 years ago

@ntanck in Chrome what size is the canvas when this occurs?

kurkle commented 4 years ago

Reproduces in master: https://codepen.io/kurkle/pen/VwaXWwY

I guess the issue is with the pixel value going out of acceptable range

myChart.scales.y.getPixelForValue(1e9)
-33783999630.160004
gfrn commented 4 years ago

@ntanck in Chrome what size is the canvas when this occurs?

It happens regardless of size, it seems. But the first time I detected it, it happened in 1809px by 295px. Reproduced it with multiple canvas sizes and it seems to happen every time

kurkle commented 4 years ago

A workaround could be to limit the pixel values to some sane range: https://codepen.io/kurkle/pen/oNxyKgg

kurkle commented 4 years ago

Interestingly the negative limit seems to be -8589934335. That does not make sense to me.

gfrn commented 4 years ago

I've noticed you're using 3.0.0 beta, what would be the equivalent of Chart.LinearScale in 2.9.3 and would there be any other changes I need to make for it to work? I can't seem to find any docs on that addition online, and the behavior is quite different

kurkle commented 4 years ago

For v2:

const originalGetPixelForValue = Chart.scaleService.constructors.linear.prototype.getPixelForValue;
Chart.scaleService.constructors.linear.prototype.getPixelForValue = function(value) {
  const pixel = originalGetPixelForValue.call(this, value);
  return Math.min(2147483647, Math.max(-2147483647, pixel))
}
gfrn commented 4 years ago

Thanks! That worked wonderfully