fnando / sparkline

Generate SVG sparklines with JavaScript without any external dependency.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Suggestion: Consider minimum values when determining a value's "y"

csharpengineer opened this issue · comments

I see the code calculates the maximum value and uses that when calculating the "y" when plotting a point. I suggest that the algorithm should also consider the minimum values as well, to keep negative values from going below the chart.

For example, [ -1, 0, 1] should show an increasing line starting at the bottom left going to the top right. In the current code, however, the line starts on the second point (0) and the first value is hidden.

I second this but for a different reason, I'm trying to display some sensor data. The data is a temperature reading.

Because all the readings are between lets say, 72-76 it barely moves the line. Ideally I'd want the y minimum considered so this shows the changes better.

@csharpengineer
I fixed this issue for my own use anyways. Should work for yours.

Using the same method as in the source I calculate the minimum and maximum values.

function defaultFetch(entry) {
	return entry.y;
}
const fetch = defaultFetch;
var values = valuesArray.map(entry => fetch(entry));
const max = Math.max(...values);
const min = Math.min(...values);

Then when you calculate your array to send I create 2 values.
A tooltipValue which is the one to display, and a value, which is calculated by the input minus the minimum.
For my purposed where all the numbers are close together but not near zero this made the graphs actually use the full range.

I may put this into a pull request

I basically did what you did. I calculated the minimum value of all the points, then adjusted each point using that value.

Something like this is also required if your data happens to be all negative - it's not safe to assume it's all positive and above zero. All zeros crash the height calculation. Add one negative point into the mix and then you hit this issue.

@Craigzyc Can you please publish your whole code? I would like to use fetch option.

Thanks.

@happytm

I created a codepen using the example adding in my code

Its using the BTC price which isn't a great example of data that doesn't work but you can see the slight difference in the fixed vs unfixed sparkline

https://codepen.io/craigzyc/pen/QWpprqB

@happytm

After doing that I decided to make another pen that actually showed the issue better. As you can see in this one the line is almost flat when you're looking at something like a room temperature without the fix

https://codepen.io/craigzyc/pen/abJJGaO

@Craigzyc Thank you for giving you time. It is clear now.

It took me some time to understand that this library only handles values >= 0.

In short: negative values are cropped, and even if there are only positive values, but high (e.g. [100, 200, 1000]), then there will be an extra space at the bottom of the series, and it will be flattened as @Craigzyc demonstrated in the codepen.

What I did:

  • normalize the values between 0 and 1 (simple math function)
  • use the datapoint.index to retrieve the original value from the input array

Cf https://git.nomics.world/dbnomics/dbnomics-website/-/merge_requests/30/diffs (It's Svelte code, showing only the diff to handle negative values)

I think that this should at least be mentioned in the README (I can do it but I'd like a "GO" from the maintainers), or add that normalization as a feature of the library, which would be less surprising for users IMHO (in that case the DataPoint should yield the original value in the mouse event).

Here's a branch-PR that normalises and then displays sparklines with support for positive and negative values.

https://github.com/robshep/sparkline-subzero/

image

I could only get this done with normalising, and so i've introduced a normalise option to try and maintain backwards compatibility.

There's also two difference style classes for fill areas above and below the x-axis.