This is an automated email from the ASF dual-hosted git repository.
sfirke pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/superset.git
The following commit(s) were added to refs/heads/master by this push:
new 2c275ed0a5b fix(echarts): restore series color markers in sanitized
tooltips (#45505)
2c275ed0a5b is described below
commit 2c275ed0a5b5878a1473408e5479b96adcccb6a8
Author: Aleem Sattar <[email protected]>
AuthorDate: Thu Oct 22 13:31:07 2026 -0500
fix(echarts): restore series color markers in sanitized tooltips (#45505)
---
.../packages/superset-ui-core/src/utils/tooltip.ts | 31 +++++++++++
.../superset-ui-core/test/utils/tooltip.test.ts | 34 ++++++++++++
.../src/Histogram/transformProps.ts | 8 ++-
.../src/Timeseries/transformProps.ts | 55 ++++---------------
.../plugins/plugin-chart-echarts/src/types.ts | 2 -
.../plugin-chart-echarts/src/utils/forecast.ts | 20 +++----
.../test/Histogram/transformProps.test.ts | 11 ++++
.../test/MixedTimeseries/transformProps.test.ts | 8 ++-
.../test/Timeseries/transformProps.test.ts | 10 ++--
.../test/utils/forecast.test.ts | 63 +++++++++-------------
10 files changed, 137 insertions(+), 105 deletions(-)
diff --git a/superset-frontend/packages/superset-ui-core/src/utils/tooltip.ts
b/superset-frontend/packages/superset-ui-core/src/utils/tooltip.ts
index 2b1312a680a..b553f1ea5ae 100644
--- a/superset-frontend/packages/superset-ui-core/src/utils/tooltip.ts
+++ b/superset-frontend/packages/superset-ui-core/src/utils/tooltip.ts
@@ -75,6 +75,37 @@ function getTruncationStyle(mode: TooltipTruncationMode):
string {
return NOWRAP_STYLE;
}
+const MARKER_SIZE = 10;
+
+// Shape tweaks layered on the base square border.
+const MARKER_SHAPES: Record<string, string> = {
+ circle: 'border-radius:50%',
+ rect: '',
+ roundRect: 'border-radius:2px',
+ // A touch larger so the corner tail reads.
+ pin: `border-width:${(MARKER_SIZE + 1) / 2}px;border-radius:50% 50% 0 50%`,
+ // A border triangle hangs below its box, so keep the font metrics and lift
+ // it by the descent plus half the x-height (~0.5em) plus half its height.
+ triangle: `font-size:inherit;vertical-align:calc(0.5em + ${MARKER_SIZE /
2}px);border-width:0 ${MARKER_SIZE / 2}px
${MARKER_SIZE}px;border-color:transparent transparent currentcolor`,
+};
+
+/**
+ * Series marker for tooltip rows, drawn with borders alone: sanitizeHtml
+ * strips display/width/height, so a sized box would render as nothing.
+ */
+export function tooltipMarker(color: unknown, symbol = 'circle'): string {
+ if (typeof color !== 'string' || !color) {
+ return '';
+ }
+ // A diamond needs transform, which the sanitizer also strips, so use a glyph
+ // sized to match; its ink is a little wider, hence the 1px margin below.
+ if (symbol === 'diamond') {
+ return `<span
style="color:${color};font-size:15px;line-height:0;margin-right:4px">◆</span>`;
+ }
+ const shape = MARKER_SHAPES[symbol] ?? MARKER_SHAPES.circle;
+ return `<span
style="color:${color};font-size:0;line-height:0;vertical-align:middle;margin:0
5px 0 1px;border:${MARKER_SIZE / 2}px solid currentcolor;${shape}"></span>`;
+}
+
export function tooltipHtml(
data: string[][],
title?: string,
diff --git
a/superset-frontend/packages/superset-ui-core/test/utils/tooltip.test.ts
b/superset-frontend/packages/superset-ui-core/test/utils/tooltip.test.ts
index 5da38cb10b8..834427d7dc3 100644
--- a/superset-frontend/packages/superset-ui-core/test/utils/tooltip.test.ts
+++ b/superset-frontend/packages/superset-ui-core/test/utils/tooltip.test.ts
@@ -19,6 +19,7 @@
import {
sanitizeHtml,
tooltipHtml,
+ tooltipMarker,
truncateLabel,
TRUNCATION_MAX_CHARS,
} from '@superset-ui/core';
@@ -272,3 +273,36 @@ describe('tooltipHtml truncation modes', () => {
});
});
});
+
+describe('tooltipMarker', () => {
+ test('keeps its color and shape through sanitizeHtml', () => {
+ const html = removeWhitespaces(
+ sanitizeHtml(tooltipMarker('#1f77b4', 'pin')),
+ );
+ expect(html).toContain('color:#1f77b4');
+ expect(html).toContain('border:5pxsolidcurrentcolor');
+ expect(html).toContain('border-radius:50%50%050%');
+ });
+
+ test('keeps the triangle borders and lift through sanitizeHtml', () => {
+ const html = removeWhitespaces(
+ sanitizeHtml(tooltipMarker('#1f77b4', 'triangle')),
+ );
+ expect(html).toContain('border-width:05px10px');
+ expect(html).toContain('border-color:transparenttransparentcurrentcolor');
+ expect(html).toContain('vertical-align:calc(0.5em+5px)');
+ });
+
+ test('draws the diamond as a glyph', () => {
+ expect(tooltipMarker('#1f77b4', 'diamond')).toContain('◆');
+ });
+
+ test('falls back to a circle for unknown symbols', () => {
+ expect(tooltipMarker('red', 'arrow')).toBe(tooltipMarker('red', 'circle'));
+ });
+
+ test('returns nothing without a color string', () => {
+ expect(tooltipMarker(undefined)).toBe('');
+ expect(tooltipMarker({ type: 'linear' })).toBe('');
+ });
+});
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/src/Histogram/transformProps.ts
b/superset-frontend/plugins/plugin-chart-echarts/src/Histogram/transformProps.ts
index 32502365a1c..3cbc8a61b67 100644
---
a/superset-frontend/plugins/plugin-chart-echarts/src/Histogram/transformProps.ts
+++
b/superset-frontend/plugins/plugin-chart-echarts/src/Histogram/transformProps.ts
@@ -27,6 +27,7 @@ import {
getColumnLabel,
getValueFormatter,
tooltipHtml,
+ tooltipMarker,
} from '@superset-ui/core';
import { HistogramChartProps, HistogramTransformedProps } from './types';
import { LegendOrientation, LegendType, Refs } from '../types';
@@ -123,8 +124,11 @@ export default function transformProps(
const tooltipFormatter = (params: CallbackDataParams[]) => {
const title = params[0].name;
const rows = params.map(param => {
- const { marker, seriesName, value } = param;
- return [`${marker}${seriesName}`, yAxisFormatter.format(value as
number)];
+ const { color, seriesName, value } = param;
+ return [
+ `${tooltipMarker(color)}${seriesName}`,
+ yAxisFormatter.format(value as number),
+ ];
});
if (groupby.length > 0) {
const total = params.reduce(
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
index 9afddc473d2..20a740afa00 100644
---
a/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
+++
b/superset-frontend/plugins/plugin-chart-echarts/src/Timeseries/transformProps.ts
@@ -244,45 +244,6 @@ function parseMinInterval(
return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
}
-function getSymbolMarker(symbol: string, color: string) {
- const size = 10;
- switch (symbol) {
- case 'circle':
- return `<span style="
- display:inline-block;width:${size}px;height:${size}px;
- border-radius:50%;background:${color};margin-right:5px"></span>`;
- case 'rect':
- return `<span style="
- display:inline-block;width:${size}px;height:${size}px;
- background:${color};margin-right:5px"></span>`;
- case 'roundRect':
- return `<span style="
-
display:inline-block;width:${size}px;height:${size}px;border-radius:2px;
- background:${color};margin-right:5px"></span>`;
- case 'triangle':
- return `<span style="
- display:inline-block;width:0;height:0;
- border-left:${size / 2}px solid transparent;
- border-right:${size / 2}px solid transparent;
- border-bottom:${size}px solid ${color};
- margin-right:5px"></span>`;
- case 'diamond':
- return `<span style="
- display:inline-block;width:${size - 2}px;height:${size - 2}px;
- background:${color};transform: rotate(45deg) translateX(1px)
translateY(-1px);
- margin-right:5px"></span>`;
- case 'pin':
- return `<span style="
- display:inline-block;width:${size - 2}px;height:${size - 2}px;
- background:${color};transform: rotate(45deg) translateX(1px)
translateY(-1px);
-
border-radius:50%;border-bottom-right-radius:0;margin-right:5px"></span>`;
- default:
- return `<span style="
- display:inline-block;width:${size}px;height:${size}px;
- border-radius:50%;background:${color};margin-right:5px"></span>`;
- }
-}
-
/**
* Given the fully-built ECharts series (each already carrying its resolved
* `stack` id, see `getTimeCompareStackId`), find the largest per-index total
@@ -1680,6 +1641,15 @@ export default function transformProps(
}
}
+ // Looked up per tooltip row; built once since the formatter runs on every
mousemove.
+ const symbolBySeriesName = new Map<string, string>();
+ series.forEach(s => {
+ const { symbol } = s as { symbol?: unknown };
+ if (typeof s.name === 'string' && typeof symbol === 'string') {
+ symbolBySeriesName.set(s.name, symbol);
+ }
+ });
+
const echartOptions: EChartsCoreOption = {
useUTC: true,
...(seriesType === EchartsTimeseriesSeriesType.Bar &&
@@ -1787,16 +1757,11 @@ export default function transformProps(
if (value.observation === 0 && stack) {
return;
}
- const seriesForKey = series.find(s => s.name === key);
- const symbolForSeries = (seriesForKey as any)?.symbol || 'circle';
- const marker = value.color
- ? getSymbolMarker(symbolForSeries, value.color)
- : value.marker;
const row = formatForecastTooltipSeries({
...value,
seriesName: key,
+ symbol: symbolBySeriesName.get(key),
formatter: getSeriesFormatter(key),
- marker,
truncation: tooltipTruncation,
});
diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
index a5c54541785..8328bd62b61 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/types.ts
@@ -33,7 +33,6 @@ import {
ChartMetadata,
} from '@superset-ui/core';
import type { EChartsCoreOption, EChartsType } from 'echarts/core';
-import type { TooltipMarker } from 'echarts/types/src/util/format';
import type { ECElementEvent } from 'echarts/types/src/util/types';
import { StackControlsValue } from './constants';
@@ -89,7 +88,6 @@ export enum LegendType {
}
export type ForecastValue = {
- marker: TooltipMarker;
observation?: number;
forecastTrend?: number;
forecastLower?: number;
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/src/utils/forecast.ts
b/superset-frontend/plugins/plugin-chart-echarts/src/utils/forecast.ts
index 555b2b6a4d7..69e8e727322 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/utils/forecast.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/utils/forecast.ts
@@ -19,12 +19,12 @@
import {
DataRecord,
DTTM_ALIAS,
+ tooltipMarker,
truncateLabel,
TooltipTruncationMode,
ValueFormatter,
} from '@superset-ui/core';
import type { OptionName, SeriesOption } from 'echarts/types/src/util/types';
-import type { TooltipMarker } from 'echarts/types/src/util/format';
import {
ForecastSeriesContext,
ForecastSeriesEnum,
@@ -81,14 +81,11 @@ export const extractForecastValuesFromTooltipParams = (
): Record<string, ForecastValue> => {
const values: Record<string, ForecastValue> = {};
params.forEach(param => {
- const { marker, seriesId, value, color } = param;
+ const { seriesId, value, color } = param;
const context = extractForecastSeriesContext(seriesId);
const numericValue = isHorizontal ? value[0] : value[1];
if (typeof numericValue === 'number') {
- if (!(context.name in values))
- values[context.name] = {
- marker: marker || '',
- };
+ if (!(context.name in values)) values[context.name] = {};
const forecastValues = values[context.name];
forecastValues.color = color;
if (context.type === ForecastSeriesEnum.Observation)
@@ -110,17 +107,20 @@ export const formatForecastTooltipSeries = ({
forecastTrend,
forecastLower,
forecastUpper,
- marker,
+ color,
+ symbol,
formatter,
truncation = 'end',
}: ForecastValue & {
seriesName: string;
- marker: TooltipMarker;
+ symbol?: string;
formatter: ValueFormatter;
truncation?: TooltipTruncationMode;
}): string[] => {
- // Truncate before sanitizing and before the marker is prepended: slicing a
- // string that already contains markup would cut into the marker's tag.
+ // The marker is built here rather than taken from ECharts: the sanitizer
+ // blanks ECharts' own box marker. Truncate before prepending it, since
+ // slicing a string that already contains markup would cut into the tag.
+ const marker = tooltipMarker(color, symbol);
const name = `${marker}${sanitizeHtml(truncateLabel(seriesName,
truncation))}`;
let value = typeof observation === 'number' ? formatter(observation) : '';
// Use finite-number checks rather than truthiness so that legitimate
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/test/Histogram/transformProps.test.ts
b/superset-frontend/plugins/plugin-chart-echarts/test/Histogram/transformProps.test.ts
index ee4d50ba8a6..83b5b491915 100644
---
a/superset-frontend/plugins/plugin-chart-echarts/test/Histogram/transformProps.test.ts
+++
b/superset-frontend/plugins/plugin-chart-echarts/test/Histogram/transformProps.test.ts
@@ -110,3 +110,14 @@ test('does not treat adhoc groupby labels as histogram bin
edges', () => {
expect(series[0].name).toBe('WEST');
expect(series[0].data).toEqual([3, 7]);
});
+
+test('tooltip rows start with a marker in the series color', () => {
+ const { tooltip } = transformProps(
+ createChartProps([{ '0 - 5': 3, '5 - 10': 7 }]) as HistogramChartProps,
+ ).echartOptions as { tooltip: { formatter: (params: unknown) => string } };
+ const html = tooltip.formatter([
+ { name: '0 - 5', seriesName: 'price', value: 3, color: '#1f77b4' },
+ ]);
+ expect(html.replace(/\s/g, '')).toContain('style="color:#1f77b4;');
+ expect(html).toContain('price');
+});
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/test/MixedTimeseries/transformProps.test.ts
b/superset-frontend/plugins/plugin-chart-echarts/test/MixedTimeseries/transformProps.test.ts
index 360209244df..6fa27290a68 100644
---
a/superset-frontend/plugins/plugin-chart-echarts/test/MixedTimeseries/transformProps.test.ts
+++
b/superset-frontend/plugins/plugin-chart-echarts/test/MixedTimeseries/transformProps.test.ts
@@ -1024,7 +1024,6 @@ test('tooltip resolves per-metric formats through the
display-keyed label map',
const html = formatter({
value: [599616000000, 0.5],
seriesId: 'sum__num, boy',
- marker: '',
color: '#333',
});
@@ -1086,7 +1085,6 @@ test('tooltip resolves per-metric formats for
secondary-query series', () => {
const html = formatter({
value: [599616000000, 2.5],
seriesId: 'count__num, boy',
- marker: '',
color: '#333',
});
@@ -1569,7 +1567,7 @@ test('y-axis title position: non-Left sets nameLocation
to end', () => {
describe('EchartsMixedTimeseries tooltip truncation', () => {
const longSeriesName = 'prod-us-east-1-service-checkout-latency-p99';
- const marker = '<span style="background-color:#1f77b4;"></span>';
+ const color = '#1f77b4';
const buildTooltip = (tooltipTruncation?: TooltipTruncationMode) => {
const chartProps = createEchartsTimeseriesTestChartProps<
@@ -1594,7 +1592,7 @@ describe('EchartsMixedTimeseries tooltip truncation', ()
=> {
seriesId: longSeriesName,
seriesName: longSeriesName,
value: [599616000000, 1],
- marker,
+ color,
});
};
@@ -1614,7 +1612,7 @@ describe('EchartsMixedTimeseries tooltip truncation', ()
=> {
const html = buildTooltip('start');
expect(html).not.toContain('prod-us-east');
expect(html).toContain('latency-p99');
- expect(html).toContain('background-color:#1f77b4');
+ expect(html.replace(/\s/g, '')).toContain('style="color:#1f77b4;');
});
test('keeps both ends when truncating the middle', () => {
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts
b/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts
index db531c26d55..a9ecd0e2c37 100644
---
a/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts
+++
b/superset-frontend/plugins/plugin-chart-echarts/test/Timeseries/transformProps.test.ts
@@ -3244,7 +3244,7 @@ test('honors the snake_case flag the compare-chart
migration stores in params',
});
describe('EchartsTimeseries tooltip truncation', () => {
const longSeriesName = 'prod-us-east-1-service-checkout-latency-p99';
- const marker = '<span style="background-color:#1f77b4;"></span>';
+ const color = '#1f77b4';
const buildTooltip = (
tooltipTruncation?: TooltipTruncationMode,
@@ -3283,7 +3283,7 @@ describe('EchartsTimeseries tooltip truncation', () => {
seriesId: longSeriesName,
seriesName: longSeriesName,
value: [xValue, 1],
- marker,
+ color,
},
]);
};
@@ -3315,9 +3315,11 @@ describe('EchartsTimeseries tooltip truncation', () => {
expect(html).not.toContain(longSeriesName);
});
- test('preserves the echarts marker in every mode', () => {
+ test('keeps the series color marker in every mode', () => {
(['off', 'end', 'start', 'middle'] as const).forEach(mode => {
- expect(buildTooltip(mode)).toContain('background-color:#1f77b4');
+ expect(buildTooltip(mode).replace(/\s/g, '')).toContain(
+ 'style="color:#1f77b4;',
+ );
});
});
diff --git
a/superset-frontend/plugins/plugin-chart-echarts/test/utils/forecast.test.ts
b/superset-frontend/plugins/plugin-chart-echarts/test/utils/forecast.test.ts
index 12adf4d096f..2e8dbe55b81 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/test/utils/forecast.test.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/test/utils/forecast.test.ts
@@ -19,6 +19,7 @@
import {
getNumberFormatter,
NumberFormats,
+ tooltipMarker,
TRUNCATION_MAX_CHARS,
} from '@superset-ui/core';
import { SeriesOption } from 'echarts';
@@ -206,41 +207,34 @@ test('extractForecastValuesFromTooltipParams should
extract the proper data from
expect(
extractForecastValuesFromTooltipParams([
{
- marker: '<img>',
seriesId: 'abc',
value: [new Date(0), 10],
},
{
- marker: '<img>',
seriesId: 'abc__yhat',
value: [new Date(0), 1],
},
{
- marker: '<img>',
seriesId: 'abc__yhat_lower',
value: [new Date(0), 5],
},
{
- marker: '<img>',
seriesId: 'abc__yhat_upper',
value: [new Date(0), 6],
},
{
- marker: '<img>',
seriesId: 'qwerty',
value: [new Date(0), 2],
},
]),
).toEqual({
abc: {
- marker: '<img>',
observation: 10,
forecastTrend: 1,
forecastLower: 5,
forecastUpper: 6,
},
qwerty: {
- marker: '<img>',
observation: 2,
},
});
@@ -250,176 +244,171 @@ test('extractForecastValuesFromTooltipParams should
extract valid values', () =>
expect(
extractForecastValuesFromTooltipParams([
{
- marker: '<img>',
seriesId: 'foo',
value: [0, 10],
},
{
- marker: '<img>',
seriesId: 'bar',
value: [100, 0],
},
]),
).toEqual({
foo: {
- marker: '<img>',
observation: 10,
},
bar: {
- marker: '<img>',
observation: 0,
},
});
});
const formatter = getNumberFormatter(NumberFormats.INTEGER);
+const marker = tooltipMarker('#1f77b4');
test('formatForecastTooltipSeries should apply format to value', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'abc',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10.1,
formatter,
}),
- ).toEqual(['<img>abc', '10']);
+ ).toEqual([`${marker}abc`, '10']);
});
test('formatForecastTooltipSeries should show falsy value', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'abc',
- marker: '<img>',
+ color: '#1f77b4',
observation: 0,
formatter,
}),
- ).toEqual(['<img>abc', '0']);
+ ).toEqual([`${marker}abc`, '0']);
});
test('formatForecastTooltipSeries should format full forecast', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10.1,
forecastTrend: 20.1,
forecastLower: 5.1,
forecastUpper: 7.1,
formatter,
}),
- ).toEqual(['<img>qwerty', '10, ŷ = 20 (5, 12)']);
+ ).toEqual([`${marker}qwerty`, '10, ŷ = 20 (5, 12)']);
});
test('formatForecastTooltipSeries should format forecast without observation',
() => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
forecastTrend: 20,
forecastLower: 5,
forecastUpper: 7,
formatter,
}),
- ).toEqual(['<img>qwerty', 'ŷ = 20 (5, 12)']);
+ ).toEqual([`${marker}qwerty`, 'ŷ = 20 (5, 12)']);
});
test('formatForecastTooltipSeries should format forecast without point
estimate', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10.1,
forecastLower: 6,
forecastUpper: 7,
formatter,
}),
- ).toEqual(['<img>qwerty', '10 (6, 13)']);
+ ).toEqual([`${marker}qwerty`, '10 (6, 13)']);
});
test('formatForecastTooltipSeries should format forecast with only confidence
band', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
forecastLower: 7,
forecastUpper: 8,
formatter,
}),
- ).toEqual(['<img>qwerty', '(7, 15)']);
+ ).toEqual([`${marker}qwerty`, '(7, 15)']);
});
test('formatForecastTooltipSeries should show forecast trend equal to zero',
() => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10,
forecastTrend: 0,
forecastLower: 5,
forecastUpper: 7,
formatter,
}),
- ).toEqual(['<img>qwerty', '10, ŷ = 0 (5, 12)']);
+ ).toEqual([`${marker}qwerty`, '10, ŷ = 0 (5, 12)']);
});
test('formatForecastTooltipSeries should show confidence band when lower bound
is zero', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10,
forecastTrend: 5,
forecastLower: 0,
forecastUpper: 7,
formatter,
}),
- ).toEqual(['<img>qwerty', '10, ŷ = 5 (0, 7)']);
+ ).toEqual([`${marker}qwerty`, '10, ŷ = 5 (0, 7)']);
});
test('formatForecastTooltipSeries should show confidence band when band height
is zero', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10,
forecastTrend: 5,
forecastLower: 4,
forecastUpper: 0,
formatter,
}),
- ).toEqual(['<img>qwerty', '10, ŷ = 5 (4, 4)']);
+ ).toEqual([`${marker}qwerty`, '10, ŷ = 5 (4, 4)']);
});
test('formatForecastTooltipSeries should show forecast trend and band all at
zero', () => {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
forecastTrend: 0,
forecastLower: 0,
forecastUpper: 0,
formatter,
}),
- ).toEqual(['<img>qwerty', 'ŷ = 0 (0, 0)']);
+ ).toEqual([`${marker}qwerty`, 'ŷ = 0 (0, 0)']);
});
test('formatForecastTooltipSeries should skip non-finite forecast values', ()
=> {
expect(
formatForecastTooltipSeries({
seriesName: 'qwerty',
- marker: '<img>',
+ color: '#1f77b4',
observation: 10,
forecastTrend: NaN,
forecastLower: Infinity,
forecastUpper: -Infinity,
formatter,
}),
- ).toEqual(['<img>qwerty', '10']);
+ ).toEqual([`${marker}qwerty`, '10']);
});
describe('formatForecastTooltipSeries truncation', () => {
- const marker =
- '<span
style="display:inline-block;width:10px;height:10px;background-color:#1f77b4;"></span>';
const longName = 'prod-us-east-1-service-checkout-latency-p99'; // 43 chars
const intFormatter = getNumberFormatter(NumberFormats.INTEGER);
@@ -427,7 +416,7 @@ describe('formatForecastTooltipSeries truncation', () => {
formatForecastTooltipSeries({
seriesName: longName,
observation: 1,
- marker,
+ color: '#1f77b4',
formatter: intFormatter,
...(truncation ? { truncation } : {}),
})[0];
@@ -458,7 +447,7 @@ describe('formatForecastTooltipSeries truncation', () => {
const [cell] = formatForecastTooltipSeries({
seriesName: 'cpu',
observation: 1,
- marker,
+ color: '#1f77b4',
formatter: intFormatter,
truncation: 'start',
});