Skip to content

Commit d0c808b

Browse files
authored
Merge pull request #8039 from Dmao233/cursor/fix-8008-bar-pattern-unified-hover-f220
Fix unified hover bar pattern swatch for per-point marker.pattern
2 parents 1ef3c78 + e8c6dd0 commit d0c808b

3 files changed

Lines changed: 87 additions & 6 deletions

File tree

‎draftlogs/8039_fix.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Fix unified hover swatch color and pattern for bar `marker.pattern` arrays [[#8039](https://github.com/plotly/plotly.js/pull/8039)], with thanks to @Dmao233 for the contribution!

‎src/components/legend/style.js‎

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,15 +387,25 @@ module.exports = function style(s, gd, legend) {
387387

388388
var markerPattern = marker.pattern;
389389
var pAttr = Drawing.getPatternAttr;
390-
var patternShape = markerPattern && (pAttr(markerPattern.shape, 0, '') || pAttr(markerPattern.path, 0, ''));
390+
let patternIndex = 0;
391+
if (legend._inHover && d0._distinct && d0.index != null) {
392+
patternIndex = d0.index;
393+
}
394+
const patternShape =
395+
markerPattern &&
396+
(pAttr(markerPattern.shape, patternIndex, '') || pAttr(markerPattern.path, patternIndex, ''));
391397

392398
if (patternShape) {
393-
var patternBGColor = pAttr(markerPattern.bgcolor, 0, null);
394-
var patternFGColor = pAttr(markerPattern.fgcolor, 0, null);
399+
const patternBGColor = pAttr(markerPattern.bgcolor, patternIndex, null);
400+
const patternFGColor = pAttr(markerPattern.fgcolor, patternIndex, null);
395401
var patternFGOpacity = markerPattern.fgopacity;
396-
var patternSize = dimAttr(markerPattern.size, 8, 10);
397-
var patternSolidity = dimAttr(markerPattern.solidity, 0.5, 1);
398-
var patternID = 'legend-' + trace.uid;
402+
const patternSize = legend._inHover
403+
? dimAttr(pAttr(markerPattern.size, patternIndex, 8), 8, 10)
404+
: dimAttr(markerPattern.size, 8, 10);
405+
const patternSolidity = legend._inHover
406+
? dimAttr(pAttr(markerPattern.solidity, patternIndex, 0.5), 0.5, 1)
407+
: dimAttr(markerPattern.solidity, 0.5, 1);
408+
const patternID = legend._inHover ? `hover-${trace.uid}-${patternIndex}` : `legend-${trace.uid}`;
399409
p.call(
400410
Drawing.pattern,
401411
'legend',

‎test/jasmine/tests/hover_test.js‎

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7141,6 +7141,76 @@ describe('hovermode: (x|y)unified', function () {
71417141
.then(done, done.fail);
71427142
});
71437143

7144+
it('should style bar pattern swatches from the hovered point', async () => {
7145+
const getSwatch = () => getHoverLabel().select('g.legendpoints path');
7146+
7147+
const getPatternId = (fill) => {
7148+
const match = /url\(["']?#([^"')]+)["']?\)/.exec(fill);
7149+
return match ? match[1] : null;
7150+
};
7151+
7152+
const getPatternStroke = (patternId) => {
7153+
const pattern = document.getElementById(patternId);
7154+
if (!pattern) return null;
7155+
const painted = pattern.querySelector('path, circle');
7156+
return painted ? painted.getAttribute('stroke') || painted.getAttribute('fill') : null;
7157+
};
7158+
7159+
const getSwatchStroke = () => getPatternStroke(getPatternId(getSwatch().node().style.fill));
7160+
7161+
await Plotly.newPlot(
7162+
gd,
7163+
[
7164+
{
7165+
type: 'bar',
7166+
x: [0, 1],
7167+
y: [1, 2],
7168+
marker: {
7169+
color: ['red', 'purple'],
7170+
pattern: { shape: ['/', '\\'] }
7171+
}
7172+
}
7173+
],
7174+
{
7175+
hovermode: 'x unified',
7176+
showlegend: false,
7177+
width: 400,
7178+
height: 400,
7179+
margin: { t: 50, b: 50, l: 50, r: 50 }
7180+
}
7181+
);
7182+
7183+
_hover(gd, { xval: 0 });
7184+
assertLabel({ title: '0', items: ['1'] });
7185+
7186+
const patternId0 = getPatternId(getSwatch().node().style.fill);
7187+
expect(patternId0).toBeTruthy('first bar swatch uses a pattern fill');
7188+
expect(getPatternStroke(patternId0)).toBe('rgb(255, 0, 0)');
7189+
7190+
_hover(gd, { xval: 1 });
7191+
assertLabel({ title: '1', items: ['2'] });
7192+
7193+
const patternId1 = getPatternId(getSwatch().node().style.fill);
7194+
expect(patternId1).toBeTruthy('second bar swatch uses a pattern fill');
7195+
expect(patternId1).not.toBe(patternId0);
7196+
expect(getPatternStroke(patternId1)).toBe('rgb(128, 0, 128)');
7197+
7198+
await Plotly.restyle(gd, 'marker.pattern.fgcolor', [['blue', 'green']]);
7199+
7200+
_hover(gd, { xval: 0 });
7201+
expect(getSwatchStroke()).toBe('rgb(0, 0, 255)');
7202+
7203+
_hover(gd, { xval: 1 });
7204+
expect(getSwatchStroke()).toBe('rgb(0, 128, 0)');
7205+
7206+
await Plotly.restyle(gd, 'marker.pattern.shape', [['/', '']]);
7207+
7208+
_hover(gd, { xval: 1 });
7209+
assertLabel({ title: '1', items: ['2'] });
7210+
expect(getSwatch().node().style.fill).toBe('rgb(128, 0, 128)');
7211+
expect(getPatternId(getSwatch().node().style.fill)).toBe(null);
7212+
});
7213+
71447214
it('should style funnel symbols accordingly', function (done) {
71457215
var mock = require('../../image/mocks/funnel_custom.json');
71467216
var mockCopy = Lib.extendDeep({}, mock);

0 commit comments

Comments
 (0)