How to draw two independent lines with recharts - reactjs

Here is my data
const DATA = [
{
name: '0',
data: [
{x: "07/16/20 01:50", y: "0.397"},
{x: "07/16/20 02:51", y: "0.480"},
{x: "07/16/20 02:52", y: "0.416"},
{x: "07/16/20 02:53", y: "0.396"},
{x: "07/16/20 02:54", y: "0.418"},
{x: "07/16/20 02:55", y: "0.390"}
]
},
{
name: '1',
data: [
{x: "07/16/20 04:54", y: "0.384"},
{x: "07/16/20 05:57", y: "0.432"}
],
}
]
I am trying to plot these points but failing.

In your data structure, you need to have the general array of data objects only. Here, you are trying to have sub data arrays, that's probably why the graphs won't display.
I assumed you wanted to have a simple line graph, so tweaking your data array, it could result into this:
const customData = [
{x: "07/16/20 01:50", y: "0.397"},
{x: "07/16/20 02:51", y: "0.480"},
{x: "07/16/20 02:52", y: "0.416"},
{x: "07/16/20 02:53", y: "0.396"},
{x: "07/16/20 02:54", y: "0.418"},
{x: "07/16/20 02:55", y: "0.390"},
{x: "07/16/20 04:54", y2: "0.384"},
{x: "07/16/20 05:57", y2: "0.432"}
]
Where x is the label to use on the XAxis, y the data for name: '0' in your data structure, and y2 for name: '1'.
The resulted graph would look like this in the code, where there would be two distinct lines; one for the y1 values, and the other for the y2 values.
export default function App() {
return (
<LineChart
width={500}
height={300}
data={customData}
>
<XAxis dataKey="x" />
<YAxis />
<Line
type="monotone"
dataKey="y"
stroke="#8884d8"
activeDot={{ r: 8 }}
/>
<Line
type="monotone"
dataKey="y2"
stroke="#8884d8"
activeDot={{ r: 8 }}
/>
</LineChart>
);
}

Related

Victory Area date axis is not rendering properly when svg fill gradient is added

I am new to using the Formidable Victory-Charts via victory native. I am learning to use it on a react-native app. Initially, I had the following graph that used the following code:
render() {
return (
<View>
<VictoryChart
domainPadding={{ y: 10 }}
containerComponent={
<VictoryCursorContainer
cursorDimension="x"
cursorLabel={({ datum }) =>
`${datum.x}, ${Math.round(datum.y, 2)}`
}
/>
}
>
<VictoryArea
style={{
data: {stroke: "#4074E6}
}}
data={[
{x: new Date(1982, 1, 1), y: 125,y0: 0 },
{x: new Date(1987, 1, 1), y: 257,y0: 0 },
{x: new Date(1993, 1, 1), y: 345,y0: 0 },
{x: new Date(1997, 1, 1), y: 515,y0: 0 },
{x: new Date(2001, 1, 1), y: 132,y0: 0 },
{x: new Date(2005, 1, 1), y: 305,y0: 0 },
{x: new Date(2011, 1, 1), y: 270,y0: 0 },
{x: new Date(2015, 1, 1), y: 470, y0: 0 }
]} />
</VictoryChart>
</View>
);
This Generates a graph which looks like this:
Initial Graph plot without gradient
Then I was playing around to add gradient to the backfill of the graph:
render() {
return (
<View>
<VictoryChart
domainPadding={{ y: 10 }}
containerComponent={
<VictoryCursorContainer
cursorDimension="x"
cursorLabel={({ datum }) =>
`${datum.x}, ${Math.round(datum.y, 2)}`
}
/>
}
>
<Defs>
<LinearGradient id="blueGrad" x1="0" y1="1" x2="0" y2="0">
<Stop offset="0" stopColor="white" stopOpacity="1" />
<Stop offset="1" stopColor="#3592FF" stopOpacity="1" />
</LinearGradient>
</Defs>
<VictoryArea
style={{
data: {stroke: "#4074E6", fill:"url(#blueGrad)"}
}}
data={[
{x: new Date(1982, 1, 1), y: 125,y0: 0 },
{x: new Date(1987, 1, 1), y: 257,y0: 0 },
{x: new Date(1993, 1, 1), y: 345,y0: 0 },
{x: new Date(1997, 1, 1), y: 515,y0: 0 },
{x: new Date(2001, 1, 1), y: 132,y0: 0 },
{x: new Date(2005, 1, 1), y: 305,y0: 0 },
{x: new Date(2011, 1, 1), y: 270,y0: 0 },
{x: new Date(2015, 1, 1), y: 470, y0: 0 }
]} />
</VictoryChart>
</View>
);
This is the output that I got: Gradient Graph plot
You can see in the output that the x-axis is pretty messed up. If I remove the Defs section it will not add the gradient and function properly. The existence of Defs is causing it to render improperly. Is there any solution to this? or am I doing something wrong?

Plotly React keep zoom and rotation between re-rendering

I'm using the React version of plot.ly to render a 3D scatter plot, but every time I re-render my component, the plot gets reset to its default configuration.
How can I prevent this, and keep the zoom/rotation configuration?
Below is a minimal code example. To re-iterate, how can I save the zoom and rotation, and how can I set it on the plot?
setPlotData() {
const points = {
1: {x: 1, y: 1, z: 1},
2: {x: 2, y: 1, z: 1},
3: {x: 3, y: 2, z: 1}
}
const x=[], y=[], z=[]
Object.keys(points).forEach((key, index) => {
x.push(points[key].x); y.push(points[key].y); z.push(points[key].z)
})
const data1 = {
x: x, y: y, z: z,
mode: "markers",
marker: {
color: "rgb(16, 52, 166)",
size: 4,
symbol: "circle",
opacity: 1
},
type: "scatter3d"
}
this.setState({
scatterPlotData: [data1]
})
}
render() {
return(
<Plot
data={this.state.scatterPlotData}
layout={{
autosize: true,
l: 0, r: 0, b: 0, t: 0, pad: 0,
showlegend: false,
margin:{l:0,r:0,b:0,t:0}
}}
style={{ width: '100%', height: '100%' }}
/>
)
}
Update the layout to add uirevision parameter
layout={{
autosize: true,
l: 0, r: 0, b: 0, t: 0, pad: 0,
showlegend: false,
margin:{l:0,r:0,b:0,t:0},
xaxis: {
uirevision: 'time',
},
yaxis: {
uirevision: 'time',
},
}}
you can change the uirevision: "time" to whatever x,y axis parameters you use

Recharts ReferenceLine between data points

I have a Recharts LineChart with numeric x-Axis. I would like to draw a ReferenceLine on an arbitrary x-value, but if the x property of ReferenceLine is not any of the x values in my data, it is not showing.
with
const data = [{ x: 1, y: 3 }, { x: 1.5, y: 4 }, { x: 2, y: 3 }];
...
<ReferenceLine x={1.7} stroke="green" label="actual" alwaysShow={true} />
nothing is showing, where as
const data = [{ x: 1, y: 3 }, { x: 1.5, y: 4 }, { x: 2, y: 3 }];
...
<ReferenceLine x={1.5} stroke="green" label="actual" alwaysShow={true} />
works.
I have built the sandbox here:
https://codesandbox.io/s/recharts-playground-xxwnl
Is there a way to make the ReferenceLine show for every x?
The problem was that I had not explicitly set the XAxis type to number. After changing
<XAxis dataKey="x" />
this to
<XAxis type="number" dataKey="x" />
it's behaving as expected

D3 - adding an interpolated point to a trend line

I am writing a React application and want to draw a line chart with an interpolated point, similar to the blue cross in the below:
I have been able to achieve mostly what I want using Nivo but this only drawers points based explicitly on data. What I want to do is illustrate an interpolated point along the trend line based on the x-axis. Is there a way to do this, either using Nivo or D3 directly?
The code I'm using for my line graph currently:
import React, { Component } from 'react';
import { Line } from 'nivo';
class LineGraph extends Component {
render() {
return (
<div className="line-graph">
<Line
width={600}
height={350}
margin={{
top: 20,
right: 20,
bottom: 60,
left: 60,
}}
data={[{
id: 'Distribution',
data: [
{x: '1', y: 0.09 },
{x: '2', y: 0.16 },
{x: '3', y: 0.5 },
{x: '4', y: 0.06 },
{x: '5', y: 0.19 },
]
}]}
colors="#ff6384"
enableArea
yScale={{ type: 'linear', stacked: false }}
curve="monotoneX"
dotSize={8}
dotBorderColor="#ff6384"
dotBorderWidth={2}
/>
</div>
);
}
}

Angular-nvd3 change animation transitions

I'm using angular-nvd3 and I'm having a lot of trouble figuring out how to change the way things animate.
Below is what currently happens when you toggle a dataset on. As you can see the Expenses animate in from the upper right and the Distances animate in directly from the right. What I would like them both to do is one of two things. Either animate with a basic fade in, or grow upward.
Here is my controller. Interestingly when I added yDomain1: [1, 200] it caused the Distance chart to animate directly from the right, prior to that it was also animating in from the upper right.
controllers.controller("DashboardController", ['$scope','MileageRestService',
($scope,MileageRestService)->
$scope.vehicle_log_data = {}
MileageRestService.dashboard(
(result)->
console.log('dashboard result', result)
$scope.vehicle_log_data = result
distances = result.current_year.chart_data.distances
expenses = result.current_year.chart_data.expenses
$scope.data = [
{
key: "Distances",
color: '#ff7f0e',
area: true,
type: "line",
yAxis: 1,
values: distances
},
{
key: "Expenses",
color: '#7777ff',
area: true,
type: "line",
yAxis: 2,
values: expenses
}
]
$scope.options = {
chart: {
type: 'multiChart',
height: 256,
margin : {
top: 20,
left: 50
},
x: (d)-> d.x,
y: (d)-> (d.y),
showValues: true,
lines1: {
duration: 500
},
lines2: {
duration: 500
},
yDomain1: [1, 200],
transitions: true,
useInteractiveGuideline: true,
clipEdge: false
}
}
(error)->
console.log('dashboard error', error)
)
])
The Distance and Expense data is:
distance = [
{x: 1, y: 100},
{x: 2, y: 25},
{x: 3, y: 150},
{x: 4, y: 110},
{x: 5, y: 0},
{x: 6, y: 175},
{x: 7, y: 0},
{x: 8, y: 0},
{x: 9, y: 0},
{x: 10, y: 0},
{x: 11, y: 0},
{x: 12, y: 0}
]
expenses = [
{x: 1, y: 10},
{x: 2, y: 5},
{x: 3, y: 15},
{x: 4, y: 7.75},
{x: 5, y: 0},
{x: 6, y: 20},
{x: 7, y: 0},
{x: 8, y: 0},
{x: 9, y: 0},
{x: 10, y: 0},
{x: 11, y: 0},
{x: 12, y: 0}
]

Resources