From 5fc092edfbf13d91e2331942d6bb4396b3866eb9 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 11 Apr 2026 21:28:34 -0700 Subject: [PATCH 1/2] smaller tip corners --- src/marks/tip.js | 16 +++---- test/output/tipAnchors.svg | 98 ++++++++++++++++++++++++++++++++++++++ test/plots/tip.ts | 26 ++++++++++ 3 files changed, 132 insertions(+), 8 deletions(-) create mode 100644 test/output/tipAnchors.svg diff --git a/src/marks/tip.js b/src/marks/tip.js index 89a0d808ad..a23bedb994 100644 --- a/src/marks/tip.js +++ b/src/marks/tip.js @@ -281,19 +281,19 @@ function getTextTranslate(anchor, m, r, width, height) { case "middle": return [-width / 2, height / 2]; case "top-left": - return [r, m + r]; + return [r, m / 2 + r]; case "top": return [-width / 2, m / 2 + r]; case "top-right": - return [-width - r, m + r]; + return [-width - r, m / 2 + r]; case "right": return [-m / 2 - width - r, height / 2]; case "bottom-left": - return [r, -m - r]; + return [r, -m / 2 - r]; case "bottom": return [-width / 2, -m / 2 - r]; case "bottom-right": - return [-width - r, -m - r]; + return [-width - r, -m / 2 - r]; case "left": return [r + m / 2, height / 2]; } @@ -306,19 +306,19 @@ function getPath(anchor, m, r, width, height) { case "middle": return `M${-w / 2},${-h / 2}h${w}v${h}h${-w}z`; case "top-left": - return `M0,0l${m},${m}h${w - m}v${h}h${-w}z`; + return `M0,0l${m / 2},${m / 2}h${w - m / 2}v${h}h${-w}z`; case "top": return `M0,0l${m / 2},${m / 2}h${(w - m) / 2}v${h}h${-w}v${-h}h${(w - m) / 2}z`; case "top-right": - return `M0,0l${-m},${m}h${m - w}v${h}h${w}z`; + return `M0,0l${-m / 2},${m / 2}h${m / 2 - w}v${h}h${w}z`; case "right": return `M0,0l${-m / 2},${-m / 2}v${m / 2 - h / 2}h${-w}v${h}h${w}v${m / 2 - h / 2}z`; case "bottom-left": - return `M0,0l${m},${-m}h${w - m}v${-h}h${-w}z`; + return `M0,0l${m / 2},${-m / 2}h${w - m / 2}v${-h}h${-w}z`; case "bottom": return `M0,0l${m / 2},${-m / 2}h${(w - m) / 2}v${-h}h${-w}v${h}h${(w - m) / 2}z`; case "bottom-right": - return `M0,0l${-m},${-m}h${m - w}v${-h}h${w}z`; + return `M0,0l${-m / 2},${-m / 2}h${m / 2 - w}v${-h}h${w}z`; case "left": return `M0,0l${m / 2},${-m / 2}v${m / 2 - h / 2}h${w}v${h}h${-w}v${m / 2 - h / 2}z`; } diff --git a/test/output/tipAnchors.svg b/test/output/tipAnchors.svg new file mode 100644 index 0000000000..4d66196970 --- /dev/null +++ b/test/output/tipAnchors.svg @@ -0,0 +1,98 @@ + + + + + + + + + + ​top + + + + + + + + + ​right + + + + + + + + + ​bottom + + + + + + + + + ​left + + + + + + + + + ​top-left + + + + + + + + + ​top-right + + + + + + + + + ​bottom-right + + + + + + + + + ​bottom-left + + + + + + + + + ​middle + + + \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index 4540b9cf35..a4012a24c8 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -3,6 +3,32 @@ import * as d3 from "d3"; import {feature, mesh} from "topojson-client"; import {test} from "test/plot"; +test(async function tipAnchors() { + return Plot.plot({ + style: "overflow: visible;", + height: 160, + marks: [ + Plot.frame({strokeOpacity: 0.2}), + ( + [ + "top", + "right", + "bottom", + "left", // sides + "top-left", + "top-right", + "bottom-right", + "bottom-left", // corners + "middle" + ] as const + ).map((anchor) => [ + Plot.dot({length: 1}, {frameAnchor: anchor, fill: "blue"}), + Plot.tip([anchor], {frameAnchor: anchor, anchor}) + ]) + ] + }); +}); + test(async function tipAreaBand() { const aapl = await d3.csv("data/aapl.csv", d3.autoType); return Plot.areaY(aapl, {x: "Date", y1: "Low", y2: "High", tip: true, curve: "step", stroke: "currentColor"}).plot(); From 44a6790dfa4e09f057e66257530433fd3fcc44b6 Mon Sep 17 00:00:00 2001 From: Mike Bostock Date: Sat, 11 Apr 2026 21:34:30 -0700 Subject: [PATCH 2/2] await postrender in test --- test/output/tipAnchors.svg | 54 +++++++++++++++++++------------------- test/plots/tip.ts | 3 ++- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/test/output/tipAnchors.svg b/test/output/tipAnchors.svg index 4d66196970..b2a3d74ba7 100644 --- a/test/output/tipAnchors.svg +++ b/test/output/tipAnchors.svg @@ -17,82 +17,82 @@ - + - - ​top + + ​top - + - - ​right + + ​right - + - - ​bottom + + ​bottom - + - - ​left + + ​left - + - - ​top-left + + ​top-left - + - - ​top-right + + ​top-right - + - - ​bottom-right + + ​bottom-right - + - - ​bottom-left + + ​bottom-left - + - - ​middle + + ​middle \ No newline at end of file diff --git a/test/plots/tip.ts b/test/plots/tip.ts index a4012a24c8..48c4b30c00 100644 --- a/test/plots/tip.ts +++ b/test/plots/tip.ts @@ -4,7 +4,7 @@ import {feature, mesh} from "topojson-client"; import {test} from "test/plot"; test(async function tipAnchors() { - return Plot.plot({ + const plot = Plot.plot({ style: "overflow: visible;", height: 160, marks: [ @@ -27,6 +27,7 @@ test(async function tipAnchors() { ]) ] }); + return Object.assign(plot, {ready: new Promise((resolve) => setTimeout(resolve, 100))}); // postrender }); test(async function tipAreaBand() {