From dce50aaffd71f667dc0ea7e4edd3fd088625abac Mon Sep 17 00:00:00 2001 From: Mark McDowell Date: Fri, 4 Oct 2019 14:20:49 +0100 Subject: [PATCH] fix(charts): arrowWidth was being ignored Setting arrowWidth now actually draws an arrow. Closes #75 --- package-lock.json | 7 +- .../src/coordinates/EdgeCoordinateV3.tsx | 21 ++++- .../charts/src/coordinates/EdgeIndicator.tsx | 18 ++--- .../src/coordinates/MouseCoordinateY.tsx | 17 ++-- .../src/features/coordinates/coordinates.tsx | 80 +++++++++++++++++++ .../features/coordinates/index.stories.tsx | 12 +++ 6 files changed, 133 insertions(+), 22 deletions(-) create mode 100644 packages/stories/src/features/coordinates/coordinates.tsx create mode 100644 packages/stories/src/features/coordinates/index.stories.tsx diff --git a/package-lock.json b/package-lock.json index faf9a5a3c..e9bffecdf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3035,8 +3035,9 @@ "d3-dsv": "^1.1.1", "d3-format": "^1.4.1", "d3-time-format": "^2.1.3", - "react": "^16.10.1", - "react-dom": "^16.10.1", + "react": "^16.10.2", + "react-dom": "^16.10.2", + "react-financial-charts": "file:packages/charts", "react-virtualized-auto-sizer": "^1.0.2" }, "dependencies": { @@ -14497,7 +14498,7 @@ "react-financial-charts": { "version": "file:packages/charts", "requires": { - "d3-array": "^2.3.1", + "d3-array": "^2.3.2", "d3-force": "^2.0.1", "d3-format": "^1.4.1", "d3-interpolate": "^1.3.2", diff --git a/packages/charts/src/coordinates/EdgeCoordinateV3.tsx b/packages/charts/src/coordinates/EdgeCoordinateV3.tsx index cb0e1dfe0..05cdf576f 100644 --- a/packages/charts/src/coordinates/EdgeCoordinateV3.tsx +++ b/packages/charts/src/coordinates/EdgeCoordinateV3.tsx @@ -224,6 +224,7 @@ export function drawOnCanvas(ctx: CanvasRenderingContext2D, props) { ctx.setLineDash([]); if (isDefined(edge.coordinateBase)) { const { + arrowWidth, rectWidth, rectHeight, rectRadius, @@ -241,12 +242,28 @@ export function drawOnCanvas(ctx: CanvasRenderingContext2D, props) { ctx.lineWidth = edge.coordinateBase.strokeWidth; } - const x = edge.coordinateBase.edgeXRect; + let x = edge.coordinateBase.edgeXRect; const y = edge.coordinateBase.edgeYRect; + const halfHeight = rectHeight / 2; ctx.beginPath(); - if (rectRadius) { + if (arrowWidth > 0 && edge.orient === "right") { + x -= arrowWidth; + ctx.moveTo(x, y + halfHeight); + ctx.lineTo(x + arrowWidth, y); + ctx.lineTo(x + rectWidth + arrowWidth, y); + ctx.lineTo(x + rectWidth + arrowWidth, y + rectHeight); + ctx.lineTo(x + arrowWidth, y + rectHeight); + ctx.closePath(); + } else if (arrowWidth > 0 && edge.orient === "left") { + ctx.moveTo(x, y); + ctx.lineTo(x + rectWidth, y); + ctx.lineTo(x + rectWidth + arrowWidth, y + halfHeight); + ctx.lineTo(x + rectWidth, y + rectHeight); + ctx.lineTo(x, y + rectHeight); + ctx.closePath(); + } else if (rectRadius) { roundRect(ctx, x, y, rectWidth, rectHeight, 3); } else { ctx.rect(x + 0.5, y + 0.5, rectWidth, rectHeight); diff --git a/packages/charts/src/coordinates/EdgeIndicator.tsx b/packages/charts/src/coordinates/EdgeIndicator.tsx index d1bd00957..572d57ffc 100644 --- a/packages/charts/src/coordinates/EdgeIndicator.tsx +++ b/packages/charts/src/coordinates/EdgeIndicator.tsx @@ -8,20 +8,20 @@ import { drawOnCanvas, renderSVG } from "./EdgeCoordinateV3"; import { first, functor, isDefined, last, noop, strokeDashTypes } from "../utils"; interface EdgeIndicatorProps { - readonly yAccessor?: any; // func - readonly type?: "horizontal"; + readonly arrowWidth?: number; readonly className?: string; + readonly displayFormat?: any; // func + readonly edgeAt?: "left" | "right"; readonly fill?: string | any; // func - readonly lineStroke?: string | any; // func - readonly textFill?: string | any; // func readonly itemType: "first" | "last"; + readonly lineStroke?: string | any; // func + readonly lineStrokeDasharray?: strokeDashTypes; readonly orient?: "left" | "right"; - readonly edgeAt?: "left" | "right"; - readonly displayFormat?: any; // func readonly rectHeight?: number; readonly rectWidth?: number; - readonly arrowWidth?: number; - readonly lineStrokeDasharray?: strokeDashTypes; + readonly textFill?: string | any; // func + readonly type?: "horizontal"; + readonly yAccessor?: any; // func } export class EdgeIndicator extends React.Component { @@ -36,7 +36,7 @@ export class EdgeIndicator extends React.Component { yAxisPad: 0, rectHeight: 20, rectWidth: 50, - arrowWidth: 10, + arrowWidth: 0, fontFamily: "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", fontSize: 13, dx: 0, diff --git a/packages/charts/src/coordinates/MouseCoordinateY.tsx b/packages/charts/src/coordinates/MouseCoordinateY.tsx index 10ef6060b..c94fc5a6b 100644 --- a/packages/charts/src/coordinates/MouseCoordinateY.tsx +++ b/packages/charts/src/coordinates/MouseCoordinateY.tsx @@ -8,30 +8,31 @@ import { drawOnCanvas, renderSVG } from "./EdgeCoordinateV3"; import { isNotDefined } from "../utils"; interface MouseCoordinateYProps { - readonly displayFormat: any; // func - readonly yAxisPad?: number; - readonly rectWidth?: number; - readonly rectHeight?: number; - readonly orient?: "bottom" | "top" | "left" | "right"; + readonly arrowWidth?: number; readonly at?: "bottom" | "top" | "left" | "right"; + readonly displayFormat: any; // func readonly dx?: number; - readonly fill?: string; - readonly opacity?: number; readonly fontFamily?: string; readonly fontSize?: number; + readonly fill?: string; + readonly opacity?: number; + readonly orient?: "bottom" | "top" | "left" | "right"; + readonly rectWidth?: number; + readonly rectHeight?: number; readonly textFill?: string; + readonly yAxisPad?: number; } export class MouseCoordinateY extends React.Component { public static defaultProps = { + arrowWidth: 0, yAxisPad: 0, rectWidth: 50, rectHeight: 20, orient: "right", at: "right", dx: 0, - arrowWidth: 10, fill: "#37474F", opacity: 1, fontFamily: "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", diff --git a/packages/stories/src/features/coordinates/coordinates.tsx b/packages/stories/src/features/coordinates/coordinates.tsx new file mode 100644 index 000000000..ae78d171a --- /dev/null +++ b/packages/stories/src/features/coordinates/coordinates.tsx @@ -0,0 +1,80 @@ +import { format } from "d3-format"; +import * as React from "react"; +import { Chart, ChartCanvas } from "react-financial-charts"; +import { XAxis, YAxis } from "react-financial-charts/lib/axes"; +import { MouseCoordinateY } from "react-financial-charts/lib/coordinates"; +import { discontinuousTimeScaleProviderBuilder } from "react-financial-charts/lib/scale"; +import { CandlestickSeries } from "react-financial-charts/lib/series"; +import { withDeviceRatio } from "react-financial-charts/lib/utils"; +import { IOHLCData, withOHLCData, withSize } from "../../data"; + +interface ChartProps { + readonly arrowWidth?: number; + readonly data: IOHLCData[]; + readonly height: number; + readonly ratio: number; + readonly width: number; +} + +class Coordinates extends React.Component { + + private readonly margin = { left: 0, right: 48, top: 0, bottom: 24 }; + private readonly xScaleProvider = discontinuousTimeScaleProviderBuilder() + .inputDateAccessor((d: IOHLCData) => d.date); + private readonly pricesDisplayFormat = format(".2f"); + + public render() { + + const { + arrowWidth, + data: initialData, + height, + ratio, + width, + } = this.props; + + const { margin, xScaleProvider } = this; + + const { + data, + xScale, + xAccessor, + displayXAccessor, + } = xScaleProvider(initialData); + + const start = xAccessor(data[data.length - 1]); + const end = xAccessor(data[Math.max(0, data.length - 100)]); + const xExtents = [start, end]; + + return ( + + + + + + + + + ); + } + + private readonly yExtents = (data: IOHLCData) => { + return [data.high, data.low]; + } +} + +export default withOHLCData()(withSize()(withDeviceRatio()(Coordinates))); diff --git a/packages/stories/src/features/coordinates/index.stories.tsx b/packages/stories/src/features/coordinates/index.stories.tsx new file mode 100644 index 000000000..0cbd57f8e --- /dev/null +++ b/packages/stories/src/features/coordinates/index.stories.tsx @@ -0,0 +1,12 @@ +import * as React from "react"; +import { MouseCoordinateY } from "react-financial-charts/lib/coordinates"; +import Coordinates from "./coordinates"; + +export default { + component: MouseCoordinateY, + title: "Features|Coordinates", +}; + +export const edge = () => ; + +export const arrows = () => ;