Skip to content

Commit bc6cd09

Browse files
authored
Merge pull request #284 from plasma-umass/fix-282-tooltip-cutoff-followup
Flip tooltip below point using its real rendered height (#282 follow-up)
2 parents ba2e79e + 118ee95 commit bc6cd09

3 files changed

Lines changed: 72 additions & 37 deletions

File tree

viewer/js/profile.js

Lines changed: 36 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

viewer/js/profile.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

viewer/ts/profile.ts

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1302,28 +1302,47 @@ class Profile {
13021302
'<strong>Progress Speedup:</strong> ' + percentFormat(d.progress_speedup);
13031303
});
13041304

1305-
// Choose a tooltip direction from the point's actual screen position so it
1306-
// is never clipped by the top edge of the viewport (see issue #282). The
1307-
// static .direction() callback only sees the datum, so we compute it here
1308-
// in the mouseover handler where `this` is the hovered circle.
1309-
let tip_direction = function (node: Element, d: any) {
1310-
let rect = node.getBoundingClientRect();
1311-
// Roughly the height of the 3-line tooltip plus padding/arrow.
1312-
let tip_margin = 80;
1313-
if (rect.top < tip_margin) {
1314-
// Near the top: drop the tooltip below the point instead of above.
1315-
return 's';
1316-
} else if (d.speedup > 0.8) {
1317-
// Near the right edge: place the tooltip to the left.
1318-
return 'w';
1319-
}
1305+
// Choose a tooltip direction from the point's position so it is not clipped
1306+
// by the edges of the viewport (see issue #282). The static .direction()
1307+
// callback only sees the datum, so we compute it in the mouseover handler
1308+
// where `this` is the hovered circle. This is only an initial guess; after
1309+
// the tooltip is rendered we measure its real box and flip it if it still
1310+
// overflows the top (see show_tip below), which avoids guessing its height.
1311+
let tip_direction = function (d: any) {
1312+
// Near the right edge: place the tooltip to the left so it isn't clipped.
1313+
if (d.speedup > 0.8) return 'w';
13201314
return 'n';
13211315
};
13221316
let tip_offset = function (dir: string) {
13231317
if (dir === 's') return [5, 0];
13241318
if (dir === 'w') return [0, -5];
13251319
return [-5, 0];
13261320
};
1321+
// The currently-visible tip node (d3-tip appends one div per tip instance;
1322+
// pick the one that is actually shown rather than any stale leftovers).
1323+
let active_tip_node = function (): HTMLElement | null {
1324+
let nodes = document.querySelectorAll('.d3-tip');
1325+
for (let i = nodes.length - 1; i >= 0; i--) {
1326+
let el = nodes[i] as HTMLElement;
1327+
if (el.style.opacity === '1') return el;
1328+
}
1329+
return null;
1330+
};
1331+
// Show the tooltip, then correct for any remaining top-edge clipping by
1332+
// measuring the rendered tooltip (its real height) and flipping it below
1333+
// the point when the 'north' placement overflows the top of the viewport.
1334+
let show_tip = function (d: any, target: Element) {
1335+
let dir = tip_direction(d);
1336+
tip.direction(dir).offset(tip_offset(dir));
1337+
tip.show(d, target);
1338+
if (dir === 'n') {
1339+
let node = active_tip_node();
1340+
if (node && node.getBoundingClientRect().top < 0) {
1341+
tip.direction('s').offset(tip_offset('s'));
1342+
tip.show(d, target);
1343+
}
1344+
}
1345+
};
13271346

13281347
/****** Add or update divs to hold each plot ******/
13291348
let plot_div_sel = container.selectAll('div.plot')
@@ -1715,9 +1734,7 @@ class Profile {
17151734
.attr('cy', function(d) { return yscale(d.progress_speedup); })
17161735
.on('mouseover', function(d) {
17171736
d3.select(this).classed('highlight', true);
1718-
let dir = tip_direction(this, d);
1719-
tip.direction(dir).offset(tip_offset(dir));
1720-
tip.show(d, this);
1737+
show_tip(d, this);
17211738
})
17221739
.on('mouseout', function() {
17231740
d3.select(this).classed('highlight', false);

0 commit comments

Comments
 (0)