feat(ui) - analytics sample charts
This commit is contained in:
parent
f47252ed11
commit
37a66bd400
6 changed files with 211 additions and 0 deletions
|
|
@ -0,0 +1,20 @@
|
|||
import { storiesOf } from '@storybook/react';
|
||||
import SankeyChart from './SankeyChart';
|
||||
|
||||
const data = {
|
||||
nodes: [
|
||||
{ name: 'Home Page' },
|
||||
{ name: 'Dashboard' },
|
||||
{ name: 'Preferences' },
|
||||
{ name: 'Billing' },
|
||||
|
||||
],
|
||||
links: [
|
||||
{ source: 0, target: 1, value: 100 },
|
||||
{ source: 1, target: 2, value: 50 },
|
||||
{ source: 1, target: 3, value: 50 },
|
||||
{ source: 2, target: 3, value: 10 },
|
||||
],
|
||||
};
|
||||
|
||||
storiesOf('SankeyChart', module).add('Pure', () => <SankeyChart data={data} />);
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
import React from 'react';
|
||||
import { Sankey, Tooltip, Rectangle, Layer, ResponsiveContainer } from 'recharts';
|
||||
|
||||
interface Props {
|
||||
data: any;
|
||||
}
|
||||
function SankeyChart(props: Props) {
|
||||
const { data } = props;
|
||||
return (
|
||||
<div className="rounded border shadow">
|
||||
<div className="text-lg p-3 border-b bg-gray-lightest">Sankey Chart</div>
|
||||
<div className="">
|
||||
<ResponsiveContainer height={500} width="100%">
|
||||
<Sankey
|
||||
width={960}
|
||||
height={500}
|
||||
data={data}
|
||||
// node={{ stroke: '#77c878', strokeWidth: 0 }}
|
||||
node={<CustomNodeComponent />}
|
||||
nodePadding={50}
|
||||
nodeWidth={10}
|
||||
margin={{
|
||||
left: 10,
|
||||
right: 100,
|
||||
top: 10,
|
||||
bottom: 10,
|
||||
}}
|
||||
link={<CustomLinkComponent />}
|
||||
>
|
||||
<defs>
|
||||
<linearGradient id={'linkGradient'}>
|
||||
<stop offset="0%" stopColor="rgba(0, 136, 254, 0.5)" />
|
||||
<stop offset="100%" stopColor="rgba(0, 197, 159, 0.3)" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<Tooltip content={<CustomTooltip /> }/>
|
||||
</Sankey>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default SankeyChart;
|
||||
|
||||
const CustomTooltip = (props: any) => {
|
||||
console.log('props', props);
|
||||
return (
|
||||
<div className="rounded bg-white border p-0 px-1 text-sm">test</div>
|
||||
)
|
||||
// if (active && payload && payload.length) {
|
||||
// return (
|
||||
// <div className="custom-tooltip">
|
||||
// <p className="label">{`${label} : ${payload[0].value}`}</p>
|
||||
// <p className="intro">{getIntroOfPage(label)}</p>
|
||||
// <p className="desc">Anything you want can be displayed here.</p>
|
||||
// </div>
|
||||
// );
|
||||
// }
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
function CustomNodeComponent({ x, y, width, height, index, payload, containerWidth }: any) {
|
||||
const isOut = x + width + 6 > containerWidth;
|
||||
return (
|
||||
<Layer key={`CustomNode${index}`}>
|
||||
<Rectangle x={x} y={y} width={width} height={height} fill="#5192ca" fillOpacity="1" />
|
||||
<text
|
||||
textAnchor={isOut ? 'end' : 'start'}
|
||||
x={isOut ? x - 6 : x + width + 6}
|
||||
y={y + height / 2}
|
||||
fontSize="8"
|
||||
// stroke="#333"
|
||||
>
|
||||
{payload.name}
|
||||
</text>
|
||||
<text
|
||||
textAnchor={isOut ? 'end' : 'start'}
|
||||
x={isOut ? x - 6 : x + width + 6}
|
||||
y={y + height / 2 + 13}
|
||||
fontSize="12"
|
||||
// stroke="#333"
|
||||
// strokeOpacity="0.5"
|
||||
>
|
||||
{payload.value + 'k'}
|
||||
</text>
|
||||
</Layer>
|
||||
);
|
||||
}
|
||||
|
||||
const CustomLinkComponent = (props: any) => {
|
||||
const [fill, setFill] = React.useState('url(#linkGradient)');
|
||||
const { sourceX, targetX, sourceY, targetY, sourceControlX, targetControlX, linkWidth, index } =
|
||||
props;
|
||||
return (
|
||||
<Layer key={`CustomLink${index}`}>
|
||||
<path
|
||||
d={`
|
||||
M${sourceX},${sourceY + linkWidth / 2}
|
||||
C${sourceControlX},${sourceY + linkWidth / 2}
|
||||
${targetControlX},${targetY + linkWidth / 2}
|
||||
${targetX},${targetY + linkWidth / 2}
|
||||
L${targetX},${targetY - linkWidth / 2}
|
||||
C${targetControlX},${targetY - linkWidth / 2}
|
||||
${sourceControlX},${sourceY - linkWidth / 2}
|
||||
${sourceX},${sourceY - linkWidth / 2}
|
||||
Z
|
||||
`}
|
||||
fill={fill}
|
||||
strokeWidth="0"
|
||||
onMouseEnter={() => {
|
||||
setFill('rgba(0, 136, 254, 0.5)');
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
setFill('url(#linkGradient)');
|
||||
}}
|
||||
/>
|
||||
</Layer>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './SankeyChart';
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import { storiesOf } from '@storybook/react';
|
||||
import ScatterChart from './ScatterChart';
|
||||
|
||||
const data01 = [
|
||||
{ x: 100, y: 200, z: 200 },
|
||||
{ x: 120, y: 100, z: 260 },
|
||||
{ x: 170, y: 300, z: 400 },
|
||||
{ x: 140, y: 250, z: 280 },
|
||||
{ x: 150, y: 400, z: 500 },
|
||||
{ x: 110, y: 280, z: 200 },
|
||||
];
|
||||
const data02 = [
|
||||
{ x: 200, y: 260, z: 240 },
|
||||
{ x: 240, y: 290, z: 220 },
|
||||
{ x: 190, y: 290, z: 250 },
|
||||
{ x: 198, y: 250, z: 210 },
|
||||
{ x: 180, y: 280, z: 260 },
|
||||
{ x: 210, y: 220, z: 230 },
|
||||
];
|
||||
|
||||
storiesOf('ScatterChart', module).add('Pure', () => (
|
||||
<ScatterChart dataFirst={data01} dataSecond={data02} />
|
||||
));
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
ScatterChart,
|
||||
Scatter,
|
||||
Tooltip,
|
||||
CartesianGrid,
|
||||
XAxis,
|
||||
YAxis,
|
||||
ZAxis,
|
||||
Legend,
|
||||
ResponsiveContainer,
|
||||
} from 'recharts';
|
||||
|
||||
interface Props {
|
||||
dataFirst: any;
|
||||
dataSecond: any;
|
||||
}
|
||||
function ScatterChartComponent(props: Props) {
|
||||
const { dataFirst, dataSecond } = props;
|
||||
return (
|
||||
<div className="rounded border shadow">
|
||||
<div className="text-lg p-3 border-b bg-gray-lightest">Scatter Chart</div>
|
||||
<div className="">
|
||||
<ResponsiveContainer height={500} width="100%">
|
||||
<ScatterChart
|
||||
width={730}
|
||||
height={250}
|
||||
margin={{ top: 20, right: 20, bottom: 10, left: 10 }}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" />
|
||||
<XAxis dataKey="x" name="stature" unit="cm" />
|
||||
<YAxis dataKey="y" name="weight" unit="kg" />
|
||||
<ZAxis dataKey="z" range={[64, 144]} name="score" unit="km" />
|
||||
<Tooltip cursor={{ strokeDasharray: '3 3' }} />
|
||||
<Legend />
|
||||
<Scatter name="A school" data={dataFirst} fill="#8884d8" />
|
||||
<Scatter name="B school" data={dataSecond} fill="#82ca9d" />
|
||||
</ScatterChart>
|
||||
</ResponsiveContainer>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default ScatterChartComponent;
|
||||
|
|
@ -0,0 +1 @@
|
|||
export { default } from './ScatterChart';
|
||||
Loading…
Add table
Reference in a new issue