From 225e47db4d2d7c6a80f8f12bab38f7c6d8f3d120 Mon Sep 17 00:00:00 2001 From: CenFangyu <164994318+Dmao233@users.noreply.github.com> Date: Mon, 14 Sep 2026 01:29:33 +0000 Subject: [PATCH 1/3] Fix unified hover pattern swatch for bar shape.pattern arrays Unified hover built the bar swatch from pattern index 0. Use the hovered point index so color and pattern match that bar. Co-authored-by: CenFangyu --- draftlogs/XXXX_fix.md | 1 + src/components/legend/style.js | 23 ++++++++--- test/jasmine/tests/hover_test.js | 69 ++++++++++++++++++++++++++++++++ 3 files changed, 87 insertions(+), 6 deletions(-) create mode 100644 draftlogs/XXXX_fix.md diff --git a/draftlogs/XXXX_fix.md b/draftlogs/XXXX_fix.md new file mode 100644 index 00000000000..e41c62222ff --- /dev/null +++ b/draftlogs/XXXX_fix.md @@ -0,0 +1 @@ +- Fix unified hover swatch color and pattern for bar `marker.pattern` arrays [[#XXXX](https://github.com/plotly/plotly.js/issues/8008)] diff --git a/src/components/legend/style.js b/src/components/legend/style.js index a149a535f84..96f098265ee 100644 --- a/src/components/legend/style.js +++ b/src/components/legend/style.js @@ -379,15 +379,26 @@ module.exports = function style(s, gd, legend) { var markerPattern = marker.pattern; var pAttr = Drawing.getPatternAttr; - var patternShape = markerPattern && (pAttr(markerPattern.shape, 0, '') || pAttr(markerPattern.path, 0, '')); + var patternIndex = 0; + if (legend._inHover && d0._distinct && d0.index != null) { + patternIndex = d0.index; + } + var patternShape = + markerPattern && + (pAttr(markerPattern.shape, patternIndex, '') || pAttr(markerPattern.path, patternIndex, '')); if (patternShape) { - var patternBGColor = pAttr(markerPattern.bgcolor, 0, null); - var patternFGColor = pAttr(markerPattern.fgcolor, 0, null); + var patternBGColor = pAttr(markerPattern.bgcolor, patternIndex, null); + var patternFGColor = pAttr(markerPattern.fgcolor, patternIndex, null); var patternFGOpacity = markerPattern.fgopacity; - var patternSize = dimAttr(markerPattern.size, 8, 10); - var patternSolidity = dimAttr(markerPattern.solidity, 0.5, 1); - var patternID = 'legend-' + trace.uid; + var patternSize = legend._inHover + ? dimAttr(pAttr(markerPattern.size, patternIndex, 8), 8, 10) + : dimAttr(markerPattern.size, 8, 10); + var patternSolidity = legend._inHover + ? dimAttr(pAttr(markerPattern.solidity, patternIndex, 0.5), 0.5, 1) + : dimAttr(markerPattern.solidity, 0.5, 1); + var patternID = (legend._inHover ? 'hover-' : 'legend-') + trace.uid; + if (legend._inHover) patternID += '-' + patternIndex; p.call( Drawing.pattern, 'legend', diff --git a/test/jasmine/tests/hover_test.js b/test/jasmine/tests/hover_test.js index 061fd8ac4e5..752fa3bbd6d 100644 --- a/test/jasmine/tests/hover_test.js +++ b/test/jasmine/tests/hover_test.js @@ -7103,6 +7103,75 @@ describe('hovermode: (x|y)unified', function () { .then(done, done.fail); }); + it('should style bar pattern swatches from the hovered point', function (done) { + function getSwatch() { + return getHoverLabel().select('g.legendpoints path'); + } + + function getPatternId(fill) { + var match = /url\(["']?#([^"')]+)["']?\)/.exec(fill); + return match ? match[1] : null; + } + + function getPatternStroke(patternId) { + var pattern = document.getElementById(patternId); + if (!pattern) return null; + var painted = pattern.querySelector('path, circle'); + return painted ? painted.getAttribute('stroke') || painted.getAttribute('fill') : null; + } + + var patternId0; + + Plotly.newPlot( + gd, + [ + { + type: 'bar', + x: [0, 1], + y: [1, 2], + marker: { + color: ['red', 'purple'], + pattern: { shape: ['/', '\\'] } + } + } + ], + { + hovermode: 'x unified', + showlegend: false, + width: 400, + height: 400, + margin: { t: 50, b: 50, l: 50, r: 50 } + } + ) + .then(function () { + _hover(gd, { xval: 0 }); + assertLabel({ title: '0', items: ['1'] }); + + patternId0 = getPatternId(getSwatch().node().style.fill); + expect(patternId0).toBeTruthy('first bar swatch uses a pattern fill'); + expect(getPatternStroke(patternId0)).toBe('rgb(255, 0, 0)'); + }) + .then(function () { + _hover(gd, { xval: 1 }); + assertLabel({ title: '1', items: ['2'] }); + + var patternId1 = getPatternId(getSwatch().node().style.fill); + expect(patternId1).toBeTruthy('second bar swatch uses a pattern fill'); + expect(patternId1).not.toBe(patternId0); + expect(getPatternStroke(patternId1)).toBe('rgb(128, 0, 128)'); + }) + .then(function () { + return Plotly.restyle(gd, 'marker.pattern.shape', [['/', '']]); + }) + .then(function () { + _hover(gd, { xval: 1 }); + assertLabel({ title: '1', items: ['2'] }); + expect(getSwatch().node().style.fill).toBe('rgb(128, 0, 128)'); + expect(getPatternId(getSwatch().node().style.fill)).toBe(null); + }) + .then(done, done.fail); + }); + it('should style funnel symbols accordingly', function (done) { var mock = require('../../image/mocks/funnel_custom.json'); var mockCopy = Lib.extendDeep({}, mock); From f341c93a021af2f3ad354c524bc0b71b3dae97ae Mon Sep 17 00:00:00 2001 From: CenFangyu <164994318+Dmao233@users.noreply.github.com> Date: Mon, 14 Sep 2026 01:29:57 +0000 Subject: [PATCH 2/3] Rename draftlog to pull request 1 The fork pull request number is now known. Co-authored-by: CenFangyu --- draftlogs/1_fix.md | 1 + draftlogs/XXXX_fix.md | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 draftlogs/1_fix.md delete mode 100644 draftlogs/XXXX_fix.md diff --git a/draftlogs/1_fix.md b/draftlogs/1_fix.md new file mode 100644 index 00000000000..1eabb634731 --- /dev/null +++ b/draftlogs/1_fix.md @@ -0,0 +1 @@ +- Fix unified hover swatch color and pattern for bar `marker.pattern` arrays [[#1](https://github.com/Dmao233/plotly.js/pull/1)] diff --git a/draftlogs/XXXX_fix.md b/draftlogs/XXXX_fix.md deleted file mode 100644 index e41c62222ff..00000000000 --- a/draftlogs/XXXX_fix.md +++ /dev/null @@ -1 +0,0 @@ -- Fix unified hover swatch color and pattern for bar `marker.pattern` arrays [[#XXXX](https://github.com/plotly/plotly.js/issues/8008)] From b5a08dd32e86a8c117ab9a8d9796b76bf4e4f718 Mon Sep 17 00:00:00 2001 From: CenFangyu <164994318+Dmao233@users.noreply.github.com> Date: Mon, 14 Sep 2026 01:33:55 +0000 Subject: [PATCH 3/3] Rename draftlog to pull request 8039 Co-authored-by: CenFangyu --- draftlogs/1_fix.md | 1 - draftlogs/8039_fix.md | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 draftlogs/1_fix.md create mode 100644 draftlogs/8039_fix.md diff --git a/draftlogs/1_fix.md b/draftlogs/1_fix.md deleted file mode 100644 index 1eabb634731..00000000000 --- a/draftlogs/1_fix.md +++ /dev/null @@ -1 +0,0 @@ -- Fix unified hover swatch color and pattern for bar `marker.pattern` arrays [[#1](https://github.com/Dmao233/plotly.js/pull/1)] diff --git a/draftlogs/8039_fix.md b/draftlogs/8039_fix.md new file mode 100644 index 00000000000..348d9b65bd8 --- /dev/null +++ b/draftlogs/8039_fix.md @@ -0,0 +1 @@ +- Fix unified hover swatch color and pattern for bar `marker.pattern` arrays [[#8039](https://github.com/plotly/plotly.js/pull/8039)]