how to render multiple 'vis-react' component in react js - reactjs

I want to render multiple topology using vis-react component using react js.
Any suggestions how to proceed?
I am using ES6

if you have an array that you want to fill chart data with its items you can do this
render() {
let counter = 0;
const items= this.props.data.map(item => {
return (
<XYPlot
width={300}
height={300}>
<HorizontalGridLines />
<LineSeries data={[item.data]}/>
<XAxis />
<YAxis />
</XYPlot>
)
})
return (
<div>
{items}
</div>
)
}
if you have some other sources you have to set it manually like this :
render() {
return (
<XYPlot key='1'
width={300}
height={300}>
<HorizontalGridLines />
<LineSeries
data={[
{x: 1, y: 10},
{x: 2, y: 5},
{x: 3, y: 15}
]}/>
<XAxis />
<YAxis />
</XYPlot>
<XYPlot key = '2'
width={300}
height={300}>
<HorizontalGridLines />
<LineSeries
data={[
{x: 1, y: 10},
{x: 2, y: 5},
{x: 3, y: 15}
]}/>
<XAxis />
<YAxis />
</XYPlot>
)
}

Related

How to sort values in Rechart on x-axis in ascending order

I've 3 demo datasets to visualize in React using Recharts.js.
{ x: 80, y: 50, name: "Page A" },
{ x: 14, y: 80, name: "Page B" },
{ x: 70, y: 38, name: "Page C" },
Unfortunately, the values on the x-axis are not ordered correctly (80 -> 14 -> 70), but follow the order of objects in the data array.
const rechart = () => {
return (
<div>
<ScatterChart width={400} height={400} data={data}>
<XAxis dataKey="x" domain={[0, 100]} />
<YAxis dataKey="y" domain={[0, 100]} axisLine={false} tick={false} />
<Scatter data={data}>
<LabelList dataKey="name" position="right" />
</Scatter>
</ScatterChart>
</div>
);
};
What can I do to sort the values from 0 to 100, not Page A to Page C?
Try sorting your data before passing it as props to the Scatter component
data.sort((a,b) => a.x - b.x)
const rechart = () => {
const sortedData = data.sort((a,b) => a.x - b.x)
return (
<div>
<ScatterChart width={400} height={400} data={data}>
<XAxis dataKey="x" domain={[0, 100]} />
<YAxis dataKey="y" domain={[0, 100]} axisLine={false} tick={false} />
<Scatter data={sortedData}>
<LabelList dataKey="name" position="right" />
</Scatter>
</ScatterChart>
</div>
);
};

Recharts grouping x-axis Labels

I have a requirement where I need to show the values between 1,2 as a group and 2,3 as a seperate group. I am trying to customise the x-axis but it's not working
In the above picture I need to show the bars 3 and 3.5 together with miminum gap between them and in sameway 4 and 4.5 together
and this is my code
<ResponsiveContainer width="100%" height="100%">
<ComposedChart
width={500}
height={400}
data={data}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis scale="point" dataKey="label" />
<YAxis label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} />
<Tooltip />
<Bar dataKey="count" barSize={40} fill="#AAE5F9" />
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="count" stroke="#3080ED" />
</ComposedChart>
</ResponsiveContainer>
Any help would be thankfull
I assume your data looks like this:
const data = [
{label: "0", count: 0},
{label: "1", count: null},
{label: "2", count: 1},
{label: "3", count: 1},
{label: "3.5", count: 1},
{label: "4", count: 2},
{label: "4.5", count: 1},
{label: "5", count: 0},
];
They must be converted to the following form:
const data = [
{label: "0", countA: 0, countB: null},
{label: "1", countA: null, countB: null},
{label: "2", countA: 1, countB: null},
{label: "3-3.5", countA: 1, countB: 1},
{label: "4-4.5", countA: 2, countB: 1},
{label: "5", countA: 0, countB: 0},
];
The first method
Add another Bar component to display values in group.
export default function App() {
return (
// <ResponsiveContainer width="100%" height="100%">
<ComposedChart
width={500}
height={400}
data={data}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis scale="point" dataKey="label" />
<YAxis label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} />
<Tooltip />
<Bar dataKey="countA" barSize={20} fill="#AAE5F9" />
<Bar dataKey="countB" barSize={20} fill="#79B473" />
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="countA" stroke="#3080ED" />
</ComposedChart>
// </ResponsiveContainer>
);
}
Result:
The second method
If you want the columns in the groups to be the same width regardless of how many elements are in the group, then you can draw the rectangle for the group yourself.
const getPath = (x, y, width, height, uv, pv) => {
const height1= pv?(height/uv)*pv:height;
return `M${x},${y}
v${height}
h${width}
v${-height1}
h${-width/2}
v${(height1-height)}
h${-width/2}
Z`;
};
const MultiBar: FunctionComponent = (props) => {
const { fill, x, y, width, height, countA, countB } = props;
return <path d={getPath(x, y, width, height, countA, countB)} stroke="none" fill={fill} />;
};
export default function App() {
return (
<ComposedChart
width={500}
height={400}
data={data}
>
<CartesianGrid horizontal={false} strokeDasharray="4 4" />
<XAxis dataKey="label" />
<YAxis type="number" domain={[0, 2]} label={{ value: 'No.Of Employees', angle: -90, position: 'insideLeft' }} tick={false} />
<Bar
dataKey="countA"
fill="#AAE5F9"
shape={<MultiBar />}
>
</Bar>
<Line connectNulls={true} strokeWidth={3} dot={false} type="monotone" dataKey="countA" stroke="#3080ED" />
</ComposedChart>
);
}
Result:
The getPath function returns the path of the SVG element for drawing each bar of the chart. If required, you can add a stroke or make a gap between the bars in the group.
Also, you need to set the domain for the Y-axis by the maximum value of all countA and countB values:
<YAxis type="number" domain={[0, 2]} ... />

React Recharts data with array

I have an array of data with the following structure:
0:
date: '01-12-2020',
data: Array(2)
{name: "plants", count: 5}
{name: "water", count: 2}
1:
date: '02-12-2020',
data: Array(2)
{name: "plants", count: 1}
{name: "water", count: 4}
...
I would like to show the dates on the x-axis and render a line for each `name' category. In this case two lines, one for plants and one for water.
Should I format this code or can I use this array directly in recharts? I'm creating the array myself in the backend so I can also format it there.
I've tried something like this but it is not working:
<ResponsiveContainer width="100%" height={200}>
<LineChart data={data}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="x" />
<YAxis />
<Tooltip />
{data.map((item, i) => (
<Line
dataKey={data[0].data[0].count}
type="monotone"
stroke={colors[0]}
activeDot={{ r: 8 }}
/>
))}
</LineChart>
</ResponsiveContainer>
Your data needs to be formatted into this :
[{name: '01-12-2020',
plants: 5
water : 4}]
you can do as following :
let result = [];
data.map(entry) => {
let obj = {date: entry.date}
entry.data.map((entry1) => {
obj[entry1.name] = entry1.count;
});
result.push(obj)
})
and your chart as following (your dataKey on XAxis is false)
<ChartContainer>
<ResponsiveContainer>
<LineChart
width={500}
height={300}
style={{ color: scoopBlue }}
data={data}
margin={{
top: 5,
right: 30,
left: 20,
bottom: 5
}}
>
<CartesianGrid strokeDasharray="3 3" />
<Legend />
<Line
type="monotone"
dataKey="plants"
stroke={scoopBlue}
strokeWidth={2}
activeDot={{ r: 5 }}
/>
<Line
type="monotone"
dataKey="water"
stroke={"orange"}
strokeWidth={2}
activeDot={{ r: 5 }}
/>
</LineChart>
</ResponsiveContainer>
</ChartContainer>

How to change the label in recharts?

<BarChart
isAnimationActive={false}
width={400}
height={200}
data={value}
margin={{
top: 5, right: 30, left: 20,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="x"
/>
<YAxis label={{ value: `no.`, angle: -90, position: 'insideBottomLeft' }} />
<Tooltip
content={<CustomTooltip />}
/>
<Bar dataKey="y" /* fill={colors[0]} */ >
</BarChart>
My data on x axis is numerical [0,1,2,3...] but I want my ticks to be [A1,A2,A3...]
you can use formatter attribute, here is an example
<XAxis dataKey="x" tickFormatter={(t) => `A${t+1}`} />
Change your value key
const value = [
{
x: 'A1', ......
},
{
x: 'A2', .....
},
]
Or you can use this:
<XAxis
dataKey="x"
tickFormatter={(t) => {
const count = parseInt(t) + 1
return 'A'+ count;
}
}
/>

React Recharts -> Tooltip problem with LabelList in Scatter chart

We are facing for some time problem with LabelList which is displayed over the elements of Scatter chart. If user is hovering over them, Tooltip is not displayed.
Code:
const {ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, LabelList, Tooltip, Legend} = Recharts;
const data = [{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 SimpleScatterChart = React.createClass({
render () {
return (
<ScatterChart width={400} height={400} margin={{top: 20, right: 20, bottom: 20, left: 20}}>
<XAxis type="number" dataKey={'x'} name='stature' unit='cm'/>
<YAxis type="number" dataKey={'y'} name='weight' unit='kg'/>
<CartesianGrid />
<Tooltip cursor={{strokeDasharray: '3 3'}}/>
<Legend onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} />
<Scatter name='A school' data={data} fill='#8884d8'>
<LabelList dataKey="x" />
</Scatter>
</ScatterChart>
);
}
})
ReactDOM.render(
<SimpleScatterChart />,
document.getElementById('container')
);
Example: https://jsfiddle.net/alidingling/gvsspn0h/
Once you will remove LabelList, it is working fine:
const {ScatterChart, Scatter, XAxis, YAxis, CartesianGrid, LabelList, Tooltip, Legend} = Recharts;
const data = [{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 SimpleScatterChart = React.createClass({
render () {
return (
<ScatterChart width={400} height={400} margin={{top: 20, right: 20, bottom: 20, left: 20}}>
<XAxis type="number" dataKey={'x'} name='stature' unit='cm'/>
<YAxis type="number" dataKey={'y'} name='weight' unit='kg'/>
<CartesianGrid />
<Tooltip cursor={{strokeDasharray: '3 3'}}/>
<Legend onMouseEnter={this.handleMouseEnter} onMouseLeave={this.handleMouseLeave} />
<Scatter name='A school' data={data} fill='#8884d8'>
</Scatter>
</ScatterChart>
);
}
})
ReactDOM.render(
<SimpleScatterChart />,
document.getElementById('container')
);
Example: https://jsfiddle.net/gt0uy92a/2/
Problem is, we need LabelList displayed as it is in a first example, we can't change the position, but Tooltip must be working properly.
<LabelList
dataKey="x"
style={{pointerEvents: 'none'}}
/>
will work for you.you can bind onMouseEnter event to LabelList component as well.
Solution was not so simple, it was little bit tricky, but still logical. If we can't do anything with way how is SVG rendering elements, can't use z-index, we still can set them opacity.
const CustomizedCircle = props => {
const {
cx, cy, fill, size, z,
} = props;
const radius = size / 70;
const value = z;
return (
<svg width={radius} height={radius} style={{overflow: 'visible'}}>
<text style={{fontWeight: FONT_WEIGHT, fontSize: FONT_SIZE}} x={cx} y={cy + 5} textAnchor="middle">{value}</text>
<circle style={{opacity: OPACITY}} cx={cx} cy={cy} r={radius} fill={fill} />
</svg>
);
};
So we are first rendering the text, then we render the circle and to see text beneath the circle we are setting the circle some kind of opacity.

Resources