Skip to content

Commit ba2428d

Browse files
authored
[charts-pro] Allow source/target keywords in sankey link color (#19634)
Signed-off-by: Jose C Quintas Jr <[email protected]>
1 parent 26dbfde commit ba2428d

File tree

7 files changed

+206
-6
lines changed

7 files changed

+206
-6
lines changed
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import * as React from 'react';
2+
import { Unstable_SankeyChart as SankeyChart } from '@mui/x-charts-pro/SankeyChart';
3+
import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo';
4+
5+
const data = {
6+
nodes: [
7+
{ id: 'Input', label: 'Input' },
8+
{ id: 'ProcessA', label: 'Process A' },
9+
{ id: 'ProcessB', label: 'Process B' },
10+
{ id: 'Output', label: 'Output' },
11+
],
12+
links: [
13+
{ source: 'Input', target: 'ProcessA', value: 30 },
14+
{ source: 'Input', target: 'ProcessB', value: 20 },
15+
{ source: 'ProcessA', target: 'Output', value: 25 },
16+
{ source: 'ProcessB', target: 'Output', value: 15 },
17+
],
18+
};
19+
20+
export default function SankeyLinkKeywordColors() {
21+
return (
22+
<ChartsUsageDemo
23+
componentName="SankeyChart"
24+
data={{
25+
linkColorMode: {
26+
knob: 'radio',
27+
options: ['default', 'source', 'target'],
28+
defaultValue: 'source',
29+
},
30+
}}
31+
renderDemo={(props) => {
32+
const linkColor =
33+
props.linkColorMode === 'default' ? undefined : props.linkColorMode;
34+
35+
return (
36+
<SankeyChart
37+
height={300}
38+
series={{
39+
data,
40+
nodeOptions: {
41+
showLabels: true,
42+
},
43+
linkOptions: {
44+
color: linkColor,
45+
opacity: 0.6,
46+
},
47+
}}
48+
/>
49+
);
50+
}}
51+
getCode={({ props }) => {
52+
const linkColor =
53+
props.linkColorMode === 'default' ? undefined : props.linkColorMode;
54+
55+
return `import { Unstable_SankeyChart as SankeyChart } from '@mui/x-charts-pro/SankeyChart';
56+
57+
<SankeyChart
58+
height={300}
59+
series={{
60+
data,
61+
linkOptions: {
62+
color: ${linkColor ? `'${linkColor}'` : 'undefined'},
63+
opacity: 0.6,
64+
},
65+
}}
66+
/>`;
67+
}}
68+
/>
69+
);
70+
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import * as React from 'react';
2+
import { Unstable_SankeyChart as SankeyChart } from '@mui/x-charts-pro/SankeyChart';
3+
import ChartsUsageDemo from 'docsx/src/modules/components/ChartsUsageDemo';
4+
5+
const data = {
6+
nodes: [
7+
{ id: 'Input', label: 'Input' },
8+
{ id: 'ProcessA', label: 'Process A' },
9+
{ id: 'ProcessB', label: 'Process B' },
10+
{ id: 'Output', label: 'Output' },
11+
],
12+
links: [
13+
{ source: 'Input', target: 'ProcessA', value: 30 },
14+
{ source: 'Input', target: 'ProcessB', value: 20 },
15+
{ source: 'ProcessA', target: 'Output', value: 25 },
16+
{ source: 'ProcessB', target: 'Output', value: 15 },
17+
],
18+
};
19+
20+
export default function SankeyLinkKeywordColors() {
21+
return (
22+
<ChartsUsageDemo
23+
componentName="SankeyChart"
24+
data={{
25+
linkColorMode: {
26+
knob: 'radio',
27+
options: ['default', 'source', 'target'],
28+
defaultValue: 'source',
29+
},
30+
}}
31+
renderDemo={(props) => {
32+
const linkColor =
33+
props.linkColorMode === 'default' ? undefined : props.linkColorMode;
34+
35+
return (
36+
<SankeyChart
37+
height={300}
38+
series={{
39+
data,
40+
nodeOptions: {
41+
showLabels: true,
42+
},
43+
linkOptions: {
44+
color: linkColor,
45+
opacity: 0.6,
46+
},
47+
}}
48+
/>
49+
);
50+
}}
51+
getCode={({ props }) => {
52+
const linkColor =
53+
props.linkColorMode === 'default' ? undefined : props.linkColorMode;
54+
55+
return `import { Unstable_SankeyChart as SankeyChart } from '@mui/x-charts-pro/SankeyChart';
56+
57+
<SankeyChart
58+
height={300}
59+
series={{
60+
data,
61+
linkOptions: {
62+
color: ${linkColor ? `'${linkColor}'` : 'undefined'},
63+
opacity: 0.6,
64+
},
65+
}}
66+
/>`;
67+
}}
68+
/>
69+
);
70+
}

docs/data/charts/sankey/sankey.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ Default styles can be applied to all links using the `linkOptions` prop:
4545

4646
{{"demo": "SankeyLinkStyling.js"}}
4747

48+
### Link color keywords
49+
50+
Link colors can use special keyword values to automatically inherit colors from their connected nodes:
51+
52+
- `'source'` - The link inherits the color of its source node
53+
- `'target'` - The link inherits the color of its target node
54+
55+
This feature works for both individual link colors and the default link color in `linkOptions`:
56+
57+
{{"demo": "SankeyLinkKeywordColors.js"}}
58+
4859
### Node alignment
4960

5061
The node alignment determines how nodes are positioned within the Sankey chart. The layout follows these principles:

docs/pages/x/api/charts/legend-item-params.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"name": "LegendItemParams",
33
"imports": [
4+
"import { LegendItemParams } from '@mui/x-charts-premium'",
45
"import { LegendItemParams } from '@mui/x-charts-pro'",
56
"import { LegendItemParams } from '@mui/x-charts'"
67
],

packages/x-charts-pro/src/SankeyChart/calculateSankeyLayout.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export function calculateSankeyLayout(
3636
} = nodeOptions ?? {};
3737

3838
const {
39-
color: linkColor = (theme.vars || theme).palette.text.primary,
39+
color: linkColor = 'source',
4040
sort: linkSort = null,
4141
curveCorrection = 10,
4242
} = linkOptions ?? {};
@@ -98,10 +98,18 @@ export function calculateSankeyLayout(
9898
return l.source === link.source.id && l.target === link.target.id;
9999
});
100100

101+
let resolvedColor = originalLink?.color ?? linkColor;
102+
103+
if (resolvedColor === 'source') {
104+
resolvedColor = link.source.color ?? linkColor;
105+
} else if (resolvedColor === 'target') {
106+
resolvedColor = link.target.color ?? linkColor;
107+
}
108+
101109
return {
102110
...originalLink,
103111
...link,
104-
color: originalLink?.color ?? linkColor,
112+
color: resolvedColor,
105113
path: improvedNaiveSankeyLinkPathHorizontal(link, curveCorrection),
106114
};
107115
});

packages/x-charts-pro/src/SankeyChart/sankey.types.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@ export interface SankeyLink {
5353
data?: any;
5454

5555
/**
56-
* Optional color override for the link
56+
* Optional color override for the link.
57+
* Can be a color string, or a keyword:
58+
* - 'source': Use the color of the source node
59+
* - 'target': Use the color of the target node
60+
* @default 'source'
5761
*/
58-
color?: string;
62+
color?: string | 'source' | 'target';
5963
}
6064

6165
export type SankeyNodeOptions = {
@@ -95,9 +99,13 @@ export type SankeyNodeOptions = {
9599

96100
export type SankeyLinkOptions = {
97101
/**
98-
* Default color for links without specified colors
102+
* Default color for links without specified colors.
103+
* Can be a color string, or a keyword:
104+
* - 'source': Use the color of the source node
105+
* - 'target': Use the color of the target node
106+
* @default 'source'
99107
*/
100-
color?: string;
108+
color?: string | 'source' | 'target';
101109
/**
102110
* Opacity of the links (0-1)
103111
*/

scripts/x-charts-premium.exports.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,12 @@
2121
{ "name": "AxisConfig", "kind": "TypeAlias" },
2222
{ "name": "AxisItemIdentifier", "kind": "Interface" },
2323
{ "name": "AxisValueFormatterContext", "kind": "TypeAlias" },
24+
{ "name": "BAR_CHART_PLUGINS", "kind": "Variable" },
25+
{ "name": "BAR_CHART_PRO_PLUGINS", "kind": "Variable" },
2426
{ "name": "BarChart", "kind": "Variable" },
27+
{ "name": "BarChartPluginSignatures", "kind": "TypeAlias" },
2528
{ "name": "BarChartPro", "kind": "Variable" },
29+
{ "name": "BarChartProPluginSignatures", "kind": "TypeAlias" },
2630
{ "name": "BarChartProProps", "kind": "Interface" },
2731
{ "name": "BarChartProps", "kind": "Interface" },
2832
{ "name": "BarChartProSlotProps", "kind": "Interface" },
@@ -55,6 +59,7 @@
5559
{ "name": "BarPlotProps", "kind": "Interface" },
5660
{ "name": "BarPlotSlotProps", "kind": "Interface" },
5761
{ "name": "BarPlotSlots", "kind": "Interface" },
62+
{ "name": "BarProps", "kind": "Interface" },
5863
{ "name": "BarSeries", "kind": "TypeAlias" },
5964
{ "name": "BarSeriesType", "kind": "Interface" },
6065
{ "name": "blueberryTwilightPalette", "kind": "Variable" },
@@ -136,6 +141,8 @@
136141
{ "name": "ChartsReferenceLineClasses", "kind": "Interface" },
137142
{ "name": "ChartsReferenceLineClassKey", "kind": "TypeAlias" },
138143
{ "name": "ChartsReferenceLineProps", "kind": "TypeAlias" },
144+
{ "name": "ChartsRenderer", "kind": "Function" },
145+
{ "name": "ChartsRendererProps", "kind": "Interface" },
139146
{ "name": "ChartsSurface", "kind": "Variable" },
140147
{ "name": "ChartsSurfaceProps", "kind": "Interface" },
141148
{ "name": "ChartsText", "kind": "Function" },
@@ -176,6 +183,7 @@
176183
{ "name": "cheerfulFiestaPaletteLight", "kind": "Variable" },
177184
{ "name": "ColorLegendSelector", "kind": "Interface" },
178185
{ "name": "ComputedPieRadius", "kind": "Interface" },
186+
{ "name": "configurationOptions", "kind": "Variable" },
179187
{ "name": "ContinuousColorLegend", "kind": "Variable" },
180188
{ "name": "continuousColorLegendClasses", "kind": "Variable" },
181189
{ "name": "ContinuousColorLegendClasses", "kind": "Interface" },
@@ -205,7 +213,9 @@
205213
{ "name": "defaultOnBeforeExport", "kind": "Function" },
206214
{ "name": "Direction", "kind": "TypeAlias" },
207215
{ "name": "FadeOptions", "kind": "TypeAlias" },
216+
{ "name": "FUNNEL_CHART_PLUGINS", "kind": "Variable" },
208217
{ "name": "FunnelChart", "kind": "Variable" },
218+
{ "name": "FunnelChartPluginSignatures", "kind": "TypeAlias" },
209219
{ "name": "FunnelChartProps", "kind": "Interface" },
210220
{ "name": "FunnelChartSlotExtension", "kind": "Interface" },
211221
{ "name": "FunnelChartSlotProps", "kind": "Interface" },
@@ -250,6 +260,7 @@
250260
{ "name": "getHeatmapUtilityClass", "kind": "Function" },
251261
{ "name": "getHighlightElementUtilityClass", "kind": "Function" },
252262
{ "name": "getLineElementUtilityClass", "kind": "Function" },
263+
{ "name": "getLocalizedConfigurationOptions", "kind": "Variable" },
253264
{ "name": "getMarkElementUtilityClass", "kind": "Function" },
254265
{ "name": "getPieArcLabelUtilityClass", "kind": "Function" },
255266
{ "name": "getPieArcUtilityClass", "kind": "Function" },
@@ -259,12 +270,16 @@
259270
{ "name": "greenPalette", "kind": "Variable" },
260271
{ "name": "greenPaletteDark", "kind": "Variable" },
261272
{ "name": "greenPaletteLight", "kind": "Variable" },
273+
{ "name": "GridChartsConfigurationOptions", "kind": "Interface" },
274+
{ "name": "GridChartsConfigurationSection", "kind": "Interface" },
262275
{ "name": "Heatmap", "kind": "Variable" },
276+
{ "name": "HEATMAP_PLUGINS", "kind": "Variable" },
263277
{ "name": "heatmapClasses", "kind": "Variable" },
264278
{ "name": "HeatmapClasses", "kind": "Interface" },
265279
{ "name": "HeatmapClassKey", "kind": "TypeAlias" },
266280
{ "name": "HeatmapItemIdentifier", "kind": "TypeAlias" },
267281
{ "name": "HeatmapPlot", "kind": "Function" },
282+
{ "name": "HeatmapPluginSignatures", "kind": "TypeAlias" },
268283
{ "name": "HeatmapProps", "kind": "Interface" },
269284
{ "name": "HeatmapSeries", "kind": "TypeAlias" },
270285
{ "name": "HeatmapSeriesType", "kind": "Interface" },
@@ -286,8 +301,12 @@
286301
{ "name": "legendClasses", "kind": "Variable" },
287302
{ "name": "LegendItemContext", "kind": "TypeAlias" },
288303
{ "name": "LegendItemParams", "kind": "Interface" },
304+
{ "name": "LINE_CHART_PLUGINS", "kind": "Variable" },
305+
{ "name": "LINE_CHART_PRO_PLUGINS", "kind": "Variable" },
289306
{ "name": "LineChart", "kind": "Variable" },
307+
{ "name": "LineChartPluginSignatures", "kind": "TypeAlias" },
290308
{ "name": "LineChartPro", "kind": "Variable" },
309+
{ "name": "LineChartProPluginSignatures", "kind": "TypeAlias" },
291310
{ "name": "LineChartProProps", "kind": "Interface" },
292311
{ "name": "LineChartProps", "kind": "Interface" },
293312
{ "name": "LineChartProSlotProps", "kind": "Interface" },
@@ -332,6 +351,8 @@
332351
{ "name": "orangePalette", "kind": "Variable" },
333352
{ "name": "orangePaletteDark", "kind": "Variable" },
334353
{ "name": "orangePaletteLight", "kind": "Variable" },
354+
{ "name": "PIE_CHART_PLUGINS", "kind": "Variable" },
355+
{ "name": "PIE_CHART_PRO_PLUGINS", "kind": "Variable" },
335356
{ "name": "PieArc", "kind": "Variable" },
336357
{ "name": "pieArcClasses", "kind": "Variable" },
337358
{ "name": "PieArcClasses", "kind": "Interface" },
@@ -358,7 +379,9 @@
358379
{ "name": "PiecewiseColorLegendProps", "kind": "Interface" },
359380
{ "name": "PiecewiseLabelFormatterParams", "kind": "TypeAlias" },
360381
{ "name": "PieChart", "kind": "Variable" },
382+
{ "name": "PieChartPluginSignatures", "kind": "TypeAlias" },
361383
{ "name": "PieChartPro", "kind": "Variable" },
384+
{ "name": "PieChartProPluginSignatures", "kind": "TypeAlias" },
362385
{ "name": "PieChartProProps", "kind": "Interface" },
363386
{ "name": "PieChartProps", "kind": "Interface" },
364387
{ "name": "PieChartProSlotProps", "kind": "Interface" },
@@ -385,13 +408,17 @@
385408
{ "name": "purplePalette", "kind": "Variable" },
386409
{ "name": "purplePaletteDark", "kind": "Variable" },
387410
{ "name": "purplePaletteLight", "kind": "Variable" },
411+
{ "name": "RADAR_CHART_PRO_PLUGINS", "kind": "Variable" },
412+
{ "name": "RADAR_PLUGINS", "kind": "Variable" },
388413
{ "name": "RadarAxis", "kind": "Function" },
389414
{ "name": "RadarAxisClasses", "kind": "Interface" },
390415
{ "name": "RadarAxisHighlight", "kind": "Function" },
391416
{ "name": "RadarAxisHighlightProps", "kind": "Interface" },
392417
{ "name": "RadarAxisProps", "kind": "Interface" },
393418
{ "name": "RadarChart", "kind": "Variable" },
419+
{ "name": "RadarChartPluginSignatures", "kind": "TypeAlias" },
394420
{ "name": "RadarChartPro", "kind": "Variable" },
421+
{ "name": "RadarChartProPluginSignatures", "kind": "TypeAlias" },
395422
{ "name": "RadarChartProProps", "kind": "Interface" },
396423
{ "name": "RadarChartProps", "kind": "Interface" },
397424
{ "name": "RadarChartProSlotProps", "kind": "Interface" },
@@ -423,11 +450,16 @@
423450
{ "name": "redPaletteDark", "kind": "Variable" },
424451
{ "name": "redPaletteLight", "kind": "Variable" },
425452
{ "name": "referenceLineClasses", "kind": "Variable" },
453+
{ "name": "RendererType", "kind": "TypeAlias" },
426454
{ "name": "RotationAxis", "kind": "TypeAlias" },
427455
{ "name": "ScaleName", "kind": "TypeAlias" },
428456
{ "name": "Scatter", "kind": "Function" },
457+
{ "name": "SCATTER_CHART_PLUGINS", "kind": "Variable" },
458+
{ "name": "SCATTER_CHART_PRO_PLUGINS", "kind": "Variable" },
429459
{ "name": "ScatterChart", "kind": "Variable" },
460+
{ "name": "ScatterChartPluginSignatures", "kind": "TypeAlias" },
430461
{ "name": "ScatterChartPro", "kind": "Variable" },
462+
{ "name": "ScatterChartProPluginSignatures", "kind": "TypeAlias" },
431463
{ "name": "ScatterChartProProps", "kind": "Interface" },
432464
{ "name": "ScatterChartProps", "kind": "Interface" },
433465
{ "name": "ScatterChartProSlotProps", "kind": "Interface" },

0 commit comments

Comments
 (0)