UNPKG

@react-financial-charts/interactive

Version:
220 lines 6.99 kB
import { getStrokeDasharrayCanvas, getMouseCanvas, GenericChartComponent, noop, } from "@react-financial-charts/core"; import * as React from "react"; export class InteractiveStraightLine extends React.Component { constructor() { super(...arguments); this.isHover = (moreProps) => { const { tolerance, onHover } = this.props; if (onHover !== undefined) { const { x1Value, x2Value, y1Value, y2Value, type } = this.props; const { mouseXY, xScale } = moreProps; const { chartConfig: { yScale }, } = moreProps; const hovering = isHovering({ x1Value, y1Value, x2Value, y2Value, mouseXY, type, tolerance, xScale, yScale, }); return hovering; } return false; }; this.drawOnCanvas = (ctx, moreProps) => { const { strokeWidth = InteractiveStraightLine.defaultProps.strokeWidth, strokeDasharray, strokeStyle, } = this.props; const { x1, y1, x2, y2 } = helper(this.props, moreProps); ctx.lineWidth = strokeWidth; ctx.strokeStyle = strokeStyle; const lineDash = getStrokeDasharrayCanvas(strokeDasharray); ctx.setLineDash(lineDash); ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); }; } render() { const { selected, interactiveCursorClass } = this.props; const { onDragStart, onDrag, onDragComplete, onHover, onUnHover } = this.props; return (React.createElement(GenericChartComponent, { isHover: this.isHover, canvasToDraw: getMouseCanvas, canvasDraw: this.drawOnCanvas, interactiveCursorClass: interactiveCursorClass, selected: selected, onDragStart: onDragStart, onDrag: onDrag, onDragComplete: onDragComplete, onHover: onHover, onUnHover: onUnHover, drawOn: ["mousemove", "pan", "drag"] })); } } InteractiveStraightLine.defaultProps = { onEdge1Drag: noop, onEdge2Drag: noop, edgeStrokeWidth: 3, edgeStroke: "#000000", edgeFill: "#FFFFFF", r: 10, withEdge: false, strokeWidth: 1, strokeDasharray: "Solid", children: noop, tolerance: 7, selected: false, }; export function isHovering2(start, end, [mouseX, mouseY], tolerance) { const m = getSlope(start, end); if (m !== undefined) { const b = getYIntercept(m, end); const y = m * mouseX + b; return (mouseY < y + tolerance && mouseY > y - tolerance && mouseX > Math.min(start[0], end[0]) - tolerance && mouseX < Math.max(start[0], end[0]) + tolerance); } else { return (mouseY >= Math.min(start[1], end[1]) && mouseY <= Math.max(start[1], end[1]) && mouseX < start[0] + tolerance && mouseX > start[0] - tolerance); } } export function isHovering({ x1Value, y1Value, x2Value, y2Value, mouseXY, type, tolerance, xScale, yScale }) { const line = generateLine({ type, start: [x1Value, y1Value], end: [x2Value, y2Value], xScale, yScale, }); const start = [xScale(line.x1), yScale(line.y1)]; const end = [xScale(line.x2), yScale(line.y2)]; const m = getSlope(start, end); const [mouseX, mouseY] = mouseXY; if (m !== undefined) { const b = getYIntercept(m, end); const y = m * mouseX + b; return (mouseY < y + tolerance && mouseY > y - tolerance && mouseX > Math.min(start[0], end[0]) - tolerance && mouseX < Math.max(start[0], end[0]) + tolerance); } else { return (mouseY >= Math.min(start[1], end[1]) && mouseY <= Math.max(start[1], end[1]) && mouseX < start[0] + tolerance && mouseX > start[0] - tolerance); } } function helper(props, moreProps) { const { x1Value, x2Value, y1Value, y2Value, type } = props; const { xScale, chartConfig: { yScale }, } = moreProps; const modLine = generateLine({ type, start: [x1Value, y1Value], end: [x2Value, y2Value], xScale, yScale, }); const x1 = xScale(modLine.x1); const y1 = yScale(modLine.y1); const x2 = xScale(modLine.x2); const y2 = yScale(modLine.y2); return { x1, y1, x2, y2, }; } export function getSlope(start, end) { const m /* slope */ = end[0] === start[0] ? undefined : (end[1] - start[1]) / (end[0] - start[0]); return m; } export function getYIntercept(m, end) { const b /* y intercept */ = -1 * m * end[0] + end[1]; return b; } export function generateLine({ type, start, end, xScale, yScale }) { const m /* slope */ = getSlope(start, end); const b /* y intercept */ = getYIntercept(m, start); switch (type) { case "XLINE": return getXLineCoordinates({ start, end, xScale, yScale, m, b, }); case "RAY": return getRayCoordinates({ start, end, xScale, yScale, m, b, }); default: case "LINE": return getLineCoordinates({ start, end, }); } } function getXLineCoordinates({ start, end, xScale, yScale, m, b }) { const [xBegin, xFinish] = xScale.domain(); const [yBegin, yFinish] = yScale.domain(); if (end[0] === start[0]) { return { x1: end[0], y1: yBegin, x2: end[0], y2: yFinish, }; } const [x1, x2] = end[0] > start[0] ? [xBegin, xFinish] : [xFinish, xBegin]; return { x1, y1: m * x1 + b, x2, y2: m * x2 + b, }; } function getRayCoordinates({ start, end, xScale, yScale, m, b }) { const [xBegin, xFinish] = xScale.domain(); const [yBegin, yFinish] = yScale.domain(); const x1 = start[0]; if (end[0] === start[0]) { return { x1, y1: start[1], x2: x1, y2: end[1] > start[1] ? yFinish : yBegin, }; } const x2 = end[0] > start[0] ? xFinish : xBegin; return { x1, y1: m * x1 + b, x2, y2: m * x2 + b, }; } function getLineCoordinates({ start, end }) { const [x1, y1] = start; const [x2, y2] = end; if (end[0] === start[0]) { return { x1, y1: start[1], x2: x1, y2: end[1], }; } return { x1, y1, x2, y2, }; } //# sourceMappingURL=InteractiveStraightLine.js.map