mirror of
https://github.com/apache/superset.git
synced 2024-09-12 00:29:39 -04:00
fix(plugin-chart-echarts): tooltip overflow bug (#22218)
Co-authored-by: Ville Brofeldt <ville.brofeldt@apple.com>
This commit is contained in:
parent
3bc0865d90
commit
2e650eaebe
@ -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();
|
||||
@ -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),
|
||||
|
@ -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(
|
||||
@ -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
|
||||
@ -197,6 +198,7 @@ export default function transformProps(
|
||||
type: 'boxplot',
|
||||
data: transformedData,
|
||||
tooltip: {
|
||||
...getDefaultTooltip(refs),
|
||||
formatter: (param: CallbackDataParams) => {
|
||||
// @ts-ignore
|
||||
const {
|
||||
@ -273,7 +275,7 @@ export default function transformProps(
|
||||
nameLocation: yAxisTitlePosition === 'Left' ? 'middle' : 'end',
|
||||
},
|
||||
tooltip: {
|
||||
position: getDefaultPosition(refs),
|
||||
...getDefaultTooltip(refs),
|
||||
show: !inContextMenu,
|
||||
trigger: 'item',
|
||||
axisPointer: {
|
||||
|
@ -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);
|
||||
@ -215,7 +215,7 @@ export default function transformProps(
|
||||
...defaultGrid,
|
||||
},
|
||||
tooltip: {
|
||||
position: getDefaultPosition(refs),
|
||||
...getDefaultTooltip(refs),
|
||||
show: !inContextMenu,
|
||||
trigger: 'item',
|
||||
formatter: (params: any) =>
|
||||
|
@ -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 = (
|
||||
@ -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)}`;
|
||||
@ -315,7 +315,7 @@ export default function transformProps(
|
||||
|
||||
const echartOptions: EChartsCoreOption = {
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
...getDefaultTooltip(refs),
|
||||
trigger: 'item',
|
||||
},
|
||||
series,
|
||||
|
@ -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 & {
|
||||
@ -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 } = {};
|
||||
@ -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]];
|
||||
@ -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,
|
||||
|
@ -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,
|
||||
@ -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
|
||||
|
@ -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);
|
||||
@ -303,8 +303,8 @@ export default function transformProps(
|
||||
...defaultGrid,
|
||||
},
|
||||
tooltip: {
|
||||
...getDefaultTooltip(refs),
|
||||
show: !inContextMenu,
|
||||
position: getDefaultPosition(refs),
|
||||
trigger: 'item',
|
||||
formatter: (params: any) =>
|
||||
formatPieLabel({
|
||||
|
@ -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,
|
||||
@ -232,7 +232,7 @@ export default function transformProps(
|
||||
...defaultGrid,
|
||||
},
|
||||
tooltip: {
|
||||
position: getDefaultPosition(refs),
|
||||
...getDefaultTooltip(refs),
|
||||
show: !inContextMenu,
|
||||
trigger: 'item',
|
||||
},
|
||||
|
@ -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,
|
||||
@ -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];
|
||||
|
@ -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,
|
||||
@ -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) =>
|
||||
|
@ -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({
|
||||
@ -310,7 +310,7 @@ export default function transformProps(
|
||||
|
||||
const echartOptions: EChartsCoreOption = {
|
||||
tooltip: {
|
||||
position: getDefaultPosition(refs),
|
||||
...getDefaultTooltip(refs),
|
||||
show: !inContextMenu,
|
||||
trigger: 'item',
|
||||
formatter: (params: any) =>
|
||||
|
@ -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)];
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -80,7 +80,11 @@ describe('EchartsGraph transformProps', () => {
|
||||
label: { fontWeight: 'bolder' },
|
||||
},
|
||||
symbolSize: 50,
|
||||
tooltip: { formatter: '{b}: {c}' },
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
formatter: '{b}: {c}',
|
||||
position: expect.anything(),
|
||||
},
|
||||
value: 6,
|
||||
},
|
||||
{
|
||||
@ -93,7 +97,11 @@ describe('EchartsGraph transformProps', () => {
|
||||
label: { fontWeight: 'bolder' },
|
||||
},
|
||||
symbolSize: 50,
|
||||
tooltip: { formatter: '{b}: {c}' },
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
formatter: '{b}: {c}',
|
||||
position: expect.anything(),
|
||||
},
|
||||
value: 6,
|
||||
},
|
||||
{
|
||||
@ -106,7 +114,11 @@ describe('EchartsGraph transformProps', () => {
|
||||
label: { fontWeight: 'bolder' },
|
||||
},
|
||||
symbolSize: 10,
|
||||
tooltip: { formatter: '{b}: {c}' },
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
formatter: '{b}: {c}',
|
||||
position: expect.anything(),
|
||||
},
|
||||
value: 5,
|
||||
},
|
||||
{
|
||||
@ -119,7 +131,11 @@ describe('EchartsGraph transformProps', () => {
|
||||
label: { fontWeight: 'bolder' },
|
||||
},
|
||||
symbolSize: 10,
|
||||
tooltip: { formatter: '{b}: {c}' },
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
formatter: '{b}: {c}',
|
||||
position: expect.anything(),
|
||||
},
|
||||
value: 5,
|
||||
},
|
||||
],
|
||||
@ -218,7 +234,11 @@ describe('EchartsGraph transformProps', () => {
|
||||
symbolSize: 10,
|
||||
category: 'category_value_1',
|
||||
select: DEFAULT_GRAPH_SERIES_OPTION.select,
|
||||
tooltip: DEFAULT_GRAPH_SERIES_OPTION.tooltip,
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
formatter: '{b}: {c}',
|
||||
position: expect.anything(),
|
||||
},
|
||||
label: { show: true },
|
||||
},
|
||||
{
|
||||
@ -228,7 +248,11 @@ describe('EchartsGraph transformProps', () => {
|
||||
symbolSize: 10,
|
||||
category: 'category_value_2',
|
||||
select: DEFAULT_GRAPH_SERIES_OPTION.select,
|
||||
tooltip: DEFAULT_GRAPH_SERIES_OPTION.tooltip,
|
||||
tooltip: {
|
||||
appendToBody: true,
|
||||
formatter: '{b}: {c}',
|
||||
position: expect.anything(),
|
||||
},
|
||||
label: { show: true },
|
||||
},
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user