Skip to content

Commit 35b3107

Browse files
committed
feat(echarts): sankey
1 parent 7b64b05 commit 35b3107

File tree

16 files changed

+730
-7
lines changed

16 files changed

+730
-7
lines changed

packages/react-charts/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/next
2+
/components

packages/react-charts/package.json

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
"main": "dist/js/index.js",
66
"module": "dist/esm/index.js",
77
"types": "dist/esm/index.d.ts",
8+
"typesVersions": {
9+
"*": {
10+
"next": [
11+
"dist/esm/next/index.d.ts"
12+
]
13+
}
14+
},
815
"patternfly:src": "src/",
916
"sideEffects": [
1017
"*.css",
@@ -30,6 +37,7 @@
3037
"dependencies": {
3138
"@patternfly/react-styles": "workspace:^",
3239
"@patternfly/react-tokens": "workspace:^",
40+
"echarts": "^5.5.1",
3341
"hoist-non-react-statics": "^3.3.2",
3442
"lodash": "^4.17.21",
3543
"tslib": "^2.6.3",
@@ -56,10 +64,12 @@
5664
"react-dom": "^17 || ^18"
5765
},
5866
"scripts": {
59-
"clean": "rimraf dist",
60-
"build:single:packages": "node ../../scripts/build-single-packages.js --config single-packages.config.json"
67+
"build:single:packages": "node ../../scripts/build-single-packages.js --config single-packages.config.json",
68+
"clean": "rimraf dist components next",
69+
"subpaths": "node ../../scripts/exportSubpaths.js --config subpaths.config.json"
6170
},
6271
"devDependencies": {
72+
"@types/echarts": "^4.9.22",
6373
"@types/lodash": "^4.17.6",
6474
"fs-extra": "^11.2.0"
6575
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"packageName": "@patternfly/react-charts",
3-
"exclude": ["dist/esm/deprecated/index.js", "dist/esm/next/index.js"]
3+
"exclude": ["dist/esm/deprecated/index.js"]
44
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import * as React from 'react';
2+
// import * as echarts from 'echarts';
3+
import { render } from '@testing-library/react';
4+
import { Sankey } from './Sankey';
5+
6+
const data = [
7+
{
8+
name: 'a'
9+
},
10+
{
11+
name: 'b'
12+
},
13+
{
14+
name: 'a1'
15+
},
16+
{
17+
name: 'a2'
18+
},
19+
{
20+
name: 'b1'
21+
},
22+
{
23+
name: 'c'
24+
}
25+
];
26+
27+
const links = [
28+
{
29+
source: 'a',
30+
target: 'a1',
31+
value: 5
32+
},
33+
{
34+
source: 'a',
35+
target: 'a2',
36+
value: 3
37+
},
38+
{
39+
source: 'b',
40+
target: 'b1',
41+
value: 8
42+
},
43+
{
44+
source: 'a',
45+
target: 'b1',
46+
value: 3
47+
},
48+
{
49+
source: 'b1',
50+
target: 'a1',
51+
value: 1
52+
},
53+
{
54+
source: 'b1',
55+
target: 'c',
56+
value: 2
57+
}
58+
];
59+
60+
let spy: any;
61+
62+
// beforeAll(() => {
63+
// console.log(`*** TEST 1`);
64+
// spy = jest.spyOn(echarts, 'getInstanceByDom').mockImplementation(
65+
// () =>
66+
// ({
67+
// hideLoading: jest.fn(),
68+
// setOption: jest.fn(),
69+
// showLoading: jest.fn()
70+
// }) as any
71+
// );
72+
// });
73+
//
74+
// afterAll(() => {
75+
// console.log(`*** TEST 2`);
76+
// spy.mockRestore();
77+
// });
78+
79+
// See https://stackoverflow.com/questions/54921743/testing-echarts-react-component-with-jest-echartelement-is-null
80+
xtest('renders component data', () => {
81+
const { asFragment } = render(<Sankey opts={{ renderer: 'svg' }} series={[{ data, links }]} />);
82+
expect(asFragment()).toMatchSnapshot();
83+
});
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import * as React from 'react';
2+
import * as echarts from 'echarts';
3+
import { useRef } from 'react';
4+
// import { BarChart, SankeyChart } from 'echarts/charts';
5+
// import { CanvasRenderer } from 'echarts/renderers';
6+
7+
// import {
8+
// TitleComponent,
9+
// TooltipComponent,
10+
// GridComponent,
11+
// DatasetComponent,
12+
// TransformComponent
13+
// } from 'echarts/components';
14+
15+
// Register the required components
16+
// echarts.use([
17+
// BarChart,
18+
// SankeyChart,
19+
// TitleComponent,
20+
// TooltipComponent,
21+
// GridComponent,
22+
// DatasetComponent,
23+
// TransformComponent,
24+
// LabelLayout,
25+
// UniversalTransition,
26+
// CanvasRenderer
27+
// ]);
28+
29+
import { theme } from './theme';
30+
31+
/**
32+
*/
33+
export interface SankeyProps {
34+
height?: number;
35+
id?: string;
36+
lineStyle?: any;
37+
opts?: any;
38+
series: any[];
39+
title?: any;
40+
tooltip?: any;
41+
width?: number;
42+
}
43+
44+
export const Sankey: React.FunctionComponent<SankeyProps> = ({
45+
height,
46+
id,
47+
lineStyle = {
48+
color: 'source',
49+
opacity: 0.6
50+
},
51+
opts,
52+
series,
53+
title,
54+
tooltip = {
55+
trigger: 'item',
56+
triggerOn: 'mousemove'
57+
},
58+
width
59+
}: SankeyProps) => {
60+
const containerRef = useRef<HTMLDivElement>();
61+
const echart = useRef<echarts.ECharts>();
62+
63+
React.useEffect(() => {
64+
echarts.registerTheme('pf-v5-sankey', theme);
65+
echart.current = echarts.init(containerRef.current, 'pf-v5-sankey', opts); // renderer: 'svg'
66+
67+
const newSeries = series.map((serie: any) => ({
68+
emphasis: {
69+
focus: 'adjacency'
70+
},
71+
layout: 'none',
72+
lineStyle,
73+
type: 'sankey',
74+
...serie
75+
}));
76+
77+
echart.current?.setOption({
78+
series: newSeries,
79+
...(title && title),
80+
...(tooltip && tooltip)
81+
});
82+
}, [containerRef, lineStyle, opts, series, title, tooltip]);
83+
84+
React.useEffect(() => {
85+
echart.current?.resize();
86+
}, [height, width]);
87+
88+
const getSize = () => ({
89+
...(height && { height: `${height}px` }),
90+
...(width && { width: `${width}px` })
91+
});
92+
93+
return <div id={id} ref={containerRef} style={getSize()} />;
94+
};
95+
Sankey.displayName = 'Sankey';
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import React from 'react';
2+
import { Sankey } from '@patternfly/react-charts/next';
3+
import { getResizeObserver } from '@patternfly/react-core';
4+
5+
export const FormBasic: React.FunctionComponent = () => {
6+
const data = [
7+
{
8+
name: 'a'
9+
},
10+
{
11+
name: 'b'
12+
},
13+
{
14+
name: 'a1'
15+
},
16+
{
17+
name: 'a2'
18+
},
19+
{
20+
name: 'b1'
21+
},
22+
{
23+
name: 'c'
24+
}
25+
];
26+
27+
const links = [
28+
{
29+
source: 'a',
30+
target: 'a1',
31+
value: 5
32+
},
33+
{
34+
source: 'a',
35+
target: 'a2',
36+
value: 3
37+
},
38+
{
39+
source: 'b',
40+
target: 'b1',
41+
value: 8
42+
},
43+
{
44+
source: 'a',
45+
target: 'b1',
46+
value: 3
47+
},
48+
{
49+
source: 'b1',
50+
target: 'a1',
51+
value: 1
52+
},
53+
{
54+
source: 'b1',
55+
target: 'c',
56+
value: 2
57+
}
58+
];
59+
60+
// let observer = () => {};
61+
const containerRef = React.useRef<HTMLDivElement>();
62+
const [width, setWidth] = React.useState(0);
63+
64+
React.useEffect(() => {
65+
const handleResize = () => {
66+
if (containerRef.current && containerRef.current.clientWidth) {
67+
setWidth(containerRef.current.clientWidth);
68+
}
69+
};
70+
let observer = () => {};
71+
observer = getResizeObserver(containerRef.current, handleResize);
72+
73+
return () => {
74+
observer();
75+
};
76+
}, [containerRef, width]);
77+
78+
return (
79+
<div ref={containerRef}>
80+
<Sankey
81+
height={400}
82+
series={[{ data, links }]}
83+
title={{
84+
subtext: 'Data From lisachristina1234 on GitHub',
85+
left: 'center'
86+
}}
87+
width={width}
88+
/>
89+
</div>
90+
);
91+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
---
2+
id: Sankey
3+
section: charts
4+
propComponents: [
5+
'Sankey',
6+
]
7+
hideDarkMode: true
8+
beta: true
9+
---
10+
11+
## Introduction
12+
Note: PatternFly React charts live in its own package at [@patternfly/react-charts](https://www.npmjs.com/package/@patternfly/react-charts)!
13+
14+
PatternFly React charts are based on the [Apache ECharts](https://echarts.apache.org/) chart library, along with additional functionality, custom components, and theming for PatternFly. This provides a collection of React based components you can use to build PatternFly patterns with consistent markup, styling, and behavior.
15+
16+
## Examples
17+
### Basic
18+
19+
```ts file="./Basic.tsx"
20+
21+
```
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Sankey';

0 commit comments

Comments
 (0)