Skip to content

Fix hover label coloring on white bgcolor #3048

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

Merged
merged 2 commits into from
Sep 25, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions src/components/fx/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -703,6 +703,7 @@ function createHoverText(hoverData, opts, gd) {

var commonBgColor = commonLabelOpts.bgcolor || Color.defaultLine;
var commonStroke = commonLabelOpts.bordercolor || Color.contrast(commonBgColor);
var contrastColor = Color.contrast(commonBgColor);

lpath.style({
fill: commonBgColor,
Expand All @@ -713,7 +714,7 @@ function createHoverText(hoverData, opts, gd) {
.call(Drawing.font,
commonLabelOpts.font.family || fontFamily,
commonLabelOpts.font.size || fontSize,
commonLabelOpts.font.color || Color.background
commonLabelOpts.font.color || contrastColor
)
.call(svgTextUtils.positionText, 0, 0)
.call(svgTextUtils.convertToTspans, gd);
Expand Down Expand Up @@ -795,12 +796,20 @@ function createHoverText(hoverData, opts, gd) {
var name = '';
var text = '';

// combine possible non-opaque trace color with bgColor
var baseColor = Color.opacity(d.color) ? d.color : Color.defaultLine;
var traceColor = Color.combine(baseColor, bgColor);

// combine possible non-opaque trace color with bgColor
var color0 = d.bgcolor || d.color;
// color for 'nums' part of the label
var numsColor = Color.combine(
Color.opacity(color0) ? color0 : Color.defaultLine,
bgColor
);
// color for 'name' part of the label
var nameColor = Color.combine(
Color.opacity(d.color) ? d.color : Color.defaultLine,
bgColor
);
// find a contrasting color for border and text
var contrastColor = d.borderColor || Color.contrast(traceColor);
var contrastColor = d.borderColor || Color.contrast(numsColor);

// to get custom 'name' labels pass cleanPoint
if(d.nameOverride !== undefined) d.name = d.nameOverride;
Expand Down Expand Up @@ -869,7 +878,7 @@ function createHoverText(hoverData, opts, gd) {
tx2.call(Drawing.font,
d.fontFamily || fontFamily,
d.fontSize || fontSize,
traceColor)
nameColor)
.text(name)
.attr('data-notex', 1)
.call(svgTextUtils.positionText, 0, 0)
Expand All @@ -883,7 +892,7 @@ function createHoverText(hoverData, opts, gd) {

g.select('path')
.style({
fill: traceColor,
fill: numsColor,
stroke: contrastColor
});
var tbb = tx.node().getBoundingClientRect();
Expand Down Expand Up @@ -1189,7 +1198,7 @@ function cleanPoint(d, hovermode) {
}

fill('hoverinfo', 'hi', 'hoverinfo');
fill('color', 'hbg', 'hoverlabel.bgcolor');
fill('bgcolor', 'hbg', 'hoverlabel.bgcolor');
fill('borderColor', 'hbc', 'hoverlabel.bordercolor');
fill('fontFamily', 'htf', 'hoverlabel.font.family');
fill('fontSize', 'hts', 'hoverlabel.font.size');
Expand Down
74 changes: 70 additions & 4 deletions test/jasmine/tests/hover_label_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2062,7 +2062,7 @@ describe('Test hover label custom styling:', function() {
});
assertCommonLabel({
path: ['rgb(255, 255, 255)', 'rgb(68, 68, 68)'],
text: [13, 'Arial', 'rgb(255, 255, 255)']
Copy link
Collaborator

Choose a reason for hiding this comment

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

Ha yeah, that would be a problem! FWIW, we'd have had a chance anyway of catching this bug when we wrote the test if it said something like

path: {bg: 'rgb(255, 255, 255)', border: 'rgb(68, 68, 68)'}, // or fill & line...
text: [13, 'Arial', 'rgb(255, 255, 255)']

So it'd be immediately obvious that the path bg matches the font color, and the font cannot be seen!
As it is path has two colors so it's unclear what they mean. text is unambiguous because all items are different types, so it's OK as an array, though still perhaps awkward as you need to know the order to write the test.

text: [13, 'Arial', 'rgb(68, 68, 68)']
});
})
.then(function() {
Expand All @@ -2074,7 +2074,7 @@ describe('Test hover label custom styling:', function() {
});
assertCommonLabel({
path: ['rgb(255, 255, 255)', 'rgb(68, 68, 68)'],
text: [13, 'Arial', 'rgb(255, 255, 255)']
text: [13, 'Arial', 'rgb(68, 68, 68)']
});
})
.then(function() {
Expand All @@ -2086,7 +2086,7 @@ describe('Test hover label custom styling:', function() {
});
assertCommonLabel({
path: ['rgb(255, 255, 255)', 'rgb(68, 68, 68)'],
text: [13, 'Arial', 'rgb(255, 255, 255)']
text: [13, 'Arial', 'rgb(68, 68, 68)']
});

// test arrayOk case
Expand All @@ -2113,7 +2113,7 @@ describe('Test hover label custom styling:', function() {
assertPtLabel(null);
assertCommonLabel({
path: ['rgb(255, 255, 255)', 'rgb(68, 68, 68)'],
text: [13, 'Arial', 'rgb(255, 255, 255)']
text: [13, 'Arial', 'rgb(68, 68, 68)']
});

// test base case
Expand Down Expand Up @@ -2203,6 +2203,72 @@ describe('Test hover label custom styling:', function() {
.then(done);
});

it('should work for x/y cartesian traces (multi-trace case)', function(done) {
var gd = createGraphDiv();

function assertNameLabel(expectation) {
var g = d3.selectAll('g.hovertext > text.name');

if(expectation === null) {
expect(g.size()).toBe(0);
} else {
g.each(function(_, i) {
var textStyle = window.getComputedStyle(this);
expect(textStyle.fill).toBe(expectation.color[i]);
});
}
}

Plotly.plot(gd, [{
x: [1, 2, 3],
y: [1, 2, 1],
}, {
x: [1, 2, 3],
y: [4, 5, 4],
}], {
hovermode: 'x',
})
.then(function() {
_hover(gd, { xval: gd._fullData[0].x[0] });
assertNameLabel({
color: ['rgb(31, 119, 180)', 'rgb(255, 127, 14)']
});
return Plotly.restyle(gd, 'marker.color', ['red', 'blue']);
})
.then(function() {
_hover(gd, { xval: gd._fullData[0].x[0] });
assertNameLabel({
color: ['rgb(255, 0, 0)', 'rgb(0, 0, 255)']
});
return Plotly.relayout(gd, 'hoverlabel.bgcolor', 'white');
})
.then(function() {
_hover(gd, { xval: gd._fullData[0].x[0] });
// should not affect the name font color
assertNameLabel({
color: ['rgb(255, 0, 0)', 'rgb(0, 0, 255)']
});
return Plotly.restyle(gd, 'marker.color', ['rgba(255,0,0,0.1)', 'rgba(0,0,255,0.1)']);
})
.then(function() {
_hover(gd, { xval: gd._fullData[0].x[0] });
// should blend with plot_bgcolor
assertNameLabel({
color: ['rgb(255, 179, 179)', 'rgb(179, 179, 255)']
});
return Plotly.restyle(gd, 'marker.color', ['rgba(255,0,0,0)', 'rgba(0,0,255,0)']);
})
.then(function() {
_hover(gd, { xval: gd._fullData[0].x[0] });
// uses default line color when opacity=0
assertNameLabel({
color: ['rgb(68, 68, 68)', 'rgb(68, 68, 68)']
});
})
.catch(failTest)
.then(done);
});

it('should work for 2d z cartesian traces', function(done) {
var gd = createGraphDiv();

Expand Down