have recharts show timing of substances

Viewed 98

I'm using recharts to graph some of my personal data. The test case really simply is this,

import React from 'react';
import '@testing-library/jest-dom';
import { render, screen } from '@testing-library/react';
import generateSubstanceData from './generateLineGraphSubstance';



describe('Generate Substance Timing Series', () => {
  const inputTest = [
    {
      substance: 'Dexamphetamine',
      scheduledtimes: [9, 13, 16],
      startdate: '2021-08-09T14:00:00.000Z',
      enddate: '2021-11-10T13:00:00.000Z',
      duration: 5,
      planneddose: '20',
    },
  ];

  const outputTest = {
    Dexamphetamine: [
      {
        substance: 'Dexamphetamine',
        dose: '20',
        time: 9,
        startdate: '2021-08-09T14:00:00.000Z',
        enddate: '2021-11-10T13:00:00.000Z',
        concentration: 0,
      },
      {
        substance: 'Dexamphetamine',
        dose: '20',
        time: 10,
        startdate: '2021-08-09T14:00:00.000Z',
        enddate: '2021-11-10T13:00:00.000Z',
        concentration: 3,
      },
      ....
    ],
  };
  it('should return expected data', () => {
    expect(generateSubstanceData(inputTest)).toHaveReturned;
    expect(generateSubstanceData(inputTest)).toEqual(outputTest);
  });
});

This is the function it's testing against,

    const calculateParabolaPoint = (x) => Math.abs(-Math.pow(x - 2, 2) + 4);

export default function generateSubstanceData(Substances) {

  /* make separate graphs for each dose, make 24 hour array for each substance */
  const TimingConcentration = {};

  if (Substances && Substances.length > 0) {
    let drugName;
    // check the substance name and set substance for loop if unchanged;
    Substances.map((substance) => {
      let substanceTime = [];
      if (!drugName || drugName !== substance.substance) {
        drugName = substance.substance;
      }

      // console.log('drug name: ', drugName, 'loop name: ', substance.substance);
      // get substance details and add to the array substanceTime
      substance.scheduledtimes.map((timeTaken) => {
        for (let i = timeTaken; i <= timeTaken + substance.duration; i++) {
          let counter = i - timeTaken;
          substanceTime.push({
            substance: substance.substance,
            dose: substance.planneddose,
            time: i,
            startdate: substance.startdate,
            enddate: substance.enddate,
            concentration: calculateParabolaPoint(counter),
          });
        }
        TimingConcentration[drugName] = substanceTime;
      });
      return TimingConcentration;
    });

    return TimingConcentration;
  } else {
    return {};
  }
}

To be implemented in this component,

    import { useEffect,useState } from 'react';
import {
  ComposedChart,
  AreaChart,
  Line,
  Area,
  XAxis,
  YAxis,
  CartesianGrid,
  Tooltip,
  Legend,
  ResponsiveContainer,
} from 'recharts';

export default function LineGraph({ lineGraphData, Substances, loading,selectedSubstance }) {
  /*
    transform dataset properly
    */
 

  var graphData = [];

  graphData[0] = { name: 'Emotions', data: lineGraphData ? lineGraphData : [] };

  return (
    <div data-testid="linegraph" style={{ width: '100%', height: '100%' }}>
      <ResponsiveContainer width="100%" height={300}>
        <ComposedChart
          width={500}
          height={300}
          data={graphData[0].data}
          syncId="time"
          margin={{
            top: 20,
            right: 20,
            bottom: 20,
            left: 20,
          }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="time" ticks={[25]} />
          <YAxis />
          <Tooltip />
          <Legend />
          <Line type="monotone" dataKey="emotion" stroke="#ff7300" />
        </ComposedChart>
      </ResponsiveContainer>
      <ResponsiveContainer width="100%" height={100}>
        <AreaChart
          width={500}
          height={100}
          data={Substances[selectedSubstance]}
          syncId="time"
          margin={{
            top: 10,
            right: 30,
            left: 0,
            bottom: 0,
          }}
        >
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis dataKey="time" type="number" domain={[0, 24]}/>
          <YAxis />
          <Tooltip />
          <Legend />
          <Area
            type="monotone"
            dataKey="concentration"
            stroke="#82ca9d"
            fill="#82ca9d"
          />
        </AreaChart>
      </ResponsiveContainer>
    </div>
  );
}

I want to have the graph show each specific dose (at the scheduled times) as individual area graphs on the axis, so they do not interact (so this example would have three different graphs / parabolas).

With recharts, I'm not sure how you're meant to have the data structured (or code implemented) to achieve this outcome. Would appreciate some help here!

0 Answers
Related