UNPKG

react-financial-charts

Version:
122 lines 5.92 kB
import { line as d3Line } from "d3-shape"; import * as React from "react"; import GenericChartComponent from "../GenericChartComponent"; import { getAxisCanvas, getMouseCanvas } from "../GenericComponent"; import { colorToRGBA, getClosestItemIndexes, getStrokeDasharray, getStrokeDasharrayCanvas, isDefined, } from "../utils"; export class LineSeries extends React.Component { constructor() { super(...arguments); this.renderSVG = (moreProps) => { const { yAccessor, stroke, strokeOpacity, strokeWidth, hoverStrokeWidth, defined, strokeDasharray } = this.props; const { connectNulls } = this.props; const { interpolation, style } = this.props; const { xAccessor, chartConfig } = moreProps; const { xScale, plotData, hovering } = moreProps; const { yScale } = chartConfig; const dataSeries = d3Line() .x((d) => Math.round(xScale(xAccessor(d)))) .y((d) => Math.round(yScale(yAccessor(d)))); if (isDefined(interpolation)) { dataSeries.curve(interpolation); } if (!connectNulls) { dataSeries.defined((d) => defined(yAccessor(d))); } const data = dataSeries(plotData); if (data === null) { return null; } const { fill, className } = this.props; return (React.createElement("path", { style: style, className: `${className} ${stroke ? "" : " line-stroke"}`, d: data, stroke: stroke, strokeOpacity: strokeOpacity, strokeWidth: hovering ? hoverStrokeWidth : strokeWidth, strokeDasharray: getStrokeDasharray(strokeDasharray), fill: fill })); }; this.drawOnCanvas = (ctx, moreProps) => { const { yAccessor, stroke = LineSeries.defaultProps.stroke, strokeOpacity, strokeWidth = LineSeries.defaultProps.strokeWidth, hoverStrokeWidth = LineSeries.defaultProps.hoverStrokeWidth, defined, strokeDasharray, interpolation, canvasClip, } = this.props; const { connectNulls } = this.props; const { xAccessor } = moreProps; const { xScale, chartConfig: { yScale }, plotData, hovering } = moreProps; if (canvasClip) { ctx.save(); canvasClip(ctx, moreProps); } ctx.lineWidth = hovering ? hoverStrokeWidth : strokeWidth; ctx.strokeStyle = colorToRGBA(stroke, strokeOpacity); const lineDash = getStrokeDasharrayCanvas(strokeDasharray); ctx.setLineDash(lineDash); const dataSeries = d3Line() .x((d) => Math.round(xScale(xAccessor(d)))) .y((d) => Math.round(yScale(yAccessor(d)))); if (isDefined(interpolation)) { dataSeries.curve(interpolation); } if (!connectNulls) { dataSeries.defined((d) => defined(yAccessor(d))); } ctx.beginPath(); dataSeries.context(ctx)(plotData); ctx.stroke(); if (canvasClip) { ctx.restore(); } }; this.isHover = (moreProps) => { const { highlightOnHover, yAccessor, hoverTolerance = LineSeries.defaultProps.hoverTolerance } = this.props; if (!highlightOnHover) { return false; } const { mouseXY, currentItem, xScale, plotData } = moreProps; const { chartConfig: { yScale, origin } } = moreProps; const { xAccessor } = moreProps; const [x, y] = mouseXY; const radius = hoverTolerance; const { left, right } = getClosestItemIndexes(plotData, xScale.invert(x), xAccessor); if (left === right) { const cy = yScale(yAccessor(currentItem)) + origin[1]; const cx = xScale(xAccessor(currentItem)) + origin[0]; const hovering1 = Math.pow(x - cx, 2) + Math.pow(y - cy, 2) < Math.pow(radius, 2); return hovering1; } else { const l = plotData[left]; const r = plotData[right]; const x1 = xScale(xAccessor(l)) + origin[0]; const y1 = yScale(yAccessor(l)) + origin[1]; const x2 = xScale(xAccessor(r)) + origin[0]; const y2 = yScale(yAccessor(r)) + origin[1]; // y = m * x + b const m /* slope */ = (y2 - y1) / (x2 - x1); const b /* y intercept */ = -1 * m * x1 + y1; const desiredY = Math.round(m * x + b); const hovering2 = y >= desiredY - radius && y <= desiredY + radius; return hovering2; } }; } render() { const { highlightOnHover, onHover, onUnHover } = this.props; const hoverProps = (highlightOnHover || onHover || onUnHover) ? { isHover: this.isHover, drawOn: ["mousemove", "pan"], canvasToDraw: getMouseCanvas, } : { drawOn: ["pan"], canvasToDraw: getAxisCanvas, }; return (React.createElement(GenericChartComponent, Object.assign({ svgDraw: this.renderSVG, canvasDraw: this.drawOnCanvas, onClickWhenHover: this.props.onClick, onDoubleClickWhenHover: this.props.onDoubleClick, onContextMenuWhenHover: this.props.onContextMenu, onHover: this.props.onHover, onUnHover: this.props.onUnHover }, hoverProps))); } } LineSeries.defaultProps = { className: "line", strokeWidth: 1, strokeOpacity: 1, hoverStrokeWidth: 4, fill: "none", stroke: "#2196f3", strokeDasharray: "Solid", defined: (d) => !isNaN(d), hoverTolerance: 6, highlightOnHover: false, connectNulls: false, }; //# sourceMappingURL=LineSeries.js.map