I have been trying to display a nivo line charts using data from my backend (Django). However, when the data is inserted into the nivo line chart, the react window gets unresponsive.
The backend sends the timestamps and the values like this --
Example -- timestamp = "2023-05-12 16:10:53.000000000" Values -- "39.520004"
class AddView(APIView):
from django.views.decorators.csrf import csrf_exempt
from rest_framework import status
import json
@staticmethod
@csrf_exempt
def post(request):
from awsfetch.rpm import rpm
timestamps, values = rpm()
return Response({"timestamps": timestamps, "values": values})
This is the nivo chart component --
import { ResponsiveLine } from "@nivo/line";
const MyResponsiveLine = ({ data }) => (
<ResponsiveLine
data={data}
margin={{ top: 50, right: 160, bottom: 50, left: 60 }}
xScale={{ format: "%Y-%m-%dT%H:%M:%S.%L%Z", type: "time" }}
xFormat="time:%Y-%m-%dT%H:%M:%S.%L%Z"
yScale={{ type: "linear", stacked: true, min: 0.0, max: 1.0 }}
curve="monotoneX"
axisTop={null}
axisRight={{
tickValues: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
format: "0.2",
legend: "",
legendOffset: 0
}}
axisBottom={{
tickValues: "every 1 second",
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
format: "%S.%L",
legend: "Time",
legendOffset: 36,
legendPosition: "middle"
}}
axisLeft={{
tickValues: [0.0, 0.2, 0.4, 0.6, 0.8, 1.0],
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
format: ".2",
legend: "CPU",
legendOffset: -40,
legendPosition: "middle"
}}
enableGridX={false}
colors={{ scheme: "spectral" }}
lineWidth={1}
pointSize={4}
pointColor={{ theme: "background" }}
pointBorderWidth={1}
pointBorderColor={{ from: "serieColor" }}
enablePointLabel={false}
pointLabel="y"
pointLabelYOffset={-12}
useMesh={true}
gridXValues={[0, 20, 40, 60, 80, 100, 120]}
gridYValues={[0, 500, 1000, 1500, 2000, 2500]}
legends={[
{
anchor: "bottom-right",
direction: "column",
justify: false,
translateX: 140,
translateY: 0,
itemsSpacing: 2,
itemDirection: "left-to-right",
itemWidth: 80,
itemHeight: 12,
itemOpacity: 0.75,
symbolSize: 12,
symbolShape: "circle",
symbolBorderColor: "rgba(0, 0, 0, .5)",
effects: [
{
on: "hover",
style: {
itemBackground: "rgba(0, 0, 0, .03)",
itemOpacity: 1
}
}
]
}
]}
/>
);
export default MyResponsiveLine;
My App.js file goes like this -- so the logic is, when the button is pressed the graph is supposed to be seen in the frontend.
import axios from "axios";
import React, { useState } from "react";
import MyResponsiveLine from "./components/line";
function App() {
const [data, setData] = useState([]);
const calculate = () => {
axios
.post("http://127.0.0.1:8000/add/", {})
.then((res) => {
const timestamps = res.data.timestamps;
const values = res.data.values;
const newData = timestamps.map((timestamp, i) => ({
x: new Date(timestamp),
y: values[i]
}));
setData([{
id: "Data",
data: newData
}]);
})
.catch((err) => {
console.error(err);
});
};
return (
<>
<div className="row">
<div className="col-md-1">
<button onClick={calculate}>calculate</button>
</div>
</div>
<div style={{ height: "500px" }}>
<MyResponsiveLine data={data} />
</div>
</>
);
}
export default App;
I tried many possible ways to rectify this.. can anyone please help me out?