React vis Line Chart not rendering properly - reactjs

I am using react-vis library for one of my projects. I copied the source code of a sample chart from one of their examples on the site. I copied the example directly but still the chart does not look as expected.
import React from 'react';
import {curveCatmullRom} from 'd3-shape';
import {
XYPlot,
XAxis,
YAxis,
HorizontalGridLines,
VerticalGridLines,
LineSeries
} from 'index';
export default function Example(props) {
return (
<XYPlot width={300} height={300}>
<HorizontalGridLines style={{stroke: '#B7E9ED'}} />
<VerticalGridLines style={{stroke: '#B7E9ED'}} />
<XAxis
title="X Axis"
style={{
line: {stroke: '#ADDDE1'},
ticks: {stroke: '#ADDDE1'},
text: {stroke: 'none', fill: '#6b6b76', fontWeight: 600}
}}
/>
<YAxis title="Y Axis" />
<LineSeries
className="first-series"
data={[{x: 1, y: 3}, {x: 2, y: 5}, {x: 3, y: 15}, {x: 4, y: 12}]}
style={{
strokeLinejoin: 'round',
strokeWidth: 4
}}
/>
<LineSeries className="second-series" data={null} />
<LineSeries
className="third-series"
curve={'curveMonotoneX'}
data={[{x: 1, y: 10}, {x: 2, y: 4}, {x: 3, y: 2}, {x: 4, y: 15}]}
strokeDasharray="7, 3"
/>
<LineSeries
className="fourth-series"
curve={curveCatmullRom.alpha(0.5)}
data={[{x: 1, y: 7}, {x: 2, y: 11}, {x: 3, y: 9}, {x: 4, y: 2}]}
/>
</XYPlot>
);
}

For this issue, you can import style.css from react-vis in your component like below,
import "react-vis/dist/style.css";
Working Code :- https://codesandbox.io/s/musing-yonath-bgg1i?file=/src/App.js

Related

Graph not returning after OnClick

I am trying to plot this graph on react. My graph is not displaying after OnClick. Can anyone let me know my mistake.
Or if there is any other way or method to display graphs on React, please let me know.
I have defined a function, and called it in OnClick. I have also imported all the necessary libraries. I don't see where I am going wrong. I don't get any errors.
Any help would be appreciated.
import React from "react";
import Plot from 'react-plotly.js'
import Heading from 'react-plotly.js'
import LineSeries from 'react-plotly.js'
import Axis from 'react-plotly.js'
import factor from 'react-plotly.js'
import Legend from 'react-plotly.js'
function Example () {
<Plot
width={550}
height={500}
margin={{ bottom: 50, left: 90, top: 50, right: 100 }}
>
<Heading
title="Electrical characterization"
subtitle="current vs voltage"
/>
<LineSeries
data={[
{ x: 0, y: 0 },
{ x: 1, y: 1 },
{ x: 2, y: 2 },
{ x: 3, y: 3 },
{ x: 4, y: 3 },
{ x: 5, y: 3 },
]}
xAxis="x"
yAxis="y"
lineStyle={{ strokeWidth: 3 }}
label="Vg = 7V"
displayMarker={false}
/>
<LineSeries
data={[
{ x: 0, y: 0 },
{ x: 1, y: 1 },
{ x: 2, y: 2 },
{ x: 3, y: 3 },
{ x: 4, y: 3 },
{ x: 5, y: 3 },
]}
xAxis="x"
yAxis="y"
displayMarker={true}
markerShape="circle"
label="Vg = 3V"
/>
<Axis
id="x"
position="bottom"
label="Drain voltage [V]"
displayPrimaryGridLines
max={6.1 / factor}
/>
<Axis
id="y"
position="left"
label="Drain current [mA]"
displayPrimaryGridLines
max={6.1 * factor}
/>
<Legend position="right" />
</Plot>
return (
<div className="input-group-append">
<button className="btn btn-sm btn-primary" onClick={Example}>Graph</button>
</div>
)
}
export default Example;

Gradient SVG render on web but not on mobile

I'm using react-native-svg to render a chart, which contain a gradient, work perfectly on web, but when use the same code on react-native it won't work
Here is the react-native code
const data = [
{x: new Date(2000, 3, 2), y: 100},
{x: new Date(2003, 4, 3), y: 120},
{x: new Date(2002, 5, 4), y: 140},
{x: new Date(2005, 6, 5), y: 150},
{x: new Date(2006, 7, 6), y: 130},
{x: new Date(2007, 8, 7), y: 120},
{x: new Date(2008, 9, 8), y: 150},
];
export default function Chart4() {
const dateData = data.map(i => i.x);
return (
<Svg>
<Defs>
<LinearGradient id="myGradient" x1="0" y1="0" x2="0" y2="1.3">
<Stop offset="0%" stopColor="#86CD9B" stop-opacity={1} />
<Stop offset="100%" stopColor="white" stop-opacity={1} />
</LinearGradient>
</Defs>
<VictoryChart scale={{x: 'time', y: 'linear'}}>
<VictoryAxis dependentAxis />
<VictoryAxis
tickValues={dateData}
tickFormat={x => {
return x.toLocaleString('vn-vn', {
month: 'short',
day: 'numeric',
});
}}
/>
<VictoryArea
data={data}
style={{
data: {fill: 'url(#myGradient)'},
}}
/>
<VictoryScatter
data={data}
style={{
data: {
stroke: '#86CD9B',
fill: 'white',
strokeWidth: 1,
fillOpacity: 1,
},
}}
labels={({datum}) =>
`x: ${datum.x.toLocaleString('vn-vn', {
month: 'short',
day: 'numeric',
})} \n y:${datum.y}`
}
labelComponent={
<VictoryTooltip
renderInPortal={false}
dy={0}
centerOffset={{x: 25}}
/>
}
/>
</VictoryChart>
</Svg>
);
}
And it show nothing
But on web ( react ) , it work perfectly, here is codesanbbox for that https://codesandbox.io/s/chart-blood-glucose-031dn?file=/src/App.js
What going on, please help, thank a lots

React, sorting X-axis label in Rechart in from different data sources

I need help figuring how to sort X-Axis label values in ascending order in Rechart graphs.
currently, the data for the chart is gotten from two sources.
Below is the code presented.
const series = [
{ name: 'SourceA: ', data: reportsFromSourceA },
{ name: 'SourceB: ', data: reportsFromSourceB },
]
const selectedCategories= [...]
selectedCategories.map((category, i) => (
<ResponsiveContainer height={350} width='50%' key={category}>
<LineChart
margin={{ top: 40, right: 30, left: 70, bottom: 5 }}
syncId='category'
>
<XAxis dataKey='hour' allowDuplicatedCategory={false} />
<YAxis
label={{
value: category,
position: 'top',
fontSize: 18,
offset: 20,
fontWeight: 'bold',
fill: COLORS[i % 8]
}}
tickFormatter={formatUSD}
/>
<CartesianGrid strokeDasharray='3 3' />
<Tooltip formatter={formatUSD} />
{series.map((s, i) => (
<Line dataKey='rpc' stroke={COLORS[i % 2]} data={s.data[category]} name={s.name} key={s.name} />
))}
<ReferenceArea y2={0} stroke='red' color='red' strokeOpacity={0.5} />
</LineChart>
</ResponsiveContainer>
)))
I had a similar issue, but the solution is to:
first sort out the data coming from your database
or sort the entire array it by key value (in ascending or descending order)
The issue occurs due to some missing entries of the labels in the first data source which the second one has.
The simple solution can be to create an extra data source for labels only and we'll not draw a line for that source.
A relevant sandbox example is here
The full explanation is here
The following solution can solve the issue
const labelSeries = {data: [
{category: 01}, {category: 05}, {category: 09}, {category: 10}, {category: 11},
{category: 12}, {category: 13}, {category: 14},{category: 15}, {category: 16},
{category: 17}, {category: 18}, {category: 19}, {category: 20}, {category: 21},
{category: 22}
]}
const series = [
{ name: 'SourceA: ', data: reportsFromSourceA },
{ name: 'SourceB: ', data: reportsFromSourceB },
]
const selectedCategories= [...]
selectedCategories.map((category, i) => (
<ResponsiveContainer height={350} width='50%' key={category}>
<LineChart
margin={{ top: 40, right: 30, left: 70, bottom: 5 }}
syncId='category'
>
<XAxis dataKey='hour' allowDuplicatedCategory={false} />
<YAxis
label={{
value: category,
position: 'top',
fontSize: 18,
offset: 20,
fontWeight: 'bold',
fill: COLORS[i % 8]
}}
tickFormatter={formatUSD}
/>
<CartesianGrid strokeDasharray='3 3' />
<Tooltip formatter={formatUSD} />
<Line data={labelSeries.data} /> // This line will sort the x-axis label
{series.map((s, i) => (
<Line dataKey='rpc' stroke={COLORS[i % 2]} data={s.data[category]} name={s.name} key={s.name} />
))}
<ReferenceArea y2={0} stroke='red' color='red' strokeOpacity={0.5} />
</LineChart>
</ResponsiveContainer>
)))

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.

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

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>
)
}

Resources