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
Related
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;
I am working on a React JS project. My application needs to display data in chart format. I am using Victory Chart. I can display the chart.
What I am trying to do now is that when the user hovers the mouse cursor on a bar of the bar chart, it should display a tooltip using VictoryTooltip component. But it is not working.
Here is my code:
<VictoryChart
responsive={true}
width={byMonthChartWidth}
height={byMonthChartHeight}
padding={byMonthChartPadding}
domainPadding={byMonthChartDomainPadding}
>
<VictoryAxis
style={{
axis: {
stroke: "transparent"
},
tickLabels: {
fill: props.color,
fontSize: 8,
fontWeight: "bold"
}
}}
fixLabelOverlap={true}
tickValues={[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]}
tickFormat={['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D']}
preserveAspectRatio={"none"}
/>
<VictoryAxis
style={{
axis: {
stroke: "transparent"
},
tickLabels: {
fill: props.color,
fontSize: 8,
fontFamily: "roboto",
fontWeight: "bold"
}
}}
fixLabelOverlap={true}
dependentAxis
tickValues={yAxisTicks}
tickFormat={(x) => (`${x}`)}
preserveAspectRatio={"none"}
/>
<VictoryBar
labelComponent={
<VictoryTooltip
center={{ x: 225, y: 30 }}
pointerOrientation="bottom"
flyoutWidth={150}
flyoutHeight={50}
pointerWidth={150}
cornerRadius={0}
/>
}
animate={byMonthChartBarAnimation}
barWidth={byMonthChartBarWidth}
cornerRadius={{
topLeft: (data) => 5,
topRight: (data) => 5,
bottomLeft: (data) => 5,
bottomRight: (data) => 5
}}
style={{
data: {
fill: props.color,
stroke: props.color,
fontFamily: "roboto",
fillOpacity: 1,
strokeWidth: 1
}
}}
data={data}
x="identifier"
y="value"
/>
</VictoryChart>
As you can see I am trying to display a tooltip using labelComponent prop of VictoryBar component. When I hover the mouse cursor over the bar, it is not showing any tooltips. What is wrong with my code and how can I fix it?
The data variable used inside your data={data} must carry a label property which contains tooltip's contents.
You can modify tooltip's font color by adding labels object into <VictoryBar>'s style property - example below
LIVE DEMO
Example:
<VictoryBar
barRatio={1}
cornerRadius={0}
style={{ data: { fill: "#6DB65B" }, labels: { fill: "red" } }}
alignment="middle"
labels={(d) => d.y}
labelComponent={
<VictoryTooltip
center={{ x: 225, y: 30 }}
pointerOrientation="bottom"
flyoutWidth={150}
flyoutHeight={50}
pointerWidth={150}
cornerRadius={0}
flyoutStyle={{
stroke: "blue", // border-color
fill: "yellow", // background-color
}}
/>
}
data={[
{ x: "Year 1", y: 150000, label: "My label 1" },
{ x: "Year 2", y: 250000, label: "My label 1" },
{ x: "Year 3", y: 500020, label: "My label 1" },
{ x: "Year 4", y: 750000, label: "My label 1" },
{ x: "Year 5", y: 1000000, label: "My label 1" }
]}
/>
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>
)))
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
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.