Skip to content

Commit 3d80fe7

Browse files
authored
feat(sankey): add left and right props for layout padding control (#516)
1 parent 194aea8 commit 3d80fe7

5 files changed

Lines changed: 124 additions & 0 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/kumo": patch
3+
---
4+
5+
Add `left` and `right` props to SankeyChart for controlling series layout padding

packages/kumo-docs-astro/src/components/demos/Chart/SankeyChartDemo.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,22 @@ export function SankeyChartRichTooltipDemo() {
286286
);
287287
}
288288

289+
/** Demo showing full-width layout using left={0} and right={0} to eliminate default padding */
290+
export function SankeyChartFullWidthDemo() {
291+
const isDarkMode = useIsDarkMode();
292+
return (
293+
<SankeyChart
294+
echarts={echarts}
295+
nodes={basicNodes}
296+
links={basicLinks}
297+
height={350}
298+
left={0}
299+
right={0}
300+
isDarkMode={isDarkMode}
301+
/>
302+
);
303+
}
304+
289305
export function SankeyChartInteractiveDemo() {
290306
const isDarkMode = useIsDarkMode();
291307
const handleNodeClick = (node: { name: string }) => {

packages/kumo-docs-astro/src/pages/charts/sankey.astro

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import PropsTable from "../../components/docs/PropsTable.astro";
88
import {
99
SankeyChartBasicDemo,
1010
SankeyChartMultiLevelDemo,
11+
SankeyChartFullWidthDemo,
1112
SankeyChartTooltipDemo,
1213
SankeyChartRichTooltipDemo,
1314
SankeyChartInteractiveDemo,
@@ -103,6 +104,22 @@ export default function Example() {
103104
</ComponentExample>
104105
</div>
105106

107+
<div>
108+
<Heading level={3}>Full-Width Layout</Heading>
109+
<p class="mb-4 text-kumo-subtle">
110+
Use <code class="text-kumo-default">left</code> and <code class="text-kumo-default">right</code> to control horizontal padding of the Sankey layout within its container. Set both to <code class="text-kumo-default">0</code> to eliminate the default 5% padding and fill the full width.
111+
</p>
112+
<ComponentExample code={`<SankeyChart
113+
nodes={nodes}
114+
links={links}
115+
height={350}
116+
left={0}
117+
right={0}
118+
/>`}>
119+
<SankeyChartFullWidthDemo client:visible />
120+
</ComponentExample>
121+
</div>
122+
106123
<div>
107124
<Heading level={3}>Rich Tooltips</Heading>
108125
<p class="mb-4 text-kumo-subtle">

packages/kumo/src/components/chart/SankeyChart.test.tsx

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,82 @@ describe("SankeyChart", () => {
496496
});
497497
});
498498

499+
describe("left and right layout props", () => {
500+
it("does not include left/right in series config when omitted", () => {
501+
const mockChart = createMockChart();
502+
const mockEcharts = createMockEcharts(mockChart);
503+
504+
render(
505+
<SankeyChart
506+
echarts={mockEcharts as any}
507+
nodes={baseNodes}
508+
links={baseLinks}
509+
/>,
510+
);
511+
512+
const options = mockChart.setOption.mock.calls[0][0];
513+
expect(options.series[0]).not.toHaveProperty("left");
514+
expect(options.series[0]).not.toHaveProperty("right");
515+
});
516+
517+
it("includes left: 0 and right: 0 when passed as numbers", () => {
518+
const mockChart = createMockChart();
519+
const mockEcharts = createMockEcharts(mockChart);
520+
521+
render(
522+
<SankeyChart
523+
echarts={mockEcharts as any}
524+
nodes={baseNodes}
525+
links={baseLinks}
526+
left={0}
527+
right={0}
528+
/>,
529+
);
530+
531+
const options = mockChart.setOption.mock.calls[0][0];
532+
expect(options.series[0].left).toBe(0);
533+
expect(options.series[0].right).toBe(0);
534+
});
535+
536+
it("forwards string percentage values correctly", () => {
537+
const mockChart = createMockChart();
538+
const mockEcharts = createMockEcharts(mockChart);
539+
540+
render(
541+
<SankeyChart
542+
echarts={mockEcharts as any}
543+
nodes={baseNodes}
544+
links={baseLinks}
545+
left="10%"
546+
right="15%"
547+
/>,
548+
);
549+
550+
const options = mockChart.setOption.mock.calls[0][0];
551+
expect(options.series[0].left).toBe("10%");
552+
expect(options.series[0].right).toBe("15%");
553+
});
554+
555+
it("forwards pixel number values correctly", () => {
556+
const mockChart = createMockChart();
557+
const mockEcharts = createMockEcharts(mockChart);
558+
559+
render(
560+
<SankeyChart
561+
echarts={mockEcharts as any}
562+
nodes={baseNodes}
563+
links={baseLinks}
564+
left={20}
565+
right={30}
566+
/>,
567+
);
568+
569+
const options = mockChart.setOption.mock.calls[0][0];
570+
expect(options.series[0].left).toBe(20);
571+
expect(options.series[0].right).toBe(30);
572+
});
573+
});
574+
499575
describe("dark mode", () => {
500576
it("initializes ECharts with dark theme when isDarkMode is true", () => {
501577
const mockChart = createMockChart();

packages/kumo/src/components/chart/SankeyChart.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ export interface SankeyChartProps {
7777
nodePadding?: number;
7878
showTooltip?: boolean;
7979
defaultNodeColor?: string;
80+
/** Left padding of the Sankey layout within the chart container. Accepts a number (px) or percentage string. ECharts default: '5%'. */
81+
left?: number | string;
82+
/** Right padding of the Sankey layout within the chart container. Accepts a number (px) or percentage string. ECharts default: '5%'. */
83+
right?: number | string;
8084
/** Link fill style: 'gradient' blends source to target colors, 'gray' uses flat gray */
8185
linkColor?: "gradient" | "gray";
8286
linkOpacity?: number;
@@ -168,6 +172,8 @@ export function SankeyChart({
168172
formatValue = defaultFormatValue,
169173
tooltipFormatter,
170174
defaultNodeColor,
175+
left,
176+
right,
171177
linkColor = "gradient",
172178
linkOpacity = 0.5,
173179
className,
@@ -276,6 +282,8 @@ export function SankeyChart({
276282
series: [
277283
{
278284
type: "sankey",
285+
...(left !== undefined && { left }),
286+
...(right !== undefined && { right }),
279287
data: echartsNodes,
280288
links: echartsLinks,
281289
draggable: false,
@@ -329,6 +337,8 @@ export function SankeyChart({
329337
nodeWidth,
330338
nodePadding,
331339
defaultNodeColor,
340+
left,
341+
right,
332342
isDarkMode,
333343
linkColor,
334344
linkOpacity,

0 commit comments

Comments
 (0)