diff --git a/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-X-Plot-Bands-1-chromium-linux.png b/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-X-Plot-Bands-1-chromium-linux.png index 1592a1479..4754015d8 100644 Binary files a/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-X-Plot-Bands-1-chromium-linux.png and b/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-X-Plot-Bands-1-chromium-linux.png differ diff --git a/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-Y-Plot-Bands-1-chromium-linux.png b/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-Y-Plot-Bands-1-chromium-linux.png index e2e906e37..b093cbfa6 100644 Binary files a/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-Y-Plot-Bands-1-chromium-linux.png and b/src/__snapshots__/bands.visual.test.tsx-snapshots/Plot-Bands-Datetime-Y-Plot-Bands-1-chromium-linux.png differ diff --git a/src/__snapshots__/line-series.visual.test.tsx-snapshots/Line-series-Data-labels-Positioning-of-extreme-point-dataLabels-1-chromium-linux.png b/src/__snapshots__/line-series.visual.test.tsx-snapshots/Line-series-Data-labels-Positioning-of-extreme-point-dataLabels-1-chromium-linux.png new file mode 100644 index 000000000..0844b2449 Binary files /dev/null and b/src/__snapshots__/line-series.visual.test.tsx-snapshots/Line-series-Data-labels-Positioning-of-extreme-point-dataLabels-1-chromium-linux.png differ diff --git a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-X-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-X-Plot-Lines-1-chromium-linux.png deleted file mode 100644 index f05134f63..000000000 Binary files a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-X-Plot-Lines-1-chromium-linux.png and /dev/null differ diff --git a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-Y-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-Y-Plot-Lines-1-chromium-linux.png deleted file mode 100644 index 4d831a266..000000000 Binary files a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-Y-Plot-Lines-1-chromium-linux.png and /dev/null differ diff --git a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Linear-X-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Linear-X-Plot-Lines-1-chromium-linux.png deleted file mode 100644 index 2e19d230d..000000000 Binary files a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Linear-X-Plot-Lines-1-chromium-linux.png and /dev/null differ diff --git a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Linear-Y-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Linear-Y-Plot-Lines-1-chromium-linux.png deleted file mode 100644 index da60225dd..000000000 Binary files a/src/__snapshots__/lines.visual.test.tsx-snapshots/Plot-Lines-Linear-Y-Plot-Lines-1-chromium-linux.png and /dev/null differ diff --git a/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-X-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-X-Plot-Lines-1-chromium-linux.png new file mode 100644 index 000000000..47b0cc748 Binary files /dev/null and b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-X-Plot-Lines-1-chromium-linux.png differ diff --git a/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-Y-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-Y-Plot-Lines-1-chromium-linux.png new file mode 100644 index 000000000..e278e4a24 Binary files /dev/null and b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Datetime-Y-Plot-Lines-1-chromium-linux.png differ diff --git a/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Linear-X-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Linear-X-Plot-Lines-1-chromium-linux.png new file mode 100644 index 000000000..a829b07b9 Binary files /dev/null and b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Linear-X-Plot-Lines-1-chromium-linux.png differ diff --git a/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Linear-Y-Plot-Lines-1-chromium-linux.png b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Linear-Y-Plot-Lines-1-chromium-linux.png new file mode 100644 index 000000000..0f3165e0d Binary files /dev/null and b/src/__snapshots__/plot-lines.visual.test.tsx-snapshots/Plot-Lines-Linear-Y-Plot-Lines-1-chromium-linux.png differ diff --git a/src/__tests__/line-series.visual.test.tsx b/src/__tests__/line-series.visual.test.tsx index 37ff69165..f0f718287 100644 --- a/src/__tests__/line-series.visual.test.tsx +++ b/src/__tests__/line-series.visual.test.tsx @@ -97,4 +97,30 @@ test.describe('Line series', () => { const component = await mount(); await expect(component.locator('svg')).toHaveScreenshot(); }); + + test.describe('Data labels', () => { + test('Positioning of extreme point dataLabels', async ({mount}) => { + const chartData: ChartData = { + series: { + data: [ + { + name: '', + type: 'line', + data: [ + {x: 0, y: 0, label: 'left-bottom'}, + {y: 10, x: 0, label: 'left-top'}, + {y: 10, x: 10, label: 'right-top'}, + {y: 0, x: 10, label: 'right-bottom'}, + ], + dataLabels: {enabled: true}, + }, + ], + }, + yAxis: [{maxPadding: 0}], + xAxis: {maxPadding: 0}, + }; + const component = await mount(); + await expect(component.locator('svg')).toHaveScreenshot(); + }); + }); }); diff --git a/src/__tests__/lines.visual.test.tsx b/src/__tests__/plot-lines.visual.test.tsx similarity index 100% rename from src/__tests__/lines.visual.test.tsx rename to src/__tests__/plot-lines.visual.test.tsx diff --git a/src/hooks/useShapes/line/prepare-data.ts b/src/hooks/useShapes/line/prepare-data.ts index 818544f69..59a208f7e 100644 --- a/src/hooks/useShapes/line/prepare-data.ts +++ b/src/hooks/useShapes/line/prepare-data.ts @@ -1,5 +1,5 @@ import type {HtmlItem, LabelData} from '../../../types'; -import {getLabelsSize, getLeftPosition} from '../../../utils'; +import {getLabelsSize, getTextSizeFn} from '../../../utils'; import {getFormattedValue} from '../../../utils/chart/format'; import type {PreparedXAxis, PreparedYAxis} from '../../useAxis/types'; import type {ChartScale} from '../../useAxisScales'; @@ -9,38 +9,6 @@ import {getXValue, getYValue} from '../utils'; import type {MarkerData, MarkerPointData, PreparedLineData} from './types'; -async function getLabelData(point: MarkerPointData, series: PreparedLineSeries, xMax: number) { - const text = getFormattedValue({ - value: point.data.label || point.data.y, - ...series.dataLabels, - }); - const style = series.dataLabels.style; - const size = await getLabelsSize({labels: [text], style}); - - const labelData: LabelData = { - text, - x: point.x, - y: point.y - series.dataLabels.padding, - style, - size: {width: size.maxWidth, height: size.maxHeight}, - textAnchor: 'middle', - series: series, - active: true, - }; - - const left = getLeftPosition(labelData); - if (left < 0) { - labelData.x = labelData.x + Math.abs(left); - } else { - const right = left + labelData.size.width; - if (right > xMax) { - labelData.x = labelData.x - xMax - right; - } - } - - return labelData; -} - async function getHtmlLabel( point: MarkerPointData, series: PreparedLineSeries, @@ -99,7 +67,7 @@ export const prepareLineData = async (args: { }); const htmlElements: HtmlItem[] = []; - let labels: LabelData[] = []; + const labels: LabelData[] = []; if (s.dataLabels.enabled) { if (s.dataLabels.html) { const list = await Promise.all( @@ -113,15 +81,40 @@ export const prepareLineData = async (args: { ); htmlElements.push(...list); } else { - labels = await Promise.all( - points.reduce[]>((result, p) => { - if (p.y === null) { - return result; - } - result.push(getLabelData(p as MarkerPointData, s, xMax)); - return result; - }, []), - ); + const getTextSize = getTextSizeFn({style: s.dataLabels.style}); + for (let index = 0; index < points.length; index++) { + const point = points[index]; + if (point.y !== null && point.x !== null) { + const text = getFormattedValue({ + value: point.data.label || point.data.y, + ...s.dataLabels, + }); + const labelSize = await getTextSize(text); + + const style = s.dataLabels.style; + + const y = Math.max( + yAxisTop, + point.y - s.dataLabels.padding - labelSize.height, + ); + const x = Math.min( + xMax - labelSize.width, + Math.max(0, point.x - labelSize.width / 2), + ); + const labelData: LabelData = { + text, + x, + y, + style, + size: labelSize, + textAnchor: 'start', + series: s, + active: true, + }; + + labels.push(labelData); + } + } } } diff --git a/src/hooks/useShapes/styles.scss b/src/hooks/useShapes/styles.scss index 6ca91ebbe..5f8fffe86 100644 --- a/src/hooks/useShapes/styles.scss +++ b/src/hooks/useShapes/styles.scss @@ -1,3 +1,9 @@ +.gcharts-line { + &__label { + dominant-baseline: text-before-edge; + } +} + .gcharts-scatter { &__point { stroke-width: 1px;