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!