-
Notifications
You must be signed in to change notification settings - Fork 12k
Enable data decimation plugins by separating parsed data into two arrays #8251
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
Conversation
| }; | ||
| me.chart.notifyPlugins('afterDataParse', args); | ||
|
|
||
| if (!isNullOrUndef(args.data)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd reverse the cases to avoid the !
| const me = this; | ||
| const meta = me._cachedMeta; | ||
| const _parsed = meta._parsed; | ||
| // Use filtered parsed elements if the exist, otherwise the full elements |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
isn't the correct array always available in the meta._parsed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm storing the full array in meta._parsedRaw and the filtered one in meta._parsed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if there is not filtered array, meta._parsed === meta._parsedRaw?
| } | ||
| // Re-parse the old elements (new elements are parsed in _insertElements) | ||
| me.parse(0, Math.min(numData, numMeta)); | ||
| // me.parse(0, Math.min(numData, numMeta)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need to do the parsing first and resync the element counts after that. So compare _data.length to _parsedRaw.length and if that differs parse. then compare _parsed.length to numMeta and add the elements. need to remove the parsing from the _insertElements.
|
|
||
| if (me._parsing) { | ||
| meta._parsed.splice(start, 0, ...new Array(count)); | ||
| meta._parsedRaw.splice(start, 0, ...new Array(count)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can't do the parsing here at all, because start and count refer to elements, no to the raw data.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I'm realizing that this is causing a lot of tests to fail. A lot of code assumes these can be updated in sync at the same time.
I wonder if there is a simpler way to achieve this without touching the parsing, maybe even just a good guess at the size for estimating the number of points to keep
| const meta = me._cachedMeta; | ||
| if (me._parsing) { | ||
| const removed = meta._parsed.splice(start, count); | ||
| const removed = meta._parsedRaw.splice(start, count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this might work, but against _parsed
| let i, ilen; | ||
| for (i = start, ilen = start + count; i < ilen; ++i) { | ||
| meta._parsed[i] = +data[i]; | ||
| meta._parsedRaw[i] = meta._parsed[i] = +data[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should do only one array and set the other to same instance after loop. we should make sure _parsedRaw is sufficient sized before parsing, so should set to that.
| // to ensure that decimation plugins can take advantage of the | ||
| // scale dimensions | ||
| const controller = me.getDatasetMeta(i).controller; | ||
| controller._notifyAfterParse(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we call this _notifyAfterLayout?
Edit: I see now why this was called _notifyAfterParse. I think it could be called _notifyAfterLayout if we were not setting data attribute in the args per the suggestion in https://github.com/chartjs/Chart.js/pull/8251/files#r550253989
| const {_cachedMeta: meta} = me; | ||
| const {iScale} = meta; | ||
|
|
||
| // We expect afterDataParse hooks to set the modified data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it'd be cleaner to always set meta._parsed = meta._parsedRaw and then have the plugin override meta._parsed. We could expose a setParsed method if that's preferable to setting the value of private _parsed variable. We might have to pass chart as an arg so that we can get the meta
|
Closing this since #8255 went a lot better |
Enables plugins via a new hook
afterDataParse.To Do
Testing
I tested this on the uPlot benchmark over 100 runs. It performs noticeably better than the mainline code
master
PR + decimation plugin
The plugin i used is below.