const ScreenerCharts = () => {
const symbol = useSelector((state: AppState) => state.screenerSlice.symbol);
const [windowsChart, setWindowsChart] = useState<“one” | “twoVertical” | “twoHorizontal” | “for”>(“for”);
const [intervalFirstChart, setIntervalFirstChart] = useState(“5m”);
const [intervalSecondChart, setIntervalSecondChart] = useState(“1h”);
const [intervalThirdChart, setIntervalThirdChart] = useState(“4h”);
const [intervalFourthChart, setIntervalFourthChart] = useState(“1d”);
return (
<Grid container height=“100%” borderRadius=“8px” position=“relative”>
<Box position=“absolute” top={4} right={8} borderRadius={1} border=“1px solid #d4d4d4” height={31}>
<ButtonGroup>
<IconButton onClick={() => setWindowsChart(“one”)} sx={{m: .3, height: 23, width: 23}}><ChartOneWindowIcon sx={{fill: windowsChart === “one” ? “#B41C18” : “#d4d4d4”}} /> </IconButton>
<IconButton onClick={() => setWindowsChart(“twoVertical”)} sx={{m: .3, height: 23, width: 23}}><ChartTwoVerticalWindowsIcon sx={{fill: windowsChart === “twoVertical” ? “#B41C18” : “#d4d4d4”}} /></IconButton>
<IconButton onClick={() => setWindowsChart(“twoHorizontal”)} sx={{m: .3, height: 23, width: 23}}><ChartTwoHorizontalWindowsIcon sx={{fill: windowsChart === “twoHorizontal” ? “#B41C18” : “#d4d4d4”}} /></IconButton>
<IconButton onClick={() => setWindowsChart(“for”)} sx={{m: .3, height: 23, width: 23}}><ChartForWindowsIcon sx={{fill: windowsChart === “for” ? “#B41C18” : “#d4d4d4”}} /></IconButton>
</ButtonGroup>
</Box>
{
windowsChart === “one” ?
<Grid item xs={12} height=“100%”>
<ChartInterval windowChart={1} symbol={symbol} interval={intervalFirstChart} handleIntervalChange={handleIntervalChange} />
</Grid>
: windowsChart === “twoVertical” ?
<>
<Grid item xs={6} height=“100%”>
<ChartInterval windowChart={1} symbol={symbol} interval={intervalFirstChart} handleIntervalChange={handleIntervalChange} />
</Grid><Grid item xs={6} height=“100%”>
<ChartInterval windowChart={2} symbol={symbol} interval={intervalSecondChart} handleIntervalChange={handleIntervalChange} />
</Grid>
</>
: windowsChart === “twoHorizontal” ?
<>
<Grid item xs={12} height=“49%”>
<ChartInterval windowChart={1} symbol={symbol} interval={intervalFirstChart} handleIntervalChange={handleIntervalChange} />
</Grid><Grid item xs={12} height=“50%”>
<ChartInterval windowChart={2} symbol={symbol} interval={intervalSecondChart} handleIntervalChange={handleIntervalChange} />
</Grid>
</>
:
<>
<Grid item xs={6} height=“49%”>
<ChartInterval windowChart={1} symbol={symbol} interval={intervalFirstChart} handleIntervalChange={handleIntervalChange} />
</Grid><Grid item xs={6} height=“49%”>
<ChartInterval windowChart={2} symbol={symbol} interval={intervalSecondChart} handleIntervalChange={handleIntervalChange} />
</Grid><Grid item xs={6} height=“50%”>
<ChartInterval windowChart={3} symbol={symbol} interval={intervalThirdChart} handleIntervalChange={handleIntervalChange} />
</Grid><Grid item xs={6} height=“50%”>
<ChartInterval windowChart={4} symbol={symbol} interval={intervalFourthChart} handleIntervalChange={handleIntervalChange} />
</Grid>
</>
}
</Grid>
);
};

export default ScreenerCharts;

const ChartInterval: React.FC<ChartIntervalProps> = ({symbol, windowChart, interval, handleIntervalChange}) => (
<Box height=“100%” p={0.5} width=“calc(100% - 4px)” borderRadius=“8px” sx={{bgcolor: “#fff”}}>
<FormControl sx={{mb: 1, “& .MuiSelect-select”: {paddingY: 1}, “& fieldset”: {border: “none”}, height: 31,
backgroundColor: “#eeeeee”, color: “#191919”, padding: “0”, borderRadius: “8px”,
}}>
<Select sx={{fontSize: “12px”}} value={interval} onChange={(e) => handleIntervalChange(e, windowChart)}>
<MenuItem value=“1m”>1м</MenuItem>
<MenuItem value=“5m”>5м</MenuItem>
<MenuItem value=“15m”>15м</MenuItem>
<MenuItem value=“1h”>1ч</MenuItem>
<MenuItem value=“4h”>4ч</MenuItem>
<MenuItem value=“1d”>1д</MenuItem>
<MenuItem value=“1w”>1н</MenuItem>
</Select>
</FormControl>
{
symbol ?
<KLineChart symbol={symbol} windowChart={windowChart} interval={interval} />
: <Box width=“100%” height=“88%” display=“flex” alignItems=“center” justifyContent=“center”>
<Typography fontSize={28} color=“#9999994d”> Выберите монету</Typography>
</Box>
}
</Box>
);


const KLineChart: React.FC<KLineChartProps> = React.memo(({symbol, interval, windowChart}) => {
const [candlesticks, setCandlesticks] = useState<KLineData[]>([]);
const fetchCandlesticks = () => {
setWaiting(true);
fetchSymbolsKlines(symbol, interval)
.then((data) => {
if (undefined === data) return;

setCandlesticks(data.map(item => ({
timestamp: dayjs.utc(item[0]).valueOf(),
open: parseFloat(item[1].toString()),
high: parseFloat(item[2].toString()),
low: parseFloat(item[3].toString()),
close: parseFloat(item[4].toString()),
volume: parseFloat(item[5].toString()),
})));
})
.finally(() => {
setWaiting(false);
});
};

useEffect(() => {
fetchCandlesticks();
}, [symbol, interval]);

return (
<CandleChart
candles={candlesticks}
tradeId={chart${windowChart}-${symbol}-${interval}}
symbolName={symbol}
chartInterval={interval}
/>
);
});

export const CandleChart = ({
candles,
tradeId,
symbolName,
chartInterval,
}: CandleChartProps) => {
const chart = useRef<Chart|null>();
const paneId = useRef<string>(“”);
const [figureId, setFigureId] = useState<string>(“”);
const ref = useRef<HTMLDivElement>(null);
useEffect(() => {
chart.current = init(chart-${tradeId}, {styles: chartStyles});

return () => dispose(chart-${tradeId});
}, [tradeId]);

const removeFigure = () => {
chart.current?.removeOverlay({
id: figureId,
});
setFigureId(“”);
};

console.log(tradeId, figureId);

return (<><Stack direction=“row” height={height && !handle.active ? 550 : “100%” || “calc(100% - 140px)”} width=“100%”>
<CandleChartToolbar
setFigureId={setFigureId}
chart={chart}
paneId={paneId}
handle={handle}
/>
<Box
ref={ref}
id={chart-${tradeId}}
width=“calc(100% - 55px)”
height={“100%”}
sx={{borderLeft: “2px solid #F5F5F5”}}
>
{
figureId.length > 0 &&
<Stack
sx={{
backgroundColor: “#CBD4E3”,
borderRadius: 1,
position: “absolute”,
zIndex: 10,
right: 80,
top: 30,
border: “2px solid #F5F5F5”,
}}
spacing={2}
>
<IconButton sx={{borderRadius: 1}} onClick={removeFigure}>
<Icon component={BasketIcon} />
</IconButton>
</Stack>
}
</Box>
</Stack>
</>);
});


const CandleChartToolbar = ({chart, paneId, setFigureId, handle}: CandleChartToolbarProps) => {
const removeOverlay = () => {
chart.current?.removeOverlay();
setFigureId(“”);
};

const fullScreenHandle = () => {
if(handle.active) {
handle.exit();
} else {
handle.enter();
}
};

return <>
<Stack
className=“scroll-block”
direction=“column”
alignItems=“center”
spacing={1}
sx={{
width: “55px”,
height: “100%”,
overflowY: “scroll”,
}}
>
<PriceLineTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<HorizontalStraightLineTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<RayLineTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<SegmentTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<StraightLineTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<ParallelStraightLineTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<FibonacciLineTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<RulerTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>
<RectTool chart={chart} paneId={paneId} setFigureId={setFigureId}/>

<IconButton sx={{borderRadius: 2}} style={{height: 40}} onClick={fullScreenHandle}>
<Icon component={FullScreenIcon} sx={{height: 18}} />
</IconButton>

<IconButton sx={{borderRadius: 2}} onClick={removeOverlay}>
<Icon component={BasketIcon}/>
</IconButton>
</Stack>
</>;
};

export default CandleChartToolbar;

const PriceLineTool = ({chart, paneId, setFigureId}: ToolProps) => {
const onClickHandler = () => {
chart.current?.createOverlay({
name: “priceLine”,
styles: {
text: {
color: “#1e293b”,
},
line: {
color: “#1e293b”,
},
point: {
color: “#1e293b”,
borderColor: “#1e293b”,
activeColor: “#1e293b”,
activeBorderColor: “#1e293bd1”,
},
},
onSelected: function(event) {
setFigureId(event.overlay.id);

return false;
},
onDeselected: function() {
setFigureId(“”);

return false;
},
});
};

return <>
<IconButton onClick={onClickHandler} sx={{borderRadius: 2}}>
<Icon component={PriceLineIcon} />
</IconButton>
</>;
};

export default PriceLineTool;

import {ToolProps} from “./Tool.props”;
import {Icon, IconButton} from “@mui/material”;
import React, {useEffect} from “react”;
import {RectIcon} from “…/…/…/icons”;
import {registerOverlay} from “klinecharts”;

const RectTool = ({chart, paneId, setFigureId}: ToolProps) => {
useEffect(() => {
registerOverlay({
name: “rect”,
needDefaultPointFigure: true,
needDefaultXAxisFigure: true,
needDefaultYAxisFigure: true,
totalStep: 3,
onSelected: function(event) {
setFigureId(event.overlay.id);

return false;
},
onDeselected: function() {
setFigureId(“”);

return false;
},
createPointFigures: function({coordinates}) {
if (coordinates.length === 2) {
const xDis = coordinates[1].x - coordinates[0].x;
const yDis = coordinates[1].y - coordinates[0].y;

return {
key: “rect”,
type: “rect”,
attrs: {
x: coordinates[0].x,
y: coordinates[0].y,
width: xDis,
height: yDis,
},
};
}

return [];
},
});
}, []);

const onClickHandler = () => {
chart.current?.createOverlay({
name: “rect”,
styles: {
rect: {
color: “#1e293b3d”,
},
line: {
color: “#1e293b”,
},
point: {
color: “#1e293b”,
borderColor: “#1e293b”,
activeColor: “#1e293b”,
activeBorderColor: “#1e293bd1”,
},
},
});
};

return <>
<IconButton onClick={onClickHandler} sx={{borderRadius: 2}}>
<Icon component={RectIcon} />
</IconButton>
</>;
};

export default RectTool;

когда я на первом графике рисую квадрат RectTool, то
console.log(tradeId, figureId); в компоненте CandleChart показывает 4 график, а если рисую линию, то все нормально. не могу понять в чем проблема.
Найди ошибку и исправь