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;