diff --git a/src/classes/DrawChart.js b/src/classes/DrawChart.js index 2da680b..27ac6eb 100644 --- a/src/classes/DrawChart.js +++ b/src/classes/DrawChart.js @@ -47,6 +47,7 @@ class DrawChart { // trend lines data; this.trendLinesData = signal([]); this.fibData = signal([]); + this.projectionData = signal([]); } #setData(data) { this.data.value = data; diff --git a/src/components/toolbar/toolbarItems.jsx b/src/components/toolbar/toolbarItems.jsx index 1ade4eb..1888f57 100644 --- a/src/components/toolbar/toolbarItems.jsx +++ b/src/components/toolbar/toolbarItems.jsx @@ -9,6 +9,7 @@ import { FaArrowPointer } from "react-icons/fa6"; import { cursorConfig } from "../../signals/toolbarSignals"; import { useOutsideClick } from "../navbar/navbar"; import { PiLineSegmentFill } from "react-icons/pi"; +import { FaProjectDiagram } from "react-icons/fa"; function ToolItems({ toogleToolItemsIndex, @@ -67,6 +68,11 @@ function ToolbarItems({ mode, ChartWindow }) { selectedTool.value = items[2].toolName; selectedToolItem.value = index; } + function projectionOnClickHandler(index) { + setToogleToolItemsIndex(-1); + selectedTool.value = items[3].toolName; + selectedToolItem.value = index; + } const items = [ { toolName: "Cursor", @@ -181,6 +187,19 @@ function ToolbarItems({ mode, ChartWindow }) { ], onClickFunction: fibOnClickHandler, }, + { + toolName: "Projection", + toolItemsEle: [ + , + ], + toolLabels: [ + "Long Position", + ], + onClickFunction: projectionOnClickHandler, + }, ]; return (
diff --git a/src/utility/chartUtils.js b/src/utility/chartUtils.js index 2a617d4..3255911 100644 --- a/src/utility/chartUtils.js +++ b/src/utility/chartUtils.js @@ -34,6 +34,7 @@ import { drawTrendLines, drawVerticalLineUsingPoints, } from "./drawUtils/toolsDraw/lineTool"; +import { drawLongPositionUsingPoints } from "./drawUtils/toolsDraw/projectionTool"; export async function getStockDataCallback( instrumentKey, @@ -97,7 +98,7 @@ export function handleOnMouseMove(e, state) { } const firstIndex = dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) + getObjtoStringTime(timeRange.peek().startTime) ]; const cursordata = data.peek()[0][firstIndex - dateIndex]; if (cursordata === undefined) return; @@ -294,6 +295,18 @@ export function handleOnMouseMove(e, state) { break; } break; + case "Projection": + switch (prevToolItemNo.peek()) { + case 0: + drawLongPositionUsingPoints( + state, + prevSelectedCanvas.peek(), + points, + false, + true + ) + break; + } } } } else { @@ -342,10 +355,10 @@ export function handleScroll(e, state) { Math.abs(pixelMovement) === 0 || (pixelMovement > 0 && getObjtoStringTime(timeRange.peek().startTime) === - dateConfig.peek().indexToDate[data.peek()[0].length - 1]) || + dateConfig.peek().indexToDate[data.peek()[0].length - 1]) || (pixelMovement < 0 && getObjtoStringTime(timeRange.peek().endTime) === - dateConfig.peek().indexToDate[0]) + dateConfig.peek().indexToDate[0]) ) { return; } @@ -415,7 +428,7 @@ export function updateCursorValue(state, mode) { yAxisRange.peek().minPrice + ((chartCanvasSize.peek().height - dateCursor.peek().y) * (yAxisRange.peek().maxPrice - yAxisRange.peek().minPrice)) / - chartCanvasSize.peek().height; + chartCanvasSize.peek().height; const priceText = price.toFixed(2); const yCoord1 = dateCursor.peek().y; if (isCanvas) { @@ -565,6 +578,19 @@ export function updateCursorValue(state, mode) { ); break; } + case "Projection": + switch (prevToolItemNo.peek()) { + case 0: + drawLongPositionUsingPoints( + drawChartobj, + canvas, + points, + false, + true, + ctx + ) + break; + } } } }); @@ -595,7 +621,7 @@ export const removeCursor = (e, state) => { }; export const chartMouseDown = (e, state) => { - const { chartMovement, ChartRef, trendLinesData, fibData } = state; + const { chartMovement, ChartRef, trendLinesData, fibData, projectionData } = state; const { selectedTool, selectedItem } = state.ChartWindow; const selectedEle = detectTrendLine(e, state); if (selectedTool.peek() !== "Cursor") { @@ -608,6 +634,9 @@ export const chartMouseDown = (e, state) => { case "Fib": selectedItem.value = fibData.peek()[selectedEle.index]; break; + case "Projection": + selectedItem.value = projectionData.peek()[selectedEle.index]; + break; } if (selectedEle.selectedPoint !== selectedItem.peek().points.length) { prevToolItemNo.value = selectedEle.toolItemNo; @@ -617,10 +646,10 @@ export const chartMouseDown = (e, state) => { case "Line": { prevLineData.value = trendLinesData .peek() - [selectedEle.index].points.map((_, i) => { - if (i !== selectedEle.selectedPoint) return _; - else return null; - }); + [selectedEle.index].points.map((_, i) => { + if (i !== selectedEle.selectedPoint) return _; + else return null; + }); trendLinesData.value = trendLinesData .peek() .filter((ele, i) => i !== selectedEle.index); @@ -630,16 +659,29 @@ export const chartMouseDown = (e, state) => { case "Fib": { prevLineData.value = fibData .peek() - [selectedEle.index].points.map((_, i) => { - if (i !== selectedEle.selectedPoint) return _; - else return null; - }); + [selectedEle.index].points.map((_, i) => { + if (i !== selectedEle.selectedPoint) return _; + else return null; + }); fibData.value = fibData .peek() .filter((ele, i) => i !== selectedEle.index); drawFibs(state); break; } + case "Projection": { + prevLineData.value = projectionData + .peek() + [selectedEle.index].points.map((_, i) => { + if (i !== selectedEle.selectedPoint) return _; + else return null; + }); + projectionData.value = projectionData + .peek() + .filter((ele, i) => i !== selectedEle.index); + drawProjections(state); + break; + } } } else { chartMovement.value.isItem = true; @@ -731,7 +773,7 @@ export const chartMouseMove = (e, state) => { const points = getCoordsArray(state, lineData.points); chartMovement.value.mouseMove = true; drawChartObjects.peek().forEach((obj) => { - const { trendLinesData, fibData } = obj; + const { trendLinesData, fibData, projectionData } = obj; switch (chartMovement.peek().itemData.toolName) { case "Line": trendLinesData.peek().forEach((trendLine, i) => { @@ -751,6 +793,14 @@ export const chartMouseMove = (e, state) => { } }); break; + case "Projection": + projectionData.peek().forEach((projection, i) => { + if (projection === selectedItem.peek()) { + projectionData.value = projectionData.peek().filter((_, j) => i !== j); + return; + } + }); + break; } }); chartMovement.value.itemData = { @@ -779,6 +829,7 @@ export const chartMouseUp = (e, state) => { yAxisRange, data, fibData, + projectionData, } = state; const { xAxisConfig, dateConfig, timeRange } = state.ChartWindow; if (!chartMovement.peek().mouseMove && chartMovement.peek().mouseDown) { @@ -790,7 +841,7 @@ export const chartMouseUp = (e, state) => { const { points, toolItemNo, toolName } = chartMovement.peek().itemData; const firstIndex = dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) + getObjtoStringTime(timeRange.peek().startTime) ]; const result = points.map((point, i) => { const x1 = point.x; @@ -803,7 +854,7 @@ export const chartMouseUp = (e, state) => { yAxisRange.peek().minPrice + ((chartCanvasSize.peek().height - y1) * (yAxisRange.peek().maxPrice - yAxisRange.peek().minPrice)) / - chartCanvasSize.peek().height; + chartCanvasSize.peek().height; return { xLabel: cursordata1.Date, yLabel: price1.toFixed(2), @@ -826,6 +877,13 @@ export const chartMouseUp = (e, state) => { }); drawFibs(state, true); } + case "Projection": { + projectionData.value.push({ + toolItemNo: toolItemNo, + points: result, + }); + drawProjections(state, true); + } } } if (chartMovement.peek().mouseMove) { diff --git a/src/utility/drawUtils/chartDraw.js b/src/utility/drawUtils/chartDraw.js index cfd72ec..1ffc10f 100644 --- a/src/utility/drawUtils/chartDraw.js +++ b/src/utility/drawUtils/chartDraw.js @@ -5,6 +5,7 @@ import { getYCoordinate } from "../yAxisUtils"; import { drawIndicators } from "./indicatorDraw"; import { drawFibs } from "./toolsDraw/fibTool"; import { drawTrendLines } from "./toolsDraw/lineTool"; +import { drawProjections } from "./toolsDraw/projectionTool"; export function drawChart(state, mode) { const { data, yAxisRange, ChartRef, yAxisRef, chartCanvasSize } = state; const { @@ -185,6 +186,9 @@ export function drawChart(state, mode) { state.ChartWindow.drawChartObjects .peek() .forEach((obj) => drawFibs(obj, true)); + state.ChartWindow.drawChartObjects + .peek() + .forEach((obj) => drawProjections(obj, true)); } export const drawYAxis = (ctx, yAxisCtx, mode, state) => { diff --git a/src/utility/drawUtils/toolsDraw/projectionTool.js b/src/utility/drawUtils/toolsDraw/projectionTool.js new file mode 100644 index 0000000..00310ba --- /dev/null +++ b/src/utility/drawUtils/toolsDraw/projectionTool.js @@ -0,0 +1,71 @@ +import { getCoordsArray } from "../../toolsUtils"; +import { drawPoint, drawTrendLineUsingPoints } from "./lineTool"; + +export const drawProjection = ( + state, + i, + lineSelected = false, + fromDrawChart = false +) => { + const { projectionData, ChartRef } = state; + const canvas = ChartRef.current[0]; + const canvas1 = ChartRef.current[1]; + const ctx1 = canvas1.getContext("2d"); + const projection = projectionData.peek()[i]; + switch (projection.toolItemNo) { + case 0: + drawLongPositionUsingPoints( + state, + canvas, + projection.points, + lineSelected, + fromDrawChart, + ctx1 + ); + break; + } +}; + +export const drawLongPositionUsingPoints = ( + state, + canvas, + points, + lineSelected = false, + fromDrawChart = false, + ctx1 = null +) => { + if(!fromDrawChart) return; + const [midLeft, topLeft, bottomLeft, midRight] = getCoordsArray(state, points); + if(lineSelected){ + drawPoint(ctx1, midLeft.x, midLeft.y); + drawPoint(ctx1, topLeft.x, topLeft.y); + drawPoint(ctx1, bottomLeft.x, bottomLeft.y); + drawPoint(ctx1, midRight.x, midRight.y); + } else { + const ctx = canvas.getContext("2d"); + ctx.beginPath(); + ctx.fillStyle = 'rgba(0,255,0,0.5)' + ctx.rect(topLeft.x, topLeft.y, Math.abs(midLeft.x - midRight.x), Math.abs(topLeft.y - midLeft.y)); + ctx.fill(); + ctx.closePath(); + ctx.beginPath(); + ctx.fillStyle = 'rgba(255,0,0,0.5)' + ctx.rect(midLeft.x, midLeft.y, Math.abs(midLeft.x - midRight.x), Math.abs(bottomLeft.y - midLeft.y)); + ctx.fill(); + ctx.closePath(); + ctx.beginPath(); + ctx.strokeStyle="black" + ctx.moveTo(midLeft.x,midLeft.y); + ctx.lineTo(midRight.x,midRight.y); + ctx.stroke(); + ctx.closePath(); + } +} + + +export const drawProjections = (state, fromDrawChart = false) => { + const { projectionData } = state; + projectionData.peek().forEach((lineData, i) => { + drawProjection(state, i, false, fromDrawChart); + }); +}; diff --git a/src/utility/toolsUtils.js b/src/utility/toolsUtils.js index c5d7a12..882bdf0 100644 --- a/src/utility/toolsUtils.js +++ b/src/utility/toolsUtils.js @@ -5,7 +5,8 @@ import { prevToolItemNo, } from "../signals/toolbarSignals"; import { drawFib, drawFibs } from "./drawUtils/toolsDraw/fibTool"; -import { drawTrendLine, drawTrendLines } from "./drawUtils/toolsDraw/lineTool"; +import { drawPoint, drawTrendLine, drawTrendLines } from "./drawUtils/toolsDraw/lineTool"; +import { drawProjection, drawProjections } from "./drawUtils/toolsDraw/projectionTool"; import { getObjtoStringTime, getXCoordinate } from "./xAxisUtils"; import { getYCoordinate } from "./yAxisUtils"; @@ -18,7 +19,7 @@ export const getCoordsArray = (state, points) => { const { timeRange, xAxisConfig, dateConfig } = state.ChartWindow; const firstIndex = dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) + getObjtoStringTime(timeRange.peek().startTime) ]; const coordsArray = []; points.forEach((point, index) => { @@ -57,20 +58,20 @@ function isCursorOnTrendLine(e, lineData, state) { const rect = canvas.getBoundingClientRect(); const x = parseInt(e.pageX - rect.left); const y = parseInt(e.pageY - rect.top); - if ( - x > Math.max(startCoords.x, endCoords.x) || - x < Math.min(startCoords.x, endCoords.x) - ) - return -1; - if (isIntersect(x, y, startCoords.x + 5, startCoords.y + 5, 5)) return 0; - if (isIntersect(x, y, endCoords.x - 5, endCoords.y - 5, 5)) return 1; + // if ( + // x > Math.max(startCoords.x, endCoords.x) || + // x < Math.min(startCoords.x, endCoords.x) + // ) + // return -1; + if (isIntersect(x, y, startCoords.x, startCoords.y, 5)) return 0; + if (isIntersect(x, y, endCoords.x, endCoords.y, 5)) return 1; const slope = (startCoords.y - endCoords.y) / (startCoords.x - endCoords.x); const constant = startCoords.y - slope * startCoords.x; for (let i = -5; i < 5; i++) { if (parseInt(y) + i === parseInt(slope * x + constant)) return 2; } for (let i = -5; i < 5; i++) { - if (parseInt(x) + i === parseInt((y - constant) / slope)) return 2; + if (parseInt(x) + i === parseInt(startCoords.x)) return 2; } return -1; } @@ -407,7 +408,7 @@ export const isCursorOnFibChannelLine = (e, fibData, state) => { // if (x < fibEndCoords.x || x > lineEndCoords.x) return -1; const len = Math.sqrt( (fibEndCoords.y - lineStartCoords.y) ** 2 + - (fibEndCoords.x - lineStartCoords.x) ** 2 + (fibEndCoords.x - lineStartCoords.x) ** 2 ); const yi = Math.abs(val * len); const cos0 = (fibEndCoords.x - lineStartCoords.x) / len; @@ -574,9 +575,22 @@ export const isCursorFib = (e, fibData, state) => { } } }; +export const isCursorProjection = (e, projectionData, state) => { + const { toolItemNo, points } = projectionData; + switch (toolItemNo) { + case 0: { + const onDiagonal = isCursorOnTrendLine(e, { points: points.slice(1, 3) }, state); + const onDiagonal1 = isCursorOnTrendLine(e, { points: [points[0], points[3]] }, state); + if (onDiagonal1 === 2 || onDiagonal === 2) return 4; + if (onDiagonal1 !== -1) return onDiagonal1; + if (onDiagonal !== -1) return onDiagonal; + return -1; + } + } +}; export const detectTrendLine = (e, state) => { - const { chartCanvasSize, yAxisRange, trendLinesData, fibData } = state; + const { chartCanvasSize, yAxisRange, trendLinesData, fibData, projectionData } = state; const { dateConfig, xAxisConfig, timeRange, selectedCursor } = state.ChartWindow; const canvas = e.target; @@ -592,7 +606,7 @@ export const detectTrendLine = (e, state) => { trendLinesData.peek().forEach((lineData, i) => { const firstIndex = dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) + getObjtoStringTime(timeRange.peek().startTime) ]; const points = []; lineData.points.forEach((point, i) => { @@ -653,7 +667,7 @@ export const detectTrendLine = (e, state) => { fibData.peek().forEach((fib, i) => { const firstIndex = dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) + getObjtoStringTime(timeRange.peek().startTime) ]; const points = []; fib.points.forEach((point, i) => { @@ -711,9 +725,100 @@ export const detectTrendLine = (e, state) => { return; } }); + projectionData.peek().forEach((projection, i) => { + const firstIndex = + dateConfig.peek().dateToIndex[ + getObjtoStringTime(timeRange.peek().startTime) + ]; + const points = []; + projection.points.forEach((point, i) => { + const startXCoordIndex = dateConfig.peek().dateToIndex[point.xLabel]; + const startXCoord = getXCoordinate( + chartCanvasSize.peek().width, + xAxisConfig.peek().widthOfOneCS, + timeRange.peek().scrollDirection, + timeRange.peek().scrollOffset, + firstIndex - startXCoordIndex + ); + const startYCoord = getYCoordinate( + point.yLabel, + yAxisRange.peek().minPrice, + yAxisRange.peek().maxPrice, + chartCanvasSize.peek().height + ); + points.push({ + x: startXCoord, + y: startYCoord, + }); + }); + const toolItemNo = projection.toolItemNo; + const online = isCursorProjection( + e, + { + points, + toolItemNo, + }, + state + ); + if (online === points.length) { + canvas.classList.remove(`cursor-${cursorConfig[selectedCursor.value]}`); + canvas.classList.add("cursor-pointer"); + drawProjection(state, i, true, true); + returnVal = { + ...projection, + selectedPoint: online, + index: i, + toolItemNo, + toolName: "Projection", + }; + return; + } + if (online !== -1) { + canvas.classList.remove(`cursor-${cursorConfig[selectedCursor.value]}`); + canvas.classList.add("cursor-default"); + drawProjection(state, i, true, true); + returnVal = { + selectedPoint: online, + index: i, + toolItemNo, + toolName: "Projection", + }; + return; + } + }); return returnVal; }; +const getPointFromXY = (state, x, y) => { + const { chartCanvasSize, data, yAxisRange, ChartRef } = state; + const { dateConfig, xAxisConfig, timeRange, selectedTool, selectedToolItem } = + state.ChartWindow; + const dateIndex = Math.floor( + (chartCanvasSize.peek().width - x) / xAxisConfig.peek().widthOfOneCS + ); + const firstIndex = + dateConfig.peek().dateToIndex[ + getObjtoStringTime(timeRange.peek().startTime) + ]; + const cursordata = data.peek()[0][firstIndex - dateIndex]; + let price = + yAxisRange.peek().minPrice + + ((chartCanvasSize.peek().height - y) * + (yAxisRange.peek().maxPrice - yAxisRange.peek().minPrice)) / + chartCanvasSize.peek().height; + if (price > yAxisRange.peek().maxPrice) { + price = yAxisRange.peek().maxPrice; + } else if (price < yAxisRange.peek().minPrice) { + price = yAxisRange.peek().minPrice; + } + const priceText = price.toFixed(2); + const lineStartPoint = { + xLabel: cursordata.Date, + yLabel: priceText, + }; + return lineStartPoint; +} + const setToolData = (state, lineStartPoint) => { const { selectedTool, selectedToolItem } = state.ChartWindow; state.ChartWindow.drawChartObjects.peek().forEach((obj) => { @@ -746,6 +851,14 @@ const setToolData = (state, lineStartPoint) => { drawFibs(obj, true); break; } + case "Projection": { + obj.projectionData.value.push({ + points: points, + toolItemNo: selectedToolItem.peek(), + }); + drawProjections(obj, true); + break; + } } prevLineData.value = null; prevToolItemNo.value = null; @@ -763,39 +876,20 @@ export const setTool = (e, state) => { case "Fib": setFibTool(e, state); break; + case "Projection": + setProjectionTool(e, state); + break; } }; export const setTrendLine = (e, state) => { - const { chartCanvasSize, data, yAxisRange, ChartRef } = state; - const { dateConfig, xAxisConfig, timeRange, selectedTool, selectedToolItem } = + const { ChartRef } = state; + const { selectedTool, selectedToolItem } = state.ChartWindow; const canvas = ChartRef.current[1]; const rect = canvas.getBoundingClientRect(); const x = e.pageX - rect.left; const y = e.pageY - rect.top; - const dateIndex = Math.floor( - (chartCanvasSize.peek().width - x) / xAxisConfig.peek().widthOfOneCS - ); - const firstIndex = - dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) - ]; - const cursordata = data.peek()[0][firstIndex - dateIndex]; - let price = - yAxisRange.peek().minPrice + - ((chartCanvasSize.peek().height - y) * - (yAxisRange.peek().maxPrice - yAxisRange.peek().minPrice)) / - chartCanvasSize.peek().height; - if (price > yAxisRange.peek().maxPrice) { - price = yAxisRange.peek().maxPrice; - } else if (price < yAxisRange.peek().minPrice) { - price = yAxisRange.peek().minPrice; - } - const priceText = price.toFixed(2); - const lineStartPoint = { - xLabel: cursordata.Date, - yLabel: priceText, - }; + const lineStartPoint = getPointFromXY(state, x, y); if (prevLineData.peek() !== null) { switch (prevToolItemNo.peek()) { case 0: { @@ -837,13 +931,7 @@ export const setTrendLine = (e, state) => { case 9: { if (prevLineData.peek().length === 1) { const ctx = canvas.getContext("2d"); - ctx.font = "12px Arial"; - ctx.fillStyle = "White"; - ctx.strokeStyle = "blue"; - ctx.beginPath(); - ctx.arc(x, y, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.stroke(); + drawPoint(ctx, x, y); prevLineData.value = [...prevLineData.peek(), lineStartPoint]; prevToolItemNo.value = selectedToolItem.peek(); prevSelectedCanvas.value = canvas; @@ -893,13 +981,7 @@ export const setTrendLine = (e, state) => { } } else { const ctx = canvas.getContext("2d"); - ctx.font = "12px Arial"; - ctx.fillStyle = "White"; - ctx.strokeStyle = "blue"; - ctx.beginPath(); - ctx.arc(x, y, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.stroke(); + drawPoint(ctx, x, y); prevLineData.value = [lineStartPoint]; prevToolItemNo.value = selectedToolItem.peek(); prevSelectedCanvas.value = canvas; @@ -973,36 +1055,14 @@ export const setTrendLine = (e, state) => { }; export const setFibTool = (e, state) => { - const { chartCanvasSize, data, yAxisRange, ChartRef } = state; - const { dateConfig, xAxisConfig, timeRange, selectedTool, selectedToolItem } = + const { ChartRef } = state; + const { selectedToolItem } = state.ChartWindow; const canvas = ChartRef.current[1]; const rect = canvas.getBoundingClientRect(); const x = e.pageX - rect.left; const y = e.pageY - rect.top; - const dateIndex = Math.floor( - (chartCanvasSize.peek().width - x) / xAxisConfig.peek().widthOfOneCS - ); - const firstIndex = - dateConfig.peek().dateToIndex[ - getObjtoStringTime(timeRange.peek().startTime) - ]; - const cursordata = data.peek()[0][firstIndex - dateIndex]; - let price = - yAxisRange.peek().minPrice + - ((chartCanvasSize.peek().height - y) * - (yAxisRange.peek().maxPrice - yAxisRange.peek().minPrice)) / - chartCanvasSize.peek().height; - if (price > yAxisRange.peek().maxPrice) { - price = yAxisRange.peek().maxPrice; - } else if (price < yAxisRange.peek().minPrice) { - price = yAxisRange.peek().minPrice; - } - const priceText = price.toFixed(2); - const lineStartPoint = { - xLabel: cursordata.Date, - yLabel: priceText, - }; + const lineStartPoint = getPointFromXY(state, x, y); if (prevLineData.peek() !== null) { switch (prevToolItemNo.peek()) { case 0: { @@ -1012,13 +1072,7 @@ export const setFibTool = (e, state) => { case 1: { if (prevLineData.peek().length === 1) { const ctx = canvas.getContext("2d"); - ctx.font = "12px Arial"; - ctx.fillStyle = "White"; - ctx.strokeStyle = "blue"; - ctx.beginPath(); - ctx.arc(x, y, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.stroke(); + drawPoint(ctx, x, y); prevLineData.value = [...prevLineData.peek(), lineStartPoint]; prevToolItemNo.value = selectedToolItem.peek(); prevSelectedCanvas.value = canvas; @@ -1030,13 +1084,7 @@ export const setFibTool = (e, state) => { case 2: { if (prevLineData.peek().length === 1) { const ctx = canvas.getContext("2d"); - ctx.font = "12px Arial"; - ctx.fillStyle = "White"; - ctx.strokeStyle = "blue"; - ctx.beginPath(); - ctx.arc(x, y, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.stroke(); + drawPoint(ctx, x, y); prevLineData.value = [...prevLineData.peek(), lineStartPoint]; prevToolItemNo.value = selectedToolItem.peek(); prevSelectedCanvas.value = canvas; @@ -1052,13 +1100,7 @@ export const setFibTool = (e, state) => { case 4: { if (prevLineData.peek().length === 1) { const ctx = canvas.getContext("2d"); - ctx.font = "12px Arial"; - ctx.fillStyle = "White"; - ctx.strokeStyle = "blue"; - ctx.beginPath(); - ctx.arc(x, y, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.stroke(); + drawPoint(ctx, x, y); prevLineData.value = [...prevLineData.peek(), lineStartPoint]; prevToolItemNo.value = selectedToolItem.peek(); prevSelectedCanvas.value = canvas; @@ -1070,15 +1112,58 @@ export const setFibTool = (e, state) => { } } else { const ctx = canvas.getContext("2d"); - ctx.font = "12px Arial"; - ctx.fillStyle = "White"; - ctx.strokeStyle = "blue"; - ctx.beginPath(); - ctx.arc(x, y, 5, 0, 2 * Math.PI); - ctx.fill(); - ctx.stroke(); + drawPoint(ctx, x, y); prevLineData.value = [lineStartPoint]; prevToolItemNo.value = selectedToolItem.peek(); prevSelectedCanvas.value = canvas; } }; + +export const setProjectionTool = (e, state) => { + const { ChartRef } = state; + const { selectedTool, selectedToolItem } = + state.ChartWindow; + const canvas = ChartRef.current[1]; + const rect = canvas.getBoundingClientRect(); + const x = e.pageX - rect.left; + const y = e.pageY - rect.top; + const lineStartPoint1 = getPointFromXY(state, x, y); + const lineStartPoint2 = getPointFromXY(state, x, y - 150); + const lineStartPoint3 = getPointFromXY(state, x, y + 150); + const lineStartPoint4 = getPointFromXY(state, x + 125, y); + if (prevLineData.peek() !== null) { + switch (prevToolItemNo.peek()) { + case 0: { + setToolData(state, []); + break; + } + default: + return -1; + } + } else { + const ctx = canvas.getContext("2d"); + drawPoint(ctx, x, y); + prevLineData.value = [lineStartPoint1, lineStartPoint2, lineStartPoint3, lineStartPoint4]; + prevToolItemNo.value = selectedToolItem.peek(); + prevSelectedCanvas.value = canvas; + switch (prevToolItemNo.peek()) { + case 0: { + state.ChartWindow.drawChartObjects.peek().forEach((obj) => { + if (obj.ChartRef.current[1] === prevSelectedCanvas.peek()) { + obj.projectionData.value.push({ + points: [lineStartPoint1, lineStartPoint2, lineStartPoint3, lineStartPoint4], + toolItemNo: selectedToolItem.peek(), + }); + console.log(lineStartPoint1); + drawProjections(obj, true); + } + }); + prevLineData.value = null; + prevToolItemNo.value = null; + prevSelectedCanvas.value = null; + selectedTool.value = "Cursor"; + break; + } + } + } +};