Skip to content

Custom scales or more advanced hoverinfo support #1008

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

Closed
zbjornson opened this issue Oct 5, 2016 · 6 comments
Closed

Custom scales or more advanced hoverinfo support #1008

zbjornson opened this issue Oct 5, 2016 · 6 comments

Comments

@zbjornson
Copy link

I need to scale data with a custom function (let's say log2). Right now I'm doing that by:

  1. Scaling my data before passing it into plotly. (easy)
  2. Determining nice locations for tick marks. (sort of painful)
  3. Setting tickvals and ticktext to the scaled and unscaled values, respectively. (easy enough)

This works okay, except that the hover info shows the transformed values (e.g. log2(x) instead of x). As far as I can tell, there's no way to change that. I would have to set hoverinfo: "none", listen to plotly_hover and implement my own tooltip.

Some solutions I can think of:

  1. Accept a custom scale function that would be applied to the data before plotting it, but not to the tick text or hoverinfo text. Might take some thought as far as making this work nicely with the axes code.
  2. Accept a function for hoverinfo that is called with some data (x, y, z, text, name probably); return value is displayed in the hover. This goes with the workaround I listed above, but also seems like a very nice feature.

This could help with #221 and any other future requests for new scales.

@zbjornson
Copy link
Author

Example of how my work-around falls short:

image

@etpinard
Copy link
Contributor

etpinard commented Oct 5, 2016

Thanks for writing in!

Adding fully custom scales will be a little tricky for us. The plotly.js data / layout is meant to be fully JSON-serializable - which passing in functions to e.g. layout.xaxis.type isn't an option. Maybe we could start parsing math symbols into JS functions, but that's not going to happen in the short term.

Looking forward, the best solution for such deeper customization would be using plotly.js transforms. We're still working on the details on what transforms should and what they can do. We might want to take a look at #499 and #978 for more details.

For example of transform in action, take a look at @rreusser 's http://codepen.io/rsreusser/pen/GjoAJA

@zbjornson
Copy link
Author

Thanks for the prompt and helpful reply.

Based on the issues you linked to, it looks like I should hang on for a bit until a transform type that suits this problem is available? Or do you think it's already doable? (I don't see any docs for it yet, at least.)

(https://github.com/rreusser/plotly-basis-transform looks relevant, also!)

@etpinard
Copy link
Contributor

etpinard commented Oct 11, 2016

it looks like I should hang on for a bit until a transform type that suits this problem is available?

We're not planning on adding a particular transform for your use case. I meant: you should start thinking about writing your own custom transforms to achieve tasks of the likes.

Or do you think it's already doable?

Yep, it's already doable. Though probably a little bit tricky.

As you point out, https://github.com/rreusser/plotly-basis-transform is probably the best example of a custom transform at the moment.

@zbjornson
Copy link
Author

@etpinard I finally tried to use a transform to create a log2 scale, but I'm not seeing a way to solve the original problem (show z instead of log2(z) in the hover text). I made a minimal codepen working from the demo heatmap: https://codepen.io/anon/pen/mpgNwW. Is there actually a way to do this with a transform?


From digging, it looks like I can almost do what I want by defining a trace._module.eventData function, except for what might be a bug in fx/hover.js:

This invokes trace._module.eventData, which lets me define a custom z or zLabel value, cool:

// pull out just the data that's useful to
// other people and send it to the event
for(itemnum = 0; itemnum < hoverData.length; itemnum++) {
var pt = hoverData[itemnum];
newhoverdata.push(helpers.makeEventData(pt, pt.trace, pt.cd));
}

but then createHoverText is invoked with the original hoverData, not the data returned by helpers.makeEventData:

var hoverLabels = createHoverText(hoverData, labelOpts, gd);

Is that intentional?

@zbjornson
Copy link
Author

Actually, I forgot that I can make use of text and hoverinfo: "text" to define my own hover text entirely.

So, my workaround:
https://codepen.io/anon/pen/PEvYgv?editors=1010

And implemented as a transform:
https://codepen.io/anon/pen/mpgNwW?editors=1010

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

No branches or pull requests

2 participants