UNPKG

wykrestest

Version:

Candlestick Chart made with Konva, React and Jotai

61 lines (60 loc) 3 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import React, { useState, useEffect, useRef, useLayoutEffect } from 'react'; import { Layer, Group } from 'react-konva'; import { Border } from '../utils/Border'; import { Rect, Line } from 'react-konva'; import { checkBoundry } from '../utils/utils'; import { useAtomValue, useAtom } from 'jotai'; import { dragAtom, dimsAtom, gapAtom, maxXAtom, dataAtom } from '../store'; import { xAtom, yAtom, scaleXAtom, scaleYAtom, dataHLAtom } from '../store'; export const Main = () => { const layerRef = useRef(null); const groupRef = useRef(null); const [x, setX] = useAtom(xAtom); const y = useAtomValue(yAtom); const scaleX = useAtomValue(scaleXAtom); const scaleY = useAtomValue(scaleYAtom); const dims = useAtomValue(dimsAtom); const maxX = useAtomValue(maxXAtom); const data = useAtomValue(dataAtom); const dragBound = (pos) => { const newPos = checkBoundry(pos, maxX); setX(newPos.x); return { x: newPos.x, y: y }; }; const drag = useAtomValue(dragAtom); useLayoutEffect(() => { if (drag) { groupRef.current.startDrag(); groupRef.current.cache({ pixelRatio: .9 }); } else { groupRef.current.stopDrag(); groupRef.current.clearCache(); } }, [drag]); return (_jsx(_Fragment, { children: _jsxs(Layer, { ref: layerRef, clip: { x: 0, y: 0, height: dims.height, width: dims.widthSub }, children: [_jsx(Group, { ref: groupRef, x: x, y: y, scaleX: scaleX, scaleY: scaleY, dragBoundFunc: dragBound, children: data.map((item, i) => _jsx(CandleMemo, { item: item, i: i }, item.api_date)) }), _jsx(Border, { dims: dims })] }) })); }; export const MainMemo = React.memo(Main); //the mapped items export const Candle = ({ item, i }) => { const gap = useAtomValue(gapAtom); const [openPx, setOpenPx] = useState(0); const [closePx, setClosePx] = useState(0); const [highPx, setHighPx] = useState(0); const [lowPx, setLowPx] = useState(0); const [fill, setFill] = useState('black'); const dataHL = useAtomValue(dataHLAtom); const dims = useAtomValue(dimsAtom); useEffect(() => { if (item.open != 0 && dataHL.high != 0) { setFill(item.open > item.close ? 'red' : 'green'); setOpenPx(((dataHL.high - item.open) / dataHL.diff) * dims.heightSub); setClosePx(((dataHL.high - item.close) / dataHL.diff) * dims.heightSub); setHighPx(((dataHL.high - item.high) / dataHL.diff) * dims.heightSub); setLowPx(((dataHL.high - item.low) / dataHL.diff) * dims.heightSub); } }, [dataHL, item]); return (_jsxs(_Fragment, { children: [_jsx(Rect, { x: i * gap, y: openPx, width: gap, height: closePx - openPx, fill: fill }), _jsx(Line, { x: i * gap, points: [2, highPx, 2, lowPx], stroke: fill, strokeWidth: 1 })] })); }; export const CandleMemo = React.memo(Candle);