diff --git a/__tests__/integration/issue-5474.spec.ts b/__tests__/integration/issue-5474.spec.ts
new file mode 100644
index 0000000000..d51366e32c
--- /dev/null
+++ b/__tests__/integration/issue-5474.spec.ts
@@ -0,0 +1,35 @@
+import { issue5474 as render } from '../plots/bugfix/issue-5474';
+import { createNodeGCanvas } from './utils/createNodeGCanvas';
+import { sleep } from './utils/sleep';
+import './utils/useSnapshotMatchers';
+
+describe('issue5474', () => {
+ const canvas = createNodeGCanvas(800, 500);
+
+ it('issue5474.render() should render chart with labels matching element colors', async () => {
+ const { chart } = render({
+ canvas,
+ container: document.createElement('div'),
+ });
+
+ await chart.render();
+ await sleep(20);
+
+ const labels = canvas.document.getElementsByClassName('label');
+ expect(labels.length).toBeGreaterThan(0);
+
+ labels.forEach((label) => {
+ expect(label.style.fill).toBe(
+ // @ts-ignore
+ label.__data__.dependentElement.attributes.fill,
+ );
+ });
+
+ const dir = `${__dirname}/snapshots/bugfix`;
+ await expect(canvas).toMatchDOMSnapshot(dir, render.name);
+ });
+
+ afterAll(() => {
+ canvas?.destroy();
+ });
+});
diff --git a/__tests__/integration/snapshots/bugfix/issue5474.svg b/__tests__/integration/snapshots/bugfix/issue5474.svg
new file mode 100644
index 0000000000..9c7a411610
--- /dev/null
+++ b/__tests__/integration/snapshots/bugfix/issue5474.svg
@@ -0,0 +1,1602 @@
+
\ No newline at end of file
diff --git a/__tests__/plots/bugfix/index.ts b/__tests__/plots/bugfix/index.ts
index 8e2caa72e2..5fb5c75b2f 100644
--- a/__tests__/plots/bugfix/index.ts
+++ b/__tests__/plots/bugfix/index.ts
@@ -2,3 +2,4 @@ export { issue6396 } from './issue-6396';
export { issue6399 } from './issue-6399';
export { issueChart2719 } from './issue-chart-2719';
export { issue6020 } from './issue-6020';
+export { issue5474 } from './issue-5474';
diff --git a/__tests__/plots/bugfix/issue-5474.ts b/__tests__/plots/bugfix/issue-5474.ts
new file mode 100644
index 0000000000..70d505fa35
--- /dev/null
+++ b/__tests__/plots/bugfix/issue-5474.ts
@@ -0,0 +1,37 @@
+import { Chart } from '../../../src';
+
+export function issue5474(context) {
+ const { container, canvas, callback } = context;
+
+ const chart = new Chart({
+ container: container,
+ autoFit: true,
+ insetRight: 10,
+ canvas,
+ });
+
+ if (callback) {
+ callback(chart);
+ } else {
+ chart
+ .interval()
+ .data([
+ { genre: 'Sports', sold: 0 },
+ { genre: 'Strategy', sold: 115 },
+ { genre: 'Action', sold: 120 },
+ { genre: 'Shooter', sold: 350 },
+ { genre: 'Other', sold: 150 },
+ ])
+ .encode('x', 'genre')
+ .encode('y', 'sold')
+ .encode('color', 'genre')
+ .label({
+ text: 'genre',
+ fill: (_, i, array, d) => d.elementStyle.fill,
+ });
+ }
+
+ chart.render();
+
+ return { chart };
+}
diff --git a/site/docs/spec/label/overview.zh.md b/site/docs/spec/label/overview.zh.md
index c7408b5bd0..e327ef3c85 100644
--- a/site/docs/spec/label/overview.zh.md
+++ b/site/docs/spec/label/overview.zh.md
@@ -127,7 +127,7 @@ chart
d,
i,
data,
- { channel }, // 聚合图形的样式
+ { channel, elementStyle }, // 聚合图形的样式 & label依赖元素的样式
) => (channel.y[i] < 11700 ? '#E49361' : '#4787F7'),
);
```
diff --git a/src/runtime/plot.ts b/src/runtime/plot.ts
index a5ee20e6be..ae1725b8c5 100644
--- a/src/runtime/plot.ts
+++ b/src/runtime/plot.ts
@@ -1197,7 +1197,9 @@ function plotLabel(
return elements.flatMap((e) => {
const L = getLabels(options, i, e);
L.forEach((l) => {
- labelShapeFunction.set(l, shapeFunction);
+ labelShapeFunction.set(l, (data) =>
+ shapeFunction({ ...data, elementStyle: e.attributes }),
+ );
labelDescriptor.set(l, labelOption);
});
return L;
@@ -1365,11 +1367,17 @@ function createLabelShapeFunction(
style: abstractStyle,
render,
selector,
+ elementStyle,
...abstractOptions
} = options;
+
const visualOptions = mapObject(
{ ...abstractOptions, ...abstractStyle } as Record,
- (d) => valueOf(d, datum, index, abstractData, { channel }),
+ (d) =>
+ valueOf(d, datum, index, abstractData, {
+ channel: { ...channel },
+ elementStyle,
+ }),
);
const { shape = defaultLabelShape, text, ...style } = visualOptions;
const f = typeof formatter === 'string' ? format(formatter) : formatter;
@@ -1393,7 +1401,7 @@ function valueOf(
datum: Record,
i: number,
data: Record,
- options: { channel: Record },
+ options: { channel: Record; elementStyle?: Record },
) {
if (typeof value === 'function') return value(datum, i, data, options);
if (typeof value !== 'string') return value;