Skip to content

Commit 0967885

Browse files
committed
fix: correct location of tooltip when dashboard is scrolled
Since Grafana tag 11.3.1 the tooltip position needs to be calculated w.r.t to the whole document due to changes in the scrolling behaviour described in grafana/grafana#94222 and grafana/grafana#94842. BREAKING CHANGE: The minimum version of Grafana is now 11.3.1: https://github.com/grafana/grafana/blob/9225f4a1cbd1cfe8b69f1aa2d62309a9700533a5/public/app/plugins/panel/geomap/utils/tooltip.ts#L48
1 parent 8ecb3f3 commit 0967885

File tree

6 files changed

+63
-52
lines changed

6 files changed

+63
-52
lines changed

src/GeomapOverlay.tsx

Lines changed: 49 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,56 @@
1-
import React, { PureComponent } from 'react';
2-
import { GrafanaTheme } from '@grafana/data';
3-
import { config } from '@grafana/runtime';
4-
import { stylesFactory } from '@grafana/ui';
1+
import React, { CSSProperties } from 'react';
2+
import { GrafanaTheme2 } from '@grafana/data';
3+
// import { config } from '@grafana/runtime';
4+
import { useStyles2 } from '@grafana/ui';
55
import { css } from '@emotion/css';
66

77
export interface OverlayProps {
8-
topRight?: React.ReactNode[];
8+
topRight1?: React.ReactNode[];
9+
topRight2?: React.ReactNode[];
910
bottomLeft?: React.ReactNode[];
11+
blStyle?: CSSProperties;
1012
}
1113

12-
export class GeomapOverlay extends PureComponent<OverlayProps> {
13-
style = getStyles(config.theme);
14+
export const GeomapOverlay = ({ topRight1, topRight2, bottomLeft, blStyle }: OverlayProps) => {
15+
const topRight1Exists = (topRight1 && topRight1.length > 0) ?? false;
16+
const styles = useStyles2(getStyles(topRight1Exists));
17+
return (
18+
<div className={styles.overlay}>
19+
{Boolean(topRight1?.length) && <div className={styles.TR1}>{topRight1}</div>}
20+
{Boolean(topRight2?.length) && <div className={styles.TR2}>{topRight2}</div>}
21+
{Boolean(bottomLeft?.length) && (
22+
<div className={styles.BL} style={blStyle}>
23+
{bottomLeft}
24+
</div>
25+
)}
26+
</div>
27+
);
28+
};
1429

15-
constructor(props: OverlayProps) {
16-
super(props);
17-
}
18-
19-
render() {
20-
const { topRight, bottomLeft } = this.props;
21-
return (
22-
<div className={this.style.overlay}>
23-
{Boolean(topRight?.length) && <div className={this.style.TR}>{topRight}</div>}
24-
{Boolean(bottomLeft?.length) && <div className={this.style.BL}>{bottomLeft}</div>}
25-
</div>
26-
);
27-
}
28-
}
29-
30-
const getStyles = stylesFactory((theme: GrafanaTheme) => ({
31-
overlay: css`
32-
position: absolute;
33-
width: 100%;
34-
height: 100%;
35-
z-index: 500;
36-
pointer-events: none;
37-
`,
38-
TR: css`
39-
position: absolute;
40-
top: 8px;
41-
right: 8px;
42-
pointer-events: auto;
43-
`,
44-
BL: css`
45-
position: absolute;
46-
bottom: 8px;
47-
left: 8px;
48-
pointer-events: auto;
49-
`,
50-
}));
30+
const getStyles = (topRight1Exists: boolean) => (theme: GrafanaTheme2) => ({
31+
overlay: css({
32+
position: 'absolute',
33+
width: '100%',
34+
height: '100%',
35+
zIndex: 500,
36+
pointerEvents: 'none',
37+
}),
38+
TR1: css({
39+
right: '0.5em',
40+
pointerEvents: 'auto',
41+
position: 'absolute',
42+
top: '0.5em',
43+
}),
44+
TR2: css({
45+
position: 'absolute',
46+
top: topRight1Exists ? '80px' : '8px',
47+
right: '8px',
48+
pointerEvents: 'auto',
49+
}),
50+
BL: css({
51+
position: 'absolute',
52+
bottom: '8px',
53+
left: '8px',
54+
pointerEvents: 'auto',
55+
}),
56+
});

src/GeomapPanel.tsx

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ export class GeomapPanel extends Component<Props, State> {
466466

467467
const { hoverPayload } = this;
468468
hoverPayload.pageX = mouse.pageX;
469-
hoverPayload.pageY = mouse.pageY;
469+
hoverPayload.pageY = mouse.pageY - window.scrollY; // since Grafana 11.3.1: https://github.com/grafana/grafana/blob/main/public/app/plugins/panel/geomap/utils/tooltip.ts#L59
470470
hoverPayload.point = {
471471
lat: hover[1],
472472
lon: hover[0],
@@ -743,12 +743,12 @@ export class GeomapPanel extends Component<Props, State> {
743743
}
744744

745745
// Update the react overlays
746-
let topRight: ReactNode[] = [];
746+
let topRight2: ReactNode[] = [];
747747
if (options.showDebug) {
748-
topRight = [<DebugOverlay key="debug" map={this.map} />];
748+
topRight2 = [<DebugOverlay key="debug" map={this.map} />];
749749
}
750750

751-
this.setState({ topRight });
751+
this.setState({ topRight2 });
752752
}
753753

754754
clearTooltip = () => {
@@ -762,7 +762,7 @@ export class GeomapPanel extends Component<Props, State> {
762762
};
763763

764764
render() {
765-
const { ttip, topRight, bottomLeft } = this.state;
765+
const { ttip, topRight2, bottomLeft } = this.state;
766766

767767
// Tooltip handling from: https://github.com/grafana/grafana/blob/17a3ec52b651a082bbf5604f75975c12cd2ba9ed/public/app/plugins/panel/geomap/GeomapPanel.tsx#L386
768768
// let { ttip, ttipOpen, topRight1, legends, topRight2 } = this.state;
@@ -774,19 +774,18 @@ export class GeomapPanel extends Component<Props, State> {
774774

775775
return (
776776
<>
777-
{
778-
<Global styles={this.globalCSS} />
779-
}
777+
<Global styles={this.globalCSS} />
780778
<div className={styles.wrap} data-testid={testIds.geomapPanel.container} onMouseLeave={this.clearTooltip}>
781779
<div className={styles.map} ref={this.initMapRef}></div>
782-
<GeomapOverlay bottomLeft={bottomLeft} topRight={topRight} />
780+
<GeomapOverlay bottomLeft={bottomLeft} topRight2={topRight2} />
783781
</div>
784782
{ttip && ttip.data && (
785783
<Portal>
786784
<VizTooltipContainer
787785
className={styles.viz}
788786
position={{ x: ttip.pageX, y: ttip.pageY }}
789787
offset={{ x: 10, y: 10 }}
788+
allowPointerEvents
790789
>
791790
<DataHoverView {...ttip} />
792791
</VizTooltipContainer>

src/mapcontrols/CustomLayerSwitcher.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export class CustomLayerSwitcher extends LayerSwitcher {
1616
this.icon = document.createElement('i');
1717
this.icon.setAttribute("class", hiddenClassNameButton!);
1818
this.button.appendChild(this.icon);
19+
this.button.style.pointerEvents = "auto";
1920

2021
this.text = document.createTextNode("");
2122
this.button.appendChild(this.text);

src/mapcontrols/DataExtentZoom.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ export class DataExtentZoom extends Control {
3232
// icon.className = "bi bi-aspect-ratio";
3333
// icon.className = "bi bi-arrows-fullscreen";
3434
button.appendChild(icon);
35+
button.style.pointerEvents = "auto";
3536

3637
const element = document.createElement('div');
3738
// element.className = `ol-zoom ol-touch ${olCss.CLASS_UNSELECTABLE}`;
3839
element.className = `${olCss.CLASS_CONTROL} ol-zoom ol-touch ${olCss.CLASS_UNSELECTABLE}`;
3940
element.style.bottom = "20%";
4041
element.style.top = "unset";
42+
element.style.pointerEvents = "auto";
4143

4244
element.appendChild(button);
4345

src/mapcontrols/SpatialFilter.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,13 @@ class SpatialFilterControl extends Control {
4545
const icon = document.createElement('i');
4646
icon.className = "bi bi-funnel";
4747
button.appendChild(icon);
48+
button.style.pointerEvents = "auto";
4849

4950
const element = document.createElement('div');
5051
element.className = `ol-zoom ol-touch ${olCss.CLASS_UNSELECTABLE} ${olCss.CLASS_CONTROL}`;
5152
button.setAttribute("aria-label", "spatial filter tool button");
5253
element.style.top = "50%";
54+
// element.style.cursor = "pointer";
5355
element.appendChild(button);
5456

5557
super({

src/mapcontrols/WMSLegend.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export class WMSLegend extends Control {
5454
const icon = document.createElement('i');
5555
icon.className = "bi bi-list-task";
5656
button.appendChild(icon);
57+
button.style.pointerEvents = "auto";
5758

5859
const legendContainer = document.createElement("div");
5960
legendContainer.style.display = "block";

0 commit comments

Comments
 (0)