plotly.js icon indicating copy to clipboard operation
plotly.js copied to clipboard

Inconsistent EventData for axis range

Open jppresents opened this issue 7 years ago • 7 comments

Version used: plotly.js (basic) v1.28.3

I am registered to the event "plotly_relayout". I am using a chart with one trace and a rangeslider.

When zooming / panning on the trace, the following eventData is emitted to my callback:

Object {xaxis.range[0]: "2017-04-25 02:03:12.3635", xaxis.range[1]: "2017-05-24 12:21:05.5226"}

When panning on the rangeslider the follwoing eventData is emitted to my callback:

Object {xaxis.range: Array[2]}

And the array contains: ["2017-05-16 11:13:38.5694", "2017-06-14 21:31:31.7285"]

The plotly documentation shows that you are supposed to access the eventData axis information like this: eventdata['xaxis.range[0]']

this only works for the first object, not the one emitted when using the rangeslider.

jppresents avatar Jul 13 '17 06:07 jppresents

Thanks for pointing this out.

Callbacks emitting Object {xaxis.range: Array[2]} are still valid as

Plotly.relayout(gd, 'xaxis.range', [0, 1])

// is equivalent to
Plotly.relayout(gd, {'xaxis.range[0]': 0, 'xaxis.range[1]': 1})

But, I agree we should standardise our event data. For more on this topic, see https://github.com/plotly/plotly.js/issues/168.

To me, Object {xaxis.range: Array[2]} seems more user friendly, as some users might not be accustomed to out nested property attribute string (e.g. 'xaxis.range[0]').

The plotly documentation shows that you are supposed to access the eventData axis information like this: eventdata['xaxis.range[0]']

Where do you see this exactly?


We won't be able to fix this in v1.x I'm afraid as this would be a breaking change, but we'll for sure come up with a solution in v2.

etpinard avatar Jul 13 '17 13:07 etpinard

I got this from:

https://plot.ly/javascript/zoom-events/

From the example:

  'x-axis start:' + eventdata['xaxis.range[0]'] + '\n' +
  'x-axis end:' + eventdata['xaxis.range[1]'] );

jppresents avatar Jul 13 '17 13:07 jppresents

My workaround (within the plotly_relayout callback):

var range = eventdata['xaxis.range[0]']; if (range === undefined) { range = eventdata['xaxis.range'][0]; }

jppresents avatar Jul 13 '17 13:07 jppresents

Why is this closed? It's a bug. I also get an object with keys 'xaxis.range[0]' and 'xaxis.range[1]' in the onRelayout callback. Quite daft.

SirCameron avatar Oct 30 '19 08:10 SirCameron

I just came across this bug while using the plotly_relayout callback too.

When zooming in on a plot the event data I get is: {xaxis.range[0]: 0.20859375, xaxis.range[1]: 0.265625, yaxis.range[0]: 124.36153675327559, yaxis.range[1]: 346.435709526982}

if I double click to zoom out the event data I get is: {xaxis.autorange: true, yaxis.autorange: true}

If I just resize the plot, the event data comes back as a proper object:

{width: 705
height: 327
legend: {orientation: "h"}
margin: {t: 25, b: 35, l: 25, r: 25, pad: 5}
showlegend: true
xaxis: {rangemode: "tozero", showgrid: true, showspikes: false, spikethickness: 1}
yaxis: {automargin: true, rangemode: "tozero", showgrid: true, showspikes: false, spikethickness: 1}
}

Ideally, the event data would always return an object with nested properties ie:

{ xaxis: { range: [ 0.20859375, 0.265625] }, 
yaxis: { range: [124.36153675327559, 346.435709526982] }
}

or {xaxis: {autorange: true}, yaxis: {autorange: true }}

mmakrzem avatar Apr 08 '20 14:04 mmakrzem

The plotly_relayout event data mirrors the Plotly.relayout input arguments - so nested objects are not an option, as this would overwrite far more than you want changed if passed back to Plotly.relayout - any other settings inside xaxis or yaxis would be cleared.

And for reference, the reason we tended to use {'xaxis.range[0]': x0, 'xaxis.range[1]': x1} rather than {'xaxis.range': [x0, x1]} is that you can drag or edit a single end an axis, by clicking or dragging near the end of one of the axes - then it would be incorrect to say the user changed both items in xaxis.range, and there's no way to represent that with the {'xaxis.range': [x0, x1]} form.

You can access the full gd.layout object from inside the plotly_relayout event handler, it will have been updated by the time the event is emitted.

alexcjohnson avatar Apr 08 '20 15:04 alexcjohnson

Sorry, but why is this closed? I still get {'xaxis.range[0]': x0, 'xaxis.range[1]': x1} when zooming in, but {'xaxis.range': [x0, x1]} when resetting the axes (by double clicking).

For the sake of keeping things uniform, my workaround is currently:

                var xaxis_range = eventData['xaxis.range'];
                eventData['xaxis.range[0]'] = xaxis_range[0];
                eventData['xaxis.range[1]'] = xaxis_range[1];
                }```

AviadAvr avatar Feb 02 '24 09:02 AviadAvr