0

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?

Suprava
  • 69
  • 6

0 Answers0