I'm working with a graph (recharts) in React. I need to find the positions of the x-axis ticks so that I can find where to draw a line representing today's date. To do this I pass state to the CustomizedTick component and attempt to add the x-axis value of each one to the state of the parent. However, when the code runs only one of the tick values makes it into the parent state. So at the end 'bars' is something like {4: 352} but I would expect to get something like {0: 32, 1: 98, 2: 203, 3, 278, 4: 352}
import React, { FC, useEffect } from 'react';
export const CustomizedTick: FC<any> = (props: any) => {
const { x, y, payload, index, barStates, setBars } = props;
useEffect(() => {
setBars({ ...barStates, [index]: x - 60 });
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [x]);
const parts = payload.value.split(SPLIT_PARAM);
return (
<g transform={`translate(${x},${y})`}>
<text style={{ fontSize: '10px' }} x={0} y={0} dy={16} fill="#666">
<tspan textAnchor="middle" x="0">
{parts[0]}
</tspan>
<tspan textAnchor="middle" x="0" dy="20">
{parts[1].slice(4)}
</tspan>
</text>
</g>
);
};
import React, { FC, useEffect, useMemo, useState } from 'react';
import {
BarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
ResponsiveContainer,
ReferenceLine,
LabelList,
} from 'recharts';
const Graph = () => {
const splitData = [
{
"createdAt": "2022-08-12T09:39:31.796234+00:00",
"creditorcode": "CRED1",
"costamount": 10,
"costinvoicenumber": "100001",
"type": "cost",
"updatedAt": "2022-08-12T09:39:31.796238+00:00",
"displayDate": "2022-08-17T14:51:59.014Z"
},
{
"createdAt": "2022-08-12T09:39:31.796234+00:00",
"debtorcode": "DEBT1",
"sellamount": 11.5,
"sellcurrency": "USD",
"sellinvoicedate": "2022-02-01 00:00:00",
"type": "sell",
"updatedAt": "2022-08-12T09:39:31.796238+00:00",
"displayDate": "2022-08-17T14:51:59.014Z"
},
{
"createdAt": "2022-08-12T09:46:38.379872+00:00",
"debtorcode": "DEBT2",
"sellamount": 57.5,
"sellcurrency": "USD",
"type": "sell",
"updatedAt": "2022-08-12T09:46:38.379875+00:00",
"displayDate": "2022-08-17T14:51:59.014Z"
},
{
"createdAt": "2022-08-12T09:46:38.379872+00:00",
"creditorcode": "CRED3",
"costamount": 30,
"costinvoicenumber": "100003",
"type": "cost",
"updatedAt": "2022-08-12T09:46:38.379875+00:00",
"displayDate": "2022-08-17T14:51:59.014Z"
}
]
const [bars, setBars] = useState<any>({});
useEffect(() => {
const dateNow: Date = new Date(Date.now());
let dataItemIndex: number | string;
for (dataItemIndex in splitData) {
if (!bars[dataItemIndex] || bars[dataItemIndex] === 0) {
break;
}
if (
splitData[dataItemIndex].displayDate &&
// @ts-ignore
splitData[dataItemIndex].displayDate > dateNow
) {
if (parseInt(dataItemIndex) === 0) {
setCurrentDate(15);
break;
}
const col2 = bars[dataItemIndex];
const col1 =
parseInt(dataItemIndex) > 0 ? bars[parseInt(dataItemIndex) - 1] : 0;
setCurrentDate((col2 + col1) / 2);
break;
}
}
}, [bars, splitData]);
return ( <BarChart
width={width}
height={height}
data={data}
margin={{
top: 20,
right: 20,
left: 0,
bottom: 20,
}}
>
<CartesianGrid strokeDasharray="3 3" />
<XAxis
dataKey="name"
type="category"
dy={16}
tick={<CustomizedTick barStates={barStates} />}
minTickGap={0}
interval={0}
/>
<YAxis type="number" domain={['auto', 'auto']} />
<ReferenceLine
y={0}
label={
currentDate !== 0 ? (
<TimeLine
xoffset={currentDate}
yheight={1200}
stroke={'#0079FF'}
strokeWidth={2}
strokeOpacity={1}
/>
) : undefined
}
stroke={colors.black5}
/>
<Bar dataKey="y">
<LabelList
fill={colors.black3}
position="insideTop"
formatter={(v: number) => v.toFixed(2)}
offset={8}
/>
</Bar>
</BarChart> )
}