Skip to content

Commit f0bc21f

Browse files
author
lkd01632719
committed
docs: add demos
1 parent 508513e commit f0bc21f

File tree

10 files changed

+483
-0
lines changed

10 files changed

+483
-0
lines changed
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { Line } from '@ant-design/plots';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
function tip({ container, onRemove = () => {}, offsetX = 20, offsetY = 0 }) {
6+
let div;
7+
8+
const render = (data, [x, y]) => {
9+
if (div) remove();
10+
div = document.createElement('div');
11+
div.innerHTML = `
12+
Select a node:
13+
<ul>${data.map((d) => `<li>${d.date}</li>`).join('')}</ul>
14+
`;
15+
div.style.position = 'absolute';
16+
div.style.background = '#eee';
17+
div.style.padding = '0.5em';
18+
div.style.left = x + offsetX + 'px';
19+
div.style.top = y + offsetY + 'px';
20+
div.onclick = () => {
21+
remove();
22+
onRemove();
23+
};
24+
container.append(div);
25+
};
26+
27+
const remove = () => {
28+
if (div) div.remove();
29+
div = null;
30+
};
31+
32+
return [render, remove];
33+
}
34+
35+
const DemoInteraction = () => {
36+
const data = [
37+
{ date: '2007-04-23', close: 93.24 },
38+
{ date: '2007-04-24', close: 95.35 },
39+
{ date: '2007-04-25', close: 98.84 },
40+
{ date: '2007-04-26', close: 99.92 },
41+
{ date: '2007-04-29', close: 99.8 },
42+
{ date: '2007-05-01', close: 99.47 },
43+
{ date: '2007-05-02', close: 100.39 },
44+
{ date: '2007-05-03', close: 100.4 },
45+
{ date: '2007-05-04', close: 100.81 },
46+
{ date: '2007-05-07', close: 103.92 },
47+
];
48+
49+
const config = {
50+
data,
51+
xField: (d) => new Date(d.date),
52+
yField: 'close',
53+
scale: { y: { nice: true } },
54+
interaction: { brushXHighlight: true },
55+
};
56+
return (
57+
<Line
58+
{...config}
59+
onReady={(plot) => {
60+
const chart = plot.chart;
61+
const [render, remove] = tip({
62+
container: document.getElementById('container'),
63+
onRemove: () => plot.emit('brush:remove', {}),
64+
});
65+
66+
chart.on('brush:start', () => {
67+
chart.emit('tooltip:disable');
68+
remove();
69+
});
70+
71+
chart.on('brush:end', async (e) => {
72+
const { canvas } = chart.getContext();
73+
const [mask] = canvas.document.getElementsByClassName('mask');
74+
const bounds = mask.getBounds();
75+
const x = bounds.max[0];
76+
const y = bounds.center[1];
77+
const [X] = e.data.selection;
78+
const filtered = data.filter(({ date }) => new Date(date) >= X[0] && new Date(date) <= X[1]);
79+
render(filtered, [x, y]);
80+
});
81+
82+
chart.on('brush:remove', (e) => {
83+
const { nativeEvent } = e;
84+
if (nativeEvent) remove();
85+
chart.emit('tooltip:enable');
86+
});
87+
}}
88+
/>
89+
);
90+
};
91+
92+
ReactDOM.render(<DemoInteraction />, document.getElementById('container'));

Diff for: site/examples/statistics/interaction/demo/brush.js

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { Scatter } from '@ant-design/plots';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
function tip({ container, onRemove = () => {}, offsetX = 20, offsetY = 0 }) {
6+
let div;
7+
8+
const render = (data, [x, y]) => {
9+
if (div) remove();
10+
div = document.createElement('div');
11+
div.innerHTML = `
12+
Select a node:
13+
<ul>${data.map((d) => `<li>x:${d.weight},y:${d.height}</li>`).join('')}</ul>
14+
`;
15+
div.style.position = 'absolute';
16+
div.style.background = '#eee';
17+
div.style.padding = '0.5em';
18+
div.style.left = x + offsetX + 'px';
19+
div.style.top = y + offsetY + 'px';
20+
div.onclick = () => {
21+
remove();
22+
onRemove();
23+
};
24+
container.append(div);
25+
};
26+
27+
const remove = () => {
28+
if (div) div.remove();
29+
div = null;
30+
};
31+
32+
return [render, remove];
33+
}
34+
35+
const DemoInteraction = () => {
36+
const config = {
37+
data: {
38+
type: 'fetch',
39+
value: 'https://gw.alipayobjects.com/os/antvdemo/assets/data/scatter.json',
40+
},
41+
xField: 'weight',
42+
yField: 'height',
43+
colorField: 'gender',
44+
shapeField: 'point',
45+
style: {
46+
fillOpacity: 0.2,
47+
lineWidth: 1,
48+
transform: 'scale(1, 1)',
49+
transformOrigin: 'center center',
50+
},
51+
state: {
52+
inactive: { fill: 'black', fillOpacity: 0.5, transform: 'scale(0.5, 0.5)' },
53+
},
54+
interaction: { brushHighlight: true },
55+
};
56+
return (
57+
<Scatter
58+
{...config}
59+
onReady={(plot) => {
60+
const chart = plot.chart;
61+
const [render, remove] = tip({
62+
container: document.getElementById('container'),
63+
onRemove: () => plot.emit('brush:remove', {}),
64+
});
65+
66+
chart.on('brush:start', () => {
67+
chart.emit('tooltip:disable');
68+
remove();
69+
});
70+
71+
chart.on('brush:end', async (e) => {
72+
const data = await fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/scatter.json').then((res) =>
73+
res.json(),
74+
);
75+
76+
const { canvas } = chart.getContext();
77+
const [mask] = canvas.document.getElementsByClassName('mask');
78+
const bounds = mask.getBounds();
79+
const x = bounds.max[0];
80+
const y = bounds.center[1];
81+
const [X, Y] = e.data.selection;
82+
83+
const filtered = data.filter(({ weight, height }) => {
84+
return weight >= X[0] && weight <= X[1] && height >= Y[0] && height <= Y[1];
85+
});
86+
87+
render(filtered, [x, y]);
88+
});
89+
90+
chart.on('brush:remove', (e) => {
91+
const { nativeEvent } = e;
92+
if (nativeEvent) remove();
93+
chart.emit('tooltip:enable');
94+
});
95+
}}
96+
/>
97+
);
98+
};
99+
100+
ReactDOM.render(<DemoInteraction />, document.getElementById('container'));
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import { Line } from '@ant-design/plots';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
const DemoInteraction = () => {
6+
const config = {
7+
data: {
8+
type: 'fetch',
9+
value: 'https://assets.antv.antgroup.com/g2/indices.json',
10+
},
11+
xField: (d) => new Date(d.Date),
12+
yField: 'Close',
13+
colorField: 'Symbol',
14+
scale: { y: { type: 'log' } },
15+
axis: { y: { title: '↑ Change in price (%)', labelAutoRotate: false } },
16+
labels: [{ text: 'Symbol', selector: 'last', fontSize: 10 }],
17+
interaction: {
18+
chartIndex: {
19+
ruleStroke: '#aaa',
20+
labelDx: 5,
21+
labelTextAlign: 'center',
22+
labelStroke: '#fff',
23+
labelLineWidth: 5,
24+
labelFormatter: (d) => `${d.toLocaleDateString()}`,
25+
},
26+
tooltip: false,
27+
},
28+
};
29+
return <Line {...config} />;
30+
};
31+
32+
ReactDOM.render(<DemoInteraction />, document.getElementById('container'));

Diff for: site/examples/statistics/interaction/demo/fisheye.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Scatter } from '@ant-design/plots';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
const DemoInteraction = () => {
6+
const config = {
7+
data: {
8+
type: 'fetch',
9+
value: 'https://gw.alipayobjects.com/os/antvdemo/assets/data/bubble.json',
10+
},
11+
xField: 'GDP',
12+
yField: 'LifeExpectancy',
13+
sizeField: 'Population',
14+
colorField: 'continent',
15+
shapeField: 'point',
16+
scale: { size: { type: 'log', range: [4, 20] } },
17+
style: { fillOpacity: 0.3, lineWidth: 1 },
18+
legend: { size: false },
19+
interaction: { fisheye: true },
20+
};
21+
return <Scatter {...config} />;
22+
};
23+
24+
ReactDOM.render(<DemoInteraction />, document.getElementById('container'));
+122
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
import React from 'react';
2+
import ReactDOM from 'react-dom';
3+
import { Area } from '@ant-design/plots';
4+
import { useRef } from 'react';
5+
import { useEffect } from 'react';
6+
7+
document.getElementById('container').innerHTML = `
8+
<div id="focus" ></div>
9+
<div id="context"></div>
10+
`;
11+
12+
const commonConfig = {
13+
data: {
14+
type: 'fetch',
15+
value: 'https://gw.alipayobjects.com/os/bmw-prod/551d80c6-a6be-4f3c-a82a-abd739e12977.csv',
16+
},
17+
xField: 'date',
18+
yField: 'close',
19+
animate: false,
20+
};
21+
22+
function createPathRender(compute) {
23+
return (group, options, document) => {
24+
if (!group.handle) {
25+
const path = document.createElement('path');
26+
group.handle = path;
27+
group.appendChild(group.handle);
28+
}
29+
const { handle } = group;
30+
const { width, height, ...rest } = options;
31+
if (width === undefined || height === undefined) return handle;
32+
handle.attr({ ...compute(width, height), ...rest });
33+
return handle;
34+
};
35+
}
36+
37+
const DemoInteraction = () => {
38+
const focusRef = useRef();
39+
const contextRef = useRef();
40+
41+
useEffect(() => {
42+
const focusChart = focusRef.current.chart;
43+
const contextChart = contextRef.current.chart;
44+
45+
focusChart.on('brush:filter', (e) => {
46+
const { nativeEvent } = e;
47+
if (!nativeEvent) return;
48+
const { selection } = e.data;
49+
const { x: scaleX } = focusChart.getScale();
50+
const [[x1, x2]] = selection;
51+
const domainX = scaleX.getOptions().domain;
52+
if (x1 === domainX[0] && x2 === domainX[1]) {
53+
contextChart.emit('brush:remove', {});
54+
} else {
55+
contextChart.emit('brush:highlight', { data: { selection } });
56+
}
57+
});
58+
59+
contextChart.on('brush:highlight', (e) => {
60+
const { nativeEvent, data } = e;
61+
if (!nativeEvent) return;
62+
const { selection } = data;
63+
focusChart.emit('brush:filter', { data: { selection } });
64+
});
65+
66+
contextChart.on('brush:remove', (e) => {
67+
const { nativeEvent } = e;
68+
if (!nativeEvent) return;
69+
const { x: scaleX, y: scaleY } = contextChart.getScale();
70+
const selection = [scaleX.getOptions().domain, scaleY.getOptions().domain];
71+
focusChart.emit('brush:filter', { data: { selection } });
72+
});
73+
}, []);
74+
75+
const focusConfig = {
76+
...commonConfig,
77+
autoFit: false,
78+
height: 360,
79+
paddingLeft: 60,
80+
interaction: {
81+
tooltip: false,
82+
brushXFilter: true,
83+
},
84+
};
85+
86+
const contextConfig = {
87+
...commonConfig,
88+
autoFit: false,
89+
paddingTop: 0,
90+
paddingBottom: 0,
91+
height: 90,
92+
paddingLeft: 60,
93+
axis: false,
94+
interaction: {
95+
tooltip: false,
96+
brushXHighlight: {
97+
series: true,
98+
maskOpacity: 0.3,
99+
maskFill: '#777',
100+
maskHandleWRender: createPathRender((width, height) => ({
101+
d: 'M-0.5,31.5c-2.5,0,-4.5,2,-4.5,4.5v30c0,2.5,2,4.5,4.5,4.5V31.5z',
102+
transform: `translate(${width / 2}, ${-height / 2})`,
103+
})),
104+
maskHandleERender: createPathRender((width, height) => ({
105+
d: 'M0.5,31.5c2.5,0,4.5,2,4.5,4.5v30c0,2.5,-2,4.5,-4.5,4.5V31.5z',
106+
transform: `translate(${width / 2}, ${-height / 2})`,
107+
})),
108+
maskHandleEFill: '#D3D8E0',
109+
maskHandleWFill: '#D3D8E0',
110+
},
111+
},
112+
};
113+
114+
return (
115+
<div style={{ display: 'flex', flexDirection: 'column' }}>
116+
<Area {...focusConfig} getElementById="focus" onReady={(plot) => (focusRef.current = plot)} />
117+
<Area {...contextConfig} getElementById="context" onReady={(plot) => (contextRef.current = plot)} />
118+
</div>
119+
);
120+
};
121+
122+
ReactDOM.render(<DemoInteraction />, document.getElementById('container'));
+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Column } from '@ant-design/plots';
2+
import React from 'react';
3+
import ReactDOM from 'react-dom';
4+
5+
const DemoInteraction = () => {
6+
const config = {
7+
data: {
8+
type: 'fetch',
9+
value: 'https://gw.alipayobjects.com/os/bmw-prod/fb9db6b7-23a5-4c23-bbef-c54a55fee580.csv',
10+
},
11+
xField: 'letter',
12+
yField: 'frequency',
13+
transform: [{ type: 'sortX', by: 'y', reverse: true, slice: 5 }],
14+
axis: { y: { labelFormatter: '.0%' } },
15+
interaction: { elementHighlight: { background: true } },
16+
};
17+
return <Column {...config} />;
18+
};
19+
20+
ReactDOM.render(<DemoInteraction />, document.getElementById('container'));

0 commit comments

Comments
 (0)