UNPKG

wykrestest

Version:

Candlestick Chart made with Konva, React and Jotai

89 lines (88 loc) 3.5 kB
import { useRef } from 'react'; import { atom } from 'jotai'; import { highLowFunc, winSizeFunc, maxXFunc, winPosFunc } from './utils/utils'; import { checkBoundry } from './utils/utils'; export const mainStageAtom = atom(() => useRef(null)); export const gapAtom = atom(4); export const dragAtom = atom(false); //used in chart and main as link..can be prop but w/e export const maxXAtom = atom(0); export const winSizeAtom = atom(200); export const winCountAtom = atom((get) => get(dataLengthAtom) / get(winSizeAtom)); export const winHLAtom = atom({ high: 0, low: 0, diff: 0 }); //-------------------------------------DIMS export const heightAtom = atom(500); export const widthAtom = atom(500); const padding = atom(30); export const dimsAtom = atom(get => { return { height: get(heightAtom), width: get(widthAtom), heightSub: get(heightAtom) - get(padding), widthSub: get(widthAtom) - get(padding), }; }, (_, set, arg) => { set(heightAtom, arg.height); set(widthAtom, arg.width); }); //------------------------------------- //---------------------------dataStore------------------ export const dataAtom = atom([{ high: 0, low: 0, open: 0, close: 0, api_date: '' }]); export const dataLengthAtom = atom((get) => get(dataAtom).length); export const dataHLAtom = atom((get) => highLowFunc(get(dataAtom))); export const dataStoreAtom = atom((get) => { return { data: get(dataAtom), dataLength: get(dataLengthAtom), dataHL: get(dataHLAtom) }; }, (get, set, arg) => { const newMaxX = maxXFunc(arg.length, get(winSizeAtom), get(gapAtom), get(scaleXAtom)); set(dataAtom, arg); set(xAtom, newMaxX); set(maxXAtom, newMaxX); }); //------------------------------------------------------- //-------------------------------Konva Positions --------------- export const xAtom = atom(0, (get, set, arg) => { const winPos = winPosFunc(arg, get(gapAtom), get(scaleXAtom)); const subData = get(dataAtom).slice(winPos, winPos + get(winSizeAtom)); const winHL = highLowFunc(subData); set(xAtom, arg); set(winHLAtom, winHL); }); //not a huge fan but it works...we can probably move the event part and the newX part out if we want to //but idk how much cleaner/easier to understand that would make it...had issues with jumpyness since react set was slow i think export const scaleXAtom = atom(1, (get, set, e) => { //random const getX = (newScaleX) => { const mp = get(mainStageAtom).current.getPointerPosition(); const pointTo = (mp.x - get(xAtom)) / get(scaleXAtom); const newX = (mp.x - (pointTo * newScaleX)); return { x: newX, y: get(yAtom) }; }; //mid/end const zoom = (newScaleX) => { const pos = getX(newScaleX); const ws = winSizeFunc(get(widthAtom) - get(padding), get(gapAtom), newScaleX); const maxX = maxXFunc(get(dataLengthAtom), ws, get(gapAtom), newScaleX); const newPos = checkBoundry(pos, maxX); set(scaleXAtom, newScaleX); set(maxXAtom, maxX); set(winSizeAtom, ws); set(xAtom, newPos.x); }; //pt1 if (e.evt.wheelDelta > 0) { if (get(scaleXAtom) < 2) { zoom(get(scaleXAtom) + .25); } } else { if (get(scaleXAtom) > .5) { zoom(get(scaleXAtom) - .25); } } }); export const yAtom = atom(0); export const scaleYAtom = atom(1); //---------------------------------------------------------------