Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

determineDataLimits optimizations #6695

Merged
merged 10 commits into from
Nov 13, 2019
Merged

determineDataLimits optimizations #6695

merged 10 commits into from
Nov 13, 2019

Conversation

kurkle
Copy link
Member

@kurkle kurkle commented Nov 5, 2019

  • Math.sign replaced with helpers.sign, for IE compatibility
  • ticks.min / ticks.max parsed at scale creation for early access.
  • _getOtherScale internal helper
  • controller._getMinMax: skip values limited out of chart by other scale
  • scale._getMinMax: skip loops if valid min & max are defined
  • scale.category: use _parsedMin / _parsedMax in determineDataLimits
  • scale.logarithmic: rename nonNegativeOrDefault to positiveOrDefault, better minimization

Resolves: #4131
Pen

Copy link
Contributor

@benmccann benmccann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks good to me. I think there's a lot more we can do to optimize if we update the format that we accept data in. I started a discussion on that in a new issue #6696

src/core/core.controller.js Outdated Show resolved Hide resolved
@kurkle
Copy link
Member Author

kurkle commented Nov 6, 2019

Rebased + added some optimizations to time scale. Removal of duplicate arrayUnique when ticks come from only one source (data / labels) in getAllTimestamps is noticeable (somewhere between 5-10% in uPlot bench).

etimberg
etimberg previously approved these changes Nov 6, 2019
src/scales/scale.time.js Show resolved Hide resolved
src/core/core.scale.js Outdated Show resolved Hide resolved
data = getDataTimestamps(scale);
label = getLabelTimestamps(scale);
if (data.length && label.length) {
timestamps = arrayUnique(data.concat(label)).sort(sorter);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could end up doing arrayUnique and sort three times. Once in getDataTimestamps, once in getLabelTimestamps`, and once here. I think it'd be preferable if we could make it work more like it did before the early parse PR where it could happen only once

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder why the uPlot benchmark was done with distribution: 'series'
If time is plotted linearly (default), we can get away without any arrayUnique calls.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably because your timeseries demo uses 'series' :D

https://www.chartjs.org/samples/latest/scales/time/financial.html

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems it is done for demonstrating weekend exclusion from the chart.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interesting. something for me to think about for https://leeoniya.github.io/uPlot/demos/high-low-bands.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also be able to get rid of arrayUnique if we allow passing in the data as a single dataset instead of making the user specify the timestamps again for each line #6696

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That can already be done by using labels and (primitive) data, and ticks.source='labels'.
Should try out the new data format(s), how it would work out.

@kurkle
Copy link
Member Author

kurkle commented Nov 7, 2019

New uPlot benchmarks:

master - series: ~850ms
master - linear: ~650ms
2.9.2 - series: ~700ms
2.9.2 - linear: ~550ms
pr - series: ~700ms
pr - linear: ~450ms

timestamps = timestamps.concat(metas[i].controller._getAllParsedValues(scale));
}

// We can not assume data is in order or unique - not even for single dataset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have always assumed that data is in order and unique for a single dataset. I'm not sure I want to change that. Both because I don't know what other code has those assumptions built in and also because it'd be worse from a performance point of view

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not always, this assumption was made in quite recent optimizations. Originally arrayUnique was called regardless of number of datasets.

I can think of use cases where timestamps would not be in order (and should be drawn that way). But those are not the "usual" cases, so maybe it should be behind a switch.

I think this would be a lot more maintainable, if "series" and "linear" time scales were separated. "linear" could be based mostly on LinearBase.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I agree that it'd be more maintainable to have "series" and "linear" as separate scales. There's a lot of complication trying to cram both concepts into a single scale. I'm not sure there's a lot you could share between the linear time scale and linear scale. There is a lot you could share between the linear and series time scales though. Not sure whether it'd be better to have one extend the other or make a base time scale

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll explore that in a later PR

Copy link
Contributor

@benmccann benmccann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a couple small thoughts

src/scales/scale.time.js Outdated Show resolved Hide resolved
etimberg
etimberg previously approved these changes Nov 10, 2019
src/scales/scale.time.js Outdated Show resolved Hide resolved
benmccann
benmccann previously approved these changes Nov 12, 2019
@benmccann
Copy link
Contributor

@kurkle the build failed

@kurkle
Copy link
Member Author

kurkle commented Nov 12, 2019

The improved (only visible data is accounted for) min/max determination changed scale ranges on some of those clip fixtures. Updated the images.

@etimberg etimberg merged commit 76a89f0 into chartjs:master Nov 13, 2019
@kurkle kurkle deleted the data-limits branch November 13, 2019 06:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[FEATURE] Automatic adjustment of yAxes range based on displayed data
4 participants