Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(plugin-chart-echarts): tooltip overflow bug #22218

Merged
merged 2 commits into from
Nov 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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)];
},
};
}
Loading