Skip to content

Commit f5dc9dc

Browse files
committed
fix anchor oscillation
1 parent f655983 commit f5dc9dc

2 files changed

Lines changed: 12 additions & 9 deletions

File tree

src/marks/tooltip.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export class Tooltip extends Mark {
8787
const kx = axis === "y" ? 1 / 100 : 1;
8888
const ky = axis === "x" ? 1 / 100 : 1;
8989
let i, xi, yi; // currently-focused index and position
90-
let c = anchor; // last-used anchor (for stability)
90+
let c = anchor ?? "top-left"; // last-used anchor (for stability)
9191
let sticky = false;
9292

9393
function pointermove(event) {
@@ -121,11 +121,8 @@ export class Tooltip extends Mark {
121121
}
122122
if (i === ii) return; // abort if the tooltip hasn’t moved
123123
i = ii;
124-
if (i === undefined) {
125-
dot.attr("display", "none");
126-
} else {
127-
dot.attr("display", "inline");
128-
dot.attr("transform", `translate(${Math.round(xi)},${Math.round(yi)})`);
124+
dot.attr("display", "none");
125+
if (i !== undefined) {
129126
const text = [];
130127
for (const key in channels) {
131128
const channel = getSource(channels, key);
@@ -186,14 +183,20 @@ export class Tooltip extends Mark {
186183
const {width: w, height: h} = content.node().getBBox();
187184
const {width, height} = svg.getBBox();
188185
if (anchor === undefined) {
189-
const cx = (/-left$/.test(c) ? xi + w + r * 2 > width : xi - w - r * 2 > 0) ? "right" : "left";
190-
const cy = (/^top-/.test(c) ? yi + h + m + r * 2 + 7 > height : yi - h - m - r * 2 > 0) ? "bottom" : "top";
186+
const fitLeft = xi + w + r * 2 < width;
187+
const fitRight = xi - w - r * 2 > 0;
188+
const fitTop = yi + h + m + r * 2 + 7 < height;
189+
const fitBottom = yi - h - m - r * 2 > 0;
190+
const cx = (/-left$/.test(c) ? fitLeft || !fitRight : fitLeft && !fitRight) ? "left" : "right";
191+
const cy = (/^top-/.test(c) ? fitTop || !fitBottom : fitTop && !fitBottom) ? "top" : "bottom";
191192
c = `${cy}-${cx}`;
192193
}
193194
const oy = getLineOffset(c, text) * lineHeight;
194195
tspan.attr("y", (d, i) => `${i * lineHeight + oy}em`);
195196
path.attr("d", getPath(c, m, r, w, h));
196197
content.attr("transform", getTextTransform(c, m, r, w, h));
198+
dot.attr("transform", `translate(${Math.round(xi)},${Math.round(yi)})`);
199+
dot.attr("display", "inline"); // make visible only after getBBox
197200
}
198201
}
199202

test/plots/tooltip.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,6 @@ export async function tooltipRule() {
146146
return Plot.plot({
147147
grid: true,
148148
style: "overflow: visible;",
149-
marks: [Plot.ruleX(penguins, {x: "body_mass_g"}), Plot.tooltip(penguins, {x: "body_mass_g", anchor: "bottom-left"})]
149+
marks: [Plot.ruleX(penguins, {x: "body_mass_g"}), Plot.tooltip(penguins, {x: "body_mass_g"})]
150150
});
151151
}

0 commit comments

Comments
 (0)