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

Include values of all array attributes in hover/click/select event data #1770

Merged
merged 8 commits into from
Jun 15, 2017

Conversation

etpinard
Copy link
Contributor

@etpinard etpinard commented Jun 8, 2017

I was about to just add ids and customdata values in the hover/click/select event data when I realised wouldn't it be nice to include values of all array attributes? We already need to keep track of those attributes for transforms and restyle. That is, calls to PlotSchema.findArrayAttributes aren't going anywhere. So, might as well cache that list and use it during picking/selecting!

For example,

Plotly.newPlot('graph', [{
  y: [1, 2, 1],
  ids: ['a', 'b', 'c'],
  customdata: [{sup: 'hello'}, 30, 'lol'],
  marker: {
    size: [20, 10, 30]
  }
}])
.then(gd => {
  gd.on('plotly_hover', d => console.log(d.points[0]))
})

then hovering on (x=1,y=2) gives:

{
  // as before
  x: 1,
  y: 2,
  data: /**/,
  fullData: /**/,
  xaxis: /**/,
  yaxis: /**/,
  curverNumber: 0,
  pointNumber: 1,

  // new
  id: 'c',
  customdata: 30,
  'marker.size', 10
}

@alexcjohnson @rreusser @monfera Thoughts?

etpinard added 3 commits June 8, 2017 16:54
- data attributes (e.g. ids, customdata)
  and arrayOk ('marker.size', 'text') values of click/hover'ed
  points are now included in the event data (along side the pts' coords)
- to do so, cache `findArrayAttributes` results in full trace object
  and use that cache in hover routine.
@etpinard etpinard added this to the 1.28.0 milestone Jun 8, 2017
@monfera
Copy link
Contributor

monfera commented Jun 8, 2017

@etpinard I'm strongly in favor of doing as you propose. This is in part because events then convey pertinent information, and the API is simpler for the user. Also, the current practice of relying on attached properties on the div object has several issues, e.g.

  • forces us, and the library user, to make and have a container DOM element (there's no fundamental need otherwise; React.js just relaxed an analogous need)
  • binds (commits) the API to some implementation detail, which is that
    • the data is linked to the DOM element
    • the data linked to the DOM element locks in some specific format that may constrain future implementation changes
  • not a sustainable practice once we have numerous plots on one single WebGL context, and by extension, one <canvas> element
  • gives an underdefined boundary for the user where even the contours of the API are hard to pin down (e.g. which properties are fair play to read from calcdata)
  • hard to change to a more efficient representation in the future: a DOM property may be read any time, i.e. it must be eagerly updated; while, in case of event supplied data, the event data may be assembled only on demand, e.g. derived from a more efficient internal representation
  • currently, tests must be written against calcdata and other internals rather than e.g. event data, which is an obstacle for refactoring

@monfera
Copy link
Contributor

monfera commented Jun 8, 2017

⬆️ my comments may be more pertinent to the plotly_select event, as the event data on it currently includes

{
  curveNumber: 0,
  id: 'myId'
  pointNumber: 15,
  x: 0.56429807,
  y: 24793
}

but doesn't include data, fulldata, calcdata etc. which therefore have to be queried as graphDiv element properties.

@alexcjohnson
Copy link
Collaborator

Yeah totally, this will make a lot of applications cleaner 🌟
Just be careful about 🐎 since this will apply to some pretty high-rate events.

@@ -676,6 +676,9 @@ plots.supplyDataDefaults = function(dataIn, dataOut, layout, fullLayout) {
Lib.pushUnique(modules, _module);
Lib.pushUnique(basePlotModules, fullTrace._module.basePlotModule);

// TODO remove findArrayAttributes calls downstream
fullTrace._arrayAttrs = PlotSchema.findArrayAttributes(fullTrace);
Copy link
Collaborator

Choose a reason for hiding this comment

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

possibly move this to calc since we do that whenever arrays change?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done in ee1adf8

etpinard added a commit that referenced this pull request Jun 14, 2017
etpinard added 5 commits June 14, 2017 15:26
- making them valid for all trace types
- no need to call on every update,
  when data array change is sufficient.
- note that the groupby transform still need to
  call Plots.findArrayAttributes on its own as its transform method
  is called during the defaults.
- to bring its point data on-par with hover/click/unhover
@etpinard
Copy link
Contributor Author

@monfera good call about #1770 (comment) - see patch in 3399a58

@etpinard
Copy link
Contributor Author

Tagging this PR as reviewable.

else key = astr;

if(pointData[key] === undefined) {
var val = Lib.nestedProperty(trace, astr).get();
Copy link
Collaborator

Choose a reason for hiding this comment

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

not blocking, but if we find that this starts dragging on performance (particularly for selecting I guess) then I suspect nestedProperty would be the primary cost. Could possibly store these instead of attribute strings in _arrayAttrs? It would be a little weird, since they could be referencing data arrays inside an outdated trace if we've redrawn without a recalc, but in as far as recalc is always triggered by changing an array attribute it seems like it would be ok?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good call. I didn't notice any serious slow downs so far, so I won't address this in this PR.

@alexcjohnson
Copy link
Collaborator

This is great @etpinard - really thorough, nice to get all these harmonized with each other! 💃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature something new
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants