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

Add hoverlabel.zformat attribute #1

Closed
wants to merge 12 commits into from
Closed

Conversation

jdugge
Copy link
Owner

@jdugge jdugge commented Oct 15, 2017

Resolves plotly#1383

This PR adds the hoverlabel.zformat attribute, which controls the formatting of the z-values in hover labels.
The attribute can be set both at the trace and layout level.
If hoverlabel.zformat is missing or set to undefined, no formatting will occur, leaving the current behaviour unchanged.

Copy link

@etpinard etpinard left a comment

Choose a reason for hiding this comment

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

Thanks for the PR!

@@ -50,6 +50,17 @@ module.exports = {
'`namelength - 3` characters and add an ellipsis.'
].join(' ')
},
zformat: {

Choose a reason for hiding this comment

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

We can't declare zformat in fx/ as it only makes sense for traces with z data array (e.g. heatmap, contour and surface).

Choose a reason for hiding this comment

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

... we wouldn't want traces w/o a z attribute to have a zformat under their name on https://plot.ly/javascript/reference/

Choose a reason for hiding this comment

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

... this has me thinking - maybe my hoverlabel.zformat idea of plotly#1383 (comment) was wrong. It might be best to keep the hoverlabel attribute container as is that way that set of attributes will be the same for all trace types.

Choose a reason for hiding this comment

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

So maybe zhoverformat is the best option. I hate that it doesn't extend to other trace types very well. But I prefer this over breaking hoverlabel symmetry.

Any thoughts on this @alexcjohnson @cldougl

Choose a reason for hiding this comment

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

So maybe zhoverformat is the best option. I hate that it doesn't extend to other trace types very well. But I prefer this over breaking hoverlabel symmetry.

I suppose the only other solution would be to move hoverlabel into each trace type attributes so it can be different for each one. But that's both a much more invasive change, and you're right there's something nice about keeping that container consistent in structure (though a lot of other containers, like marker and line, DO change from type to type... so it's not without precedent)

Whatever solution we adopt we should think about how it will extend to intensity and surfacecolor
plotly#1383 (comment) - surfacecolorhoverformat is getting a bit unwieldy but... so is hoverlabel.surfacecolorformat

So yeah, I guess zhoverformat is sounding better and better 😅

Copy link

@cldougl cldougl Oct 16, 2017

Choose a reason for hiding this comment

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

+1 for zhoverformat and keeping hoverlabel symmetry at this point.

if(d.zLabelVal !== undefined) d.zLabel = String(d.zLabelVal);
if(d.zLabelVal !== undefined) {
if(d.zformat !== undefined) {
d.zLabel = d3.format(d.zformat)(d.zLabelVal).replace(/-/g, constants.MINUS_SIGN);

Choose a reason for hiding this comment

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

Please reuse Axes.tickText

Choose a reason for hiding this comment

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

Referencing plotly#1965, maybe hover-only format attributes could support the notion of stops as well.

Copy link
Owner Author

Choose a reason for hiding this comment

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

The problem with using Axes.tickText is that heatmaps don't have an appropriate z-axis that could be passed to Axes.tickText. Should I create a dummy z-axis and use that, similar to what is being done here?

Choose a reason for hiding this comment

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

Should I create a dummy z-axis and use that, similar to what is being done here?

Yes, that's the approach we've used in several places. Actually I think we should do that anyway, even without a custom format, as basing the formatting on the actual range of z values in the data (ie formatting the hover text the default way we would on an x or y axis of the same range) would probably solve this issue in most cases anyway, without asking users to pick their own format.

@@ -0,0 +1,39 @@
{
"data": [

Choose a reason for hiding this comment

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

if(d.zformat !== undefined) {
d.zLabel = d3.format(d.zformat)(d.zLabelVal).replace(/-/g, constants.MINUS_SIGN);
} else {
d.zLabel = String(d.zLabelVal);

Choose a reason for hiding this comment

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

I would prefer adding the new formatting logic in the trace hoverPoints modules - e.g. this one.

@jdugge
Copy link
Owner Author

jdugge commented Oct 16, 2017

Thanks for the rapid and thorough feedback!

@jdugge
Copy link
Owner Author

jdugge commented Oct 18, 2017

Ready for another review. I've moved the option out of the hoverlabels and into the heatmap trace options and used the Axis.tickText method for formatting the labels.

Copy link

@etpinard etpinard left a comment

Choose a reason for hiding this comment

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

Looking good. This is almost ready for primetime!

To get this thing merged, you should at the very least add zhoverformat to contour traces. surface would benefit from zhoverformat too, but I can live without it for now (surface should get a surfacecolorformat attribute too!).

@@ -1095,7 +1095,9 @@ function cleanPoint(d, hovermode) {
d.yVal = d.ya.c2d(d.yLabelVal);
}

if(d.zLabelVal !== undefined) d.zLabel = String(d.zLabelVal);
if(d.zLabelVal !== undefined && d.zLabel === undefined) { // Traces like heatmaps generate the zLabel in their hoverPoints function

Choose a reason for hiding this comment

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

Hmm. Too bad we need this. Good catch ⚾ cleanPoint could use a little bit of a refactor.

Would you mind putting that // comment about the if() statement?

@@ -99,6 +104,16 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, contour)
text = cd0.text[ny][nx];
}

var zLabel;
var dummyAx = { // dummy axis for formatting the z value

Choose a reason for hiding this comment

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

Nicely done.

Creating the dummy axis here isn't optimal, but shouldn't make much of a difference. 👍

@@ -26,6 +27,10 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode, contour)
y = cd0.y,
z = cd0.z,
zmask = cd0.zmask,
zmin = trace.zmin,

Choose a reason for hiding this comment

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

Don't scope variables if you're only going to use them once. The block below could be rewritten as:

   var dummyAx = {
        type: 'linear',
        range: [trace.zmin, trace.zmax],
        hoverformat: trace.zhoverformat,
        _separators: trace._separators
   };
   var zLabel =  Axes.tickText(dummyAx, zVal, 'hover').text;

@@ -499,6 +499,43 @@ describe('hover info', function() {
.catch(fail)
.then(done);
});

it('should display correct label content with specified format', function(done) {

Choose a reason for hiding this comment

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

Looks like the two test cases you added are pretty much equivalent. Pick your favorite and 🔪 the other.

@jdugge
Copy link
Owner Author

jdugge commented Oct 19, 2017

I added it to contour traces and removed one of the test cases.
I tried adding it to surface plots, but the z-hoverformat there can already be set using scene.zaxis.hoverformat, and it seems that the surfacecolor values are never shown on hovering so a surfacecolorhoverformat wouldn't do anything?

@etpinard
Copy link

but the z-hoverformat there can already be set using scene.zaxis.hoverformat, and it seems that the surfacecolor values are never shown on hovering so a surfacecolorhoverformat wouldn't do anything?

Oh good point. I forgot about that.

All right, looks like your PR is ready for the main repo. PR away 🚀

@jdugge jdugge closed this Oct 26, 2017
@jdugge jdugge deleted the hoverlabel.zformat branch October 26, 2017 18:50
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

Successfully merging this pull request may close these issues.

4 participants