-
-
Notifications
You must be signed in to change notification settings - Fork 1.9k
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
ArrayOk hoverinfo fixups #2055
ArrayOk hoverinfo fixups #2055
Conversation
... scattergeo, choropleth, scatterternary and scattermapbox - these are all the trace type that rely on `extraText` built in their _module.hoverPoints method - this commit should've been part of PR #1761
src/traces/scattercarpet/hover.js
Outdated
@@ -67,7 +67,7 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) { | |||
var tj = ij[1] - j0; | |||
|
|||
var xy = carpet.evalxy([], i0, j0, ti, tj); | |||
text.push('y: ' + xy[1].toFixed(3)); | |||
text.push('y = ' + xy[1].toFixed(3)); |
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.
cc @rreusser unless that y:
was on purpose? This here turns it into y =
just like the a =
and b =
rows
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.
Most other places (heatmap/contour, 3d, ternary) we use :
- perhaps we should standardize on that here too?
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.
Good catch. Thank you. That seems correct.
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.
Oh. Haha, my mistake then. Perhaps it's the a/b =
that are the odd ones out. Need to check the consistent choice here.
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.
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.
Sorry, to be less vague, :
seems correct. =
seems incorrect.
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.
done in 2fe641d
src/traces/choropleth/hover.js
Outdated
if(pt.tx) tx = pt.tx; | ||
else if(trace.text) tx = trace.text; | ||
|
||
if(!Array.isArray(tx)) text.push(tx); |
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.
nice careful logic - tx
could be an array if trace.text
is too short to populate pt.tx
or if it has falsey elements (hmm, what about 0
?)
This seems like a bit of logic that's repeated a bunch - and is probably done wrong in some places where it's not repeated... worth abstracting?
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.
Worth it for sure. Shouldn't be too bad.
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.
(the hardest part will be to figure out how to call this new function)
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.
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.
Ooops I forget to update choropleth/hover.js
, now done in -> 7f2604a
@@ -59,6 +59,92 @@ exports.assertHoverLabelStyle = function(g, expectation, msg, textSelector) { | |||
expect(textStyle.fill).toBe(expectation.fontColor, msg + ': font.color'); | |||
}; | |||
|
|||
function assertLabelContent(label, expectation, msg) { | |||
var lines = label.selectAll('tspan'); |
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.
in case we want to test styled labels at some point, selectAll('tspan.line')
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.
Good eyes. Thanks!
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.
done in 294714b
return d3.selectAll(selector).size(); | ||
} | ||
|
||
exports.assertHoverLabelContent = function(expectation, msg) { |
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 like this fn - really nice idea! I find the signature a little unintuitive though... expectation
has to be something like [['a = 0.200', 'b = 3.500', 'y = 2.900'], 'a = 0.2']
... perhaps it would be clearer like {nums: 'a = 0.200\nb = 3.500\ny = 2.900', name: 'a = 0.2'}
? Array vs multiline string I don't feel that strongly about, but I think named items instead of the outer array would be quite a bit easier to read, and possibly easier to write too.
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 get annoyed of typing object keys in assertion functions arguments when writing tests.
But I guess there's value in being a little more verbose for project-wide custom assertions.
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.
... and good call about the somewhat useless single-vs-multi line logic. Our convertToTspans
tests are there for that.
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.
done in 294714b
Thoughts?
- abstracting out calcdata-to-global-trace-fallback - use it in Drawing! - use it in hover label style logic - not super happy with the name - not super happy about it being on Lib
- which handles calc/trace-wide 'hovertext'/'text' precedence logic - use it in hover.js modules
// which means the trace attribute has a corresponding | ||
// calcdata key, but its value is falsy | ||
var traceVal = lib.nestedProperty(trace, traceKey).get(); | ||
if(!Array.isArray(traceVal)) return traceVal; |
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.
Nice, I like it. Thanks for accepting 0
.
not super happy with the name
meh, it's a very specific concept that we probably don't want to go into any more detail with in the name. Seems fine to me.
not super happy about it being on Lib
It definitely belongs next to castOption
but yeah, if we make a common/
that might be more appropriate for these.
Also a style question: I just noticed all over this file we start the docs immediately after /**
, I thought the convention was to leave that first line blank and start on the next line?
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.
Also a style question: I just noticed all over this file we start the docs immediately after /**, I thought the convention was to leave that first line blank and start on the next line?
from http://usejsdoc.org/howto-commonjs-modules.html
So, I think both are acceptable.
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.
perhaps overly pedantic, but I read that as /** Single-line description */
or
/**
* Multiline still looks like it always
* leaves the first line blank.
*/
|
||
var tx = Lib.extractOption(calcPt, trace, 'tx', 'text'); | ||
if(tx && tx !== '') return fill(tx); | ||
}; |
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.
Nice! 🌴 Does this really belong in scatter
though? Perhaps in fx
?
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 have no strong opinion here. This routine felt similar to
https://github.com/plotly/plotly.js/blob/master/src/traces/scatter/arrays_to_calcdata.js
that's why I put it in traces/scatter/
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.
That's fine, we certainly have a long history of traces pulling from each other, particularly from scatter, and there is something nice about it being in the traces
dir. Perhaps at some point we introduce a traces/common
dir for stuff like this but leave it as is for now.
* - nums {string || array of strings} | ||
* - name {string || array of strings} | ||
* - axis {string} | ||
* @param {string} msg |
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.
Thanks - I find that a lot easier, especially as you point out since this lives in a different file from where it gets called.
src/traces/choropleth/hover.js
Outdated
|
||
if(!Array.isArray(tx)) text.push(tx); | ||
var tx = Lib.extractOption(pt, trace, 'tx', 'text'); | ||
if(tx && tx !== '') text.push(tx); |
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.
''
is already falsey, right?
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.
Good catch. Strictly speaking, I think this should be:
if(tx !== undefined && tx !== '') {
text.push(tx);
}
as Lib.extractOption
returns undefined
for all falsy values except 0
in calcdata. But, trace.text
is allowed to be ''
(which is the default by the way).
To make this easier to maintain (and remember 🙂 ), I'm thinking either
- (1) we could remove the
dflt: ''
line in thetext
(andhovertext
) attribute declarations. This leads to a slight change in behavior (but might more consistent) as now:
{
text: 'on-chart text',
hovertext: ''
}
would use ''
for the hover label text field (i.e. not show anything). On master
, hovertext: ''
is ignored and 'on-chart text'
shows in the hover labels.
- (2) we could make
Lib.extractOption
returnundefined
whentrace.text: ''
, making it a little more opinionated (I think this only makes sense for string attributes).
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.
Here's what I came up with 3931273
I made Lib.extractOption
less opinionated, and made scatter/fill_hover_text
handle falsy but valid text values.
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.
Yep, I like it. There are some edge cases this makes a little weird - eg trying to make one point have text but no hovertext, while all the others have both - but there are ways to get what you want (in that example using hoverinfo
as an array) and I don't see any way to make everything more intuitive. So lets keep this, it's nice clean logic, will make sense to people, and will do what people expect 99.9% of the time.
Take a look at 7f2604a#r142793932 but other than that I'm happy - patching a functionality hole while DRYing up a bunch of things -> 💃 ! |
@@ -887,6 +887,9 @@ drawing.setTextPointsScale = function(selection, xScale, yScale) { | |||
var transforms; | |||
var el = d3.select(this); | |||
var text = el.select('text'); | |||
|
|||
if(!text.node()) return; |
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.
Caught another bug. dragmode: 'pan'
is broken on http://rickyreusser.com/plotly-mock-viewer/#text_chart_arrays
This fixes it:
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.
ha, good catch! 🎉
- by returning falsy calcdata values - use fillHoverText in choropleth/hover, for consistency
fixes #2044 in 0a77239, but really, these few commits here should have been part of #1761. Adding anything hover-related is still a bit of a pain right now. As a lot of logic is scattered around
components/fx
, the base plot and trace modules, things don't just work unfortunately. Manually checking every trace type is in order until we better centralize our hover label logic.This PR also add a fairly general custom assertion in 4cf489e that checks every part of the hover label DOM nodes. I also caught a few others bug fixed and 🔒 in b24759d and 85d7061.
cc @alexcjohnson