diff --git a/.eslintrc.yaml b/.eslintrc.yaml index 233b7e786..e8671a93d 100644 --- a/.eslintrc.yaml +++ b/.eslintrc.yaml @@ -5,32 +5,34 @@ parserOptions: ecmaFeatures: jsx: true plugins: - - "@typescript-eslint" + - "@typescript-eslint" extends: - - "eslint:recommended" - - "plugin:react/recommended" - - "plugin:@typescript-eslint/eslint-recommended" - - "plugin:@typescript-eslint/recommended" - - "prettier/@typescript-eslint" - - "plugin:prettier/recommended" - - "plugin:jest/recommended" + - "eslint:recommended" + - "plugin:react/recommended" + - "plugin:@typescript-eslint/eslint-recommended" + - "plugin:@typescript-eslint/recommended" + - "prettier/@typescript-eslint" + - "plugin:prettier/recommended" + - "plugin:jest/recommended" rules: - "@typescript-eslint/explicit-module-boundary-types": off - "@typescript-eslint/interface-name-prefix": off - "@typescript-eslint/no-non-null-assertion": off - "@typescript-eslint/ban-ts-comment": off - "@typescript-eslint/ban-types": off - "@typescript-eslint/no-unused-vars": + "@typescript-eslint/explicit-member-accessibility": error + "@typescript-eslint/explicit-module-boundary-types": off + "@typescript-eslint/interface-name-prefix": off + "@typescript-eslint/no-non-null-assertion": off + "@typescript-eslint/ban-ts-comment": off + "@typescript-eslint/ban-types": off + "@typescript-eslint/no-explicit-any": off + "@typescript-eslint/no-unused-vars": - error - ignoreRestSiblings: true - "react/display-name": off - "react/prop-types": off - "arrow-spacing": error - "curly": error - "no-duplicate-imports": error - "no-multiple-empty-lines": error - "no-var": error - "prefer-rest-params": 0 + "react/display-name": off + "react/prop-types": off + "arrow-spacing": error + "curly": error + "no-duplicate-imports": error + "no-multiple-empty-lines": error + "no-var": error + "prefer-rest-params": 0 settings: react: version: detect diff --git a/README.md b/README.md index c3d019478..14454f795 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The aim with this project is create financial charts that work out of the box. ## Features - integrates multiple chart types -- over 60 technical indicators and overlays +- technical indicators and overlays - drawing objects ### Chart types diff --git a/package-lock.json b/package-lock.json index 838c0e5bf..06113744d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5487,6 +5487,21 @@ "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", "dev": true }, + "@types/lodash": { + "version": "4.14.159", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.159.tgz", + "integrity": "sha512-gF7A72f7WQN33DpqOWw9geApQPh4M3PxluMtaHxWHXEGSN12/WbcEk/eNSqWNQcQhF66VSZ06vCF94CrHwXJDg==", + "dev": true + }, + "@types/lodash.flattendeep": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/@types/lodash.flattendeep/-/lodash.flattendeep-4.4.6.tgz", + "integrity": "sha512-uLm2MaRVlqJSGsMK0RZpP5T3KqReq+9WbYDHCUhBhp98v56hMG/Yht52bsoTSui9xz2mUvQ9NfG3LrNGDL92Ng==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, "@types/markdown-to-jsx": { "version": "6.11.1", "resolved": "https://registry.npmjs.org/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.1.tgz", diff --git a/package.json b/package.json index 7e1088dbf..645312c1a 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,7 @@ "@types/d3-shape": "^1.3.2", "@types/d3-time-format": "^2.1.1", "@types/jest": "^26.0.10", + "@types/lodash.flattendeep": "^4.4.6", "@types/react": "^16.9.46", "@types/react-dom": "^16.9.8", "@types/react-virtualized-auto-sizer": "^1.0.0", diff --git a/packages/annotations/src/BarAnnotation.tsx b/packages/annotations/src/BarAnnotation.tsx index ca968f9a5..bc6eac711 100644 --- a/packages/annotations/src/BarAnnotation.tsx +++ b/packages/annotations/src/BarAnnotation.tsx @@ -4,7 +4,7 @@ import * as React from "react"; export interface BarAnnotationProps { readonly className?: string; - readonly path?: any; // func + readonly path?: ({ x, y }: { x: number; y: number }) => string; readonly onClick?: ( e: React.MouseEvent, data: { @@ -13,13 +13,14 @@ export interface BarAnnotationProps { datum: any; }, ) => void; - readonly xAccessor?: any; // func + readonly xAccessor?: (datum: any) => any; readonly xScale?: ScaleContinuousNumeric; readonly yScale?: ScaleContinuousNumeric; readonly datum?: object; readonly stroke?: string; - readonly fill?: string; + readonly fill?: string | ((datum: any) => string); readonly opacity?: number; + readonly plotData: any[]; readonly text?: string; readonly textAnchor?: string; readonly fontFamily?: string; @@ -37,6 +38,31 @@ export interface BarAnnotationProps { readonly textIconXOffset?: number; readonly textIconYOffset?: number; readonly textIconAnchor?: string; + readonly tooltip?: string | ((datum: any) => string); + readonly x?: + | number + | (({ + xScale, + xAccessor, + datum, + plotData, + }: { + xScale: ScaleContinuousNumeric; + xAccessor: (datum: any) => any; + datum: any; + plotData: any[]; + }) => number); + readonly y?: + | number + | (({ + yScale, + datum, + plotData, + }: { + yScale: ScaleContinuousNumeric; + datum: any; + plotData: any[]; + }) => number); } export class BarAnnotation extends React.Component { @@ -44,20 +70,33 @@ export class BarAnnotation extends React.Component { className: "react-financial-charts-bar-annotation", opacity: 1, fill: "#000000", - textAnchor: "middle", fontFamily: "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", fontSize: 10, + textAnchor: "middle", textFill: "#000000", textOpacity: 1, textIconFill: "#000000", textIconFontSize: 10, - x: ({ xScale, xAccessor, datum }) => xScale(xAccessor(datum)), + x: ({ + xScale, + xAccessor, + datum, + }: { + xScale: ScaleContinuousNumeric; + xAccessor: any; + datum: any; + }) => xScale(xAccessor(datum)), }; public render() { - const { className, stroke, opacity } = this.props; - const { xAccessor, xScale, yScale, path } = this.props; const { + className, + stroke, + opacity, + xAccessor, + xScale, + yScale, + path, text, textXOffset, textYOffset, @@ -67,11 +106,6 @@ export class BarAnnotation extends React.Component { textFill, textOpacity, textRotate, - } = this.props; - - const { x, y, fill, tooltip } = this.helper(this.props, xAccessor, xScale, yScale); - - const { textIcon, textIconFontSize, textIconFill, @@ -81,10 +115,12 @@ export class BarAnnotation extends React.Component { textIconYOffset, } = this.props; + const { x, y, fill, tooltip } = this.helper(this.props, xAccessor, xScale, yScale); + return ( - {tooltip != null ? {tooltip} : null} - {text != null ? ( + {tooltip !== undefined ? {tooltip} : null} + {text !== undefined ? ( { fontSize={fontSize} fill={textFill} opacity={textOpacity} - transform={textRotate != null ? `rotate(${textRotate}, ${x}, ${y})` : undefined} + transform={textRotate != undefined ? `rotate(${textRotate}, ${x}, ${y})` : undefined} textAnchor={textAnchor} > {text} ) : null} - {textIcon != null ? ( + {textIcon !== undefined ? ( { fontSize={textIconFontSize} fill={textIconFill} opacity={textIconOpacity} - transform={textIconRotate != null ? `rotate(${textIconRotate}, ${x}, ${y})` : undefined} + transform={textIconRotate != undefined ? `rotate(${textIconRotate}, ${x}, ${y})` : undefined} textAnchor={textAnchor} > {textIcon} ) : null} - {path != null ? : null} + {path !== undefined ? : null} ); } @@ -127,7 +163,7 @@ export class BarAnnotation extends React.Component { } }; - private readonly helper = (props, xAccessor, xScale, yScale) => { + private readonly helper = (props: BarAnnotationProps, xAccessor: any, xScale: any, yScale: any) => { const { x, y, datum, fill, tooltip, plotData } = props; const xFunc = functor(x); diff --git a/packages/annotations/src/Label.tsx b/packages/annotations/src/Label.tsx index 5d3db7248..c63ee2a7f 100644 --- a/packages/annotations/src/Label.tsx +++ b/packages/annotations/src/Label.tsx @@ -33,8 +33,8 @@ export class Label extends React.Component { fontWeight: "bold", fillStyle: "#dcdcdc", rotate: 0, - x: ({ xScale, xAccessor, datum }) => xScale(xAccessor(datum)), - selectCanvas: (canvases) => canvases.bg, + x: ({ xScale, xAccessor, datum }: any) => xScale(xAccessor(datum)), + selectCanvas: (canvases: any) => canvases.bg, }; public static contextTypes = { @@ -50,7 +50,7 @@ export class Label extends React.Component { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { ctx.save(); const { textAlign = "center", fontFamily, fontSize, fontWeight, rotate } = this.props; @@ -96,8 +96,8 @@ export class Label extends React.Component { }; private readonly helper = ( - moreProps, - xAccessor, + moreProps: any, + xAccessor: any, xScale: ScaleContinuousNumeric, yScale: ScaleContinuousNumeric, ) => { diff --git a/packages/annotations/src/LabelAnnotation.tsx b/packages/annotations/src/LabelAnnotation.tsx index a5a27a2a7..7d45ba1d6 100644 --- a/packages/annotations/src/LabelAnnotation.tsx +++ b/packages/annotations/src/LabelAnnotation.tsx @@ -22,11 +22,33 @@ export interface LabelAnnotationProps { readonly text?: string | ((datum: any) => string); readonly textAnchor?: string; readonly tooltip?: string | ((datum: any) => string); - readonly xAccessor?: any; // func + readonly xAccessor?: (datum: any) => any; readonly xScale?: ScaleContinuousNumeric; - readonly x?: number | any; // func + readonly x?: + | number + | (({ + xScale, + xAccessor, + datum, + plotData, + }: { + xScale: ScaleContinuousNumeric; + xAccessor: (datum: any) => any; + datum: any; + plotData: any[]; + }) => number); readonly yScale?: ScaleContinuousNumeric; - readonly y?: number | any; // func + readonly y?: + | number + | (({ + yScale, + datum, + plotData, + }: { + yScale: ScaleContinuousNumeric; + datum: any; + plotData: any[]; + }) => number); } export class LabelAnnotation extends React.Component { @@ -38,7 +60,15 @@ export class LabelAnnotation extends React.Component { fill: "#000000", opacity: 1, rotate: 0, - x: ({ xScale, xAccessor, datum }) => xScale(xAccessor(datum)), + x: ({ + xScale, + xAccessor, + datum, + }: { + xScale: ScaleContinuousNumeric; + xAccessor: any; + datum: any; + }) => xScale(xAccessor(datum)), }; public render() { diff --git a/packages/annotations/src/SvgPathAnnotation.tsx b/packages/annotations/src/SvgPathAnnotation.tsx index 5acd7445a..6f7051e41 100644 --- a/packages/annotations/src/SvgPathAnnotation.tsx +++ b/packages/annotations/src/SvgPathAnnotation.tsx @@ -15,14 +15,36 @@ export interface SvgPathAnnotationProps { }, ) => void; readonly opacity?: number; - readonly path: any; // func + readonly path: ({ x, y }: { x: number; y: number }) => string; readonly plotData: any[]; readonly stroke?: string; readonly tooltip?: string | ((datum: any) => string); - readonly xAccessor?: any; // func - readonly x?: number | any; // func + readonly xAccessor?: (datum: any) => any; + readonly x?: + | number + | (({ + xScale, + xAccessor, + datum, + plotData, + }: { + xScale: ScaleContinuousNumeric; + xAccessor: (datum: any) => any; + datum: any; + plotData: any[]; + }) => number); readonly xScale?: ScaleContinuousNumeric; - readonly y?: number | any; // func + readonly y?: + | number + | (({ + yScale, + datum, + plotData, + }: { + yScale: ScaleContinuousNumeric; + datum: any; + plotData: any[]; + }) => number); readonly yScale?: ScaleContinuousNumeric; } @@ -30,7 +52,15 @@ export class SvgPathAnnotation extends React.Component { public static defaultProps = { className: "react-financial-charts-svg-path-annotation", opacity: 1, - x: ({ xScale, xAccessor, datum }) => xScale(xAccessor(datum)), + x: ({ + xScale, + xAccessor, + datum, + }: { + xScale: ScaleContinuousNumeric; + xAccessor: any; + datum: any; + }) => xScale(xAccessor(datum)), }; public render() { diff --git a/packages/annotations/src/index.ts b/packages/annotations/src/index.ts index 700a8a9c0..ba14c02d2 100644 --- a/packages/annotations/src/index.ts +++ b/packages/annotations/src/index.ts @@ -1,4 +1,5 @@ export * from "./Annotate"; -export { LabelAnnotation } from "./LabelAnnotation"; +export * from "./BarAnnotation"; +export * from "./LabelAnnotation"; export * from "./SvgPathAnnotation"; export * from "./Label"; diff --git a/packages/annotations/tsconfig.json b/packages/annotations/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/annotations/tsconfig.json +++ b/packages/annotations/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/axes/src/Axis.tsx b/packages/axes/src/Axis.tsx index 4ba3550f1..f194490f0 100644 --- a/packages/axes/src/Axis.tsx +++ b/packages/axes/src/Axis.tsx @@ -222,6 +222,7 @@ const tickHelper = (props: AxisProps, scale: ScaleContinuousNumeric { const a: any = d[0]; const b: any = d[1]; @@ -277,7 +278,7 @@ const tickHelper = (props: AxisProps, scale: ScaleContinuousNumeric { +const drawAxisLine = (ctx: CanvasRenderingContext2D, props: AxisProps, range: any) => { const { orient, outerTickSize, strokeStyle, strokeWidth } = props; const sign = orient === "top" || orient === "left" ? -1 : 1; @@ -306,7 +307,7 @@ const drawAxisLine = (ctx: CanvasRenderingContext2D, props: AxisProps, range) => ctx.stroke(); }; -const drawTicks = (ctx: CanvasRenderingContext2D, result, moreProps) => { +const drawTicks = (ctx: CanvasRenderingContext2D, result: any, moreProps: any) => { const { showGridLines, tickStrokeStyle, tickLabelFill } = result; const { textAnchor, fontSize, fontFamily, fontWeight, ticks, showTickLabel } = result; @@ -315,12 +316,12 @@ const drawTicks = (ctx: CanvasRenderingContext2D, result, moreProps) => { ctx.fillStyle = tickStrokeStyle; } - ticks.forEach((tick) => { + ticks.forEach((tick: any) => { drawEachTick(ctx, tick, result); }); if (showGridLines) { - ticks.forEach((tick) => { + ticks.forEach((tick: any) => { drawGridLine(ctx, tick, result, moreProps); }); } @@ -330,13 +331,13 @@ const drawTicks = (ctx: CanvasRenderingContext2D, result, moreProps) => { ctx.textAlign = textAnchor === "middle" ? "center" : textAnchor; if (showTickLabel) { - ticks.forEach((tick) => { + ticks.forEach((tick: any) => { drawEachTickLabel(ctx, tick, result); }); } }; -const drawGridLine = (ctx: CanvasRenderingContext2D, tick, result, moreProps) => { +const drawGridLine = (ctx: CanvasRenderingContext2D, tick: any, result: any, moreProps: any) => { const { orient, gridLinesStrokeWidth, gridLinesStrokeStyle, gridLinesStrokeDasharray } = result; const { chartConfig } = moreProps; @@ -369,7 +370,7 @@ const drawGridLine = (ctx: CanvasRenderingContext2D, tick, result, moreProps) => ctx.stroke(); }; -const drawEachTick = (ctx: CanvasRenderingContext2D, tick, result) => { +const drawEachTick = (ctx: CanvasRenderingContext2D, tick: any, result: any) => { const { tickStrokeWidth, tickStrokeDasharray } = result; ctx.beginPath(); @@ -384,7 +385,7 @@ const drawEachTick = (ctx: CanvasRenderingContext2D, tick, result) => { ctx.stroke(); }; -const drawEachTickLabel = (ctx: CanvasRenderingContext2D, tick, result) => { +const drawEachTickLabel = (ctx: CanvasRenderingContext2D, tick: any, result: any) => { const { canvas_dy, format } = result; const text = format(tick.value); diff --git a/packages/axes/src/XAxis.tsx b/packages/axes/src/XAxis.tsx index 18f710457..8f040165e 100644 --- a/packages/axes/src/XAxis.tsx +++ b/packages/axes/src/XAxis.tsx @@ -154,7 +154,7 @@ export class XAxis extends React.Component { return 8; }; - private readonly getXScale = (moreProps) => { + private readonly getXScale = (moreProps: any) => { const { xScale: scale, width } = moreProps; if (scale.invert) { diff --git a/packages/axes/src/YAxis.tsx b/packages/axes/src/YAxis.tsx index 471da3cf6..e1026992c 100644 --- a/packages/axes/src/YAxis.tsx +++ b/packages/axes/src/YAxis.tsx @@ -47,7 +47,7 @@ export class YAxis extends React.Component { fontFamily: "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", fontSize: 12, fontWeight: 400, - getMouseDelta: (startXY, mouseXY) => startXY[1] - mouseXY[1], + getMouseDelta: (startXY: [number, number], mouseXY: [number, number]) => startXY[1] - mouseXY[1], gridLinesStrokeStyle: "#E2E4EC", gridLinesStrokeWidth: 1, innerTickSize: 4, @@ -154,7 +154,7 @@ export class YAxis extends React.Component { return 8; }; - private readonly getYScale = (moreProps) => { + private readonly getYScale = (moreProps: any) => { const { yScale: scale, flipYScale, height } = moreProps.chartConfig; if (scale.invert) { const trueRange = flipYScale ? [0, height] : [height, 0]; diff --git a/packages/axes/tsconfig.json b/packages/axes/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/axes/tsconfig.json +++ b/packages/axes/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/charts/tsconfig.json b/packages/charts/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/charts/tsconfig.json +++ b/packages/charts/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/coordinates/src/CrossHairCursor.tsx b/packages/coordinates/src/CrossHairCursor.tsx index 8518ca5e0..2ff018dc3 100644 --- a/packages/coordinates/src/CrossHairCursor.tsx +++ b/packages/coordinates/src/CrossHairCursor.tsx @@ -7,7 +7,7 @@ import { getMouseCanvas, } from "@react-financial-charts/core"; -const defaultCustomX = (props: CrossHairCursorProps, moreProps) => { +const defaultCustomX = (props: CrossHairCursorProps, moreProps: any) => { const { xScale, xAccessor, currentItem, mouseXY } = moreProps; const { snapX } = props; const x = snapX ? Math.round(xScale(xAccessor(currentItem))) : mouseXY[0]; @@ -47,7 +47,7 @@ export class CrossHairCursor extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const lines = this.getLines(this.props, moreProps); if (lines === undefined) { return; @@ -78,7 +78,7 @@ export class CrossHairCursor extends React.Component { ctx.restore(); }; - private readonly getLines = (props: CrossHairCursorProps, moreProps) => { + private readonly getLines = (props: CrossHairCursorProps, moreProps: any) => { const { mouseXY, currentItem, show, height, width } = moreProps; const { diff --git a/packages/coordinates/src/CurrentCoordinate.tsx b/packages/coordinates/src/CurrentCoordinate.tsx index 09daaaf29..c68aa1a19 100644 --- a/packages/coordinates/src/CurrentCoordinate.tsx +++ b/packages/coordinates/src/CurrentCoordinate.tsx @@ -47,7 +47,7 @@ export class CurrentCoordinate extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const circle = this.getCircle(moreProps); if (circle === undefined) { return; @@ -73,7 +73,7 @@ export class CurrentCoordinate extends React.Component { } }; - private readonly getCircle = (moreProps) => { + private readonly getCircle = (moreProps: any) => { const { show, xScale, diff --git a/packages/coordinates/src/Cursor.tsx b/packages/coordinates/src/Cursor.tsx index 034088841..e324362b2 100644 --- a/packages/coordinates/src/Cursor.tsx +++ b/packages/coordinates/src/Cursor.tsx @@ -29,7 +29,7 @@ export interface CursorProps { readonly xCursorShapeStrokeDasharray?: strokeDashTypes; } -const defaultCustomSnapX = (props: CursorProps, moreProps) => { +const defaultCustomSnapX = (props: CursorProps, moreProps: any) => { const { xScale, xAccessor, currentItem, mouseXY } = moreProps; const { snapX } = props; const x = snapX ? Math.round(xScale(xAccessor(currentItem))) : mouseXY[0]; @@ -63,7 +63,7 @@ export class Cursor extends React.Component { ); } - private getXCursorShapeStroke({ currentItem }): string | CanvasGradient | CanvasPattern | undefined { + private getXCursorShapeStroke({ currentItem }: any): string | CanvasGradient | CanvasPattern | undefined { const { xCursorShapeStrokeStyle } = this.props; return xCursorShapeStrokeStyle instanceof Function @@ -71,13 +71,13 @@ export class Cursor extends React.Component { : xCursorShapeStrokeStyle; } - private getXCursorShapeFill({ currentItem }): string | CanvasGradient | CanvasPattern | undefined { + private getXCursorShapeFill({ currentItem }: any): string | CanvasGradient | CanvasPattern | undefined { const { xCursorShapeFillStyle } = this.props; return xCursorShapeFillStyle instanceof Function ? xCursorShapeFillStyle(currentItem) : xCursorShapeFillStyle; } - private getXCursorShape(moreProps /* , ctx */) { + private getXCursorShape(moreProps: any) { const { height, xScale, currentItem, plotData } = moreProps; const { xAccessor } = moreProps; const xValue = xAccessor(currentItem); @@ -89,7 +89,7 @@ export class Cursor extends React.Component { return { height, xPos, shapeWidth }; } - private getXYCursor(props: CursorProps, moreProps) { + private getXYCursor(props: CursorProps, moreProps: any) { const { mouseXY, currentItem, show, height, width } = moreProps; const { customX = Cursor.defaultProps.customX, strokeStyle, strokeDasharray, disableYCursor } = props; @@ -123,7 +123,7 @@ export class Cursor extends React.Component { return disableYCursor ? [xCursor] : [yCursor, xCursor]; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const cursors = this.getXYCursor(this.props, moreProps); if (cursors === undefined) { return; diff --git a/packages/coordinates/src/EdgeCoordinate.tsx b/packages/coordinates/src/EdgeCoordinate.tsx index 5797aa949..762b58abf 100644 --- a/packages/coordinates/src/EdgeCoordinate.tsx +++ b/packages/coordinates/src/EdgeCoordinate.tsx @@ -1,7 +1,7 @@ import * as React from "react"; import { colorToRGBA, isDefined } from "@react-financial-charts/core"; -const helper = (props) => { +const helper = (props: any) => { const { coordinate: displayCoordinate, show, type, orient, edgeAt, hideLine } = props; const { fill, opacity, fontFamily, fontSize, textFill, lineStroke, lineOpacity, arrowWidth } = props; const { rectWidth, rectHeight } = props; @@ -102,7 +102,7 @@ export class EdgeCoordinate extends React.Component { arrowWidth: 10, }; - public static drawOnCanvasStatic = (ctx: CanvasRenderingContext2D, props) => { + public static drawOnCanvasStatic = (ctx: CanvasRenderingContext2D, props: any) => { props = { ...EdgeCoordinate.defaultProps, ...props }; const edge = helper(props); @@ -111,7 +111,7 @@ export class EdgeCoordinate extends React.Component { return; } - if (isDefined(edge.coordinateBase)) { + if (edge.coordinate !== undefined && edge.coordinateBase !== undefined) { const { rectWidth, rectHeight, arrowWidth } = edge.coordinateBase; ctx.fillStyle = colorToRGBA(edge.coordinateBase.fill, edge.coordinateBase.opacity); @@ -142,7 +142,8 @@ export class EdgeCoordinate extends React.Component { ctx.font = `${edge.coordinate.fontSize}px ${edge.coordinate.fontFamily}`; ctx.fillStyle = edge.coordinate.textFill; - ctx.textAlign = edge.coordinate.textAnchor === "middle" ? "center" : edge.coordinate.textAnchor; + ctx.textAlign = + edge.coordinate.textAnchor === "middle" ? "center" : (edge.coordinate.textAnchor as CanvasTextAlign); ctx.textBaseline = "middle"; ctx.fillText(edge.coordinate.displayCoordinate, edge.coordinate.edgeXText, edge.coordinate.edgeYText); @@ -183,7 +184,7 @@ export class EdgeCoordinate extends React.Component { ); } - if (isDefined(edge.coordinateBase)) { + if (edge.coordinate !== undefined && edge.coordinateBase !== undefined) { const { rectWidth, rectHeight, arrowWidth } = edge.coordinateBase; const path = diff --git a/packages/coordinates/src/EdgeCoordinateV2.tsx b/packages/coordinates/src/EdgeCoordinateV2.tsx index 8acc01969..5da8273d3 100644 --- a/packages/coordinates/src/EdgeCoordinateV2.tsx +++ b/packages/coordinates/src/EdgeCoordinateV2.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { colorToRGBA, isDefined } from "@react-financial-charts/core"; -export function renderSVG(props) { +export function renderSVG(props: any) { const { className } = props; const edge = helper(props); @@ -27,7 +27,7 @@ export function renderSVG(props) { ); } - if (isDefined(edge.coordinateBase)) { + if (edge.coordinate !== undefined && edge.coordinateBase !== undefined) { const { rectWidth, rectHeight, arrowWidth } = edge.coordinateBase; const path = @@ -87,7 +87,7 @@ export function renderSVG(props) { ); } -function helper(props) { +function helper(props: any) { const { coordinate: displayCoordinate, show, type, orient, edgeAt, hideLine } = props; const { fill, opacity, fontFamily, fontSize, textFill, lineStroke, lineOpacity, arrowWidth } = props; const { rectWidth, rectHeight } = props; @@ -156,14 +156,14 @@ function helper(props) { }; } -export function drawOnCanvas(ctx: CanvasRenderingContext2D, props) { +export function drawOnCanvas(ctx: CanvasRenderingContext2D, props: any) { const edge = helper(props); if (edge === null) { return; } - if (isDefined(edge.coordinateBase)) { + if (edge.coordinate !== undefined && edge.coordinateBase !== undefined) { const { rectWidth, rectHeight, arrowWidth } = edge.coordinateBase; ctx.fillStyle = colorToRGBA(edge.coordinateBase.fill, edge.coordinateBase.opacity); @@ -194,7 +194,8 @@ export function drawOnCanvas(ctx: CanvasRenderingContext2D, props) { ctx.font = `${edge.coordinate.fontSize}px ${edge.coordinate.fontFamily}`; ctx.fillStyle = edge.coordinate.textFill; - ctx.textAlign = edge.coordinate.textAnchor === "middle" ? "center" : edge.coordinate.textAnchor; + ctx.textAlign = + edge.coordinate.textAnchor === "middle" ? "center" : (edge.coordinate.textAnchor as CanvasTextAlign); ctx.textBaseline = "middle"; ctx.fillText(edge.coordinate.displayCoordinate, edge.coordinate.edgeXText, edge.coordinate.edgeYText); diff --git a/packages/coordinates/src/EdgeCoordinateV3.tsx b/packages/coordinates/src/EdgeCoordinateV3.tsx index 0426cadf1..94cbbe7e0 100644 --- a/packages/coordinates/src/EdgeCoordinateV3.tsx +++ b/packages/coordinates/src/EdgeCoordinateV3.tsx @@ -2,7 +2,7 @@ import * as React from "react"; import { colorToRGBA, getStrokeDasharray, getStrokeDasharrayCanvas, isDefined } from "@react-financial-charts/core"; -export const renderSVG = (props) => { +export const renderSVG = (props: any) => { const { className } = props; const edge = helper(props); @@ -27,7 +27,7 @@ export const renderSVG = (props) => { /> ); } - if (isDefined(edge.coordinateBase)) { + if (edge.coordinate !== undefined && edge.coordinateBase !== undefined) { const { rectWidth, rectHeight, arrowWidth } = edge.coordinateBase; const path = @@ -90,7 +90,7 @@ export const renderSVG = (props) => { ); }; -const helper = (props) => { +const helper = (props: any) => { const { coordinate: displayCoordinate, show, @@ -126,9 +126,8 @@ const helper = (props) => { let coordinateBase; let coordinate; - if (isDefined(displayCoordinate)) { + if (displayCoordinate !== undefined) { const textAnchor = "middle"; - // TODO: Below it is necessary to implement logic for the possibility of alignment from the right or from the left. let edgeXRect; let edgeYRect; @@ -192,7 +191,7 @@ const helper = (props) => { }; }; -export const drawOnCanvas = (ctx: CanvasRenderingContext2D, props) => { +export const drawOnCanvas = (ctx: CanvasRenderingContext2D, props: any) => { const { coordinate, fitToText, fontSize, fontFamily, rectWidth } = props; ctx.font = `${fontSize}px ${fontFamily}`; @@ -220,7 +219,8 @@ export const drawOnCanvas = (ctx: CanvasRenderingContext2D, props) => { } ctx.setLineDash([]); - if (isDefined(edge.coordinateBase)) { + + if (edge.coordinateBase !== undefined) { const { arrowWidth, rectWidth, rectHeight, rectRadius } = edge.coordinateBase; ctx.fillStyle = colorToRGBA(edge.coordinateBase.fill, edge.coordinateBase.opacity); @@ -258,13 +258,16 @@ export const drawOnCanvas = (ctx: CanvasRenderingContext2D, props) => { ctx.fill(); - if (isDefined(edge.coordinateBase.stroke)) { + if (edge.coordinateBase.stroke !== undefined) { ctx.stroke(); } - ctx.fillStyle = edge.coordinate.textFill; - ctx.textAlign = edge.coordinate.textAnchor === "middle" ? "center" : edge.coordinate.textAnchor; - ctx.fillText(edge.coordinate.displayCoordinate, edge.coordinate.edgeXText, edge.coordinate.edgeYText); + if (edge.coordinate !== undefined) { + ctx.fillStyle = edge.coordinate.textFill; + ctx.textAlign = + edge.coordinate.textAnchor === "middle" ? "center" : (edge.coordinate.textAnchor as CanvasTextAlign); + ctx.fillText(edge.coordinate.displayCoordinate, edge.coordinate.edgeXText, edge.coordinate.edgeYText); + } } }; diff --git a/packages/coordinates/src/EdgeIndicator.tsx b/packages/coordinates/src/EdgeIndicator.tsx index 164bda022..86c6493de 100644 --- a/packages/coordinates/src/EdgeIndicator.tsx +++ b/packages/coordinates/src/EdgeIndicator.tsx @@ -16,17 +16,22 @@ export interface EdgeIndicatorProps { readonly arrowWidth?: number; readonly displayFormat?: (n: number) => string; readonly edgeAt?: "left" | "right"; - readonly fill?: string | any; // func + readonly fill?: string | ((datum: any) => string); readonly fitToText?: boolean; + readonly fontFamily?: string; + readonly fontSize?: number; + readonly fullWidth?: boolean; readonly itemType: "first" | "last"; - readonly lineStroke?: string | any; // func + readonly lineStroke?: string | ((datum: any) => string); readonly lineStrokeDasharray?: strokeDashTypes; readonly orient?: "left" | "right"; readonly rectHeight?: number; readonly rectWidth?: number; - readonly textFill?: string | any; // func + readonly stroke?: string | ((datum: any) => string); + readonly textFill?: string | ((datum: any) => string); readonly type?: "horizontal"; readonly yAccessor?: any; // func + readonly yAxisPad?: number; } export class EdgeIndicator extends React.Component { @@ -67,8 +72,12 @@ export class EdgeIndicator extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const edge = this.helper(this.props, moreProps); + if (edge === null) { + return; + } + const props = { ...this.props, ...edge, @@ -77,7 +86,7 @@ export class EdgeIndicator extends React.Component { drawOnCanvas(ctx, props); }; - private readonly helper = (props, moreProps) => { + private readonly helper = (props: EdgeIndicatorProps, moreProps: any) => { const { itemType, yAccessor } = props; const { plotData } = moreProps; @@ -88,12 +97,19 @@ export class EdgeIndicator extends React.Component { return edge; }; - private readonly getEdge = (props, moreProps, item) => { - const { type: edgeType, displayFormat, edgeAt, yAxisPad, orient, lineStroke } = props; + private readonly getEdge = (props: EdgeIndicatorProps, moreProps: any, item: any) => { + const { + fontFamily, + fontSize, + type: edgeType, + displayFormat = EdgeIndicator.defaultProps.displayFormat, + edgeAt, + yAxisPad = EdgeIndicator.defaultProps.yAxisPad, + orient, + lineStroke, + } = props; - const { yAccessor, fill, textFill, rectHeight, rectWidth, arrowWidth } = props; - const { fontFamily, fontSize } = props; - const { stroke } = props; + const { yAccessor, fill, fullWidth, textFill, rectHeight, rectWidth, arrowWidth, stroke } = props; const { xScale, @@ -105,7 +121,7 @@ export class EdgeIndicator extends React.Component { const yValue = yAccessor(item); const xValue = xAccessor(item); - const x1 = Math.round(xScale(xValue)); + const x1 = fullWidth ? 0 : Math.round(xScale(xValue)); const y1 = Math.round(yScale(yValue)); const [left, right] = [0, width]; diff --git a/packages/coordinates/src/MouseCoordinateX.tsx b/packages/coordinates/src/MouseCoordinateX.tsx index f9ba4f347..7a9ed9eb3 100644 --- a/packages/coordinates/src/MouseCoordinateX.tsx +++ b/packages/coordinates/src/MouseCoordinateX.tsx @@ -1,5 +1,4 @@ import * as React from "react"; - import { isNotDefined, getMouseCanvas, GenericChartComponent } from "@react-financial-charts/core"; import { drawOnCanvas } from "./EdgeCoordinateV3"; @@ -24,7 +23,7 @@ export interface MouseCoordinateXProps { readonly yAxisPad?: number; } -const defaultCustomX = (props: MouseCoordinateXProps, moreProps) => { +const defaultCustomX = (props: MouseCoordinateXProps, moreProps: any) => { const { xScale, xAccessor, currentItem, mouseXY } = moreProps; const { snapX } = props; const x = snapX ? xScale(xAccessor(currentItem)) : mouseXY[0]; @@ -65,16 +64,16 @@ export class MouseCoordinateX extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const props = this.helper(this.props, moreProps); - if (isNotDefined(props)) { + if (props === null) { return; } drawOnCanvas(ctx, props); }; - private readonly helper = (props: MouseCoordinateXProps, moreProps) => { + private readonly helper = (props: MouseCoordinateXProps, moreProps: any) => { const { show, currentItem, diff --git a/packages/coordinates/src/MouseCoordinateXV2.tsx b/packages/coordinates/src/MouseCoordinateXV2.tsx index 5d5d80bf1..202ec90b9 100644 --- a/packages/coordinates/src/MouseCoordinateXV2.tsx +++ b/packages/coordinates/src/MouseCoordinateXV2.tsx @@ -2,18 +2,7 @@ import * as React from "react"; import { getMouseCanvas, GenericChartComponent } from "@react-financial-charts/core"; interface MouseCoordinateXV2Props { - readonly xPosition?: any; // func - readonly drawCoordinate?: any; // func - readonly displayFormat: any; // func readonly at?: "bottom" | "top"; - readonly orient?: "bottom" | "top"; - readonly text?: { - readonly fontStyle: string; - readonly fontWeight: string; - readonly fontFamily: string; - readonly fontSize: number; - readonly fill: string | any; // func - }; readonly bg: { readonly fill: string | any; // func readonly stroke: string; @@ -25,8 +14,19 @@ interface MouseCoordinateXV2Props { bottom: number; }; }; + readonly drawCoordinate?: any; // func + readonly displayFormat: any; // func readonly dx?: number; readonly dy?: number; + readonly orient?: "bottom" | "top"; + readonly text?: { + readonly fontStyle: string; + readonly fontWeight: string; + readonly fontFamily: string; + readonly fontSize: number; + readonly fill: string | any; // func + }; + readonly xPosition?: any; // func } export class MouseCoordinateXV2 extends React.Component { @@ -68,7 +68,7 @@ export class MouseCoordinateXV2 extends React.Component ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { show, currentItem } = moreProps; const { drawCoordinate } = this.props; @@ -79,12 +79,13 @@ export class MouseCoordinateXV2 extends React.Component }; } -function defaultXPosition(props, moreProps) { +function defaultXPosition(props: MouseCoordinateXV2Props, moreProps: any) { const { currentItem, xAccessor } = moreProps; + return xAccessor(currentItem); } -function getXCoordinateInfo(ctx: CanvasRenderingContext2D, props, moreProps) { +function getXCoordinateInfo(ctx: CanvasRenderingContext2D, props: any, moreProps: any) { const { xPosition } = props; const xValue = xPosition(props, moreProps); const { at, displayFormat } = props; @@ -109,7 +110,7 @@ function getXCoordinateInfo(ctx: CanvasRenderingContext2D, props, moreProps) { }; } -function defaultDrawCoordinate(ctx: CanvasRenderingContext2D, shape, props, moreProps) { +function defaultDrawCoordinate(ctx: CanvasRenderingContext2D, shape: any, props: any, moreProps: any) { const { x, y, textWidth, text } = shape; const { orient, dx, dy } = props; diff --git a/packages/coordinates/src/MouseCoordinateY.tsx b/packages/coordinates/src/MouseCoordinateY.tsx index 55e049818..1fd108742 100644 --- a/packages/coordinates/src/MouseCoordinateY.tsx +++ b/packages/coordinates/src/MouseCoordinateY.tsx @@ -5,7 +5,7 @@ import { drawOnCanvas } from "./EdgeCoordinateV3"; export interface MouseCoordinateYProps { readonly arrowWidth?: number; readonly at?: "left" | "right"; - readonly displayFormat: any; // func + readonly displayFormat: (value: number) => string; readonly dx?: number; readonly fontFamily?: string; readonly fontSize?: number; @@ -15,6 +15,7 @@ export interface MouseCoordinateYProps { readonly orient?: "left" | "right"; readonly rectWidth?: number; readonly rectHeight?: number; + readonly stroke?: string; readonly strokeOpacity?: number; readonly strokeWidth?: number; readonly textFill?: string; @@ -51,34 +52,38 @@ export class MouseCoordinateY extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const props = this.helper(this.props, moreProps); - if (isNotDefined(props)) { + if (props === undefined) { return; } drawOnCanvas(ctx, props); }; - private readonly helper = (props: MouseCoordinateYProps, moreProps) => { - const { chartId, currentCharts, mouseXY, show } = moreProps; + private readonly helper = (props: MouseCoordinateYProps, moreProps: any) => { + const { + chartConfig: { yScale }, + chartId, + currentCharts, + mouseXY, + show, + } = moreProps; if (!show) { - return null; + return undefined; } if (isNotDefined(mouseXY)) { - return null; + return undefined; } if (currentCharts.indexOf(chartId) < 0) { - return null; + return undefined; } const y = mouseXY[1]; - const { - chartConfig: { yScale }, - } = moreProps; + const { displayFormat } = props; const coordinate = displayFormat(yScale.invert(y)); @@ -87,12 +92,11 @@ export class MouseCoordinateY extends React.Component { }; } -export function getYCoordinate(y, displayValue, props, moreProps) { +export function getYCoordinate(y: number, coordinate: string, props: any, moreProps: any) { const { width } = moreProps; - const { orient, at, rectWidth, rectHeight, dx } = props; + const { orient, at, rectWidth, rectHeight, dx, stroke, strokeOpacity, strokeWidth } = props; const { fill, opacity, fitToText, fontFamily, fontSize, textFill, arrowWidth } = props; - const { stroke, strokeOpacity, strokeWidth } = props; const x1 = 0; const x2 = width; @@ -102,7 +106,7 @@ export function getYCoordinate(y, displayValue, props, moreProps) { const hideLine = true; const coordinateProps = { - coordinate: displayValue, + coordinate, show: true, fitToText, type, diff --git a/packages/coordinates/src/PriceCoordinate.tsx b/packages/coordinates/src/PriceCoordinate.tsx index cb6719dd4..1affaa8be 100644 --- a/packages/coordinates/src/PriceCoordinate.tsx +++ b/packages/coordinates/src/PriceCoordinate.tsx @@ -60,12 +60,13 @@ export class PriceCoordinate extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const props = this.helper(this.props, moreProps); + drawOnCanvas(ctx, props); }; - private readonly helper = (props: PriceCoordinateProps, moreProps) => { + private readonly helper = (props: PriceCoordinateProps, moreProps: any) => { const { chartConfig: { yScale }, width, diff --git a/packages/coordinates/tsconfig.json b/packages/coordinates/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/coordinates/tsconfig.json +++ b/packages/coordinates/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/core/src/Chart.tsx b/packages/core/src/Chart.tsx index c2102790e..49d91b0b7 100644 --- a/packages/core/src/Chart.tsx +++ b/packages/core/src/Chart.tsx @@ -60,7 +60,7 @@ export class Chart extends PureComponent { public getChildContext() { const { id: chartId } = this.props; - const chartConfig = this.context.chartConfig.find((each) => each.id === chartId); + const chartConfig = this.context.chartConfig.find(({ id }: any) => id === chartId); return { chartId, @@ -69,14 +69,14 @@ export class Chart extends PureComponent { } public render() { - const { origin } = this.context.chartConfig.find((each) => each.id === this.props.id); + const { origin } = this.context.chartConfig.find(({ id }: any) => id === this.props.id); const [x, y] = origin; return {this.props.children}; } - private readonly listener = (type: string, moreProps, state, e) => { + private readonly listener = (type: string, moreProps: any, _: any, e: React.MouseEvent) => { const { id, onContextMenu, onDoubleClick } = this.props; switch (type) { diff --git a/packages/core/src/ChartCanvas.tsx b/packages/core/src/ChartCanvas.tsx index a060368cf..c2581746e 100644 --- a/packages/core/src/ChartCanvas.tsx +++ b/packages/core/src/ChartCanvas.tsx @@ -16,7 +16,7 @@ import evaluator from "./utils/evaluator"; const CANDIDATES_FOR_RESET = ["seriesName"]; -function shouldResetChart(thisProps, nextProps) { +function shouldResetChart(thisProps: any, nextProps: any) { return !CANDIDATES_FOR_RESET.every((key) => { const result = shallowEqual(thisProps[key], nextProps[key]); return result; @@ -67,18 +67,18 @@ function getCursorStyle() { return ; } -function getDimensions(props) { +function getDimensions(props: any) { return { height: props.height - props.margin.top - props.margin.bottom, width: props.width - props.margin.left - props.margin.right, }; } -function getXScaleDirection(flipXScale) { +function getXScaleDirection(flipXScale: any) { return flipXScale ? -1 : 1; } -function calculateFullData(props) { +function calculateFullData(props: any) { const { data: fullData, plotFull, xScale, clamp, pointsPerPxThreshold, flipXScale } = props; const { xAccessor, displayXAccessor, minPointsPerPxThreshold } = props; @@ -102,7 +102,7 @@ function calculateFullData(props) { }; } -const resetChart = (props) => { +const resetChart = (props: any) => { const state = calculateState(props); const { xAccessor, displayXAccessor, fullData, plotData: initialPlotData, xScale } = state; const { postCalculator, children } = props; @@ -125,7 +125,13 @@ const resetChart = (props) => { }; }; -function updateChart(newState, initialXScale, props, lastItemWasVisible, initialChartConfig) { +function updateChart( + newState: any, + initialXScale: any, + props: any, + lastItemWasVisible: boolean, + initialChartConfig: any, +) { const { fullData, xScale, xAccessor, displayXAccessor, filterData } = newState; const lastItem = last(fullData); @@ -163,7 +169,7 @@ function updateChart(newState, initialXScale, props, lastItemWasVisible, initial const dx = initialXScale(xAccessor(lastItem)) - initialXScale.range()[1]; const [newStart, newEnd] = initialXScale .range() - .map((x) => x + dx) + .map((x: number) => x + dx) .map(initialXScale.invert); const response = filterData(fullData, [newStart, newEnd], xAccessor, updatedXScale); @@ -189,7 +195,7 @@ function updateChart(newState, initialXScale, props, lastItemWasVisible, initial }; } -function calculateState(props) { +function calculateState(props: any) { const { xAccessor: inputXAccesor, xExtents: xExtentsProp, data, padding, flipXScale } = props; const direction = getXScaleDirection(flipXScale); @@ -199,7 +205,7 @@ function calculateState(props) { const extent = typeof xExtentsProp === "function" ? xExtentsProp(data) - : d3Extent(xExtentsProp.map((d) => functor(d)).map((each) => each(data, inputXAccesor))); + : d3Extent(xExtentsProp.map((d: any) => functor(d)).map((each: any) => each(data, inputXAccesor))); const { xAccessor, displayXAccessor, xScale, fullData, filterData } = calculateFullData(props); @@ -217,7 +223,7 @@ function calculateState(props) { }; } -function setXRange(xScale, dimensions, padding, direction = 1) { +function setXRange(xScale: any, dimensions: any, padding: any, direction = 1) { if (xScale.rangeRoundPoints) { if (isNaN(padding)) { throw new Error("padding has to be a number for ordinal scale"); @@ -240,7 +246,7 @@ function setXRange(xScale, dimensions, padding, direction = 1) { return xScale; } -function pinchCoordinates(pinch) { +function pinchCoordinates(pinch: any) { const { touch1Pos, touch2Pos } = pinch; return { @@ -249,7 +255,7 @@ function pinchCoordinates(pinch) { }; } -function isInteractionEnabled(xScale, xAccessor, data) { +function isInteractionEnabled(xScale: any, xAccessor: any, data: any) { const interaction = !isNaN(xScale(xAccessor(head(data)))) && isDefined(xScale.invert); return interaction; } @@ -328,7 +334,7 @@ export class ChartCanvas extends React.Component number, xExtents: [min, max] as any[], zIndex: 1, zoomAnchor: mouseBasedZoomAnchor, @@ -393,11 +399,11 @@ export class ChartCanvas extends React.Component { + public subscribe = (id: string, rest: any) => { const { getPanConditions = functor({ draggable: false, @@ -475,13 +481,13 @@ export class ChartCanvas extends React.Component { + public amIOnTop = (id: string) => { const dragableComponents = this.subscriptions.filter((each) => each.getPanConditions().draggable); return dragableComponents.length > 0 && last(dragableComponents).id === id; }; - public handleContextMenu = (mouseXY, e) => { + public handleContextMenu = (mouseXY: any, e: any) => { const { xAccessor, chartConfig, plotData, xScale } = this.state; const currentCharts = getCurrentCharts(chartConfig, mouseXY); @@ -498,7 +504,7 @@ export class ChartCanvas extends React.Component { + public calculateStateForDomain = (newDomain: any) => { const { xAccessor, displayXAccessor, @@ -533,7 +539,7 @@ export class ChartCanvas extends React.Component { + public pinchZoomHelper = (initialPinch: any, finalPinch: any) => { const { xScale: initialPinchXScale } = initialPinch; const { @@ -595,7 +601,7 @@ export class ChartCanvas extends React.Component { + public handlePinchZoom = (initialPinch: any, finalPinch: any, e: any) => { if (!this.waitingForPinchZoomAnimationFrame) { this.waitingForPinchZoomAnimationFrame = true; const state = this.pinchZoomHelper(initialPinch, finalPinch); @@ -612,7 +618,7 @@ export class ChartCanvas extends React.Component { + public handlePinchZoomEnd = (initialPinch: any, e: any) => { const { xAccessor = ChartCanvas.defaultProps.xAccessor } = this.state; if (this.finalPinch) { @@ -641,7 +647,7 @@ export class ChartCanvas extends React.Component { + public handleZoom = (zoomDirection: any, mouseXY: any, e: any) => { if (this.panInProgress) { return; } @@ -716,7 +722,7 @@ export class ChartCanvas extends React.Component { + public xAxisZoom = (newDomain: any) => { const { xScale, plotData, chartConfig } = this.calculateStateForDomain(newDomain); this.clearThreeCanvas(); @@ -743,10 +749,10 @@ export class ChartCanvas extends React.Component { + public yAxisZoom = (chartId: string, newDomain: any) => { this.clearThreeCanvas(); const { chartConfig: initialChartConfig } = this.state; - const chartConfig = initialChartConfig.map((each) => { + const chartConfig = initialChartConfig.map((each: any) => { if (each.id === chartId) { const { yScale } = each; return { @@ -764,7 +770,7 @@ export class ChartCanvas extends React.Component { const state = { ...this.state, @@ -775,7 +781,7 @@ export class ChartCanvas extends React.Component { + public draw = (props: any) => { this.subscriptions.forEach((each) => { if (isDefined(each.draw)) { each.draw(props); @@ -928,7 +934,7 @@ export class ChartCanvas extends React.Component { + public handleMouseMove = (mouseXY: number[], _: string, e: any) => { if (!this.waitingForMouseMoveAnimationFrame) { this.waitingForMouseMoveAnimationFrame = true; @@ -963,13 +969,13 @@ export class ChartCanvas extends React.Component { + public handleMouseLeave = (e: any) => { this.triggerEvent("mouseleave", { show: false }, e); this.clearMouseCanvas(); this.draw({ trigger: "mouseleave" }); }; - public handleDragStart = ({ startPos }, e) => { + public handleDragStart = ({ startPos }: any, e: any) => { this.triggerEvent("dragstart", { startPos }, e); }; @@ -1049,7 +1055,7 @@ export class ChartCanvas extends React.Component { const { chartConfig } = this.state; let changed = false; - const newChartConfig = chartConfig.map((each) => { + const newChartConfig = chartConfig.map((each: any) => { if ( (isNotDefined(chartId) || each.id === chartId) && !shallowEqual(each.yScale.domain(), each.realYDomain) @@ -1170,7 +1176,7 @@ export class ChartCanvas extends React.Component - {chartConfig.map((each, idx) => ( + {chartConfig.map((each: any, idx: number) => ( diff --git a/packages/core/src/EventCapture.tsx b/packages/core/src/EventCapture.tsx index ee3a84756..03288eca7 100644 --- a/packages/core/src/EventCapture.tsx +++ b/packages/core/src/EventCapture.tsx @@ -114,14 +114,14 @@ export class EventCapture extends React.Component(); - constructor(props: EventCaptureProps) { + public constructor(props: EventCaptureProps) { super(props); this.focus = props.focus; @@ -139,6 +139,7 @@ export class EventCapture extends React.Component { + public handleLeave = (e: React.MouseEvent) => { const { onMouseLeave } = this.props; if (onMouseLeave === undefined) { return; @@ -518,7 +519,9 @@ export class EventCapture extends React.Component { + public setCursorClass = (cursorOverrideClass: string) => { if (cursorOverrideClass !== this.state.cursorOverrideClass) { this.setState({ cursorOverrideClass, diff --git a/packages/core/src/GenericChartComponent.tsx b/packages/core/src/GenericChartComponent.tsx index da436b106..3b1de5214 100644 --- a/packages/core/src/GenericChartComponent.tsx +++ b/packages/core/src/GenericChartComponent.tsx @@ -32,7 +32,7 @@ export class GenericChartComponent extends GenericComponent { ratio: PropTypes.number.isRequired, }; - public constructor(props, context) { + public constructor(props: any, context: any) { super(props, context); this.preCanvasDraw = this.preCanvasDraw.bind(this); @@ -42,7 +42,7 @@ export class GenericChartComponent extends GenericComponent { this.updateMoreProps = this.updateMoreProps.bind(this); } - public preCanvasDraw(ctx: CanvasRenderingContext2D, moreProps) { + public preCanvasDraw(ctx: CanvasRenderingContext2D, moreProps: any) { super.preCanvasDraw(ctx, moreProps); ctx.save(); @@ -74,12 +74,12 @@ export class GenericChartComponent extends GenericComponent { } } - public postCanvasDraw(ctx: CanvasRenderingContext2D, moreProps) { + public postCanvasDraw(ctx: CanvasRenderingContext2D, moreProps: any) { super.postCanvasDraw(ctx, moreProps); ctx.restore(); } - public updateMoreProps(moreProps) { + public updateMoreProps(moreProps: any) { super.updateMoreProps(moreProps); const { chartConfig: chartConfigList } = moreProps; @@ -111,7 +111,7 @@ export class GenericChartComponent extends GenericComponent { /// } - public shouldTypeProceed(type, moreProps) { + public shouldTypeProceed(type: string, moreProps: any) { if ((type === "mousemove" || type === "click") && this.props.disablePan) { return true; } diff --git a/packages/core/src/GenericComponent.tsx b/packages/core/src/GenericComponent.tsx index 4d83dd209..5f63b2646 100644 --- a/packages/core/src/GenericComponent.tsx +++ b/packages/core/src/GenericComponent.tsx @@ -27,23 +27,23 @@ interface GenericComponentProps { readonly enableDragOnHover?: boolean; readonly interactiveCursorClass?: string; readonly canvasToDraw?: (contexts: ICanvasContexts) => CanvasRenderingContext2D | undefined; - readonly isHover?: (moreProps, e: React.MouseEvent) => boolean; - readonly onClick?: (e: React.MouseEvent, moreProps) => void; - readonly onClickWhenHover?: (e: React.MouseEvent, moreProps) => void; - readonly onClickOutside?: (e: React.MouseEvent, moreProps) => void; - readonly onPan?: (e: React.MouseEvent, moreProps) => void; - readonly onPanEnd?: (e: React.MouseEvent, moreProps) => void; - readonly onDragStart?: (e: React.MouseEvent, moreProps) => void; - readonly onDrag?: (e: React.MouseEvent, moreProps) => void; - readonly onDragComplete?: (e: React.MouseEvent, moreProps) => void; - readonly onDoubleClick?: (e: React.MouseEvent, moreProps) => void; - readonly onDoubleClickWhenHover?: (e: React.MouseEvent, moreProps) => void; - readonly onContextMenu?: (e: React.MouseEvent, moreProps) => void; - readonly onContextMenuWhenHover?: (e: React.MouseEvent, moreProps) => void; - readonly onMouseMove?: (e: React.MouseEvent, moreProps) => void; - readonly onMouseDown?: (e: React.MouseEvent, moreProps) => void; - readonly onHover?: (e: React.MouseEvent, moreProps) => void; - readonly onUnHover?: (e: React.MouseEvent, moreProps) => void; + readonly isHover?: (moreProps: any, e: React.MouseEvent) => boolean; + readonly onClick?: (e: React.MouseEvent, moreProps: any) => void; + readonly onClickWhenHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onClickOutside?: (e: React.MouseEvent, moreProps: any) => void; + readonly onPan?: (e: React.MouseEvent, moreProps: any) => void; + readonly onPanEnd?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDoubleClick?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDoubleClickWhenHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onContextMenu?: (e: React.MouseEvent, moreProps: any) => void; + readonly onContextMenuWhenHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onMouseMove?: (e: React.MouseEvent, moreProps: any) => void; + readonly onMouseDown?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly selected?: boolean; } @@ -91,7 +91,7 @@ export class GenericComponent extends React.Component { this.moreProps[key] = moreProps[key]; }); } - public shouldTypeProceed(type, moreProps) { + public shouldTypeProceed(type: string, moreProps: any) { return true; } - public preEvaluate(type, moreProps, e) { + public preEvaluate(type: string, moreProps: any, e: any) { /// empty } - public listener = (type, moreProps, state, e) => { + public listener = (type: string, moreProps: any, state: any, e: any) => { if (moreProps !== undefined) { this.updateMoreProps(moreProps); } @@ -137,7 +137,8 @@ export class GenericComponent extends React.Component -1; if (!proceed) { @@ -291,7 +292,7 @@ export class GenericComponent extends React.Component -1; @@ -352,7 +354,7 @@ export class GenericComponent extends React.Component }, + moreProps: { xScale: ScaleContinuousNumeric | ScaleTime; plotData: any[] }, ): number => { const { widthRatio } = props; const { xScale } = moreProps; @@ -20,12 +20,18 @@ export const plotDataLengthBarWidth = ( const totalWidth = Math.abs(r - l); if (xScale.invert != null) { const [dl, dr] = xScale.domain(); - const width = totalWidth / Math.abs(dl - dr); - return width * widthRatio; - } else { - const width = totalWidth / xScale.domain().length; - return width * widthRatio; + if (typeof dl === "number" && typeof dr === "number") { + const width = totalWidth / Math.abs(dl - dr); + + return width * widthRatio; + } + + return 1; } + + const width = totalWidth / xScale.domain().length; + + return width * widthRatio; }; /** @@ -33,7 +39,7 @@ export const plotDataLengthBarWidth = ( * @param interval a d3-time time interval. * @return {Function} the width function. */ -export const timeIntervalBarWidth = (interval) => { +export const timeIntervalBarWidth = (interval: any) => { return function ( props: { widthRatio: number }, moreProps: { xScale: ScaleContinuousNumeric; xAccessor: any; plotData: any[] }, diff --git a/packages/core/src/utils/colors.ts b/packages/core/src/utils/colors.ts index 4c7bd806e..f3b5be472 100644 --- a/packages/core/src/utils/colors.ts +++ b/packages/core/src/utils/colors.ts @@ -29,6 +29,7 @@ const presetToRGB = (inputPreset: string, opacity: number) => { throw new Error(`preset color does not exist: ${inputPreset}`); } + // @ts-ignore const color = colorPresets[lowercasePreset]; return hexToRGBA(color, opacity); diff --git a/packages/core/src/utils/evaluator.ts b/packages/core/src/utils/evaluator.ts index 4aceaf1bf..b6673f93b 100644 --- a/packages/core/src/utils/evaluator.ts +++ b/packages/core/src/utils/evaluator.ts @@ -2,7 +2,7 @@ import { getClosestItemIndexes, getLogger, head, isDefined, isNotDefined, last } const log = getLogger("evaluator"); -function getNewEnd(fallbackEnd, xAccessor, initialXScale, start) { +function getNewEnd(fallbackEnd: any, xAccessor: any, initialXScale: any, start: any) { const { lastItem, lastItemX } = fallbackEnd; const lastItemXValue = xAccessor(lastItem); const [rangeStart, rangeEnd] = initialXScale.range(); @@ -11,12 +11,18 @@ function getNewEnd(fallbackEnd, xAccessor, initialXScale, start) { return newEnd; } -function extentsWrapper(useWholeData, clamp, pointsPerPxThreshold, minPointsPerPxThreshold, flipXScale) { +function extentsWrapper( + useWholeData: boolean, + clamp: any, + pointsPerPxThreshold: number, + minPointsPerPxThreshold: number, + flipXScale: boolean, +) { function filterData( - data, - inputDomain, - xAccessor, - initialXScale, + data: any[], + inputDomain: any, + xAccessor: any, + initialXScale: any, // @ts-ignore { currentPlotData, currentDomain, fallbackStart, fallbackEnd } = {}, ) { @@ -115,23 +121,23 @@ function extentsWrapper(useWholeData, clamp, pointsPerPxThreshold, minPointsPerP return { filterData }; } -function canShowTheseManyPeriods(width, arrayLength, maxThreshold, minThreshold) { +function canShowTheseManyPeriods(width: number, arrayLength: number, maxThreshold: number, minThreshold: number) { return arrayLength > showMinThreshold(width, minThreshold) && arrayLength < showMaxThreshold(width, maxThreshold); } -function showMinThreshold(width, threshold) { +function showMinThreshold(width: number, threshold: number) { return Math.max(1, Math.ceil(width * threshold)); } -function showMaxThreshold(width, threshold) { +function showMaxThreshold(width: number, threshold: number) { return Math.floor(width * threshold); } -function showMax(width, threshold) { +function showMax(width: number, threshold: number) { return Math.floor(showMaxThreshold(width, threshold) * 0.97); } -function getFilteredResponse(data, left, right, xAccessor) { +function getFilteredResponse(data: any[], left: any, right: any, xAccessor: any) { const newLeftIndex = getClosestItemIndexes(data, left, xAccessor).right; const newRightIndex = getClosestItemIndexes(data, right, xAccessor).left; @@ -140,7 +146,14 @@ function getFilteredResponse(data, left, right, xAccessor) { return filteredData; } -export default function ({ xScale, useWholeData, clamp, pointsPerPxThreshold, minPointsPerPxThreshold, flipXScale }) { +export default function ({ + xScale, + useWholeData, + clamp, + pointsPerPxThreshold, + minPointsPerPxThreshold, + flipXScale, +}: any) { return extentsWrapper( useWholeData || isNotDefined(xScale.invert), clamp, diff --git a/packages/core/src/utils/identity.ts b/packages/core/src/utils/identity.ts index d9aabe12a..2877eeb8b 100644 --- a/packages/core/src/utils/identity.ts +++ b/packages/core/src/utils/identity.ts @@ -1 +1 @@ -export default (d) => d; +export const identity = (d: any) => d; diff --git a/packages/core/src/utils/index.ts b/packages/core/src/utils/index.ts index d6a8cd0ae..4f999a30f 100644 --- a/packages/core/src/utils/index.ts +++ b/packages/core/src/utils/index.ts @@ -1,17 +1,15 @@ -import { bisector } from "d3-array"; -import identity from "./identity"; -import noop from "./noop"; +import { identity } from "./identity"; +import { noop } from "./noop"; export { default as rebind } from "./rebind"; export { default as zipper } from "./zipper"; export { default as merge } from "./merge"; export { default as slidingWindow } from "./slidingWindow"; -export { default as identity } from "./identity"; -export { default as noop } from "./noop"; +export * from "./identity"; +export * from "./noop"; export * from "./shallowEqual"; export { default as mappedSlidingWindow } from "./mappedSlidingWindow"; export { default as accumulatingWindow } from "./accumulatingWindow"; - export * from "./barWidth"; export * from "./colors"; export * from "./strokeDasharray"; @@ -31,8 +29,6 @@ export function sign(x) { return (x > 0) - (x < 0); } -export const yes = () => true; - export function path(loc = []) { const key = Array.isArray(loc) ? loc : [loc]; const length = key.length; @@ -54,36 +50,8 @@ export function functor(v) { return typeof v === "function" ? v : () => v; } -export function createVerticalLinearGradient(stops) { - return function (moreProps, ctx) { - const { - chartConfig: { height }, - } = moreProps; - - const grd = ctx.createLinearGradient(0, height, 0, 0); - stops.forEach((each) => { - grd.addColorStop(each.stop, each.color); - }); - - return grd; - }; -} - -export function getClosestItemIndexes2(array, value, accessor) { - let left = bisector(accessor).left(array, value); - left = Math.max(left - 1, 0); - let right = Math.min(left + 1, array.length - 1); - - const item = accessor(array[left]); - if (item >= value && item <= value) { - right = left; - } - - return { left, right }; -} - export function getClosestValue(inputValue, currentValue) { - const values = isArray(inputValue) ? inputValue : [inputValue]; + const values = Array.isArray(inputValue) ? inputValue : [inputValue]; const diff = values .map((each) => each - currentValue) @@ -210,8 +178,6 @@ export function isObject(d) { return isDefined(d) && typeof d === "object" && !Array.isArray(d); } -export const isArray = Array.isArray; - export function touchPosition(touch, e: React.TouchEvent): [number, number] { const container = e.currentTarget; const rect = container.getBoundingClientRect(); @@ -236,35 +202,6 @@ export function clearCanvas(canvasList: CanvasRenderingContext2D[], ratio: numbe }); } -export function capitalizeFirst(str: string) { - return str.charAt(0).toUpperCase() + str.substring(1); -} - -export function toObject(array: T[], iteratee = identity) { - return array.reduce((returnObj, a) => { - const [key, value] = iteratee(a); - return { - ...returnObj, - [key]: value, - }; - }, {}); -} - -// copied from https://github.com/lodash/lodash/blob/master/mapValue.js -export function mapValue(object, iteratee) { - object = Object(object); - const result = {}; - - Object.keys(object).forEach((key) => { - const mappedValue = iteratee(object[key], key, object); - - if (isDefined(mappedValue)) { - result[key] = mappedValue; - } - }); - return result; -} - // copied from https://github.com/lodash/lodash/blob/master/mapObject.js export function mapObject(object = {}, iteratee = identity) { const props = Object.keys(object); @@ -276,19 +213,3 @@ export function mapObject(object = {}, iteratee = identity) { }); return result; } - -export function replaceAtIndex(array, index, value) { - if (isDefined(array) && array.length > index) { - return array - .slice(0, index) - .concat(value) - .concat(array.slice(index + 1)); - } - return array; -} - -// copied from https://github.com/lodash/lodash/blob/master/forOwn.js -export function forOwn(obj, iteratee) { - const object = Object(obj); - Object.keys(object).forEach((key) => iteratee(object[key], key, object)); -} diff --git a/packages/core/src/utils/mappedSlidingWindow.ts b/packages/core/src/utils/mappedSlidingWindow.ts index bd3c33a53..455eaa679 100644 --- a/packages/core/src/utils/mappedSlidingWindow.ts +++ b/packages/core/src/utils/mappedSlidingWindow.ts @@ -1,15 +1,29 @@ -import identity from "./identity"; +import { identity } from "./identity"; import { functor } from "./index"; -import noop from "./noop"; +import { noop } from "./noop"; + +interface MappedSlidingWindow { + (data: any[]): any; + accumulator(): any; + accumulator(x: any): MappedSlidingWindow; + skipInitial(): number; + skipInitial(x: number): MappedSlidingWindow; + source(): any; + source(x: any): MappedSlidingWindow; + undefinedValue(): any; + undefinedValue(x: any): MappedSlidingWindow; + windowSize(): number; + windowSize(x: number): MappedSlidingWindow; +} export default function () { - let undefinedValue; + let undefinedValue: any; let windowSize = 10; let accumulator = noop; let source = identity; let skipInitial = 0; - const mappedSlidingWindow = function (data) { + const mappedSlidingWindow = function (data: any[]) { // @ts-ignore const size = functor(windowSize).apply(this, arguments); const windowData: any[] = []; @@ -40,35 +54,35 @@ export default function () { return result; }; - mappedSlidingWindow.undefinedValue = function (x) { + mappedSlidingWindow.undefinedValue = function (x: any) { if (!arguments.length) { return undefinedValue; } undefinedValue = x; return mappedSlidingWindow; }; - mappedSlidingWindow.windowSize = function (x) { + mappedSlidingWindow.windowSize = function (x: number) { if (!arguments.length) { return windowSize; } windowSize = x; return mappedSlidingWindow; }; - mappedSlidingWindow.accumulator = function (x) { + mappedSlidingWindow.accumulator = function (x: any) { if (!arguments.length) { return accumulator; } accumulator = x; return mappedSlidingWindow; }; - mappedSlidingWindow.skipInitial = function (x) { + mappedSlidingWindow.skipInitial = function (x: number) { if (!arguments.length) { return skipInitial; } skipInitial = x; return mappedSlidingWindow; }; - mappedSlidingWindow.source = function (x) { + mappedSlidingWindow.source = function (x: any) { if (!arguments.length) { return source; } @@ -76,5 +90,5 @@ export default function () { return mappedSlidingWindow; }; - return mappedSlidingWindow; + return mappedSlidingWindow as MappedSlidingWindow; } diff --git a/packages/core/src/utils/merge.ts b/packages/core/src/utils/merge.ts index 8d66539c1..bbfd21d52 100644 --- a/packages/core/src/utils/merge.ts +++ b/packages/core/src/utils/merge.ts @@ -24,8 +24,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -import identity from "./identity"; -import noop from "./noop"; +import { identity } from "./identity"; +import { noop } from "./noop"; import zipper from "./zipper"; import { isNotDefined } from "./index"; @@ -48,7 +48,7 @@ export default function () { let merge = noop; const mergeCompute = (data: any[]) => { - const zip = zipper().combine((datum, indicator) => { + const zip = zipper().combine((datum: any, indicator: any) => { const result = skipUndefined && isNotDefined(indicator) ? datum diff --git a/packages/core/src/utils/noop.ts b/packages/core/src/utils/noop.ts index 77b823f4b..4b1407a80 100644 --- a/packages/core/src/utils/noop.ts +++ b/packages/core/src/utils/noop.ts @@ -1,2 +1,2 @@ // eslint-disable-next-line @typescript-eslint/no-empty-function -export default () => {}; +export const noop = () => {}; diff --git a/packages/core/src/utils/rebind.ts b/packages/core/src/utils/rebind.ts index 8f9cacbb3..118fc68bf 100644 --- a/packages/core/src/utils/rebind.ts +++ b/packages/core/src/utils/rebind.ts @@ -1,17 +1,17 @@ // copied from https://github.com/d3fc/d3fc-rebind/blob/master/src/rebind.js -function createReboundMethod(target, source, name) { +function createReboundMethod(target: any, source: any, name: string) { const method = source[name]; if (typeof method !== "function") { throw new Error(`Attempt to rebind ${name} which isn't a function on the source object`); } - return (...args) => { + return (...args: any[]) => { const value = method.apply(source, args); return value === source ? target : value; }; } -export default function rebind(target, source, ...names) { +export default function rebind(target: any, source: any, ...names: string[]) { for (const name of names) { target[name] = createReboundMethod(target, source, name); } diff --git a/packages/core/src/utils/shallowEqual.ts b/packages/core/src/utils/shallowEqual.ts index e04300b08..50c2b4fb4 100644 --- a/packages/core/src/utils/shallowEqual.ts +++ b/packages/core/src/utils/shallowEqual.ts @@ -1,4 +1,4 @@ -export const shallowEqual = (a, b) => { +export const shallowEqual = (a: any, b: any) => { if (a === b) { return true; } diff --git a/packages/core/src/utils/slidingWindow.ts b/packages/core/src/utils/slidingWindow.ts index f3bc58659..f7030ce48 100644 --- a/packages/core/src/utils/slidingWindow.ts +++ b/packages/core/src/utils/slidingWindow.ts @@ -27,7 +27,7 @@ THE SOFTWARE. */ import { functor, path } from "./index"; -import noop from "./noop"; +import { noop } from "./noop"; interface SlidingWindow { (data: any[]): any[]; @@ -48,13 +48,13 @@ interface SlidingWindow { } export default function () { - let undefinedValue; + let undefinedValue: any; let windowSize = 10; let accumulator = noop; - let sourcePath; - let source; + let sourcePath: any; + let source: any; let skipInitial = 0; - let misc; + let misc: any; const slidingWindow = (data: any[]) => { const sourceFunction = source || path(sourcePath); @@ -80,7 +80,7 @@ export default function () { }); }; - slidingWindow.undefinedValue = function (x) { + slidingWindow.undefinedValue = function (x: any) { if (!arguments.length) { return undefinedValue; } @@ -88,7 +88,7 @@ export default function () { return slidingWindow; }; - slidingWindow.windowSize = function (x) { + slidingWindow.windowSize = function (x: any) { if (!arguments.length) { return windowSize; } @@ -96,7 +96,7 @@ export default function () { return slidingWindow; }; - slidingWindow.misc = function (x) { + slidingWindow.misc = function (x: any) { if (!arguments.length) { return misc; } @@ -104,7 +104,7 @@ export default function () { return slidingWindow; }; - slidingWindow.accumulator = function (x) { + slidingWindow.accumulator = function (x: any) { if (!arguments.length) { return accumulator; } @@ -112,7 +112,7 @@ export default function () { return slidingWindow; }; - slidingWindow.skipInitial = function (x) { + slidingWindow.skipInitial = function (x: any) { if (!arguments.length) { return skipInitial; } @@ -120,7 +120,7 @@ export default function () { return slidingWindow; }; - slidingWindow.sourcePath = function (x) { + slidingWindow.sourcePath = function (x: any) { if (!arguments.length) { return sourcePath; } @@ -128,7 +128,7 @@ export default function () { return slidingWindow; }; - slidingWindow.source = function (x) { + slidingWindow.source = function (x: any) { if (!arguments.length) { return source; } diff --git a/packages/core/src/utils/zipper.ts b/packages/core/src/utils/zipper.ts index 9fdce2923..3e0565dd2 100644 --- a/packages/core/src/utils/zipper.ts +++ b/packages/core/src/utils/zipper.ts @@ -1,22 +1,26 @@ /* an extension to d3.zip so we call a function instead of an array */ import { min } from "d3-array"; +import { identity } from "./identity"; -import identity from "./identity"; +interface Zip { + (...args: any[]): any[]; + combine(): any; + combine(x: any): Zip; +} export default function zipper() { let combine = identity; function zip() { const n = arguments.length; - if (!n) { + if (n === 0) { return []; } - const m = min(arguments, d3_zipLength); + const m = min(arguments, d3_zipLength) ?? 0; - let i; const zips = new Array(m); - for (i = -1; ++i < m; ) { + for (let i = -1; ++i < m; ) { // tslint:disable-next-line: no-shadowed-variable for (let j = -1, zip = (zips[i] = new Array(n)); ++j < n; ) { zip[j] = arguments[j][i]; @@ -27,15 +31,15 @@ export default function zipper() { } return zips; } - function d3_zipLength(d) { + function d3_zipLength(d: any[]) { return d.length; } - zip.combine = function (x) { + zip.combine = function (x: any) { if (!arguments.length) { return combine; } combine = x; return zip; }; - return zip; + return zip as Zip; } diff --git a/packages/indicators/src/indicator/atr.ts b/packages/indicators/src/indicator/atr.ts index faf1700f1..afe1e0f79 100644 --- a/packages/indicators/src/indicator/atr.ts +++ b/packages/indicators/src/indicator/atr.ts @@ -24,6 +24,8 @@ interface ATRIndicator { merge(newMerge: any): ATRIndicator; options(): ATROptions; options(newOptions: ATROptions): ATRIndicator; + skipUndefined(): boolean; + skipUndefined(newSkipUndefined: boolean): ATRIndicator; } export default function () { diff --git a/packages/indicators/src/indicator/rsi.ts b/packages/indicators/src/indicator/rsi.ts index c48144f6d..05d9750b6 100644 --- a/packages/indicators/src/indicator/rsi.ts +++ b/packages/indicators/src/indicator/rsi.ts @@ -30,7 +30,7 @@ interface RSIIndicator { export default function () { const base = baseIndicator() .type(ALGORITHM_TYPE) - .accessor((d) => d.rsi); + .accessor((d: any) => d.rsi); const underlyingAlgorithm = rsi(); diff --git a/packages/interactive/src/Brush.tsx b/packages/interactive/src/Brush.tsx index 4ecbdb3d1..3471c805e 100644 --- a/packages/interactive/src/Brush.tsx +++ b/packages/interactive/src/Brush.tsx @@ -3,14 +3,12 @@ import { getStrokeDasharrayCanvas, getMouseCanvas, GenericChartComponent, - noop, strokeDashTypes, } from "@react-financial-charts/core"; interface BrushProps { readonly enabled: boolean; - readonly onStart: any; // func - readonly onBrush: any; // func + readonly onBrush: ({ start, end }: any, moreProps: any) => void; readonly type?: "1D" | "2D"; readonly strokeStyle?: string; readonly fillStyle?: string; @@ -31,14 +29,12 @@ export class Brush extends React.Component { type: "2D", strokeStyle: "#000000", fillStyle: "#3h3h3h", - onBrush: noop, - onStart: noop, strokeDashArray: "ShortDash", }; private zoomHappening?: boolean; - constructor(props: BrushProps, context) { + public constructor(props: BrushProps, context) { super(props, context); this.terminate = this.terminate.bind(this); @@ -78,26 +74,28 @@ export class Brush extends React.Component { private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D) => { const { rect } = this.state; - if (rect !== null) { - const { x, y, height, width } = rect; - const { - strokeStyle = Brush.defaultProps.strokeStyle, - fillStyle = Brush.defaultProps.fillStyle, - strokeDashArray, - } = this.props; - - const dashArray = getStrokeDasharrayCanvas(strokeDashArray); - - ctx.strokeStyle = strokeStyle; - ctx.fillStyle = fillStyle; - ctx.setLineDash(dashArray); - ctx.beginPath(); - ctx.fillRect(x, y, width, height); - ctx.strokeRect(x, y, width, height); + if (rect === null) { + return; } + + const { x, y, height, width } = rect; + const { + strokeStyle = Brush.defaultProps.strokeStyle, + fillStyle = Brush.defaultProps.fillStyle, + strokeDashArray, + } = this.props; + + const dashArray = getStrokeDasharrayCanvas(strokeDashArray); + + ctx.strokeStyle = strokeStyle; + ctx.fillStyle = fillStyle; + ctx.setLineDash(dashArray); + ctx.beginPath(); + ctx.fillRect(x, y, width, height); + ctx.strokeRect(x, y, width, height); }; - private readonly handleZoomStart = (moreProps) => { + private readonly handleZoomStart = (_: React.MouseEvent, moreProps: any) => { this.zoomHappening = false; const { mouseXY: [, mouseY], @@ -120,7 +118,7 @@ export class Brush extends React.Component { }); }; - private readonly handleDrawSquare = (moreProps) => { + private readonly handleDrawSquare = (_: React.MouseEvent, moreProps: any) => { if (this.state.x1y1 == null) { return; } @@ -162,12 +160,15 @@ export class Brush extends React.Component { }); }; - private readonly handleZoomComplete = (moreProps) => { + private readonly handleZoomComplete = (_: React.MouseEvent, moreProps: any) => { if (this.zoomHappening) { const { onBrush } = this.props; - const { start, end } = this.state; - onBrush({ start, end }, moreProps); + if (onBrush !== undefined) { + const { start, end } = this.state; + onBrush({ start, end }, moreProps); + } } + this.setState({ selected: false, rect: null, diff --git a/packages/interactive/src/ClickCallback.tsx b/packages/interactive/src/ClickCallback.tsx index 3a2520cb5..7adb883a5 100644 --- a/packages/interactive/src/ClickCallback.tsx +++ b/packages/interactive/src/ClickCallback.tsx @@ -3,13 +3,13 @@ import { getMouseCanvas, GenericChartComponent } from "@react-financial-charts/c interface ClickCallbackProps { readonly disablePan: boolean; - readonly onMouseDown?: any; // func - readonly onClick?: any; // func - readonly onDoubleClick?: any; // func - readonly onContextMenu?: any; // func - readonly onMouseMove?: any; // func - readonly onPan?: any; // func - readonly onPanEnd?: any; // func + readonly onMouseDown?: (e: React.MouseEvent, moreProps: any) => void; + readonly onClick?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDoubleClick?: (e: React.MouseEvent, moreProps: any) => void; + readonly onContextMenu?: (e: React.MouseEvent, moreProps: any) => void; + readonly onMouseMove?: (e: React.MouseEvent, moreProps: any) => void; + readonly onPan?: (e: React.MouseEvent, moreProps: any) => void; + readonly onPanEnd?: (e: React.MouseEvent, moreProps: any) => void; } export class ClickCallback extends React.Component { diff --git a/packages/interactive/src/DrawingObjectSelector.tsx b/packages/interactive/src/DrawingObjectSelector.tsx index b13ab4860..7eeef5058 100644 --- a/packages/interactive/src/DrawingObjectSelector.tsx +++ b/packages/interactive/src/DrawingObjectSelector.tsx @@ -4,8 +4,8 @@ import { getMorePropsForChart, getSelected } from "./utils"; interface DrawingObjectSelectorProps { readonly getInteractiveNodes: () => any[]; - readonly onSelect?: (interactives, moreProps) => void; - readonly onDoubleClick?: (item, moreProps) => void; + readonly onSelect?: (e: React.MouseEvent, interactives: any[], moreProps: any) => void; + readonly onDoubleClick?: (e: React.MouseEvent, item: any, moreProps: any) => void; readonly drawingObjectMap: object; readonly enabled: boolean; } @@ -26,7 +26,7 @@ export class DrawingObjectSelector extends React.Component { + private readonly getInteraction = (moreProps: any) => { const { getInteractiveNodes, drawingObjectMap } = this.props; const interactiveNodes = getInteractiveNodes(); const interactives = mapObject(interactiveNodes, (each) => { @@ -56,7 +56,7 @@ export class DrawingObjectSelector extends React.Component { + private readonly handleClick = (e: React.MouseEvent, moreProps: any) => { e.preventDefault(); const { onSelect } = this.props; const { enabled } = this.props; @@ -66,11 +66,11 @@ export class DrawingObjectSelector extends React.Component { + private readonly handleDoubleClick = (e: React.MouseEvent, moreProps: any) => { e.preventDefault(); const { onDoubleClick } = this.props; const { enabled } = this.props; @@ -90,7 +90,7 @@ export class DrawingObjectSelector extends React.Component void; + readonly onComplete: (e: React.MouseEvent, newChannels: any[], moreProps: any) => void; readonly onSelect: any; // func readonly currentPositionStroke?: string; readonly currentPositionStrokeWidth?: number; @@ -39,8 +39,6 @@ interface EquidistantChannelState { export class EquidistantChannel extends React.Component { public static defaultProps = { - onStart: noop, - onComplete: noop, onSelect: noop, currentPositionStroke: "#000000", currentPositionOpacity: 1, @@ -149,7 +147,7 @@ export class EquidistantChannel extends React.Component { + private readonly handleDragChannel = (_: React.MouseEvent, index: any, newXYValue: any) => { this.setState({ override: { index, @@ -158,7 +156,7 @@ export class EquidistantChannel extends React.Component { + private readonly handleDragChannelComplete = (e: React.MouseEvent, moreProps: any) => { const { override } = this.state; const { channels } = this.props; @@ -173,13 +171,16 @@ export class EquidistantChannel extends React.Component { - this.props.onComplete(newChannels, moreProps); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newChannels, moreProps); + } }, ); } }; - private readonly handleStart = (xyValue) => { + private readonly handleStart = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isNotDefined(current) || isNotDefined(current.startXY)) { @@ -192,13 +193,16 @@ export class EquidistantChannel extends React.Component { - this.props.onStart(); + const { onStart } = this.props; + if (onStart !== undefined) { + onStart(); + } }, ); } }; - private readonly handleEnd = (xyValue, moreProps, e) => { + private readonly handleEnd = (e: React.MouseEvent, _: any, moreProps: any) => { const { current } = this.state; const { channels, appearance } = this.props; @@ -225,14 +229,17 @@ export class EquidistantChannel extends React.Component { - this.props.onComplete(newChannels, moreProps, e); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newChannels, moreProps); + } }, ); } } }; - private readonly handleDrawChannel = (xyValue) => { + private readonly handleDrawChannel = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isDefined(current) && isDefined(current.startXY)) { diff --git a/packages/interactive/src/FibonacciRetracement.tsx b/packages/interactive/src/FibonacciRetracement.tsx index b92c0e500..320d958f4 100644 --- a/packages/interactive/src/FibonacciRetracement.tsx +++ b/packages/interactive/src/FibonacciRetracement.tsx @@ -8,8 +8,8 @@ import { EachFibRetracement } from "./wrapper/EachFibRetracement"; interface FibonacciRetracementProps { readonly enabled: boolean; readonly width?: number; - readonly onStart?: any; // func - readonly onComplete?: any; // func + readonly onStart?: (moreProps: any) => void; + readonly onComplete?: (e: React.MouseEvent, newRetracements: any[], moreProps: any) => void; readonly onSelect?: any; // func readonly type: | "EXTEND" // extends from -Infinity to +Infinity @@ -46,8 +46,6 @@ export class FibonacciRetracement extends React.Component { + private readonly handleDrawRetracement = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isDefined(current) && isDefined(current.x1)) { this.mouseMoved = true; @@ -183,7 +181,7 @@ export class FibonacciRetracement extends React.Component { + private readonly handleEdge1Drag = (_: React.MouseEvent, echo, newXYValue, origXYValue) => { const { retracements } = this.props; const { index } = echo; @@ -200,7 +198,7 @@ export class FibonacciRetracement extends React.Component { + private readonly handleDrag = (_: React.MouseEvent, index, xy) => { this.setState({ override: { index, @@ -209,7 +207,7 @@ export class FibonacciRetracement extends React.Component { + private readonly handleEdge2Drag = (_: React.MouseEvent, echo, newXYValue, origXYValue) => { const { retracements } = this.props; const { index } = echo; @@ -226,7 +224,7 @@ export class FibonacciRetracement extends React.Component { + private readonly handleDragComplete = (e: React.MouseEvent, moreProps: any) => { const { retracements } = this.props; const { override } = this.state; if (isDefined(override)) { @@ -240,13 +238,16 @@ export class FibonacciRetracement extends React.Component { - this.props.onComplete(newRetracements, moreProps); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newRetracements, moreProps); + } }, ); } }; - private readonly handleStart = (xyValue, moreProps) => { + private readonly handleStart = (e: React.MouseEvent, xyValue: any, moreProps: any) => { const { current } = this.state; if (isNotDefined(current) || isNotDefined(current.x1)) { this.mouseMoved = false; @@ -260,13 +261,16 @@ export class FibonacciRetracement extends React.Component { - this.props.onStart(moreProps); + const { onStart } = this.props; + if (onStart !== undefined) { + onStart(moreProps); + } }, ); } }; - private readonly handleEnd = (xyValue, moreProps, e) => { + private readonly handleEnd = (e: React.MouseEvent, xyValue: any, moreProps: any) => { const { retracements, appearance, type } = this.props; const { current } = this.state; @@ -285,7 +289,10 @@ export class FibonacciRetracement extends React.Component { - this.props.onComplete(newRetracements, moreProps, e); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newRetracements, moreProps); + } }, ); } diff --git a/packages/interactive/src/GannFan.tsx b/packages/interactive/src/GannFan.tsx index 7d3f750e4..2985948d2 100644 --- a/packages/interactive/src/GannFan.tsx +++ b/packages/interactive/src/GannFan.tsx @@ -5,10 +5,10 @@ import { MouseLocationIndicator } from "./components/MouseLocationIndicator"; import { isHoverForInteractiveType, saveNodeType, terminate } from "./utils"; import { EachGannFan } from "./wrapper/EachGannFan"; -interface GannFanProps { +export interface GannFanProps { readonly enabled: boolean; - readonly onStart: any; // func - readonly onComplete: any; // func + readonly onStart?: () => void; + readonly onComplete: (e: React.MouseEvent, newfans: any[], moreProps: any) => void; readonly onSelect?: any; // func readonly currentPositionStroke?: string; readonly currentPositionStrokeWidth?: number; @@ -53,8 +53,6 @@ export class GannFan extends React.Component { fontSize: 12, fontFill: "#000000", }, - onStart: noop, - onComplete: noop, onSelect: noop, currentPositionStroke: "#000000", currentPositionOpacity: 1, @@ -146,7 +144,7 @@ export class GannFan extends React.Component { ); } - private readonly handleEnd = (xyValyue, moreProps, e) => { + private readonly handleEnd = (e: React.MouseEvent, _: any, moreProps: any) => { const { current } = this.state; const { fans, appearance } = this.props; @@ -160,13 +158,16 @@ export class GannFan extends React.Component { current: null, }, () => { - this.props.onComplete(newfans, moreProps, e); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newfans, moreProps); + } }, ); } }; - private readonly handleStart = (xyValue) => { + private readonly handleStart = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isNotDefined(current) || isNotDefined(current.startXY)) { @@ -180,13 +181,16 @@ export class GannFan extends React.Component { }, }, () => { - this.props.onStart(); + const { onStart } = this.props; + if (onStart !== undefined) { + onStart(); + } }, ); } }; - private readonly handleDrawFan = (xyValue) => { + private readonly handleDrawFan = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isDefined(current) && isDefined(current.startXY)) { @@ -201,7 +205,7 @@ export class GannFan extends React.Component { } }; - private readonly handleDragFanComplete = (moreProps) => { + private readonly handleDragFanComplete = (e: React.MouseEvent, moreProps: any) => { const { override } = this.state; const { fans } = this.props; @@ -213,13 +217,13 @@ export class GannFan extends React.Component { override: null, }, () => { - this.props.onComplete(newfans, moreProps); + this.props.onComplete(e, newfans, moreProps); }, ); } }; - private readonly handleDragFan = (index, newXYValue) => { + private readonly handleDragFan = (_: React.MouseEvent, index: number | undefined, newXYValue: any) => { this.setState({ override: { index, diff --git a/packages/interactive/src/InteractiveText.tsx b/packages/interactive/src/InteractiveText.tsx index a93085545..b8a17ae8a 100644 --- a/packages/interactive/src/InteractiveText.tsx +++ b/packages/interactive/src/InteractiveText.tsx @@ -6,8 +6,8 @@ import { getValueFromOverride, isHoverForInteractiveType, saveNodeType, terminat import { EachText } from "./wrapper/EachText"; interface InteractiveTextProps { - readonly onChoosePosition: any; // func - readonly onDragComplete: any; // func + readonly onChoosePosition: (e: React.MouseEvent, newText: any, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, newTextList: any[], moreProps: any) => void; readonly onSelect?: any; // func readonly defaultText: { bgFill: string; @@ -33,8 +33,6 @@ interface InteractiveTextState { export class InteractiveText extends React.Component { public static defaultProps = { - onChoosePosition: noop, - onDragComplete: noop, onSelect: noop, defaultText: { bgFill: "#D3D3D3", @@ -72,11 +70,10 @@ export class InteractiveText extends React.Component { + private readonly handleDraw = (e: React.MouseEvent, moreProps: any) => { const { enabled } = this.props; if (enabled) { const { @@ -133,19 +130,20 @@ export class InteractiveText extends React.Component { + private readonly handleDragComplete = (e: React.MouseEvent, moreProps: any) => { const { override } = this.state; if (isDefined(override)) { const { textList } = this.props; @@ -167,13 +165,16 @@ export class InteractiveText extends React.Component { - this.props.onDragComplete(newTextList, moreProps); + const { onDragComplete } = this.props; + if (onDragComplete !== undefined) { + onDragComplete(e, newTextList, moreProps); + } }, ); } }; - private readonly handleDrag = (index, position) => { + private readonly handleDrag = (_: React.MouseEvent, index, position) => { this.setState({ override: { index, diff --git a/packages/interactive/src/InteractiveYCoordinate.tsx b/packages/interactive/src/InteractiveYCoordinate.tsx index 8f761b836..5f8bc4792 100644 --- a/packages/interactive/src/InteractiveYCoordinate.tsx +++ b/packages/interactive/src/InteractiveYCoordinate.tsx @@ -1,9 +1,7 @@ import * as PropTypes from "prop-types"; import * as React from "react"; - import { format } from "d3-format"; -import { isDefined, noop, strokeDashTypes } from "@react-financial-charts/core"; - +import { isDefined, strokeDashTypes } from "@react-financial-charts/core"; import { HoverTextNearMouse } from "./components/HoverTextNearMouse"; import { getValueFromOverride, isHoverForInteractiveType, saveNodeType, terminate } from "./utils"; import { EachInteractiveYCoordinate } from "./wrapper/EachInteractiveYCoordinate"; @@ -61,19 +59,13 @@ interface InteractiveYCoordinateState { export class InteractiveYCoordinate extends React.Component { public static defaultProps = { - onChoosePosition: noop, - onDragComplete: noop, - onSelect: noop, - onDelete: noop, defaultPriceCoordinate: { bgFill: "#FFFFFF", bgOpacity: 1, - stroke: "#6574CD", strokeOpacity: 1, strokeDasharray: "ShortDash2", strokeWidth: 1, - textFill: "#6574CD", fontFamily: "-apple-system, system-ui, Roboto, 'Helvetica Neue', Ubuntu, sans-serif", fontSize: 12, @@ -93,7 +85,6 @@ export class InteractiveYCoordinate extends React.Component { + private readonly handleDelete = (e: React.MouseEvent, index, moreProps) => { const { onDelete, yCoordinateList } = this.props; - - onDelete(yCoordinateList[index], moreProps); + if (onDelete !== undefined) { + onDelete(e, yCoordinateList[index], moreProps); + } }; - private readonly handleDragComplete = (moreProps) => { + private readonly handleDragComplete = (e: React.MouseEvent, moreProps) => { const { override } = this.state; if (isDefined(override)) { const { yCoordinateList } = this.props; @@ -195,13 +186,16 @@ export class InteractiveYCoordinate extends React.Component { - this.props.onDragComplete(newAlertList, moreProps, draggedAlert); + const { onDragComplete } = this.props; + if (onDragComplete !== undefined) { + onDragComplete(e, newAlertList, moreProps, draggedAlert); + } }, ); } }; - private readonly handleDrag = (index, yValue) => { + private readonly handleDrag = (_: React.MouseEvent, index, yValue) => { this.setState({ override: { index, diff --git a/packages/interactive/src/StandardDeviationChannel.tsx b/packages/interactive/src/StandardDeviationChannel.tsx index fa2b6c536..ecb574a29 100644 --- a/packages/interactive/src/StandardDeviationChannel.tsx +++ b/packages/interactive/src/StandardDeviationChannel.tsx @@ -1,18 +1,15 @@ import * as React from "react"; - -import { isDefined, isNotDefined, noop } from "@react-financial-charts/core"; - +import { isDefined, isNotDefined } from "@react-financial-charts/core"; import { getValueFromOverride, isHoverForInteractiveType, saveNodeType, terminate } from "./utils"; - import { HoverTextNearMouse } from "./components/HoverTextNearMouse"; import { MouseLocationIndicator } from "./components/MouseLocationIndicator"; import { EachLinearRegressionChannel } from "./wrapper/EachLinearRegressionChannel"; -interface StandardDeviationChannelProps { +export interface StandardDeviationChannelProps { readonly enabled: boolean; readonly snapTo?: any; // func - readonly onStart?: any; // func - readonly onComplete: any; // func + readonly onStart?: () => void; + readonly onComplete?: (e: React.MouseEvent, newChannels: any, moreProps: any) => void; readonly onSelect?: any; // func readonly currentPositionStroke?: string; readonly currentPositionStrokeWidth?: number; @@ -43,7 +40,7 @@ export class StandardDeviationChannel extends React.Component< StandardDeviationChannelState > { public static defaultProps = { - snapTo: (d) => d.close, + snapTo: (d: any) => d.close, appearance: { stroke: "#000000", fillOpacity: 0.2, @@ -55,9 +52,6 @@ export class StandardDeviationChannel extends React.Component< edgeFill: "#FFFFFF", r: 5, }, - onStart: noop, - onComplete: noop, - onSelect: noop, currentPositionStroke: "#000000", currentPositionOpacity: 1, currentPositionStrokeWidth: 3, @@ -81,12 +75,11 @@ export class StandardDeviationChannel extends React.Component< // @ts-ignore private terminate; - public constructor(props) { + public constructor(props: StandardDeviationChannelProps) { super(props); this.terminate = terminate.bind(this); this.saveNodeType = saveNodeType.bind(this); - this.getSelectionState = isHoverForInteractiveType("channels").bind(this); this.state = {}; @@ -172,7 +165,7 @@ export class StandardDeviationChannel extends React.Component< ); } - private handleEnd = (xyValue, moreProps, e) => { + private handleEnd = (e: React.MouseEvent, xyValue: any, moreProps: any) => { const { current } = this.state; const { appearance, channels } = this.props; @@ -192,13 +185,16 @@ export class StandardDeviationChannel extends React.Component< current: null, }, () => { - this.props.onComplete(newChannels, moreProps, e); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newChannels, moreProps); + } }, ); } }; - private readonly handleStart = (xyValue) => { + private readonly handleStart = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isNotDefined(current) || isNotDefined(current.start)) { @@ -212,13 +208,16 @@ export class StandardDeviationChannel extends React.Component< }, }, () => { - this.props.onStart(); + const { onStart } = this.props; + if (onStart !== undefined) { + onStart(); + } }, ); } }; - private readonly handleDrawLine = (xyValue) => { + private readonly handleDrawLine = (e: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isDefined(current) && isDefined(current.start)) { @@ -232,7 +231,7 @@ export class StandardDeviationChannel extends React.Component< } }; - private readonly handleDragLineComplete = (moreProps) => { + private readonly handleDragLineComplete = (e: React.MouseEvent, moreProps: any) => { const { override } = this.state; const { channels } = this.props; if (isDefined(override)) { @@ -251,13 +250,16 @@ export class StandardDeviationChannel extends React.Component< override: null, }, () => { - this.props.onComplete(newChannels, moreProps); + const { onComplete } = this.props; + if (onComplete !== undefined) { + onComplete(e, newChannels, moreProps); + } }, ); } }; - private readonly handleDragLine = (index, newXYValue) => { + private readonly handleDragLine = (e: React.MouseEvent, index: number | undefined, newXYValue: any) => { this.setState({ override: { index, diff --git a/packages/interactive/src/TrendLine.tsx b/packages/interactive/src/TrendLine.tsx index 8a50df35e..fe92106a9 100644 --- a/packages/interactive/src/TrendLine.tsx +++ b/packages/interactive/src/TrendLine.tsx @@ -181,7 +181,7 @@ export class TrendLine extends React.Component { ); } - private readonly handleEnd = (xyValue, moreProps, e) => { + private readonly handleEnd = (e: React.MouseEvent, xyValue: any, moreProps: any) => { const { current } = this.state; const { trends, appearance, type } = this.props; @@ -202,13 +202,13 @@ export class TrendLine extends React.Component { trends: newTrends, }, () => { - this.props.onComplete(newTrends, moreProps, e); + this.props.onComplete(e, newTrends, moreProps); }, ); } }; - private readonly handleStart = (xyValue, moreProps, e) => { + private readonly handleStart = (e: React.MouseEvent, xyValue: any, moreProps: any) => { const { current } = this.state; if (isNotDefined(current) || isNotDefined(current.start)) { @@ -222,13 +222,13 @@ export class TrendLine extends React.Component { }, }, () => { - this.props.onStart(moreProps, e); + this.props.onStart(e, moreProps); }, ); } }; - private readonly handleDrawLine = (xyValue) => { + private readonly handleDrawLine = (_: React.MouseEvent, xyValue: any) => { const { current } = this.state; if (isDefined(current) && isDefined(current.start)) { this.mouseMoved = true; @@ -241,7 +241,7 @@ export class TrendLine extends React.Component { } }; - private readonly handleDragLineComplete = (moreProps) => { + private readonly handleDragLineComplete = (e: React.MouseEvent, moreProps: any) => { const { override } = this.state; if (isDefined(override)) { const { trends } = this.props; @@ -264,13 +264,13 @@ export class TrendLine extends React.Component { override: null, }, () => { - this.props.onComplete(newTrends, moreProps); + this.props.onComplete(e, newTrends, moreProps); }, ); } }; - private readonly handleDragLine = (index, newXYValue) => { + private readonly handleDragLine = (_: React.MouseEvent, index: number | undefined, newXYValue: any) => { this.setState({ override: { index, diff --git a/packages/interactive/src/ZoomButtons.tsx b/packages/interactive/src/ZoomButtons.tsx index 1e37c6f5e..8f59f8d9a 100644 --- a/packages/interactive/src/ZoomButtons.tsx +++ b/packages/interactive/src/ZoomButtons.tsx @@ -1,14 +1,13 @@ import { interpolateNumber } from "d3-interpolate"; import * as PropTypes from "prop-types"; import * as React from "react"; - -import { last, noop } from "@react-financial-charts/core"; +import { last } from "@react-financial-charts/core"; interface ZoomButtonsProps { readonly fill: string; readonly fillOpacity: number; readonly heightFromBase: number; - readonly onReset: () => void; + readonly onReset?: () => void; readonly r: number; readonly stroke: string; readonly strokeWidth: number; @@ -26,7 +25,6 @@ export class ZoomButtons extends React.Component { strokeWidth: 1, textFill: "#000000", zoomMultiplier: 1.5, - onReset: noop, }; public static contextTypes = { diff --git a/packages/interactive/src/components/ChannelWithArea.tsx b/packages/interactive/src/components/ChannelWithArea.tsx index d1fe4dbd5..355d1e109 100644 --- a/packages/interactive/src/components/ChannelWithArea.tsx +++ b/packages/interactive/src/components/ChannelWithArea.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { isDefined, isNotDefined, getMouseCanvas, GenericChartComponent, noop } from "@react-financial-charts/core"; +import { isDefined, isNotDefined, getMouseCanvas, GenericChartComponent } from "@react-financial-charts/core"; import { generateLine, isHovering } from "./StraightLine"; interface ChannelWithAreaProps { @@ -14,11 +14,11 @@ interface ChannelWithAreaProps { | "XLINE" // extends from -Infinity to +Infinity | "RAY" // extends to +/-Infinity in one direction | "LINE"; // extends between the set bounds - readonly onDragStart: any; // func - readonly onDrag: any; // func - readonly onDragComplete: any; // func - readonly onHover?: any; // func - readonly onUnHover?: any; // func + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly defaultClassName?: string; readonly tolerance: number; readonly selected: boolean; @@ -26,9 +26,6 @@ interface ChannelWithAreaProps { export class ChannelWithArea extends React.Component { public static defaultProps = { - onDragStart: noop, - onDrag: noop, - onDragComplete: noop, type: "LINE", strokeWidth: 1, tolerance: 4, @@ -96,7 +93,7 @@ export class ChannelWithArea extends React.Component { private readonly isHover = (moreProps) => { const { tolerance, onHover } = this.props; - if (isDefined(onHover)) { + if (onHover !== undefined) { const { line1, line2 } = helper(this.props, moreProps); if (line1 !== undefined && line2 !== undefined) { @@ -144,6 +141,7 @@ function getLines(props: ChannelWithAreaProps, moreProps) { if (isNotDefined(startXY) || isNotDefined(endXY)) { return {}; } + const line1 = generateLine({ type, start: startXY, @@ -151,6 +149,7 @@ function getLines(props: ChannelWithAreaProps, moreProps) { xScale, yScale: undefined, }); + const line2 = isDefined(dy) ? { ...line1, diff --git a/packages/interactive/src/components/ClickableCircle.tsx b/packages/interactive/src/components/ClickableCircle.tsx index ec0f33a09..3af2cc0a1 100644 --- a/packages/interactive/src/components/ClickableCircle.tsx +++ b/packages/interactive/src/components/ClickableCircle.tsx @@ -1,11 +1,11 @@ import * as React from "react"; -import { isDefined, noop, getMouseCanvas, GenericChartComponent } from "@react-financial-charts/core"; +import { getMouseCanvas, GenericChartComponent } from "@react-financial-charts/core"; -interface ClickableCircleProps { - readonly onDragStart: any; // func - readonly onDrag: any; // func - readonly onDragComplete: any; // func +export interface ClickableCircleProps { + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; readonly strokeWidth: number; readonly strokeStyle: string | CanvasGradient | CanvasPattern; readonly fillStyle: string | CanvasGradient | CanvasPattern; @@ -15,23 +15,17 @@ interface ClickableCircleProps { readonly className: string; readonly show: boolean; readonly interactiveCursorClass?: string; - readonly xyProvider?: any; // func + readonly xyProvider?: (moreProps: any) => number[]; } export class ClickableCircle extends React.Component { public static defaultProps = { className: "react-financial-charts-interactive-line-edge", - onDragStart: noop, - onDrag: noop, - onDragComplete: noop, - onMove: noop, show: false, }; public render() { - const { interactiveCursorClass } = this.props; - const { show } = this.props; - const { onDragStart, onDrag, onDragComplete } = this.props; + const { interactiveCursorClass, onDragStart, onDrag, onDragComplete, show } = this.props; if (!show) { return null; @@ -52,7 +46,7 @@ export class ClickableCircle extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { strokeStyle, strokeWidth, fillStyle, r } = this.props; ctx.lineWidth = strokeWidth; @@ -67,7 +61,7 @@ export class ClickableCircle extends React.Component { ctx.stroke(); }; - private readonly isHover = (moreProps) => { + private readonly isHover = (moreProps: any) => { const { mouseXY } = moreProps; const r = this.props.r + 7; const [x, y] = this.helper(moreProps); @@ -78,10 +72,10 @@ export class ClickableCircle extends React.Component { return hover; }; - private readonly helper = (moreProps) => { + private readonly helper = (moreProps: any) => { const { xyProvider, cx, cy } = this.props; - if (isDefined(xyProvider)) { + if (xyProvider !== undefined) { return xyProvider(moreProps); } diff --git a/packages/interactive/src/components/ClickableShape.tsx b/packages/interactive/src/components/ClickableShape.tsx index d174a126c..699d826b4 100644 --- a/packages/interactive/src/components/ClickableShape.tsx +++ b/packages/interactive/src/components/ClickableShape.tsx @@ -18,9 +18,9 @@ interface ClickableShapeProps { readonly hovering?: boolean; readonly interactiveCursorClass?: string; readonly show?: boolean; - readonly onHover?: any; // func - readonly onUnHover?: any; // func - readonly onClick?: any; // func + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onClick?: (e: React.MouseEvent, moreProps: any) => void; readonly yValue: number; } @@ -33,9 +33,7 @@ export class ClickableShape extends React.Component { private closeIcon; public render() { - const { interactiveCursorClass } = this.props; - const { show } = this.props; - const { onHover, onUnHover, onClick } = this.props; + const { interactiveCursorClass, onHover, onUnHover, onClick, show } = this.props; if (!show) { return null; @@ -55,7 +53,7 @@ export class ClickableShape extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { strokeStyle, strokeWidth, hovering, textBox } = this.props; const [x, y] = this.helper(this.props, moreProps, ctx); @@ -73,7 +71,7 @@ export class ClickableShape extends React.Component { ctx.stroke(); }; - private readonly isHover = (moreProps) => { + private readonly isHover = (moreProps: any) => { const { mouseXY } = moreProps; if (this.closeIcon) { const { textBox } = this.props; @@ -92,7 +90,7 @@ export class ClickableShape extends React.Component { return false; }; - private readonly helper = (props: ClickableShapeProps, moreProps, ctx) => { + private readonly helper = (props: ClickableShapeProps, moreProps: any, ctx: CanvasRenderingContext2D) => { const { yValue, text, textBox } = props; const { fontFamily, fontStyle, fontWeight, fontSize } = props; ctx.font = `${fontStyle} ${fontWeight} ${fontSize}px ${fontFamily}`; diff --git a/packages/interactive/src/components/GannFan.tsx b/packages/interactive/src/components/GannFan.tsx index 022da90ee..ab9a01a30 100644 --- a/packages/interactive/src/components/GannFan.tsx +++ b/packages/interactive/src/components/GannFan.tsx @@ -7,7 +7,6 @@ import { colorToRGBA, isDefined, isNotDefined, - noop, getMouseCanvas, GenericChartComponent, } from "@react-financial-charts/core"; @@ -24,11 +23,11 @@ interface GannFanProps { readonly fontFamily: string; readonly fontSize: number; readonly fontFill: string; - readonly onDragStart: any; // func - readonly onDrag: any; // func - readonly onDragComplete: any; // func - readonly onHover?: any; // func - readonly onUnHover?: any; // func + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly defaultClassName?: string; readonly tolerance: number; readonly selected: boolean; @@ -36,9 +35,6 @@ interface GannFanProps { export class GannFan extends React.Component { public static defaultProps = { - onDragStart: noop, - onDrag: noop, - onDragComplete: noop, strokeWidth: 1, tolerance: 4, selected: false, @@ -65,7 +61,7 @@ export class GannFan extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { stroke, strokeWidth, strokeOpacity, fill, fillOpacity, fontFamily, fontSize, fontFill } = this.props; const lines = this.helper(this.props, moreProps); @@ -100,7 +96,7 @@ export class GannFan extends React.Component { }); }; - private readonly isHover = (moreProps) => { + private readonly isHover = (moreProps: any) => { const { tolerance, onHover } = this.props; const { mouseXY } = moreProps; const [mouseX, mouseY] = mouseXY; @@ -131,7 +127,7 @@ export class GannFan extends React.Component { return hovering; }; - private readonly getLineCoordinates = (start, endX, endY, text) => { + private readonly getLineCoordinates = (start: number[], endX: number, endY: number, text: string) => { const end = [endX, endY]; return { start, @@ -140,7 +136,7 @@ export class GannFan extends React.Component { }; }; - private readonly helper = (props: GannFanProps, moreProps) => { + private readonly helper = (props: GannFanProps, moreProps: any) => { const { startXY, endXY } = props; const { diff --git a/packages/interactive/src/components/HoverTextNearMouse.tsx b/packages/interactive/src/components/HoverTextNearMouse.tsx index 6cb8340a5..e40af346b 100644 --- a/packages/interactive/src/components/HoverTextNearMouse.tsx +++ b/packages/interactive/src/components/HoverTextNearMouse.tsx @@ -58,7 +58,7 @@ export class HoverTextNearMouse extends React.Component { + private readonly renderSVG = (moreProps: any) => { const { fontFamily, fontSize, fill, bgFill, bgOpacity } = this.props; const textMetaData = helper( @@ -141,7 +141,7 @@ export class HoverTextNearMouse extends React.Component void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly position?: any; - readonly defaultClassName?: string; readonly interactiveCursorClass?: string; - readonly tolerance: number; readonly selected: boolean; + readonly text: string; + readonly textFill: string; + readonly tolerance: number; } export class InteractiveText extends React.Component { public static defaultProps = { - onDragStart: noop, - onDrag: noop, - onDragComplete: noop, type: "SD", // standard dev fontWeight: "normal", // standard dev tolerance: 4, @@ -36,7 +33,7 @@ export class InteractiveText extends React.Component { }; private calculateTextWidth = true; - private textWidth; + private textWidth?: number; public componentDidUpdate(previousProps: InteractiveTextProps) { this.calculateTextWidth = @@ -72,8 +69,8 @@ export class InteractiveText extends React.Component { private readonly isHover = (moreProps) => { const { onHover } = this.props; - if (isDefined(onHover) && isDefined(this.textWidth) && !this.calculateTextWidth) { - const { rect } = this.helper(this.props, moreProps, this.textWidth); + if (onHover !== undefined && this.textWidth !== undefined && !this.calculateTextWidth) { + const { rect } = this.helper(moreProps, this.textWidth); const { mouseXY: [x, y], } = moreProps; @@ -85,7 +82,7 @@ export class InteractiveText extends React.Component { return false; }; - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { bgFill, bgOpacity, @@ -108,7 +105,7 @@ export class InteractiveText extends React.Component { const { selected } = this.props; - const { x, y, rect } = this.helper(this.props, moreProps, this.textWidth); + const { x, y, rect } = this.helper(moreProps, this.textWidth ?? 0); ctx.fillStyle = colorToRGBA(bgFill, bgOpacity); @@ -130,8 +127,8 @@ export class InteractiveText extends React.Component { ctx.fillText(text, x, y); }; - private readonly helper = (props, moreProps, textWidth) => { - const { position, fontSize } = props; + private readonly helper = (moreProps: any, textWidth: number) => { + const { position, fontSize } = this.props; const { xScale, diff --git a/packages/interactive/src/components/InteractiveYCoordinate.tsx b/packages/interactive/src/components/InteractiveYCoordinate.tsx index 04cf550e1..2ab4d2f83 100644 --- a/packages/interactive/src/components/InteractiveYCoordinate.tsx +++ b/packages/interactive/src/components/InteractiveYCoordinate.tsx @@ -7,12 +7,10 @@ import { getStrokeDasharrayCanvas, getMouseCanvas, GenericChartComponent, - isDefined, - noop, strokeDashTypes, } from "@react-financial-charts/core"; -interface InteractiveYCoordinateProps { +export interface InteractiveYCoordinateProps { readonly bgFill: string; readonly bgOpacity: number; readonly stroke: string; @@ -28,14 +26,16 @@ interface InteractiveYCoordinateProps { readonly edge: object; readonly textBox: { closeIcon: any; + left: number; + height: number; padding: any; }; readonly yValue: number; - readonly onDragStart: any; // func - readonly onDrag: any; // func - readonly onDragComplete: any; // func - readonly onHover?: any; // func - readonly onUnHover?: any; // func + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly defaultClassName?: string; readonly interactiveCursorClass?: string; readonly tolerance: number; @@ -45,9 +45,6 @@ interface InteractiveYCoordinateProps { export class InteractiveYCoordinate extends React.Component { public static defaultProps = { - onDragStart: noop, - onDrag: noop, - onDragComplete: noop, fontWeight: "normal", // standard dev strokeWidth: 1, tolerance: 4, @@ -55,7 +52,7 @@ export class InteractiveYCoordinate extends React.Component { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { bgFill, bgOpacity, - textFill, fontFamily, fontSize, - fontStyle, fontWeight, stroke, @@ -98,11 +93,11 @@ export class InteractiveYCoordinate extends React.Component { + private readonly isHover = (moreProps: any) => { const { onHover } = this.props; - if (isDefined(onHover)) { - const values = helper(this.props, moreProps); + if (onHover !== undefined) { + const values = this.helper(moreProps); if (values == null) { return false; } @@ -190,28 +185,28 @@ export class InteractiveYCoordinate extends React.Component { + const { yValue, textBox } = this.props; - if (y >= 0 && y <= height) { - const rect = { - x: textBox.left, - y: y - textBox.height / 2, - height: textBox.height, - }; - return { - x1: 0, - x2: width, - y, - rect, - }; - } + const { + chartConfig: { width, yScale, height }, + } = moreProps; + + const y = Math.round(yScale(yValue)); + + if (y >= 0 && y <= height) { + const rect = { + x: textBox.left, + y: y - textBox.height / 2, + height: textBox.height, + }; + return { + x1: 0, + x2: width, + y, + rect, + }; + } + }; } diff --git a/packages/interactive/src/components/LinearRegressionChannelWithArea.tsx b/packages/interactive/src/components/LinearRegressionChannelWithArea.tsx index 18a07ae2e..f9b0d6273 100644 --- a/packages/interactive/src/components/LinearRegressionChannelWithArea.tsx +++ b/packages/interactive/src/components/LinearRegressionChannelWithArea.tsx @@ -5,8 +5,6 @@ import { getClosestItemIndexes, getMouseCanvas, GenericChartComponent, - isDefined, - noop, } from "@react-financial-charts/core"; import { isHovering2 } from "./StraightLine"; @@ -22,11 +20,11 @@ interface LinearRegressionChannelWithAreaProps { readonly fill: string; readonly fillOpacity: number; readonly strokeOpacity: number; - readonly onDragStart: any; // func - readonly onDrag: any; // func - readonly onDragComplete: any; // func - readonly onHover?: any; // func - readonly onUnHover?: any; // func + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly defaultClassName?: string; readonly tolerance: number; readonly selected: boolean; @@ -34,9 +32,6 @@ interface LinearRegressionChannelWithAreaProps { export class LinearRegressionChannelWithArea extends React.Component { public static defaultProps = { - onDragStart: noop, - onDrag: noop, - onDragComplete: noop, type: "SD", // standard dev strokeWidth: 1, tolerance: 4, @@ -45,7 +40,7 @@ export class LinearRegressionChannelWithArea extends React.Component { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { stroke, strokeWidth, fillOpacity, strokeOpacity, fill } = this.props; const { x1, y1, x2, y2, dy } = helper(this.props, moreProps); @@ -93,10 +91,10 @@ export class LinearRegressionChannelWithArea extends React.Component { + private readonly isHover = (moreProps: any) => { const { tolerance, onHover } = this.props; - if (isDefined(onHover)) { + if (onHover !== undefined) { const { mouseXY } = moreProps; const { x1, y1, x2, y2, dy } = helper(this.props, moreProps); @@ -112,21 +110,21 @@ export class LinearRegressionChannelWithArea extends React.Component void; + readonly onMouseDown: (e: React.MouseEvent, xyValue: number[], moreProps: any) => void; + readonly onClick: (e: React.MouseEvent, xyValue: number[], moreProps: any) => void; readonly r: number; readonly stroke: string; readonly strokeWidth: number; @@ -56,7 +56,7 @@ export class MouseLocationIndicator extends React.Component { + private readonly xy = (e: React.MouseEvent, moreProps: any) => { const { xAccessor, plotData } = moreProps; const { mouseXY, @@ -83,36 +83,36 @@ export class MouseLocationIndicator extends React.Component { - const pos = this.xy(moreProps, e); + private readonly handleClick = (e: React.MouseEvent, moreProps: any) => { + const pos = this.xy(e, moreProps); if (pos !== undefined && isDefined(pos)) { const { xValue, yValue, x, y } = pos; this.mutableState = { x, y }; - this.props.onClick([xValue, yValue], moreProps, e); + this.props.onClick(e, [xValue, yValue], moreProps); } }; - private readonly handleMouseDown = (moreProps, e) => { - const pos = this.xy(moreProps, e); + private readonly handleMouseDown = (e: React.MouseEvent, moreProps: any) => { + const pos = this.xy(e, moreProps); if (pos !== undefined && isDefined(pos)) { const { xValue, yValue, x, y } = pos; this.mutableState = { x, y }; - this.props.onMouseDown([xValue, yValue], moreProps, e); + this.props.onMouseDown(e, [xValue, yValue], moreProps); } }; - private readonly handleMousePosChange = (moreProps, e) => { + private readonly handleMousePosChange = (e: React.MouseEvent, moreProps: any) => { if (!shallowEqual(moreProps.mousXY, moreProps.prevMouseXY)) { - const pos = this.xy(moreProps, e); + const pos = this.xy(e, moreProps); if (pos !== undefined && isDefined(pos)) { const { xValue, yValue, x, y } = pos; this.mutableState = { x, y }; - this.props.onMouseMove([xValue, yValue], e); + this.props.onMouseMove(e, [xValue, yValue], moreProps); } } }; - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { enabled, r, stroke, strokeWidth } = this.props; const { x, y } = this.mutableState; const { show } = moreProps; diff --git a/packages/interactive/src/components/StraightLine.tsx b/packages/interactive/src/components/StraightLine.tsx index 893187918..ce897fe1a 100644 --- a/packages/interactive/src/components/StraightLine.tsx +++ b/packages/interactive/src/components/StraightLine.tsx @@ -24,11 +24,11 @@ interface StraightLineProps { | "LINE"; // extends between the set bounds readonly onEdge1Drag?: any; // func readonly onEdge2Drag?: any; // func - readonly onDragStart?: any; // func - readonly onDrag?: any; // func - readonly onDragComplete?: any; // func - readonly onHover?: any; // func - readonly onUnHover?: any; // func + readonly onDragStart?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDrag?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onHover?: (e: React.MouseEvent, moreProps: any) => void; + readonly onUnHover?: (e: React.MouseEvent, moreProps: any) => void; readonly defaultClassName?: string; readonly r?: number; readonly edgeFill?: string; @@ -45,8 +45,6 @@ class StraightLine extends React.Component { onEdge1Drag: noop, onEdge2Drag: noop, onDragStart: noop, - onDrag: noop, - onDragComplete: noop, edgeStrokeWidth: 3, edgeStroke: "#000000", edgeFill: "#FFFFFF", @@ -80,7 +78,7 @@ class StraightLine extends React.Component { ); } - private readonly isHover = (moreProps) => { + private readonly isHover = (moreProps: any) => { const { tolerance, onHover } = this.props; if (isDefined(onHover)) { @@ -107,7 +105,7 @@ class StraightLine extends React.Component { return false; }; - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { strokeWidth = StraightLine.defaultProps.strokeWidth, strokeDasharray, strokeStyle } = this.props; const { x1, y1, x2, y2 } = helper(this.props, moreProps); @@ -147,7 +145,7 @@ export function isHovering2(start, end, [mouseX, mouseY], tolerance) { } } -export function isHovering({ x1Value, y1Value, x2Value, y2Value, mouseXY, type, tolerance, xScale, yScale }) { +export function isHovering({ x1Value, y1Value, x2Value, y2Value, mouseXY, type, tolerance, xScale, yScale }: any) { const line = generateLine({ type, start: [x1Value, y1Value], @@ -182,7 +180,7 @@ export function isHovering({ x1Value, y1Value, x2Value, y2Value, mouseXY, type, } } -function helper(props, moreProps) { +function helper(props: any, moreProps: any) { const { x1Value, x2Value, y1Value, y2Value, type } = props; const { @@ -211,16 +209,16 @@ function helper(props, moreProps) { }; } -export function getSlope(start, end) { +export function getSlope(start: any, end: any) { const m /* slope */ = end[0] === start[0] ? undefined : (end[1] - start[1]) / (end[0] - start[0]); return m; } -export function getYIntercept(m, end) { +export function getYIntercept(m: any, end: any) { const b /* y intercept */ = -1 * m * end[0] + end[1]; return b; } -export function generateLine({ type, start, end, xScale, yScale }) { +export function generateLine({ type, start, end, xScale, yScale }: any) { const m /* slope */ = getSlope(start, end); const b /* y intercept */ = getYIntercept(m, start); @@ -252,7 +250,7 @@ export function generateLine({ type, start, end, xScale, yScale }) { } } -function getXLineCoordinates({ start, end, xScale, yScale, m, b }) { +function getXLineCoordinates({ start, end, xScale, yScale, m, b }: any) { const [xBegin, xFinish] = xScale.domain(); const [yBegin, yFinish] = yScale.domain(); @@ -274,7 +272,7 @@ function getXLineCoordinates({ start, end, xScale, yScale, m, b }) { }; } -function getRayCoordinates({ start, end, xScale, yScale, m, b }) { +function getRayCoordinates({ start, end, xScale, yScale, m, b }: any) { const [xBegin, xFinish] = xScale.domain(); const [yBegin, yFinish] = yScale.domain(); @@ -298,7 +296,7 @@ function getRayCoordinates({ start, end, xScale, yScale, m, b }) { }; } -function getLineCoordinates({ start, end }) { +function getLineCoordinates({ start, end }: any) { const [x1, y1] = start; const [x2, y2] = end; if (end[0] === start[0]) { diff --git a/packages/interactive/src/components/Text.tsx b/packages/interactive/src/components/Text.tsx index 44788ec8c..0a9fc3f3e 100644 --- a/packages/interactive/src/components/Text.tsx +++ b/packages/interactive/src/components/Text.tsx @@ -33,7 +33,7 @@ export class Text extends React.Component { return false; }; - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { xyProvider, fontFamily, fontSize, fillStyle, children } = this.props; const [x, y] = xyProvider(moreProps); diff --git a/packages/interactive/src/wrapper/EachEquidistantChannel.tsx b/packages/interactive/src/wrapper/EachEquidistantChannel.tsx index 18612b205..f4941a1c7 100644 --- a/packages/interactive/src/wrapper/EachEquidistantChannel.tsx +++ b/packages/interactive/src/wrapper/EachEquidistantChannel.tsx @@ -36,8 +36,8 @@ interface EachEquidistantChannelProps { r: number; }; readonly index?: number; - readonly onDrag: any; // func - readonly onDragComplete: any; // func + readonly onDrag: (e: React.MouseEvent, index: number | undefined, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; } interface EachEquidistantChannelState { @@ -50,7 +50,6 @@ export class EachEquidistantChannel extends React.Component { + private readonly handleChannelHeightChange = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { startXY, endXY } = this.dragStart; @@ -189,14 +188,14 @@ export class EachEquidistantChannel extends React.Component { + private readonly handleLine1Edge2Drag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { endXY } = this.dragStart; @@ -218,14 +217,14 @@ export class EachEquidistantChannel extends React.Component { + private readonly handleLine1Edge1Drag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { startXY } = this.dragStart; @@ -247,14 +246,14 @@ export class EachEquidistantChannel extends React.Component { + private readonly handleChannelDrag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { startXY, endXY } = this.dragStart; @@ -280,9 +279,7 @@ export class EachEquidistantChannel extends React.Component { + private readonly handleHover = (_: React.MouseEvent, moreProps) => { if (this.state.hover !== moreProps.hovering) { this.setState({ hover: moreProps.hovering, diff --git a/packages/interactive/src/wrapper/EachFibRetracement.tsx b/packages/interactive/src/wrapper/EachFibRetracement.tsx index 63158de0b..143c269f7 100644 --- a/packages/interactive/src/wrapper/EachFibRetracement.tsx +++ b/packages/interactive/src/wrapper/EachFibRetracement.tsx @@ -44,8 +44,8 @@ interface EachFibRetracementProps { selectedText: string; }; readonly index?: number; - readonly onDrag: any; // func - readonly onDragComplete: any; // func + readonly onDrag: (e: React.MouseEvent, index: number | undefined, moreProps: any) => void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; } interface EachFibRetracementState { @@ -70,7 +70,6 @@ export class EachFibRetracement extends React.Component { - const { index, onDrag } = this.props; - const { x1, y1, y2 } = this.props; + private readonly handleEdge2Drag = (e: React.MouseEvent, moreProps: any) => { + const { index, onDrag, x1, y1, y2 } = this.props; const [x2] = getNewXY(moreProps); - onDrag(index, { + onDrag(e, index, { x1, y1, x2, @@ -243,13 +241,12 @@ export class EachFibRetracement extends React.Component { - const { index, onDrag } = this.props; - const { y1, x2, y2 } = this.props; + private readonly handleEdge1Drag = (e: React.MouseEvent, moreProps: any) => { + const { index, onDrag, y1, x2, y2 } = this.props; const [x1] = getNewXY(moreProps); - onDrag(index, { + onDrag(e, index, { x1, y1, x2, @@ -257,13 +254,12 @@ export class EachFibRetracement extends React.Component { - const { index, onDrag } = this.props; - const { x1, y1, x2 } = this.props; + private readonly handleLineNSResizeBottom = (e: React.MouseEvent, moreProps: any) => { + const { index, onDrag, x1, y1, x2 } = this.props; const [, y2] = getNewXY(moreProps); - onDrag(index, { + onDrag(e, index, { x1, y1, x2, @@ -271,13 +267,12 @@ export class EachFibRetracement extends React.Component { - const { index, onDrag } = this.props; - const { x1, x2, y2 } = this.props; + private readonly handleLineNSResizeTop = (e: React.MouseEvent, moreProps: any) => { + const { index, onDrag, x1, x2, y2 } = this.props; const [, y1] = getNewXY(moreProps); - onDrag(index, { + onDrag(e, index, { x1, y1, x2, @@ -285,7 +280,7 @@ export class EachFibRetracement extends React.Component { + private readonly handleLineMove = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { x1: x1Value, y1: y1Value, x2: x2Value, y2: y2Value } = this.dragStart; @@ -311,7 +306,7 @@ export class EachFibRetracement extends React.Component { + private readonly handleHover = (_: React.MouseEvent, moreProps: any) => { if (this.state.hover !== moreProps.hovering) { this.setState({ hover: moreProps.hovering, @@ -339,7 +334,7 @@ export class EachFibRetracement extends React.Component ({ percent: each, diff --git a/packages/interactive/src/wrapper/EachGannFan.tsx b/packages/interactive/src/wrapper/EachGannFan.tsx index eabd3f950..ee19e2b1f 100644 --- a/packages/interactive/src/wrapper/EachGannFan.tsx +++ b/packages/interactive/src/wrapper/EachGannFan.tsx @@ -41,8 +41,8 @@ interface EachGannFanProps { selectedText: string; }; index?: number; - onDrag: any; // func - onDragComplete: any; // func + onDrag: (e: React.MouseEvent, index: number | undefined, moreProps: any) => void; + onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; } interface EachGannFanState { @@ -69,7 +69,6 @@ export class EachGannFan extends React.Component { + private readonly handleLine1Edge2Drag = (e: React.MouseEvent, moreProps) => { const { index, onDrag } = this.props; const { endXY } = this.dragStart; @@ -200,14 +199,14 @@ export class EachGannFan extends React.Component { + private readonly handleLine1Edge1Drag = (e: React.MouseEvent, moreProps) => { const { index, onDrag } = this.props; const { startXY } = this.dragStart; @@ -229,14 +228,14 @@ export class EachGannFan extends React.Component { + private readonly handleFanDrag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { startXY, endXY } = this.dragStart; @@ -264,7 +263,7 @@ export class EachGannFan extends React.Component void; + readonly onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; + readonly onDelete?: (e: React.MouseEvent, index: number | undefined, moreProps: any) => void; } interface EachInteractiveYCoordinateState { @@ -44,8 +43,6 @@ export class EachInteractiveYCoordinate extends React.Component< EachInteractiveYCoordinateState > { public static defaultProps = { - onDrag: noop, - onDragComplete: noop, strokeWidth: 1, opacity: 1, selected: false, @@ -151,7 +148,7 @@ export class EachInteractiveYCoordinate extends React.Component< ); } - private readonly handleCloseIconHover = (moreProps) => { + private readonly handleCloseIconHover = (_: React.MouseEvent, moreProps: any) => { if (this.state.closeIconHover !== moreProps.hovering) { this.setState({ closeIconHover: moreProps.hovering, @@ -159,7 +156,7 @@ export class EachInteractiveYCoordinate extends React.Component< } }; - private readonly handleHover = (moreProps) => { + private readonly handleHover = (e: React.MouseEvent, moreProps: any) => { if (this.state.hover !== moreProps.hovering) { this.setState({ hover: moreProps.hovering, @@ -168,13 +165,19 @@ export class EachInteractiveYCoordinate extends React.Component< } }; - private readonly handleDelete = (moreProps) => { + private readonly handleDelete = (e: React.MouseEvent, moreProps: any) => { const { index, onDelete } = this.props; - onDelete(index, moreProps); + if (onDelete !== undefined) { + onDelete(e, index, moreProps); + } }; - private readonly handleDrag = (moreProps) => { + private readonly handleDrag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; + if (onDrag === undefined) { + return; + } + const { mouseXY: [, mouseY], chartConfig: { yScale }, @@ -184,10 +187,10 @@ export class EachInteractiveYCoordinate extends React.Component< const newYValue = yScale.invert(mouseY - dy); - onDrag(index, newYValue); + onDrag(e, index, newYValue); }; - private readonly handleDragStart = (moreProps) => { + private readonly handleDragStart = (_: React.MouseEvent, moreProps: any) => { const { yValue } = this.props; const { mouseXY } = moreProps; const { diff --git a/packages/interactive/src/wrapper/EachLinearRegressionChannel.tsx b/packages/interactive/src/wrapper/EachLinearRegressionChannel.tsx index 52eae8d4b..21818710c 100644 --- a/packages/interactive/src/wrapper/EachLinearRegressionChannel.tsx +++ b/packages/interactive/src/wrapper/EachLinearRegressionChannel.tsx @@ -86,7 +86,7 @@ export class EachLinearRegressionChannel extends React.Component< private isHover; private saveNodeType; - constructor(props) { + public constructor(props) { super(props); this.isHover = isHover.bind(this); @@ -177,7 +177,7 @@ export class EachLinearRegressionChannel extends React.Component< ); } - private readonly handleHover = (moreProps) => { + private readonly handleHover = (_: React.MouseEvent, moreProps: any) => { if (this.state.hover !== moreProps.hovering) { this.setState({ hover: moreProps.hovering, @@ -185,32 +185,32 @@ export class EachLinearRegressionChannel extends React.Component< } }; - private readonly handleEdge2Drag = (moreProps) => { + private readonly handleEdge2Drag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag, snapTo } = this.props; const { x1Value } = this.props; const [x2Value] = getNewXY(moreProps, snapTo); - onDrag(index, { + onDrag(e, index, { x1Value, x2Value, }); }; - private readonly handleEdge1Drag = (moreProps) => { + private readonly handleEdge1Drag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag, snapTo } = this.props; const { x2Value } = this.props; const [x1Value] = getNewXY(moreProps, snapTo); - onDrag(index, { + onDrag(e, index, { x1Value, x2Value, }); }; } -export function getNewXY(moreProps, snapTo) { +export function getNewXY(moreProps: any, snapTo: any) { const { xScale, xAccessor, plotData, mouseXY } = moreProps; const currentItem = getCurrentItem(xScale, xAccessor, mouseXY, plotData); diff --git a/packages/interactive/src/wrapper/EachText.tsx b/packages/interactive/src/wrapper/EachText.tsx index 7c765e5ee..14780e522 100644 --- a/packages/interactive/src/wrapper/EachText.tsx +++ b/packages/interactive/src/wrapper/EachText.tsx @@ -1,9 +1,6 @@ import * as React from "react"; - -import { noop } from "@react-financial-charts/core"; import { getXValue } from "@react-financial-charts/core/lib/utils/ChartDataUtil"; import { isHover, saveNodeType } from "../utils"; - import { HoverTextNearMouse } from "../components/HoverTextNearMouse"; import { InteractiveText } from "../components/InteractiveText"; @@ -21,8 +18,8 @@ interface EachTextProps { fontSize: number; text: string; selected: boolean; - onDrag: any; // func - onDragComplete: any; // func + onDrag?: (e: React.MouseEvent, index: number | undefined, xyValue: number[]) => void; + onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; hoverText: { enable: boolean; fontFamily: string; @@ -43,8 +40,6 @@ interface EachTextState { export class EachText extends React.Component { public static defaultProps = { - onDrag: noop, - onDragComplete: noop, bgOpacity: 1, bgStrokeWidth: 1, selected: false, @@ -63,7 +58,7 @@ export class EachText extends React.Component { private isHover; private saveNodeType; - constructor(props) { + public constructor(props) { super(props); this.handleHover = this.handleHover.bind(this); @@ -141,7 +136,7 @@ export class EachText extends React.Component { ); } - private readonly handleHover = (moreProps) => { + private readonly handleHover = (_: React.MouseEvent, moreProps: any) => { if (this.state.hover !== moreProps.hovering) { this.setState({ hover: moreProps.hovering, @@ -149,8 +144,12 @@ export class EachText extends React.Component { } }; - private readonly handleDrag = (moreProps) => { + private readonly handleDrag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; + if (onDrag === undefined) { + return; + } + const { mouseXY: [, mouseY], chartConfig: { yScale }, @@ -165,10 +164,10 @@ export class EachText extends React.Component { // xScale.invert(xScale(xAccessor(currentItem)) - dx); const xyValue = [xValue, yScale.invert(mouseY - dy)]; - onDrag(index, xyValue); + onDrag(e, index, xyValue); }; - private readonly handleDragStart = (moreProps) => { + private readonly handleDragStart = (_: React.MouseEvent, moreProps: any) => { const { position } = this.props; const { mouseXY } = moreProps; const { diff --git a/packages/interactive/src/wrapper/EachTrendLine.tsx b/packages/interactive/src/wrapper/EachTrendLine.tsx index e0d2e5e04..7ea3dbc77 100644 --- a/packages/interactive/src/wrapper/EachTrendLine.tsx +++ b/packages/interactive/src/wrapper/EachTrendLine.tsx @@ -19,10 +19,10 @@ interface EachTrendLineProps { | "XLINE" // extends from -Infinity to +Infinity | "RAY" // extends to +/-Infinity in one direction | "LINE"; // extends between the set bounds - onDrag: any; // func + onDrag: (e: React.MouseEvent, index: number | undefined, moreProps: any) => void; onEdge1Drag: any; // func onEdge2Drag: any; // func - onDragComplete: any; // func + onDragComplete?: (e: React.MouseEvent, moreProps: any) => void; onSelect: any; // func onUnSelect: any; // func r: number; @@ -61,7 +61,6 @@ export class EachTrendLine extends React.Component { + private readonly handleHover = (_: React.MouseEvent, moreProps: any) => { if (this.state.hover !== moreProps.hovering) { this.setState({ hover: moreProps.hovering, @@ -187,13 +186,13 @@ export class EachTrendLine extends React.Component { + private readonly handleEdge2Drag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { x1Value, y1Value } = this.props; const [x2Value, y2Value] = getNewXY(moreProps); - onDrag(index, { + onDrag(e, index, { x1Value, y1Value, x2Value, @@ -201,13 +200,13 @@ export class EachTrendLine extends React.Component { + private readonly handleEdge1Drag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { x2Value, y2Value } = this.props; const [x1Value, y1Value] = getNewXY(moreProps); - onDrag(index, { + onDrag(e, index, { x1Value, y1Value, x2Value, @@ -215,11 +214,17 @@ export class EachTrendLine extends React.Component { + private readonly handleDragComplete = (e: React.MouseEvent, moreProps: any) => { this.setState({ anchor: undefined, }); - this.props.onDragComplete(...rest); + + const { onDragComplete } = this.props; + if (onDragComplete === undefined) { + return; + } + + onDragComplete(e, moreProps); }; private readonly handleEdge2DragStart = () => { @@ -234,7 +239,7 @@ export class EachTrendLine extends React.Component { + private readonly handleLineDrag = (e: React.MouseEvent, moreProps: any) => { const { index, onDrag } = this.props; const { x1Value, y1Value, x2Value, y2Value } = this.dragStart; @@ -260,7 +265,7 @@ export class EachTrendLine extends React.Component { +const evaluateLevel = (row: any, date: Date, i: number, formatters: any) => { return levelDefinition .map((eachLevel, idx) => { return { @@ -18,7 +18,7 @@ const evaluateLevel = (row, date: Date, i, formatters) => { const discontinuousIndexCalculator = slidingWindow() .windowSize(2) - .undefinedValue((d: Date, idx, { initialIndex, formatters }) => { + .undefinedValue((d: Date, idx: number, { initialIndex, formatters }: any) => { const i = initialIndex; const row = { date: d.getTime(), @@ -44,7 +44,7 @@ const discontinuousIndexCalculator = slidingWindow() }); const discontinuousIndexCalculatorLocalTime = discontinuousIndexCalculator.accumulator( - ([prevDate, nowDate], i: number, idx, { initialIndex, formatters }) => { + ([prevDate, nowDate]: [Date, Date], i: number, idx: number, { initialIndex, formatters }: any) => { const startOf30Seconds = nowDate.getSeconds() % 30 === 0; const startOfMinute = nowDate.getMinutes() !== prevDate.getMinutes(); @@ -94,8 +94,8 @@ const discontinuousIndexCalculatorLocalTime = discontinuousIndexCalculator.accum }, ); -function doStuff(realDateAccessor, inputDateAccessor, initialIndex, formatters) { - return function (data) { +function doStuff(realDateAccessor: any, inputDateAccessor: any, initialIndex: any, formatters: any) { + return function (data: any[]) { const dateAccessor = realDateAccessor(inputDateAccessor); const calculate = discontinuousIndexCalculatorLocalTime.source(dateAccessor).misc({ initialIndex, formatters }); @@ -116,15 +116,15 @@ function doStuff(realDateAccessor, inputDateAccessor, initialIndex, formatters) export function discontinuousTimeScaleProviderBuilder() { let initialIndex = 0; - let realDateAccessor = identity; - let inputDateAccessor = (d) => d.date; - let indexAccessor = (d) => d.idx; - let indexMutator = (d, idx) => ({ ...d, idx }); - let withIndex; + let realDateAccessor = identity as (x: any) => any; + let inputDateAccessor = (d: any) => d.date; + let indexAccessor = (d: any) => d.idx; + let indexMutator = (d: any, idx: any) => ({ ...d, idx }); + let withIndex: any; let currentFormatters = defaultFormatters; - const discontinuousTimeScaleProvider = function (data) { + const discontinuousTimeScaleProvider = function (data: any[]) { let index = withIndex; if (index === undefined) { @@ -139,46 +139,45 @@ export function discontinuousTimeScaleProviderBuilder() { const mergedData = zipper().combine(indexMutator); - // @ts-ignore const finalData = mergedData(data, inputIndex); return { data: finalData, xScale, - xAccessor: (d) => d && indexAccessor(d).index, + xAccessor: (d: any) => d && indexAccessor(d).index, displayXAccessor: realDateAccessor(inputDateAccessor), }; }; - discontinuousTimeScaleProvider.initialIndex = function (x) { + discontinuousTimeScaleProvider.initialIndex = function (x: any) { if (!arguments.length) { return initialIndex; } initialIndex = x; return discontinuousTimeScaleProvider; }; - discontinuousTimeScaleProvider.inputDateAccessor = function (x) { + discontinuousTimeScaleProvider.inputDateAccessor = function (x: any) { if (!arguments.length) { return inputDateAccessor; } inputDateAccessor = x; return discontinuousTimeScaleProvider; }; - discontinuousTimeScaleProvider.indexAccessor = function (x) { + discontinuousTimeScaleProvider.indexAccessor = function (x: any) { if (!arguments.length) { return indexAccessor; } indexAccessor = x; return discontinuousTimeScaleProvider; }; - discontinuousTimeScaleProvider.indexMutator = function (x) { + discontinuousTimeScaleProvider.indexMutator = function (x: any) { if (!arguments.length) { return indexMutator; } indexMutator = x; return discontinuousTimeScaleProvider; }; - discontinuousTimeScaleProvider.withIndex = function (x) { + discontinuousTimeScaleProvider.withIndex = function (x: any) { if (!arguments.length) { return withIndex; } @@ -186,7 +185,7 @@ export function discontinuousTimeScaleProviderBuilder() { return discontinuousTimeScaleProvider; }; discontinuousTimeScaleProvider.utc = function () { - realDateAccessor = (dateAccessor) => (d) => { + realDateAccessor = (dateAccessor) => (d: any) => { const date = dateAccessor(d); // The getTimezoneOffset() method returns the time-zone offset from UTC, in minutes, for the current locale. const offsetInMillis = date.getTimezoneOffset() * 60 * 1000; @@ -194,7 +193,7 @@ export function discontinuousTimeScaleProviderBuilder() { }; return discontinuousTimeScaleProvider; }; - discontinuousTimeScaleProvider.setLocale = function (locale, formatters = null) { + discontinuousTimeScaleProvider.setLocale = function (locale: any, formatters = null) { if (locale) { timeFormatDefaultLocale(locale); } diff --git a/packages/scales/src/financeDiscontinuousScale.ts b/packages/scales/src/financeDiscontinuousScale.ts index c2b2ddd3a..a52f6fa1c 100644 --- a/packages/scales/src/financeDiscontinuousScale.ts +++ b/packages/scales/src/financeDiscontinuousScale.ts @@ -1,54 +1,54 @@ import { head, isDefined, last } from "@react-financial-charts/core"; import { ascending } from "d3-array"; -import { scaleLinear } from "d3-scale"; +import { scaleLinear, InterpolatorFactory } from "d3-scale"; import { levelDefinition } from "./levels"; const MAX_LEVEL = levelDefinition.length - 1; -export default function financeDiscontinuousScale(index, backingLinearScale = scaleLinear()) { +export default function financeDiscontinuousScale(index: any[], backingLinearScale = scaleLinear()) { if (index === undefined) { throw new Error("Use the discontinuousTimeScaleProvider to create financeDiscontinuousScale"); } - function scale(x) { + function scale(x: number) { return backingLinearScale(x); } - scale.invert = function (x) { + scale.invert = function (x: number) { const inverted = backingLinearScale.invert(x); return Math.round(inverted * 10000) / 10000; }; - scale.domain = function (x) { + scale.domain = function (domain: number[]) { if (!arguments.length) { return backingLinearScale.domain(); } - backingLinearScale.domain(x); + backingLinearScale.domain(domain); return scale; }; - scale.range = function (x) { + scale.range = function (range: number[]) { if (!arguments.length) { return backingLinearScale.range(); } - backingLinearScale.range(x); + backingLinearScale.range(range); return scale; }; - scale.rangeRound = function (x) { - return backingLinearScale.range(x); + scale.rangeRound = function (range: number[]) { + return backingLinearScale.range(range); }; - scale.clamp = function (x) { + scale.clamp = function (clamp: boolean) { if (!arguments.length) { return backingLinearScale.clamp(); } - backingLinearScale.clamp(x); + backingLinearScale.clamp(clamp); return scale; }; - scale.interpolate = function (x) { + scale.interpolate = function (interpolate: InterpolatorFactory) { if (!arguments.length) { return backingLinearScale.interpolate(); } - backingLinearScale.interpolate(x); + backingLinearScale.interpolate(interpolate); return scale; }; - scale.ticks = function (m) { + scale.ticks = function (m?: number) { const backingTicks = backingLinearScale.ticks(m); const ticksMap = new Map(); @@ -113,24 +113,24 @@ export default function financeDiscontinuousScale(index, backingLinearScale = sc return ticks; }; scale.tickFormat = function () { - return function (x) { + return function (x: any) { const d = Math.abs(head(index).index); const { format, date } = index[Math.floor(x + d)]; return format(date); }; }; - scale.value = function (x) { + scale.value = function (x: any) { const d = Math.abs(head(index).index); if (isDefined(index[Math.floor(x + d)])) { const { date } = index[Math.floor(x + d)]; return date; } }; - scale.nice = function (m) { - backingLinearScale.nice(m); + scale.nice = function (count?: number) { + backingLinearScale.nice(count); return scale; }; - scale.index = function (x) { + scale.index = function (x: any) { if (!arguments.length) { return index; } diff --git a/packages/scales/src/index.ts b/packages/scales/src/index.ts index 12bbb9c54..fcf7f34c0 100644 --- a/packages/scales/src/index.ts +++ b/packages/scales/src/index.ts @@ -6,5 +6,5 @@ export { export { default as financeDiscontinuousScale } from "./financeDiscontinuousScale"; export const defaultScaleProvider = (xScale: ScaleContinuousNumeric) => { - return (data, xAccessor) => ({ data, xScale, xAccessor, displayXAccessor: xAccessor }); + return (data: any, xAccessor: any) => ({ data, xScale, xAccessor, displayXAccessor: xAccessor }); }; diff --git a/packages/scales/src/levels.ts b/packages/scales/src/levels.ts index 287eebabd..3e074c3d3 100644 --- a/packages/scales/src/levels.ts +++ b/packages/scales/src/levels.ts @@ -12,24 +12,24 @@ export const defaultFormatters = { }; export const levelDefinition = [ - /* 19 */ (d, date: Date, i: number) => d.startOfYear && date.getFullYear() % 12 === 0 && "yearFormat", - /* 18 */ (d, date: Date, i: number) => d.startOfYear && date.getFullYear() % 4 === 0 && "yearFormat", - /* 17 */ (d, date: Date, i: number) => d.startOfYear && date.getFullYear() % 2 === 0 && "yearFormat", - /* 16 */ (d, date: Date, i: number) => d.startOfYear && "yearFormat", - /* 15 */ (d, date: Date, i: number) => d.startOfQuarter && "quarterFormat", - /* 14 */ (d, date: Date, i: number) => d.startOfMonth && "monthFormat", - /* 13 */ (d, date: Date, i: number) => d.startOfWeek && "weekFormat", - /* 12 */ (d, date: Date, i: number) => d.startOfDay && i % 2 === 0 && "dayFormat", - /* 11 */ (d, date: Date, i: number) => d.startOfDay && "dayFormat", - /* 10 */ (d, date: Date, i: number) => d.startOfHalfDay && "hourFormat", // 12h - /* 9 */ (d, date: Date, i: number) => d.startOfQuarterDay && "hourFormat", // 6h - /* 8 */ (d, date: Date, i: number) => d.startOfEighthOfADay && "hourFormat", // 3h - /* 7 */ (d, date: Date, i: number) => d.startOfHour && date.getHours() % 2 === 0 && "hourFormat", // 2h -- REMOVE THIS - /* 6 */ (d, date: Date, i: number) => d.startOfHour && "hourFormat", // 1h - /* 5 */ (d, date: Date, i: number) => d.startOf30Minutes && "minuteFormat", - /* 4 */ (d, date: Date, i: number) => d.startOf15Minutes && "minuteFormat", - /* 3 */ (d, date: Date, i: number) => d.startOf5Minutes && "minuteFormat", - /* 2 */ (d, date: Date, i: number) => d.startOfMinute && "minuteFormat", - /* 1 */ (d, date: Date, i: number) => d.startOf30Seconds && "secondFormat", - /* 0 */ (d, date: Date, i: number) => "secondFormat", + /* 19 */ (d: any, date: Date, i: number) => d.startOfYear && date.getFullYear() % 12 === 0 && "yearFormat", + /* 18 */ (d: any, date: Date, i: number) => d.startOfYear && date.getFullYear() % 4 === 0 && "yearFormat", + /* 17 */ (d: any, date: Date, i: number) => d.startOfYear && date.getFullYear() % 2 === 0 && "yearFormat", + /* 16 */ (d: any, date: Date, i: number) => d.startOfYear && "yearFormat", + /* 15 */ (d: any, date: Date, i: number) => d.startOfQuarter && "quarterFormat", + /* 14 */ (d: any, date: Date, i: number) => d.startOfMonth && "monthFormat", + /* 13 */ (d: any, date: Date, i: number) => d.startOfWeek && "weekFormat", + /* 12 */ (d: any, date: Date, i: number) => d.startOfDay && i % 2 === 0 && "dayFormat", + /* 11 */ (d: any, date: Date, i: number) => d.startOfDay && "dayFormat", + /* 10 */ (d: any, date: Date, i: number) => d.startOfHalfDay && "hourFormat", // 12h + /* 9 */ (d: any, date: Date, i: number) => d.startOfQuarterDay && "hourFormat", // 6h + /* 8 */ (d: any, date: Date, i: number) => d.startOfEighthOfADay && "hourFormat", // 3h + /* 7 */ (d: any, date: Date, i: number) => d.startOfHour && date.getHours() % 2 === 0 && "hourFormat", // 2h -- REMOVE THIS + /* 6 */ (d: any, date: Date, i: number) => d.startOfHour && "hourFormat", // 1h + /* 5 */ (d: any, date: Date, i: number) => d.startOf30Minutes && "minuteFormat", + /* 4 */ (d: any, date: Date, i: number) => d.startOf15Minutes && "minuteFormat", + /* 3 */ (d: any, date: Date, i: number) => d.startOf5Minutes && "minuteFormat", + /* 2 */ (d: any, date: Date, i: number) => d.startOfMinute && "minuteFormat", + /* 1 */ (d: any, date: Date, i: number) => d.startOf30Seconds && "secondFormat", + /* 0 */ (d: any, date: Date, i: number) => "secondFormat", ]; diff --git a/packages/scales/tsconfig.json b/packages/scales/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/scales/tsconfig.json +++ b/packages/scales/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/series/src/AlternatingFillAreaSeries.tsx b/packages/series/src/AlternatingFillAreaSeries.tsx index 09153b913..d97342185 100644 --- a/packages/series/src/AlternatingFillAreaSeries.tsx +++ b/packages/series/src/AlternatingFillAreaSeries.tsx @@ -115,7 +115,7 @@ export class AlternatingFillAreaSeries extends React.Component { + private readonly renderClip = (moreProps: any) => { const { chartConfig } = moreProps; const { baseAt } = this.props; const { yScale, width, height } = chartConfig; @@ -132,7 +132,7 @@ export class AlternatingFillAreaSeries extends React.Component { + private readonly bottomClip = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { chartConfig } = moreProps; const { baseAt } = this.props; const { yScale, width, height } = chartConfig; @@ -142,7 +142,7 @@ export class AlternatingFillAreaSeries extends React.Component { + private readonly topClip = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { chartConfig } = moreProps; const { baseAt } = this.props; const { yScale, width } = chartConfig; diff --git a/packages/series/src/AreaOnlySeries.tsx b/packages/series/src/AreaOnlySeries.tsx index 0405b531a..3b96cf8eb 100644 --- a/packages/series/src/AreaOnlySeries.tsx +++ b/packages/series/src/AreaOnlySeries.tsx @@ -1,7 +1,7 @@ import { first, functor, getAxisCanvas, GenericChartComponent } from "@react-financial-charts/core"; +import { ScaleContinuousNumeric } from "d3-scale"; import { area as d3Area, CurveFactory } from "d3-shape"; import * as React from "react"; -import { ScaleContinuousNumeric } from "d3-scale"; export interface AreaOnlySeriesProps { readonly base?: @@ -29,14 +29,14 @@ export interface AreaOnlySeriesProps { export class AreaOnlySeries extends React.Component { public static defaultProps = { defined: (d: number) => !isNaN(d), - base: (yScale) => first(yScale.range()), + base: (yScale: ScaleContinuousNumeric) => first(yScale.range()), }; public render() { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { fillStyle, interpolation, diff --git a/packages/series/src/BarSeries.tsx b/packages/series/src/BarSeries.tsx index f38e1f7b3..48c1c6e9d 100644 --- a/packages/series/src/BarSeries.tsx +++ b/packages/series/src/BarSeries.tsx @@ -14,7 +14,12 @@ import { drawOnCanvasHelper, identityStack } from "./StackedBarSeries"; export interface BarSeriesProps { readonly baseAt?: | number - | ((yScale: ScaleContinuousNumeric, d: [number, number], moreProps: any) => number); + | (( + xScale: ScaleContinuousNumeric, + yScale: ScaleContinuousNumeric, + d: [number, number], + moreProps: any, + ) => number); readonly clip?: boolean; readonly fillStyle?: | string @@ -34,7 +39,10 @@ export interface BarSeriesProps { */ export class BarSeries extends React.Component { public static defaultProps = { - baseAt: (xScale, yScale /* , d*/) => head(yScale.range()), + baseAt: ( + xScale: ScaleContinuousNumeric, + yScale: ScaleContinuousNumeric /* , d*/, + ) => head(yScale.range()), clip: true, direction: "up", fillStyle: "rgba(70, 130, 180, 0.5)", @@ -57,7 +65,7 @@ export class BarSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { if (this.props.swapScales) { const { xAccessor } = moreProps; @@ -91,7 +99,7 @@ export class BarSeries extends React.Component { } }; - private readonly getBars = (moreProps) => { + private readonly getBars = (moreProps: any) => { const { baseAt, fillStyle, width, yAccessor } = this.props; const { @@ -114,8 +122,8 @@ export class BarSeries extends React.Component { const offset = Math.floor(0.5 * barWidth); return plotData - .filter((d) => isDefined(yAccessor(d))) - .map((d) => { + .filter((d: any) => isDefined(yAccessor(d))) + .map((d: any) => { const xValue = xAccessor(d); const yValue = yAccessor(d); let y = yScale(yValue); diff --git a/packages/series/src/BollingerSeries.tsx b/packages/series/src/BollingerSeries.tsx index 9e97a9e80..7debcf861 100644 --- a/packages/series/src/BollingerSeries.tsx +++ b/packages/series/src/BollingerSeries.tsx @@ -44,25 +44,25 @@ export class BollingerSeries extends React.Component { ); } - private readonly yAccessorForScaledBottom = (scale: ScaleContinuousNumeric, d) => { + private readonly yAccessorForScaledBottom = (scale: ScaleContinuousNumeric, d: any) => { const { yAccessor = BollingerSeries.defaultProps.yAccessor } = this.props; return scale(yAccessor(d) && yAccessor(d).bottom); }; - private readonly yAccessorForBottom = (d) => { + private readonly yAccessorForBottom = (d: any) => { const { yAccessor = BollingerSeries.defaultProps.yAccessor } = this.props; return yAccessor(d) && yAccessor(d).bottom; }; - private readonly yAccessorForMiddle = (d) => { + private readonly yAccessorForMiddle = (d: any) => { const { yAccessor = BollingerSeries.defaultProps.yAccessor } = this.props; return yAccessor(d) && yAccessor(d).middle; }; - private readonly yAccessorForTop = (d) => { + private readonly yAccessorForTop = (d: any) => { const { yAccessor = BollingerSeries.defaultProps.yAccessor } = this.props; return yAccessor(d) && yAccessor(d).top; diff --git a/packages/series/src/CandlestickSeries.tsx b/packages/series/src/CandlestickSeries.tsx index 9d36b5bc1..255506d77 100644 --- a/packages/series/src/CandlestickSeries.tsx +++ b/packages/series/src/CandlestickSeries.tsx @@ -50,15 +50,15 @@ export class CandlestickSeries extends React.Component { candleClassName: "react-financial-charts-candlestick-candle", candleStrokeWidth: 0.5, className: "react-financial-charts-candlestick", - classNames: (d) => (d.close > d.open ? "up" : "down"), + classNames: (d: any) => (d.close > d.open ? "up" : "down"), clip: true, - fill: (d) => (d.close > d.open ? "#26a69a" : "#ef5350"), - stroke: (d) => (d.close > d.open ? "#26a69a" : "#ef5350"), + fill: (d: any) => (d.close > d.open ? "#26a69a" : "#ef5350"), + stroke: (d: any) => (d.close > d.open ? "#26a69a" : "#ef5350"), wickClassName: "react-financial-charts-candlestick-wick", - wickStroke: (d) => (d.close > d.open ? "#26a69a" : "#ef5350"), + wickStroke: (d: any) => (d.close > d.open ? "#26a69a" : "#ef5350"), width: plotDataLengthBarWidth, widthRatio: 0.8, - yAccessor: (d) => ({ open: d.open, high: d.high, low: d.low, close: d.close }), + yAccessor: (d: any) => ({ open: d.open, high: d.high, low: d.low, close: d.close }), }; public render() { @@ -74,7 +74,7 @@ export class CandlestickSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { candleStrokeWidth = CandlestickSeries.defaultProps.candleStrokeWidth } = this.props; const { xScale, diff --git a/packages/series/src/ElderRaySeries.tsx b/packages/series/src/ElderRaySeries.tsx index fbf4c2ec9..6415ac3a9 100644 --- a/packages/series/src/ElderRaySeries.tsx +++ b/packages/series/src/ElderRaySeries.tsx @@ -93,7 +93,7 @@ export class ElderRaySeries extends React.Component { ); }; - private readonly yAccessorForBarBase = (_, yScale, d) => { + private readonly yAccessorForBarBase = (_: any, yScale: any, d: any) => { const { yAccessor } = this.props; const y = yAccessor(d) && Math.min(yAccessor(d).bearPower, 0); return yScale(y); diff --git a/packages/series/src/GroupedBarSeries.tsx b/packages/series/src/GroupedBarSeries.tsx index bedfbd8fb..c686a83c3 100644 --- a/packages/series/src/GroupedBarSeries.tsx +++ b/packages/series/src/GroupedBarSeries.tsx @@ -28,7 +28,7 @@ export class GroupedBarSeries extends React.Component { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { xAccessor } = moreProps; drawOnCanvasHelper(ctx, this.props, moreProps, xAccessor, identityStack, this.postProcessor); diff --git a/packages/series/src/KagiSeries.tsx b/packages/series/src/KagiSeries.tsx index 6bb4eabf5..8a60bd3e9 100644 --- a/packages/series/src/KagiSeries.tsx +++ b/packages/series/src/KagiSeries.tsx @@ -38,7 +38,7 @@ export class KagiSeries extends React.Component { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { stroke = KagiSeries.defaultProps.stroke, strokeWidth, currentValueStroke } = this.props; const { xAccessor, @@ -52,14 +52,15 @@ export class KagiSeries extends React.Component { let begin = true; paths.forEach((each) => { + // @ts-ignore ctx.strokeStyle = stroke[each.type]; if (strokeWidth !== undefined) { ctx.lineWidth = strokeWidth; } ctx.beginPath(); - let prevX; - each.plot.forEach((d) => { + let prevX: any; + each.plot.forEach((d: any) => { const [x1, y] = [xScale(d[0]), yScale(d[1])]; if (begin) { ctx.moveTo(x1, y); @@ -95,7 +96,7 @@ export class KagiSeries extends React.Component { }; } -const helper = (plotData: any[], xAccessor) => { +const helper = (plotData: any[], xAccessor: any) => { const kagiLine: any[] = []; let kagi: { added?: boolean; diff --git a/packages/series/src/LineSeries.tsx b/packages/series/src/LineSeries.tsx index 6e3dae91f..6e78a118b 100644 --- a/packages/series/src/LineSeries.tsx +++ b/packages/series/src/LineSeries.tsx @@ -85,7 +85,7 @@ export class LineSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { connectNulls, yAccessor, @@ -142,7 +142,7 @@ export class LineSeries extends React.Component { } }; - private readonly isHover = (moreProps) => { + private readonly isHover = (moreProps: any) => { const { highlightOnHover, yAccessor, hoverTolerance = LineSeries.defaultProps.hoverTolerance } = this.props; if (!highlightOnHover) { return false; diff --git a/packages/series/src/MACDSeries.tsx b/packages/series/src/MACDSeries.tsx index 9cf611a81..c3397a565 100644 --- a/packages/series/src/MACDSeries.tsx +++ b/packages/series/src/MACDSeries.tsx @@ -1,5 +1,5 @@ +import { ScaleContinuousNumeric } from "d3-scale"; import * as React from "react"; - import { BarSeries } from "./BarSeries"; import { LineSeries } from "./LineSeries"; import { StraightLine } from "./StraightLine"; @@ -72,21 +72,24 @@ export class MACDSeries extends React.Component { ); } - private readonly yAccessorForDivergenceBase = (xScale, yScale) => { + private readonly yAccessorForDivergenceBase = ( + xScale: ScaleContinuousNumeric, + yScale: ScaleContinuousNumeric, + ) => { return yScale(0); }; - private readonly yAccessorForDivergence = (d) => { + private readonly yAccessorForDivergence = (d: any) => { const { yAccessor } = this.props; return yAccessor(d) && yAccessor(d).divergence; }; - private readonly yAccessorForSignal = (d) => { + private readonly yAccessorForSignal = (d: any) => { const { yAccessor } = this.props; return yAccessor(d) && yAccessor(d).signal; }; - private readonly yAccessorForMACD = (d) => { + private readonly yAccessorForMACD = (d: any) => { const { yAccessor } = this.props; return yAccessor(d) && yAccessor(d).macd; }; diff --git a/packages/series/src/OHLCSeries.tsx b/packages/series/src/OHLCSeries.tsx index 66f686b12..efc2252f6 100644 --- a/packages/series/src/OHLCSeries.tsx +++ b/packages/series/src/OHLCSeries.tsx @@ -14,9 +14,9 @@ export interface OHLCSeriesProps { export class OHLCSeries extends React.Component { public static defaultProps = { className: "react-financial-charts-ohlc", - yAccessor: (d) => ({ open: d.open, high: d.high, low: d.low, close: d.close }), - classNames: (d) => (isDefined(d.absoluteChange) ? (d.absoluteChange > 0 ? "up" : "down") : "firstbar"), - stroke: (d) => (isDefined(d.absoluteChange) ? (d.absoluteChange > 0 ? "#26a69a" : "#ef5350") : "#000000"), + yAccessor: (d: any) => ({ open: d.open, high: d.high, low: d.low, close: d.close }), + classNames: (d: any) => (isDefined(d.absoluteChange) ? (d.absoluteChange > 0 ? "up" : "down") : "firstbar"), + stroke: (d: any) => (isDefined(d.absoluteChange) ? (d.absoluteChange > 0 ? "#26a69a" : "#ef5350") : "#000000"), strokeWidth: 1, clip: true, }; @@ -34,7 +34,7 @@ export class OHLCSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { yAccessor } = this.props; const { xAccessor } = moreProps; const { @@ -48,8 +48,15 @@ export class OHLCSeries extends React.Component { this.drawBarDataOnCanvas(ctx, barData); }; - private readonly getOHLCBars = (props, xAccessor, yAccessor, xScale, yScale, plotData) => { - const { classNames: classNamesProp, stroke: strokeProp, strokeWidth: strokeWidthProp } = props; + private readonly getOHLCBars = ( + props: OHLCSeriesProps, + xAccessor: any, + yAccessor: any, + xScale: any, + yScale: any, + plotData: any, + ) => { + const { classNames: classNamesProp, stroke: strokeProp, strokeWidth: strokeWidthProp = 1 } = props; const strokeFunc = functor(strokeProp); const classNameFunc = functor(classNamesProp); @@ -61,8 +68,8 @@ export class OHLCSeries extends React.Component { const strokeWidth = Math.min(barWidth, strokeWidthProp); const bars = plotData - .filter((d) => isDefined(yAccessor(d).close)) - .map((d) => { + .filter((d: any) => isDefined(yAccessor(d).close)) + .map((d: any) => { const ohlc = yAccessor(d); const x = Math.round(xScale(xAccessor(d))); const y1 = yScale(ohlc.high); @@ -82,7 +89,7 @@ export class OHLCSeries extends React.Component { return { barWidth, strokeWidth, bars }; }; - private readonly drawBarDataOnCanvas = (ctx: CanvasRenderingContext2D, barData) => { + private readonly drawBarDataOnCanvas = (ctx: CanvasRenderingContext2D, barData: any) => { const { strokeWidth, bars } = barData; const wickNest = group(bars, (d: any) => d.stroke); diff --git a/packages/series/src/OverlayBarSeries.tsx b/packages/series/src/OverlayBarSeries.tsx index 20b1802f6..88cf2b545 100644 --- a/packages/series/src/OverlayBarSeries.tsx +++ b/packages/series/src/OverlayBarSeries.tsx @@ -34,7 +34,8 @@ export interface OverlayBarSeriesProps { export class OverlayBarSeries extends React.Component { public static defaultProps = { - baseAt: (xScale, yScale /* , d*/) => first(yScale.range()), + baseAt: (xScale: ScaleContinuousNumeric, yScale: ScaleContinuousNumeric) => + first(yScale.range()), direction: "up", className: "bar", stroke: false, @@ -57,7 +58,7 @@ export class OverlayBarSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { yAccessor } = this.props; const bars = this.getBars(moreProps, yAccessor); @@ -65,7 +66,7 @@ export class OverlayBarSeries extends React.Component { drawOnCanvas2(this.props, ctx, bars); }; - private readonly getBars = (moreProps, yAccessor) => { + private readonly getBars = (moreProps: any, yAccessor: any) => { const { xScale, xAccessor, @@ -82,9 +83,9 @@ export class OverlayBarSeries extends React.Component { const width = widthFunctor(this.props, moreProps); const offset = Math.floor(0.5 * width); - const bars = plotData.map((d) => { + const bars = plotData.map((d: any) => { const innerBars = yAccessor - .map((eachYAccessor, i) => { + .map((eachYAccessor: any, i: number) => { const yValue = eachYAccessor(d); if (isNotDefined(yValue)) { return undefined; @@ -103,7 +104,7 @@ export class OverlayBarSeries extends React.Component { i, }; }) - .filter((yValue) => isDefined(yValue)); + .filter((yValue: any) => isDefined(yValue)); let b = getBase(xScale, yScale, d); let h; diff --git a/packages/series/src/PointAndFigureSeries.tsx b/packages/series/src/PointAndFigureSeries.tsx index b75d8d7b6..daca26106 100644 --- a/packages/series/src/PointAndFigureSeries.tsx +++ b/packages/series/src/PointAndFigureSeries.tsx @@ -1,3 +1,4 @@ +import { ScaleContinuousNumeric } from "d3-scale"; import * as React from "react"; import { isDefined, isNotDefined, getAxisCanvas, GenericChartComponent } from "@react-financial-charts/core"; @@ -43,7 +44,7 @@ export class PointAndFigureSeries extends React.Component { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { xAccessor, xScale, @@ -56,7 +57,12 @@ export class PointAndFigureSeries extends React.Component { + private readonly getColumns = ( + xScale: ScaleContinuousNumeric, + xAccessor: any, + yScale: ScaleContinuousNumeric, + plotData: any[], + ) => { const width = xScale(xAccessor(plotData[plotData.length - 1])) - xScale(xAccessor(plotData[0])); const columnWidth = width / (plotData.length - 1); @@ -77,7 +83,7 @@ export class PointAndFigureSeries extends React.Component isDefined(d.close)) .map((d) => { - const boxes = d.boxes.map((box) => ({ + const boxes = d.boxes.map((box: any) => ({ columnWidth, boxHeight, open: yScale(box.open), @@ -94,14 +100,14 @@ export class PointAndFigureSeries extends React.Component { + private readonly drawOnCanvasPrivate = (ctx: CanvasRenderingContext2D, props: any, columns: any[]) => { const { stroke, fill, strokeWidth } = props; ctx.lineWidth = strokeWidth; columns.forEach((col) => { const [offsetX, offsetY] = col.offset; - col.boxes.forEach((box) => { + col.boxes.forEach((box: any) => { if (col.direction > 0) { ctx.fillStyle = fill.up; ctx.strokeStyle = stroke.up; diff --git a/packages/series/src/RSISeries.tsx b/packages/series/src/RSISeries.tsx index 445e7c09d..5e0b8b49e 100644 --- a/packages/series/src/RSISeries.tsx +++ b/packages/series/src/RSISeries.tsx @@ -117,7 +117,7 @@ export class RSISeries extends React.Component { ); } - private readonly renderClip = (moreProps) => { + private readonly renderClip = (moreProps: any) => { const { chartConfig } = moreProps; const { overSold, overBought } = this.props; const { yScale, width, height } = chartConfig; @@ -135,7 +135,7 @@ export class RSISeries extends React.Component { ); }; - private readonly mainClip = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly mainClip = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { chartConfig } = moreProps; const { overSold, overBought } = this.props; const { yScale, width, height } = chartConfig; @@ -146,7 +146,7 @@ export class RSISeries extends React.Component { ctx.clip(); }; - private readonly topAndBottomClip = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly topAndBottomClip = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { chartConfig } = moreProps; const { overSold, overBought } = this.props; const { yScale, width } = chartConfig; diff --git a/packages/series/src/RenkoSeries.tsx b/packages/series/src/RenkoSeries.tsx index 13c520124..3615aa09a 100644 --- a/packages/series/src/RenkoSeries.tsx +++ b/packages/series/src/RenkoSeries.tsx @@ -1,3 +1,4 @@ +import { ScaleContinuousNumeric } from "d3-scale"; import * as React from "react"; import { isDefined, getAxisCanvas, GenericChartComponent } from "@react-financial-charts/core"; @@ -27,7 +28,7 @@ export class RenkoSeries extends React.Component { up: "none", down: "none", }, - yAccessor: (d) => ({ open: d.open, high: d.high, low: d.low, close: d.close }), + yAccessor: (d: any) => ({ open: d.open, high: d.high, low: d.low, close: d.close }), }; public render() { @@ -43,7 +44,7 @@ export class RenkoSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { xAccessor, xScale, @@ -70,7 +71,12 @@ export class RenkoSeries extends React.Component { }); }; - private readonly getRenko = (plotData: any[], xScale, xAccessor, yScale) => { + private readonly getRenko = ( + plotData: any[], + xScale: ScaleContinuousNumeric, + xAccessor: any, + yScale: ScaleContinuousNumeric, + ) => { const { fill, stroke, yAccessor = RenkoSeries.defaultProps.yAccessor } = this.props; const width = xScale(xAccessor(plotData[plotData.length - 1])) - xScale(xAccessor(plotData[0])); diff --git a/packages/series/src/SARSeries.tsx b/packages/series/src/SARSeries.tsx index d777df1b3..9e6080381 100644 --- a/packages/series/src/SARSeries.tsx +++ b/packages/series/src/SARSeries.tsx @@ -64,7 +64,7 @@ export class SARSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { yAccessor, fill = SARSeries.defaultProps.fill, opacity } = this.props; const { xAccessor, @@ -79,7 +79,7 @@ export class SARSeries extends React.Component { const d = ((width / plotData.length) * 0.5) / 2; const radius = Math.min(2, Math.max(0.5, d)) + (hovering ? 2 : 0); - plotData.forEach((each) => { + plotData.forEach((each: any) => { const centerX = xScale(xAccessor(each)); const centerY = yScale(yAccessor(each)); const color = yAccessor(each) > each.close ? fill.falling : fill.rising; @@ -95,7 +95,7 @@ export class SARSeries extends React.Component { }); }; - private readonly isHover = (moreProps) => { + private readonly isHover = (moreProps: any) => { const { mouseXY, currentItem, diff --git a/packages/series/src/ScatterSeries.tsx b/packages/series/src/ScatterSeries.tsx index fe0ee3f32..c04f625c1 100644 --- a/packages/series/src/ScatterSeries.tsx +++ b/packages/series/src/ScatterSeries.tsx @@ -14,7 +14,7 @@ export class ScatterSeries extends React.Component { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const points = this.getMarkers(moreProps); const { markerProps } = this.props; @@ -43,7 +43,7 @@ export class ScatterSeries extends React.Component { }); }; - private readonly getMarkers = (moreProps) => { + private readonly getMarkers = (moreProps: any) => { const { yAccessor, markerProvider, markerProps } = this.props; const { @@ -58,7 +58,7 @@ export class ScatterSeries extends React.Component { throw new Error("required prop, either marker or markerProvider missing"); } - return plotData.map((d) => { + return plotData.map((d: any) => { if (markerProvider) { Marker = markerProvider(d); } diff --git a/packages/series/src/StackedBarSeries.tsx b/packages/series/src/StackedBarSeries.tsx index 967f0d6ab..9d7524ef3 100644 --- a/packages/series/src/StackedBarSeries.tsx +++ b/packages/series/src/StackedBarSeries.tsx @@ -14,7 +14,12 @@ import { export interface StackedBarSeriesProps { readonly baseAt?: | number - | ((yScale: ScaleContinuousNumeric, d: [number, number], moreProps: any) => number); + | (( + xScale: ScaleContinuousNumeric, + yScale: ScaleContinuousNumeric, + d: [number, number], + moreProps: any, + ) => number); readonly className?: string | any; // func readonly clip?: boolean; readonly direction?: "up" | "down"; @@ -33,7 +38,8 @@ export interface StackedBarSeriesProps { export class StackedBarSeries extends React.Component { public static defaultProps = { - baseAt: (xScale, yScale /* , d*/) => head(yScale.range()), + baseAt: (xScale: ScaleContinuousNumeric, yScale: ScaleContinuousNumeric) => + head(yScale.range()), direction: "up", className: "bar", stroke: false, @@ -57,7 +63,7 @@ export class StackedBarSeries extends React.Component { ); } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { xAccessor } = moreProps; drawOnCanvasHelper(ctx, this.props, moreProps, xAccessor, d3Stack); @@ -65,10 +71,10 @@ export class StackedBarSeries extends React.Component { } export function identityStack() { - let keys = []; - function stack(data) { + let keys: any[] = []; + function stack(data: any) { const response = keys.map((key, i) => { - const arrays = data.map((d) => { + const arrays = data.map((d: any) => { const array = [0, d[key]]; // @ts-ignore @@ -81,7 +87,7 @@ export function identityStack() { }); return response; } - stack.keys = function (x) { + stack.keys = function (x: any) { if (!arguments.length) { return keys; } @@ -94,9 +100,9 @@ export function identityStack() { export function drawOnCanvasHelper( ctx: CanvasRenderingContext2D, props: StackedBarSeriesProps, - moreProps, - xAccessor, - stackFn, + moreProps: any, + xAccessor: any, + stackFn: any, defaultPostAction = identity, postRotateAction = rotateXY, ) { @@ -111,19 +117,19 @@ export function drawOnCanvasHelper( drawOnCanvas2(props, ctx, bars); } -function convertToArray(item) { +function convertToArray(item: any) { return Array.isArray(item) ? item : [item]; } const doStuff = ( props: StackedBarSeriesProps, - xAccessor, - plotData, - xScale, - yScale, - stackFn, - postRotateAction, - defaultPostAction, + xAccessor: any, + plotData: any[], + xScale: any, + yScale: any, + stackFn: any, + postRotateAction: any, + defaultPostAction: any, ) => { const { yAccessor, swapScales } = props; @@ -149,7 +155,7 @@ const doStuff = ( return bars; }; -export const rotateXY = (array) => +export const rotateXY = (array: any[]) => array.map((each) => { return { ...each, @@ -160,7 +166,7 @@ export const rotateXY = (array) => }; }); -export const drawOnCanvas2 = (props: StackedBarSeriesProps, ctx: CanvasRenderingContext2D, bars) => { +export const drawOnCanvas2 = (props: StackedBarSeriesProps, ctx: CanvasRenderingContext2D, bars: any) => { const { stroke } = props; const nest = group(bars, (d: any) => d.fillStyle); @@ -186,11 +192,11 @@ export const drawOnCanvas2 = (props: StackedBarSeriesProps, ctx: CanvasRendering export function getBars( props: StackedBarSeriesProps, - xAccessor, - yAccessor, - xScale, - yScale, - plotData, + xAccessor: any, + yAccessor: any, + xScale: any, + yScale: any, + plotData: any[], stack = identityStack, after = identity, ) { @@ -218,27 +224,29 @@ export function getBars( appearance: {}, x: xAccessor(each), }; - yAccessor.forEach((eachYAccessor, i) => { + yAccessor.forEach((eachYAccessor: any, i: number) => { const key = `y${i}`; + // @ts-ignore d[key] = eachYAccessor(each); const appearance = { className: getClassName(each, i), stroke: stroke ? getFill(each, i) : "none", fillStyle: getFill(each, i), }; + // @ts-ignore d.appearance[key] = appearance; }); return d; }); - const keys = yAccessor.map((_, i) => `y${i}`); + const keys = yAccessor.map((_: any, i: number) => `y${i}`); // @ts-ignore const data = stack().keys(keys)(ds); - const newData = data.map((each, i) => { + const newData = data.map((each: any, i: number) => { const key = each.key; - return each.map((d) => { + return each.map((d: any) => { const array = [d[0], d[1]]; // @ts-ignore diff --git a/packages/series/src/StochasticSeries.tsx b/packages/series/src/StochasticSeries.tsx index 959b7bdd1..5089828b4 100644 --- a/packages/series/src/StochasticSeries.tsx +++ b/packages/series/src/StochasticSeries.tsx @@ -56,13 +56,13 @@ export class StochasticSeries extends React.Component { ); } - private readonly yAccessorForK = (d) => { + private readonly yAccessorForK = (d: any) => { const { yAccessor } = this.props; return yAccessor(d) && yAccessor(d).K; }; - private readonly yAccessorForD = (d) => { + private readonly yAccessorForD = (d: any) => { const { yAccessor } = this.props; return yAccessor(d) && yAccessor(d).D; diff --git a/packages/series/src/StraightLine.tsx b/packages/series/src/StraightLine.tsx index 86a925d6d..9494468c0 100644 --- a/packages/series/src/StraightLine.tsx +++ b/packages/series/src/StraightLine.tsx @@ -1,3 +1,4 @@ +import { ScaleContinuousNumeric } from "d3-scale"; import * as React from "react"; import { getAxisCanvas, @@ -27,7 +28,7 @@ export class StraightLine extends React.Component { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { type, strokeStyle, lineWidth, lineDash, yValue, xValue } = this.props; const { @@ -58,9 +59,17 @@ export class StraightLine extends React.Component { ctx.stroke(); }; - private readonly getLineCoordinates = (type, xScale, yScale, xValue, yValue, width, height) => { + private readonly getLineCoordinates = ( + type: "horizontal" | "vertical" | undefined, + xScale: ScaleContinuousNumeric, + yScale: ScaleContinuousNumeric, + xValue: number | undefined, + yValue: number | undefined, + width: number, + height: number, + ) => { return type === "horizontal" - ? { x1: 0, y1: Math.round(yScale(yValue)), x2: width, y2: Math.round(yScale(yValue)) } - : { x1: Math.round(xScale(xValue)), y1: 0, x2: Math.round(xScale(xValue)), y2: height }; + ? { x1: 0, y1: Math.round(yScale(yValue!)), x2: width, y2: Math.round(yScale(yValue!)) } + : { x1: Math.round(xScale(xValue!)), y1: 0, x2: Math.round(xScale(xValue!)), y2: height }; }; } diff --git a/packages/series/src/TriangleMarker.tsx b/packages/series/src/TriangleMarker.tsx index ad3ccfad6..464ff177e 100644 --- a/packages/series/src/TriangleMarker.tsx +++ b/packages/series/src/TriangleMarker.tsx @@ -109,7 +109,7 @@ const getTrianglePoints = (width: number) => { }; }; -const getRotationInDegrees = (props: TriangleProps, point) => { +const getRotationInDegrees = (props: TriangleProps, point: any) => { const { direction = Triangle.defaultProps.direction } = props; const directionVal = functor(direction)(point.datum); diff --git a/packages/series/src/VolumeProfileSeries.tsx b/packages/series/src/VolumeProfileSeries.tsx index 476621ea5..5c6f30924 100644 --- a/packages/series/src/VolumeProfileSeries.tsx +++ b/packages/series/src/VolumeProfileSeries.tsx @@ -26,16 +26,16 @@ export class VolumeProfileSeries extends React.Component (type === "up" ? "#6BA583" : "#FF0000"), + fill: ({ type }: any) => (type === "up" ? "#6BA583" : "#FF0000"), stroke: "#FFFFFF", showSessionBackground: false, sessionBackGround: "#4682B4", sessionBackGroundOpacity: 0.3, - source: (d) => d.close, - volume: (d) => d.volume, - absoluteChange: (d) => d.absoluteChange, + source: (d: any) => d.close, + volume: (d: any) => d.volume, + absoluteChange: (d: any) => d.absoluteChange, bySession: false, - sessionStart: ({ d, i, plotData }) => i > 0 && plotData[i - 1].date.getMonth() !== d.date.getMonth(), + sessionStart: ({ d, i, plotData }: any) => i > 0 && plotData[i - 1].date.getMonth() !== d.date.getMonth(), orient: "left", partialStartOK: true, partialEndOK: true, @@ -45,20 +45,20 @@ export class VolumeProfileSeries extends React.Component; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { xAccessor, width } = moreProps; const { rects, sessionBg } = this.helper(this.props, moreProps, xAccessor, width); this.drawOnCanvasContext(ctx, this.props, rects, sessionBg); }; - private readonly drawOnCanvasContext = (ctx: CanvasRenderingContext2D, props, rects, sessionBg) => { + private readonly drawOnCanvasContext = (ctx: CanvasRenderingContext2D, props: any, rects: any, sessionBg: any) => { const { opacity, sessionBackGround, sessionBackGroundOpacity, showSessionBackground } = props; if (showSessionBackground) { ctx.fillStyle = colorToRGBA(sessionBackGround, sessionBackGroundOpacity); - sessionBg.forEach((each) => { + sessionBg.forEach((each: any) => { const { x, y, height, width } = each; ctx.beginPath(); @@ -68,7 +68,7 @@ export class VolumeProfileSeries extends React.Component { + rects.forEach((each: any) => { const { x, y, height, w1, w2, stroke1, stroke2, fill1, fill2 } = each; if (w1 > 0) { @@ -105,7 +105,7 @@ export class VolumeProfileSeries extends React.Component { + private readonly helper = (props: any, moreProps: any, xAccessor: any, width: number) => { const { xScale: realXScale, chartConfig: { yScale }, @@ -120,7 +120,7 @@ export class VolumeProfileSeries extends React.Component { + .accumulateTill((d: any, i: any) => { return sessionStart({ d, i, ...moreProps }); }) .accumulator(identity); @@ -129,7 +129,7 @@ export class VolumeProfileSeries extends React.Component { + const allRects = sessions.map((session: any) => { const begin = bySession ? realXScale(xAccessor(head(session))) : 0; const finish = bySession ? realXScale(xAccessor(last(session))) : width; const sessionWidth = finish - begin + dx; @@ -162,7 +162,7 @@ export class VolumeProfileSeries extends React.Component sum(each.map((d) => d[1]))); - const base = (xScaleD) => head(xScaleD.range()); + const base = (xScaleD: any) => head(xScaleD.range()); const [start, end] = orient === "right" @@ -221,8 +221,8 @@ export class VolumeProfileSeries extends React.Component(allRects.map((d) => d.rects)), - sessionBg: allRects.map((d) => d.sessionBg), + rects: merge(allRects.map((d: any) => d.rects)), + sessionBg: allRects.map((d: any) => d.sessionBg), }; }; } diff --git a/packages/series/tsconfig.json b/packages/series/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/series/tsconfig.json +++ b/packages/series/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/stories/src/Intro.stories.mdx b/packages/stories/src/Intro.stories.mdx index 1fb56eac4..8cd92f6a6 100644 --- a/packages/stories/src/Intro.stories.mdx +++ b/packages/stories/src/Intro.stories.mdx @@ -10,7 +10,7 @@ Charts dedicated to finance. ## Features - integrates multiple chart types -- over 60 technical indicators and overlays +- technical indicators and overlays - drawing objects diff --git a/packages/stories/src/features/StockChart.tsx b/packages/stories/src/features/StockChart.tsx index 93ae787e7..318bd3952 100644 --- a/packages/stories/src/features/StockChart.tsx +++ b/packages/stories/src/features/StockChart.tsx @@ -7,6 +7,7 @@ import { discontinuousTimeScaleProviderBuilder, Chart, ChartCanvas, + CurrentCoordinate, BarSeries, CandlestickSeries, ElderRaySeries, @@ -105,7 +106,9 @@ class StockChart extends React.Component { + + { origin={elderRayOrigin} padding={{ top: 8, bottom: 8 }} > - + @@ -178,7 +181,7 @@ class StockChart extends React.Component { }; private readonly volumeColor = (data: IOHLCData) => { - return data.close > data.open ? "rgba(38, 166, 154, 0.7)" : "rgba(239, 83, 80, 0.7)"; + return data.close > data.open ? "rgba(38, 166, 154, 0.3)" : "rgba(239, 83, 80, 0.3)"; }; private readonly volumeSeries = (data: IOHLCData) => { diff --git a/packages/stories/src/features/annotations/Annotations.tsx b/packages/stories/src/features/annotations/Annotations.tsx index 19f3925ad..112c8327d 100644 --- a/packages/stories/src/features/annotations/Annotations.tsx +++ b/packages/stories/src/features/annotations/Annotations.tsx @@ -28,7 +28,7 @@ class Annotations extends React.Component { ); public render() { - const { data: initialData, height, ratio, width, ...rest } = this.props; + const { data: initialData, height, ratio, width, selectCanvas, ...rest } = this.props; const ema12 = ema() .id(1) diff --git a/packages/stories/src/features/axis/index.stories.tsx b/packages/stories/src/features/axis/index.stories.tsx index 5120a4194..2cf51a706 100644 --- a/packages/stories/src/features/axis/index.stories.tsx +++ b/packages/stories/src/features/axis/index.stories.tsx @@ -16,7 +16,7 @@ export default { gridLinesStrokeStyle: { control: "color" }, strokeStyle: { control: "color" }, tickLabelFill: { control: "color" }, - tickStroke: { control: "color" }, + tickStrokeStyle: { control: "color" }, }, }; diff --git a/packages/stories/src/features/tooltips/index.stories.tsx b/packages/stories/src/features/tooltips/index.stories.tsx index 8ed121463..543af4b2c 100644 --- a/packages/stories/src/features/tooltips/index.stories.tsx +++ b/packages/stories/src/features/tooltips/index.stories.tsx @@ -1,8 +1,10 @@ import * as React from "react"; +import { HoverTooltip } from "../../../../tooltip/src/HoverTooltip"; import Tooltips from "./Tooltips"; export default { title: "Features/Tooltips", + component: HoverTooltip, }; export const hover = () => ; diff --git a/packages/stories/tsconfig.json b/packages/stories/tsconfig.json index 143759301..0b4200974 100644 --- a/packages/stories/tsconfig.json +++ b/packages/stories/tsconfig.json @@ -13,8 +13,9 @@ ], "module": "esnext", "moduleResolution": "node", + "noImplicitReturns": true, + "noImplicitAny": true, "noImplicitThis": true, - "noImplicitAny": false, "noResolve": false, "outDir": "lib", "sourceMap": true, diff --git a/packages/tooltip/src/BollingerBandTooltip.tsx b/packages/tooltip/src/BollingerBandTooltip.tsx index c3c75378d..9d93fa674 100644 --- a/packages/tooltip/src/BollingerBandTooltip.tsx +++ b/packages/tooltip/src/BollingerBandTooltip.tsx @@ -28,7 +28,7 @@ export class BollingerBandTooltip extends React.Component props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, displayInit: "n/a", origin: [8, 8], yAccessor: (data: any) => data.bb, @@ -38,7 +38,7 @@ export class BollingerBandTooltip extends React.Component; } - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { onClick, displayFormat, diff --git a/packages/tooltip/src/GroupTooltip.tsx b/packages/tooltip/src/GroupTooltip.tsx index aef45c34b..b02914ddb 100644 --- a/packages/tooltip/src/GroupTooltip.tsx +++ b/packages/tooltip/src/GroupTooltip.tsx @@ -32,7 +32,7 @@ export class GroupTooltip extends React.Component { layout: "horizontal", displayFormat: format(".2f"), displayInit: "", - displayValuesFor: (_, props) => props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, origin: [0, 0], width: 60, verticalSize: 13, @@ -42,7 +42,7 @@ export class GroupTooltip extends React.Component { return ; } - private readonly getPosition = (moreProps) => { + private readonly getPosition = (moreProps: any) => { const { position } = this.props; const { height, width } = moreProps.chartConfig; @@ -74,7 +74,7 @@ export class GroupTooltip extends React.Component { return { xyPos, textAnchor }; }; - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { chartId, fullData } = moreProps; const { diff --git a/packages/tooltip/src/HoverTooltip.tsx b/packages/tooltip/src/HoverTooltip.tsx index 1753b9935..def7d3714 100644 --- a/packages/tooltip/src/HoverTooltip.tsx +++ b/packages/tooltip/src/HoverTooltip.tsx @@ -1,4 +1,4 @@ -import { sum } from "d3-array"; +import { max, sum } from "d3-array"; import * as PropTypes from "prop-types"; import * as React from "react"; import { first, isDefined, GenericComponent, last } from "@react-financial-charts/core"; @@ -28,7 +28,11 @@ const roundRect = ( ctx.closePath(); }; -const defaultBackgroundShapeCanvas = (props: HoverTooltipProps, { width, height }, ctx: CanvasRenderingContext2D) => { +const defaultBackgroundShapeCanvas = ( + props: HoverTooltipProps, + { width, height }: { width: number; height: number }, + ctx: CanvasRenderingContext2D, +) => { const { toolTipFillStyle, toolTipStrokeStyle } = props; ctx.beginPath(); @@ -40,13 +44,14 @@ const defaultBackgroundShapeCanvas = (props: HoverTooltipProps, { width, height ctx.fill(); ctx.shadowBlur = 0; } + if (toolTipStrokeStyle !== undefined) { ctx.strokeStyle = toolTipStrokeStyle; ctx.stroke(); } }; -const defaultTooltipCanvas = (props: HoverTooltipProps, content, ctx: CanvasRenderingContext2D) => { +const defaultTooltipCanvas = (props: HoverTooltipProps, content: any, ctx: CanvasRenderingContext2D) => { const { fontSize = 14, fontFamily, fontFill } = props; const startY = Y + fontSize * 0.9; @@ -57,6 +62,8 @@ const defaultTooltipCanvas = (props: HoverTooltipProps, content, ctx: CanvasRend ctx.textAlign = "left"; ctx.fillText(content.x, X, startY); + const maxLabel = max(content.y, (y: any) => ctx.measureText(y.label as string).width) ?? 0; + for (let i = 0; i < content.y.length; i++) { const y = content.y[i]; const textY = (i + 1) * PADDING + startY + fontSize * (i + 1); @@ -67,11 +74,17 @@ const defaultTooltipCanvas = (props: HoverTooltipProps, content, ctx: CanvasRend if (fontFill !== undefined) { ctx.fillStyle = fontFill; } - ctx.fillText(": " + y.value, X + ctx.measureText(y.label).width, textY); + ctx.fillText(y.value, X * 2 + maxLabel, textY); } }; -const drawOnCanvas = (ctx: CanvasRenderingContext2D, props: HoverTooltipProps, context, pointer, height) => { +const drawOnCanvas = ( + ctx: CanvasRenderingContext2D, + props: HoverTooltipProps, + context: any, + pointer: any, + height: number, +) => { const { margin, ratio } = context; const { backgroundShapeCanvas, tooltipCanvas, background } = props; @@ -103,26 +116,24 @@ const drawOnCanvas = (ctx: CanvasRenderingContext2D, props: HoverTooltipProps, c ctx.restore(); }; -const calculateTooltipSize = (props: HoverTooltipProps, content, ctx?) => { +const calculateTooltipSize = (props: HoverTooltipProps, content: any, ctx: CanvasRenderingContext2D) => { const { fontFamily, fontSize = 12, fontFill } = props; - if (ctx === undefined) { - const canvas = document.createElement("canvas"); - ctx = canvas.getContext("2d"); - } ctx.font = `bold ${fontSize}px ${fontFamily}`; - ctx.fillStyle = fontFill; + if (fontFill !== undefined) { + ctx.fillStyle = fontFill; + } ctx.textAlign = "left"; - const measureText = (str) => ({ + const measureText = (str: string) => ({ width: ctx.measureText(str).width, height: fontSize + PADDING, }); const { width, height } = content.y - .map(({ label, value }) => measureText(`${label}: ${value}`)) + .map(({ label, value }: any) => measureText(`${label} ${value}`)) // Sum all y and x sizes (begin with x label size) - .reduce((res, size) => sumSizes(res, size), measureText(String(content.x))); + .reduce((res: any, size: any) => sumSizes(res, size), measureText(String(content.x))); return { width: width + 2 * X, @@ -130,22 +141,22 @@ const calculateTooltipSize = (props: HoverTooltipProps, content, ctx?) => { }; }; -const sumSizes = (...sizes) => { +const sumSizes = (...sizes: any[]) => { return { width: Math.max(...sizes.map((size) => size.width)), height: sum(sizes, (d) => d.height), }; }; -const normalizeX = (x, bgSize, pointWidth, width) => { +const normalizeX = (x: number, bgSize: any, pointWidth: number, width: number) => { return x < width / 2 ? x + pointWidth / 2 + PADDING : x - bgSize.width - pointWidth / 2 - PADDING; }; -const normalizeY = (y, bgSize) => { +const normalizeY = (y: number, bgSize: any) => { return y - bgSize.height <= 0 ? y + PADDING : y - bgSize.height - PADDING; }; -const defaultOrigin = (props: HoverTooltipProps, moreProps, bgSize, pointWidth) => { +const defaultOrigin = (props: HoverTooltipProps, moreProps: any, bgSize: any, pointWidth: any) => { const { chartId, yAccessor } = props; const { mouseXY, xAccessor, currentItem, xScale, chartConfig, width } = moreProps; @@ -158,7 +169,7 @@ const defaultOrigin = (props: HoverTooltipProps, moreProps, bgSize, pointWidth) if (isDefined(chartId) && isDefined(yAccessor) && isDefined(chartConfig) && isDefined(chartConfig.findIndex)) { const yValue = yAccessor(currentItem); - const chartIndex = chartConfig.findIndex((c) => c.id === chartId); + const chartIndex = chartConfig.findIndex((c: any) => c.id === chartId); y = Math.round(chartConfig[chartIndex].yScale(yValue)); } @@ -192,7 +203,7 @@ export interface HoverTooltipProps { }; readonly toolTipFillStyle?: string | CanvasGradient | CanvasPattern; readonly toolTipStrokeStyle?: string | CanvasGradient | CanvasPattern; - readonly tooltipCanvas?: any; // func + readonly tooltipCanvas: (props: HoverTooltipProps, content: any, ctx: CanvasRenderingContext2D) => void; readonly yAccessor: (data: any) => number; } @@ -220,7 +231,7 @@ export class HoverTooltip extends React.Component { return ; } - private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly drawOnCanvas = (ctx: CanvasRenderingContext2D, moreProps: any) => { const pointer = this.helper(ctx, moreProps); if (pointer === undefined) { return; @@ -231,7 +242,7 @@ export class HoverTooltip extends React.Component { drawOnCanvas(ctx, this.props, this.context, pointer, height); }; - private readonly helper = (ctx: CanvasRenderingContext2D, moreProps) => { + private readonly helper = (ctx: CanvasRenderingContext2D, moreProps: any) => { const { show, xScale, currentItem, plotData, xAccessor, displayXAccessor } = moreProps; const { origin = HoverTooltip.defaultProps.origin, tooltip } = this.props; diff --git a/packages/tooltip/src/MACDTooltip.tsx b/packages/tooltip/src/MACDTooltip.tsx index 2adf9c097..2b1aaec7d 100644 --- a/packages/tooltip/src/MACDTooltip.tsx +++ b/packages/tooltip/src/MACDTooltip.tsx @@ -36,7 +36,7 @@ export class MACDTooltip extends React.Component { className: "react-financial-charts-tooltip", displayFormat: format(".2f"), displayInit: "n/a", - displayValuesFor: (_, props) => props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, origin: [0, 0], }; @@ -44,7 +44,7 @@ export class MACDTooltip extends React.Component { return ; } - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { onClick, displayInit, diff --git a/packages/tooltip/src/MovingAverageTooltip.tsx b/packages/tooltip/src/MovingAverageTooltip.tsx index e30b1406d..0e0a2da4a 100644 --- a/packages/tooltip/src/MovingAverageTooltip.tsx +++ b/packages/tooltip/src/MovingAverageTooltip.tsx @@ -72,7 +72,7 @@ export class MovingAverageTooltip extends React.Component props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, origin: [0, 10], width: 65, }; @@ -81,7 +81,7 @@ export class MovingAverageTooltip extends React.Component; } - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { chartId, chartConfig, diff --git a/packages/tooltip/src/OHLCTooltip.tsx b/packages/tooltip/src/OHLCTooltip.tsx index f41554882..0fa9ebd54 100644 --- a/packages/tooltip/src/OHLCTooltip.tsx +++ b/packages/tooltip/src/OHLCTooltip.tsx @@ -40,7 +40,7 @@ export class OHLCTooltip extends React.Component { changeFormat: format("+.2f"), className: "react-financial-charts-tooltip-hover", displayTexts: displayTextsDefault, - displayValuesFor: (_, props) => props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, fontFamily: "-apple-system, system-ui, 'Helvetica Neue', Ubuntu, sans-serif", ohlcFormat: format(".2f"), origin: [0, 0], @@ -51,7 +51,7 @@ export class OHLCTooltip extends React.Component { return ; } - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { accessor, changeFormat = OHLCTooltip.defaultProps.changeFormat, diff --git a/packages/tooltip/src/RSITooltip.tsx b/packages/tooltip/src/RSITooltip.tsx index a8747a793..c9a3ddc48 100644 --- a/packages/tooltip/src/RSITooltip.tsx +++ b/packages/tooltip/src/RSITooltip.tsx @@ -25,7 +25,7 @@ export class RSITooltip extends React.Component { public static defaultProps = { displayFormat: format(".2f"), displayInit: "n/a", - displayValuesFor: (_, props) => props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, origin: [0, 0], className: "react-financial-charts-tooltip", }; @@ -34,7 +34,7 @@ export class RSITooltip extends React.Component { return ; } - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { onClick, displayInit, fontFamily, fontSize, yAccessor, displayFormat, className } = this.props; const { options, labelFill, textFill, displayValuesFor } = this.props; diff --git a/packages/tooltip/src/SingleValueTooltip.tsx b/packages/tooltip/src/SingleValueTooltip.tsx index fd33c07e0..0c33a3ad7 100644 --- a/packages/tooltip/src/SingleValueTooltip.tsx +++ b/packages/tooltip/src/SingleValueTooltip.tsx @@ -18,7 +18,7 @@ export interface SingleValueTooltipProps { readonly fontFamily?: string; readonly fontSize?: number; readonly onClick?: (event: React.MouseEvent) => void; - readonly displayValuesFor?: (props: SingleValueTooltipProps, moreProps) => any; + readonly displayValuesFor?: (props: SingleValueTooltipProps, moreProps: any) => any; readonly xAccessor?: (d: any) => number; readonly yAccessor?: (d: any) => number; } @@ -26,15 +26,15 @@ export interface SingleValueTooltipProps { export class SingleValueTooltip extends React.Component { public static defaultProps = { className: "react-financial-charts-tooltip", - displayValuesFor: (_, props) => props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, labelFill: "#4682B4", origin: [0, 0], valueFill: "#000000", xAccessor: noop, - xDisplayFormat: identity, + xDisplayFormat: identity as (value: number) => string, xInitDisplay: "n/a", - yAccessor: identity, - yDisplayFormat: format(".2f"), + yAccessor: identity as (d: any) => number, + yDisplayFormat: format(".2f") as (value: number) => string, yInitDisplay: "n/a", }; diff --git a/packages/tooltip/src/StochasticTooltip.tsx b/packages/tooltip/src/StochasticTooltip.tsx index 3cd337891..f022e33c6 100644 --- a/packages/tooltip/src/StochasticTooltip.tsx +++ b/packages/tooltip/src/StochasticTooltip.tsx @@ -34,7 +34,7 @@ export class StochasticTooltip extends React.Component { className: "react-financial-charts-tooltip", displayFormat: format(".2f"), displayInit: "n/a", - displayValuesFor: (_, props) => props.currentItem, + displayValuesFor: (_: any, props: any) => props.currentItem, label: "STO", origin: [0, 0], }; @@ -43,7 +43,7 @@ export class StochasticTooltip extends React.Component { return ; } - private readonly renderSVG = (moreProps) => { + private readonly renderSVG = (moreProps: any) => { const { onClick, fontFamily, diff --git a/packages/tooltip/tsconfig.json b/packages/tooltip/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/tooltip/tsconfig.json +++ b/packages/tooltip/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib", diff --git a/packages/utils/tsconfig.json b/packages/utils/tsconfig.json index 364ec155b..b9f1f87c3 100644 --- a/packages/utils/tsconfig.json +++ b/packages/utils/tsconfig.json @@ -7,7 +7,7 @@ "jsx": "react", "module": "esnext", "moduleResolution": "node", - "noImplicitAny": false, + "noImplicitAny": true, "noImplicitThis": true, "noUnusedLocals": true, "outDir": "lib",