Skip to content

Commit

Permalink
fix(plugin-chart-echarts): tooltip overflow bug (#22218)
Browse files Browse the repository at this point in the history
Co-authored-by: Ville Brofeldt <ville.brofeldt@apple.com>
  • Loading branch information
villebro and villebro committed Nov 24, 2022
1 parent 3bc0865 commit 2e650ea
Show file tree
Hide file tree
Showing 13 changed files with 105 additions and 74 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import {
TimeSeriesDatum,
} from '../types';
import { getDateFormatter, parseMetricValue } from '../utils';
import { getDefaultPosition } from '../../utils/tooltip';
import { getDefaultTooltip } from '../../utils/tooltip';
import { Refs } from '../../types';

const defaultNumberFormatter = getNumberFormatter();
Expand Down Expand Up @@ -234,8 +234,7 @@ export default function transformProps(
bottom: 0,
},
tooltip: {
position: getDefaultPosition(refs),
appendToBody: true,
...getDefaultTooltip(refs),
show: !inContextMenu,
trigger: 'axis',
formatter: renderTooltipFactory(formatTime, headerFormatter),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ import { convertInteger } from '../utils/convertInteger';
import { defaultGrid, defaultYAxis } from '../defaults';
import { getPadding } from '../Timeseries/transformers';
import { OpacityEnum } from '../constants';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';

export default function transformProps(
Expand Down Expand Up @@ -139,6 +139,7 @@ export default function transformProps(
type: 'scatter',
data: outlierDatum.map(val => [name, val]),
tooltip: {
...getDefaultTooltip(refs),
formatter: (param: { data: [string, number] }) => {
const [outlierName, stats] = param.data;
const headline = groupbyLabels.length
Expand Down Expand Up @@ -197,6 +198,7 @@ export default function transformProps(
type: 'boxplot',
data: transformedData,
tooltip: {
...getDefaultTooltip(refs),
formatter: (param: CallbackDataParams) => {
// @ts-ignore
const {
Expand Down Expand Up @@ -273,7 +275,7 @@ export default function transformProps(
nameLocation: yAxisTitlePosition === 'Left' ? 'middle' : 'end',
},
tooltip: {
position: getDefaultPosition(refs),
...getDefaultTooltip(refs),
show: !inContextMenu,
trigger: 'item',
axisPointer: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import {
} from '../utils/series';
import { defaultGrid } from '../defaults';
import { OpacityEnum, DEFAULT_LEGEND_FORM_DATA } from '../constants';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';

const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
Expand Down Expand Up @@ -215,7 +215,7 @@ export default function transformProps(
...defaultGrid,
},
tooltip: {
position: getDefaultPosition(refs),
...getDefaultTooltip(refs),
show: !inContextMenu,
trigger: 'item',
formatter: (params: any) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
FONT_SIZE_MULTIPLIERS,
} from './constants';
import { OpacityEnum } from '../constants';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';

const setIntervalBoundsAndColors = (
Expand Down Expand Up @@ -261,7 +261,7 @@ export default function transformProps(
color: gaugeSeriesOptions.detail?.color,
};
const tooltip = {
position: getDefaultPosition(refs),
...getDefaultTooltip(refs),
formatter: (params: CallbackDataParams) => {
const { name, value } = params;
return `${name} : ${formatValue(value as number)}`;
Expand Down Expand Up @@ -315,7 +315,7 @@ export default function transformProps(

const echartOptions: EChartsCoreOption = {
tooltip: {
appendToBody: true,
...getDefaultTooltip(refs),
trigger: 'item',
},
series,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import {
} from './types';
import { DEFAULT_GRAPH_SERIES_OPTION } from './constants';
import { getChartPadding, getLegendProps, sanitizeHtml } from '../utils/series';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';

type EdgeWithStyles = GraphEdgeItemOption & {
Expand Down Expand Up @@ -192,6 +192,7 @@ export default function transformProps(
sliceId,
}: EchartsGraphFormData = { ...DEFAULT_GRAPH_FORM_DATA, ...formData };

const refs: Refs = {};
const metricLabel = getMetricLabel(metric);
const colorFn = CategoricalColorNamespace.getScale(colorScheme as string);
const nodes: { [name: string]: number } = {};
Expand All @@ -212,7 +213,10 @@ export default function transformProps(
value: 0,
category,
select: DEFAULT_GRAPH_SERIES_OPTION.select,
tooltip: DEFAULT_GRAPH_SERIES_OPTION.tooltip,
tooltip: {
...getDefaultTooltip(refs),
...DEFAULT_GRAPH_SERIES_OPTION.tooltip,
},
});
}
const node = echartNodes[nodes[name]];
Expand Down Expand Up @@ -296,13 +300,12 @@ export default function transformProps(
},
];

const refs: Refs = {};
const echartOptions: EChartsCoreOption = {
animationDuration: DEFAULT_GRAPH_SERIES_OPTION.animationDuration,
animationEasing: DEFAULT_GRAPH_SERIES_OPTION.animationEasing,
tooltip: {
...getDefaultTooltip(refs),
show: !inContextMenu,
position: getDefaultPosition(refs),
formatter: (params: any): string =>
edgeFormatter(
params.data.source,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ import {
transformTimeseriesAnnotation,
} from '../Timeseries/transformers';
import { TIMESERIES_CONSTANTS, TIMEGRAIN_TO_TIMESTAMP } from '../constants';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';

export default function transformProps(
chartProps: EchartsMixedTimeseriesProps,
Expand Down Expand Up @@ -425,9 +425,8 @@ export default function transformProps(
},
],
tooltip: {
position: getDefaultPosition(refs),
...getDefaultTooltip(refs),
show: !inContextMenu,
appendToBody: true,
trigger: richTooltip ? 'axis' : 'item',
formatter: (params: any) => {
const xValue: number = richTooltip
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import {
} from '../utils/series';
import { defaultGrid } from '../defaults';
import { convertInteger } from '../utils/convertInteger';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';

const percentFormatter = getNumberFormatter(NumberFormats.PERCENT_2_POINT);
Expand Down Expand Up @@ -303,8 +303,8 @@ export default function transformProps(
...defaultGrid,
},
tooltip: {
...getDefaultTooltip(refs),
show: !inContextMenu,
position: getDefaultPosition(refs),
trigger: 'item',
formatter: (params: any) =>
formatPieLabel({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
} from '../utils/series';
import { defaultGrid } from '../defaults';
import { Refs } from '../types';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';

export function formatLabel({
params,
Expand Down Expand Up @@ -232,7 +232,7 @@ export default function transformProps(
...defaultGrid,
},
tooltip: {
position: getDefaultPosition(refs),
...getDefaultTooltip(refs),
show: !inContextMenu,
trigger: 'item',
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ import {
TIMESERIES_CONSTANTS,
TIMEGRAIN_TO_TIMESTAMP,
} from '../constants';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';

export default function transformProps(
chartProps: EchartsTimeseriesChartProps,
Expand Down Expand Up @@ -381,9 +381,8 @@ export default function transformProps(
xAxis,
yAxis,
tooltip: {
...getDefaultTooltip(refs),
show: !inContextMenu,
position: getDefaultPosition(refs),
appendToBody: true,
trigger: richTooltip ? 'axis' : 'item',
formatter: (params: any) => {
const [xIndex, yIndex] = isHorizontal ? [1, 0] : [0, 1];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import {
} from './types';
import { DEFAULT_FORM_DATA, DEFAULT_TREE_SERIES_OPTION } from './constants';
import { Refs } from '../types';
import { getDefaultTooltip } from '../utils/tooltip';

export function formatTooltip({
params,
Expand Down Expand Up @@ -205,6 +206,7 @@ export default function transformProps(
animationEasing: DEFAULT_TREE_SERIES_OPTION.animationEasing,
series,
tooltip: {
...getDefaultTooltip(refs),
trigger: 'item',
triggerOn: 'mousemove',
formatter: (params: any) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import {
BORDER_COLOR,
} from './constants';
import { OpacityEnum } from '../constants';
import { getDefaultPosition } from '../utils/tooltip';
import { getDefaultTooltip } from '../utils/tooltip';
import { Refs } from '../types';

export function formatLabel({
Expand Down Expand Up @@ -310,7 +310,7 @@ export default function transformProps(

const echartOptions: EChartsCoreOption = {
tooltip: {
position: getDefaultPosition(refs),
...getDefaultTooltip(refs),
show: !inContextMenu,
trigger: 'item',
formatter: (params: any) =>
Expand Down
87 changes: 45 additions & 42 deletions superset-frontend/plugins/plugin-chart-echarts/src/utils/tooltip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,56 +21,59 @@ import { CallbackDataParams } from 'echarts/types/src/util/types';
import { TOOLTIP_OVERFLOW_MARGIN, TOOLTIP_POINTER_MARGIN } from '../constants';
import { Refs } from '../types';

export function getDefaultPosition(refs: Refs) {
return (
canvasMousePos: [number, number],
params: CallbackDataParams,
tooltipDom: HTMLDivElement | null,
rect: any,
sizes: { contentSize: [number, number]; viewSize: [number, number] },
) => {
// algorithm partially based on this snippet:
// https://github.com/apache/echarts/issues/5004#issuecomment-559668309
export function getDefaultTooltip(refs: Refs) {
return {
appendToBody: true,
position: (
canvasMousePos: [number, number],
params: CallbackDataParams,
tooltipDom: HTMLDivElement | null,
rect: any,
sizes: { contentSize: [number, number]; viewSize: [number, number] },
) => {
// algorithm partially based on this snippet:
// https://github.com/apache/echarts/issues/5004#issuecomment-559668309

// The chart canvas position
const divRect = refs.divRef?.current?.getBoundingClientRect();
// The chart canvas position
const divRect = refs.divRef?.current?.getBoundingClientRect();

// The mouse coordinates relative to the whole window
// The first parameter to the position function is the mouse position relative to the canvas
const mouseX = canvasMousePos[0] + (divRect?.x || 0);
const mouseY = canvasMousePos[1] + (divRect?.y || 0);
// The mouse coordinates relative to the whole window
// The first parameter to the position function is the mouse position relative to the canvas
const mouseX = canvasMousePos[0] + (divRect?.x || 0);
const mouseY = canvasMousePos[1] + (divRect?.y || 0);

// The width and height of the tooltip dom element
const tooltipWidth = sizes.contentSize[0];
const tooltipHeight = sizes.contentSize[1];
// The width and height of the tooltip dom element
const tooltipWidth = sizes.contentSize[0];
const tooltipHeight = sizes.contentSize[1];

// Start by placing the tooltip top and right relative to the mouse position
let xPos = mouseX + TOOLTIP_POINTER_MARGIN;
let yPos = mouseY - TOOLTIP_POINTER_MARGIN - tooltipHeight;
// Start by placing the tooltip top and right relative to the mouse position
let xPos = mouseX + TOOLTIP_POINTER_MARGIN;
let yPos = mouseY - TOOLTIP_POINTER_MARGIN - tooltipHeight;

// The tooltip is overflowing past the right edge of the window
if (xPos + tooltipWidth >= document.documentElement.clientWidth) {
// Attempt to place the tooltip to the left of the mouse position
xPos = mouseX - TOOLTIP_POINTER_MARGIN - tooltipWidth;
// The tooltip is overflowing past the right edge of the window
if (xPos + tooltipWidth >= document.documentElement.clientWidth) {
// Attempt to place the tooltip to the left of the mouse position
xPos = mouseX - TOOLTIP_POINTER_MARGIN - tooltipWidth;

// The tooltip is overflowing past the left edge of the window
if (xPos <= 0)
// Place the tooltip a fixed distance from the left edge of the window
xPos = TOOLTIP_OVERFLOW_MARGIN;
}
// The tooltip is overflowing past the left edge of the window
if (xPos <= 0)
// Place the tooltip a fixed distance from the left edge of the window
xPos = TOOLTIP_OVERFLOW_MARGIN;
}

// The tooltip is overflowing past the top edge of the window
if (yPos <= 0) {
// Attempt to place the tooltip to the bottom of the mouse position
yPos = mouseY + TOOLTIP_POINTER_MARGIN;
// The tooltip is overflowing past the top edge of the window
if (yPos <= 0) {
// Attempt to place the tooltip to the bottom of the mouse position
yPos = mouseY + TOOLTIP_POINTER_MARGIN;

// The tooltip is overflowing past the bottom edge of the window
if (yPos + tooltipHeight >= document.documentElement.clientHeight)
// Place the tooltip a fixed distance from the top edge of the window
yPos = TOOLTIP_OVERFLOW_MARGIN;
}
// The tooltip is overflowing past the bottom edge of the window
if (yPos + tooltipHeight >= document.documentElement.clientHeight)
// Place the tooltip a fixed distance from the top edge of the window
yPos = TOOLTIP_OVERFLOW_MARGIN;
}

// Return the position (converted back to a relative position on the canvas)
return [xPos - (divRect?.x || 0), yPos - (divRect?.y || 0)];
// Return the position (converted back to a relative position on the canvas)
return [xPos - (divRect?.x || 0), yPos - (divRect?.y || 0)];
},
};
}

0 comments on commit 2e650ea

Please sign in to comment.