@react-financial-charts/core
Advanced tools
Comparing version 1.3.1 to 2.0.0
import { ScaleContinuousNumeric } from "d3-scale"; | ||
import * as PropTypes from "prop-types"; | ||
import * as React from "react"; | ||
import { PureComponent } from "./utils"; | ||
import { ChartCanvasContextType } from "./ChartCanvas"; | ||
import type { ChartConfig } from "./utils/ChartDataUtil"; | ||
export type ChartContextType = Omit<ChartCanvasContextType<number | Date>, "chartConfig"> & { | ||
chartConfig: ChartConfig; | ||
}; | ||
export declare const ChartContext: React.Context<ChartContextType>; | ||
export interface ChartProps { | ||
@@ -28,29 +32,2 @@ readonly flipYScale?: boolean; | ||
} | ||
export declare class Chart extends PureComponent<ChartProps> { | ||
static defaultProps: { | ||
flipYScale: boolean; | ||
id: number; | ||
origin: number[]; | ||
padding: number; | ||
yPan: boolean; | ||
yPanEnabled: boolean; | ||
yScale: import("d3-scale").ScaleLinear<number, number, never>; | ||
}; | ||
static contextTypes: { | ||
chartConfig: PropTypes.Requireable<any[]>; | ||
subscribe: PropTypes.Validator<(...args: any[]) => any>; | ||
unsubscribe: PropTypes.Validator<(...args: any[]) => any>; | ||
}; | ||
static childContextTypes: { | ||
chartConfig: PropTypes.Validator<object>; | ||
chartId: PropTypes.Validator<string | number>; | ||
}; | ||
componentDidMount(): void; | ||
componentWillUnmount(): void; | ||
getChildContext(): { | ||
chartId: string | number; | ||
chartConfig: any; | ||
}; | ||
render(): JSX.Element; | ||
private readonly listener; | ||
} | ||
export declare const Chart: React.MemoExoticComponent<(props: React.PropsWithChildren<ChartProps>) => JSX.Element>; |
121
lib/Chart.js
@@ -1,78 +0,57 @@ | ||
import { scaleLinear } from "d3-scale"; | ||
import * as PropTypes from "prop-types"; | ||
import * as React from "react"; | ||
import { PureComponent } from "./utils"; | ||
export class Chart extends PureComponent { | ||
constructor() { | ||
super(...arguments); | ||
this.listener = (type, moreProps, _, e) => { | ||
const { id, onContextMenu, onDoubleClick } = this.props; | ||
switch (type) { | ||
case "contextmenu": { | ||
if (onContextMenu === undefined) { | ||
return; | ||
} | ||
const { currentCharts } = moreProps; | ||
if (currentCharts.indexOf(id) > -1) { | ||
onContextMenu(e, moreProps); | ||
} | ||
break; | ||
import { ChartCanvasContext, chartCanvasContextDefaultValue } from "./ChartCanvas"; | ||
export const ChartContext = React.createContext(Object.assign(Object.assign({}, chartCanvasContextDefaultValue), { | ||
// @ts-ignore | ||
chartConfig: {}, chartId: 0 })); | ||
export const Chart = React.memo((props) => { | ||
const { | ||
// flipYScale = false, | ||
id = 0, | ||
// origin = [0, 0], | ||
// padding = 0, | ||
// yPan = true, | ||
// yPanEnabled = false, | ||
// yScale = scaleLinear(), | ||
onContextMenu, onDoubleClick, } = props; | ||
const chartCanvasContextValue = React.useContext(ChartCanvasContext); | ||
const { subscribe, unsubscribe, chartConfigs } = chartCanvasContextValue; | ||
const listener = React.useCallback((type, moreProps, _, e) => { | ||
switch (type) { | ||
case "contextmenu": { | ||
if (onContextMenu === undefined) { | ||
return; | ||
} | ||
case "dblclick": { | ||
if (onDoubleClick === undefined) { | ||
return; | ||
} | ||
const { currentCharts } = moreProps; | ||
if (currentCharts.indexOf(id) > -1) { | ||
onDoubleClick(e, moreProps); | ||
} | ||
break; | ||
const { currentCharts } = moreProps; | ||
if (currentCharts.indexOf(id) > -1) { | ||
onContextMenu(e, moreProps); | ||
} | ||
break; | ||
} | ||
}; | ||
} | ||
componentDidMount() { | ||
const { id } = this.props; | ||
const { subscribe } = this.context; | ||
case "dblclick": { | ||
if (onDoubleClick === undefined) { | ||
return; | ||
} | ||
const { currentCharts } = moreProps; | ||
if (currentCharts.indexOf(id) > -1) { | ||
onDoubleClick(e, moreProps); | ||
} | ||
break; | ||
} | ||
} | ||
}, [onContextMenu, onDoubleClick, id]); | ||
React.useEffect(() => { | ||
subscribe(`chart_${id}`, { | ||
listener: this.listener, | ||
listener, | ||
}); | ||
} | ||
componentWillUnmount() { | ||
const { id } = this.props; | ||
const { unsubscribe } = this.context; | ||
unsubscribe(`chart_${id}`); | ||
} | ||
getChildContext() { | ||
const { id: chartId } = this.props; | ||
const chartConfig = this.context.chartConfig.find(({ id }) => id === chartId); | ||
return { | ||
chartId, | ||
chartConfig, | ||
}; | ||
} | ||
render() { | ||
const { origin } = this.context.chartConfig.find(({ id }) => id === this.props.id); | ||
const [x, y] = origin; | ||
return React.createElement("g", { transform: `translate(${x}, ${y})` }, this.props.children); | ||
} | ||
} | ||
Chart.defaultProps = { | ||
flipYScale: false, | ||
id: 0, | ||
origin: [0, 0], | ||
padding: 0, | ||
yPan: true, | ||
yPanEnabled: false, | ||
yScale: scaleLinear(), | ||
}; | ||
Chart.contextTypes = { | ||
chartConfig: PropTypes.array, | ||
subscribe: PropTypes.func.isRequired, | ||
unsubscribe: PropTypes.func.isRequired, | ||
}; | ||
Chart.childContextTypes = { | ||
chartConfig: PropTypes.object.isRequired, | ||
chartId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, | ||
}; | ||
return () => unsubscribe(`chart_${id}`); | ||
}, [subscribe, unsubscribe, id, listener]); | ||
const config = chartConfigs.find(({ id }) => id === props.id); | ||
const contextValue = React.useMemo(() => { | ||
return Object.assign(Object.assign({}, chartCanvasContextValue), { chartId: id, chartConfig: config }); | ||
}, [id, config, chartCanvasContextValue]); | ||
const { origin: [x, y], } = config; | ||
return (React.createElement(ChartContext.Provider, { value: contextValue }, | ||
React.createElement("g", { transform: `translate(${x}, ${y})`, id: `chart_${id}` }, props.children))); | ||
}); | ||
Chart.displayName = "Chart"; | ||
//# sourceMappingURL=Chart.js.map |
import { ScaleContinuousNumeric, ScaleTime } from "d3-scale"; | ||
import * as PropTypes from "prop-types"; | ||
import * as React from "react"; | ||
import { IZoomAnchorOptions } from "./zoom/zoomBehavior"; | ||
import { IZoomAnchorOptions } from "./zoom"; | ||
import { ChartConfig } from "./utils/ChartDataUtil"; | ||
import { ICanvasContexts } from "./CanvasContainer"; | ||
export interface ChartCanvasContextType<TXAxis extends number | Date> { | ||
width: number; | ||
height: number; | ||
margin: { | ||
top: number; | ||
right: number; | ||
bottom: number; | ||
left: number; | ||
}; | ||
chartId: number | string; | ||
getCanvasContexts?: () => ICanvasContexts | undefined; | ||
xScale: Function; | ||
ratio: number; | ||
xAccessor: (data: any) => TXAxis; | ||
displayXAccessor: (data: any) => TXAxis; | ||
xAxisZoom?: (newDomain: any) => void; | ||
yAxisZoom?: (chartId: string, newDomain: any) => void; | ||
redraw: () => void; | ||
plotData: any[]; | ||
fullData: any[]; | ||
chartConfigs: ChartConfig[]; | ||
morePropsDecorator?: () => void; | ||
generateSubscriptionId?: () => number; | ||
getMutableState: () => {}; | ||
amIOnTop: (id: string | number) => boolean; | ||
subscribe: (id: string | number, rest: any) => void; | ||
unsubscribe: (id: string | number) => void; | ||
setCursorClass: (className: string | null | undefined) => void; | ||
} | ||
export declare const chartCanvasContextDefaultValue: ChartCanvasContextType<number | Date>; | ||
export declare const ChartCanvasContext: React.Context<ChartCanvasContextType<number | Date>>; | ||
export interface ChartCanvasProps<TXAxis extends number | Date> { | ||
@@ -63,9 +95,17 @@ readonly clamp?: boolean | ("left" | "right" | "both") | ((domain: [number, number], items: [number, number]) => [number, number]); | ||
interface ChartCanvasState<TXAxis extends number | Date> { | ||
xAccessor?: (data: any) => TXAxis; | ||
lastProps?: ChartCanvasProps<TXAxis>; | ||
propIteration?: number; | ||
xAccessor: (data: any) => TXAxis; | ||
displayXAccessor?: any; | ||
filterData?: any; | ||
chartConfig?: any; | ||
chartConfigs: ChartConfig[]; | ||
plotData: any[]; | ||
xScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>; | ||
fullData: any[]; | ||
} | ||
interface MutableState { | ||
mouseXY: [number, number]; | ||
currentItem: any; | ||
currentCharts: string[]; | ||
} | ||
export declare class ChartCanvas<TXAxis extends number | Date> extends React.Component<ChartCanvasProps<TXAxis>, ChartCanvasState<TXAxis>> { | ||
@@ -99,44 +139,5 @@ static defaultProps: { | ||
}; | ||
static childContextTypes: { | ||
plotData: PropTypes.Requireable<any[]>; | ||
fullData: PropTypes.Requireable<any[]>; | ||
chartConfig: PropTypes.Validator<(PropTypes.InferProps<{ | ||
id: PropTypes.Validator<string | number>; | ||
origin: PropTypes.Validator<(number | null | undefined)[]>; | ||
padding: PropTypes.Requireable<number | PropTypes.InferProps<{ | ||
top: PropTypes.Requireable<number>; | ||
bottom: PropTypes.Requireable<number>; | ||
}>>; | ||
yExtents: PropTypes.Requireable<(((...args: any[]) => any) | null | undefined)[]>; | ||
yExtentsProvider: PropTypes.Requireable<(...args: any[]) => any>; | ||
yScale: PropTypes.Validator<(...args: any[]) => any>; | ||
mouseCoordinates: PropTypes.Requireable<PropTypes.InferProps<{ | ||
at: PropTypes.Requireable<string>; | ||
format: PropTypes.Requireable<(...args: any[]) => any>; | ||
}>>; | ||
width: PropTypes.Validator<number>; | ||
height: PropTypes.Validator<number>; | ||
}> | null | undefined)[]>; | ||
xScale: PropTypes.Validator<(...args: any[]) => any>; | ||
xAccessor: PropTypes.Validator<(...args: any[]) => any>; | ||
displayXAccessor: PropTypes.Validator<(...args: any[]) => any>; | ||
width: PropTypes.Validator<number>; | ||
height: PropTypes.Validator<number>; | ||
margin: PropTypes.Validator<object>; | ||
ratio: PropTypes.Validator<number>; | ||
getCanvasContexts: PropTypes.Requireable<(...args: any[]) => any>; | ||
xAxisZoom: PropTypes.Requireable<(...args: any[]) => any>; | ||
yAxisZoom: PropTypes.Requireable<(...args: any[]) => any>; | ||
amIOnTop: PropTypes.Requireable<(...args: any[]) => any>; | ||
redraw: PropTypes.Requireable<(...args: any[]) => any>; | ||
subscribe: PropTypes.Requireable<(...args: any[]) => any>; | ||
unsubscribe: PropTypes.Requireable<(...args: any[]) => any>; | ||
setCursorClass: PropTypes.Requireable<(...args: any[]) => any>; | ||
generateSubscriptionId: PropTypes.Requireable<(...args: any[]) => any>; | ||
getMutableState: PropTypes.Requireable<(...args: any[]) => any>; | ||
}; | ||
private readonly canvasContainerRef; | ||
private readonly eventCaptureRef; | ||
private finalPinch?; | ||
private fullData; | ||
private lastSubscriptionId; | ||
@@ -153,13 +154,7 @@ private mutableState; | ||
constructor(props: ChartCanvasProps<TXAxis>); | ||
getMutableState: () => {}; | ||
getDataInfo: () => { | ||
fullData: any[]; | ||
xAccessor?: ((data: any) => TXAxis) | undefined; | ||
displayXAccessor?: any; | ||
filterData?: any; | ||
chartConfig?: any; | ||
plotData: any[]; | ||
xScale: ScaleContinuousNumeric<number, number, never> | ScaleTime<number, number, never>; | ||
}; | ||
getCanvasContexts: () => import("./CanvasContainer").ICanvasContexts | undefined; | ||
static getDerivedStateFromProps<TXAxis extends number | Date>(props: ChartCanvasProps<TXAxis>, state: ChartCanvasState<TXAxis>): ChartCanvasState<TXAxis>; | ||
getSnapshotBeforeUpdate(prevProps: Readonly<ChartCanvasProps<TXAxis>>, prevState: Readonly<ChartCanvasState<TXAxis>>): null; | ||
componentDidUpdate(prevProps: ChartCanvasProps<TXAxis>): void; | ||
getMutableState: () => MutableState; | ||
getCanvasContexts: () => ICanvasContexts | undefined; | ||
generateSubscriptionId: () => number; | ||
@@ -169,7 +164,10 @@ clearBothCanvas(): void; | ||
clearThreeCanvas(): void; | ||
subscribe: (id: string, rest: any) => void; | ||
unsubscribe: (id: string) => void; | ||
getAllPanConditions: () => any[]; | ||
setCursorClass: (className: string) => void; | ||
amIOnTop: (id: string) => boolean; | ||
subscribe: (id: string | number, rest: any) => void; | ||
unsubscribe: (id: string | number) => void; | ||
getAllPanConditions: () => { | ||
draggable: boolean; | ||
panEnabled: boolean; | ||
}[]; | ||
setCursorClass: (className: string | null | undefined) => void; | ||
amIOnTop: (id: string | number) => boolean; | ||
handleContextMenu: (mouseXY: number[], e: React.MouseEvent) => void; | ||
@@ -179,6 +177,6 @@ calculateStateForDomain: (newDomain: any) => { | ||
plotData: any; | ||
chartConfig: any[]; | ||
chartConfigs: ChartConfig[]; | ||
}; | ||
pinchZoomHelper: (initialPinch: any, finalPinch: any) => { | ||
chartConfig: any[]; | ||
chartConfigs: ChartConfig[]; | ||
xScale: ScaleContinuousNumeric<number, number, never> | ScaleTime<number, number, never>; | ||
@@ -188,2 +186,4 @@ plotData: any; | ||
currentItem: any; | ||
xAccessor: (data: any) => TXAxis; | ||
fullData: any[]; | ||
}; | ||
@@ -197,5 +197,9 @@ cancelDrag(): void; | ||
triggerEvent(type: any, props?: any, e?: any): void; | ||
draw: (props: any) => void; | ||
draw: (props: { | ||
trigger: string; | ||
} | { | ||
force: boolean; | ||
}) => void; | ||
redraw: () => void; | ||
panHelper: (mouseXY: number[], initialXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, { dx, dy }: { | ||
panHelper: (mouseXY: [number, number], initialXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, { dx, dy }: { | ||
dx: number; | ||
@@ -206,12 +210,12 @@ dy: number; | ||
plotData: any; | ||
chartConfig: any[]; | ||
mouseXY: number[]; | ||
currentCharts: any; | ||
chartConfigs: ChartConfig[]; | ||
mouseXY: [number, number]; | ||
currentCharts: any[]; | ||
currentItem: any; | ||
}; | ||
handlePan: (mousePosition: number[], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, dxdy: { | ||
handlePan: (mousePosition: [number, number], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, dxdy: { | ||
dx: number; | ||
dy: number; | ||
}, chartsToPan: string[], e: React.MouseEvent) => void; | ||
handlePanEnd: (mousePosition: number[], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, dxdy: { | ||
handlePanEnd: (mousePosition: [number, number], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, dxdy: { | ||
dx: number; | ||
@@ -222,8 +226,8 @@ dy: number; | ||
handleMouseEnter: (e: React.MouseEvent) => void; | ||
handleMouseMove: (mouseXY: number[], _: string, e: any) => void; | ||
handleMouseMove: (mouseXY: [number, number], _: string, e: any) => void; | ||
handleMouseLeave: (e: any) => void; | ||
handleDragStart: ({ startPos }: any, e: any) => void; | ||
handleDrag: ({ startPos, mouseXY }: { | ||
startPos: number[]; | ||
mouseXY: number[]; | ||
startPos: [number, number]; | ||
mouseXY: [number, number]; | ||
}, e: React.MouseEvent) => void; | ||
@@ -235,31 +239,4 @@ handleDragEnd: ({ mouseXY }: { | ||
handleDoubleClick: (_: number[], e: React.MouseEvent) => void; | ||
getChildContext(): { | ||
fullData: any[]; | ||
plotData: any[]; | ||
width: number; | ||
height: number; | ||
chartConfig: any; | ||
xScale: ScaleContinuousNumeric<number, number, never> | ScaleTime<number, number, never>; | ||
xAccessor: ((data: any) => TXAxis) | undefined; | ||
displayXAccessor: any; | ||
margin: { | ||
bottom: number; | ||
left: number; | ||
right: number; | ||
top: number; | ||
}; | ||
ratio: number; | ||
xAxisZoom: (newDomain: any) => void; | ||
yAxisZoom: (chartId: string, newDomain: any) => void; | ||
getCanvasContexts: () => import("./CanvasContainer").ICanvasContexts | undefined; | ||
redraw: () => void; | ||
subscribe: (id: string, rest: any) => void; | ||
unsubscribe: (id: string) => void; | ||
generateSubscriptionId: () => number; | ||
getMutableState: () => {}; | ||
amIOnTop: (id: string) => boolean; | ||
setCursorClass: (className: string) => void; | ||
}; | ||
UNSAFE_componentWillReceiveProps(nextProps: ChartCanvasProps<TXAxis>): void; | ||
resetYDomain: (chartId?: string | undefined) => void; | ||
getContextValues(): ChartCanvasContextType<TXAxis>; | ||
resetYDomain: (chartId?: string) => void; | ||
shouldComponentUpdate(): boolean; | ||
@@ -266,0 +243,0 @@ render(): JSX.Element; |
@@ -1,17 +0,5 @@ | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
import { extent as d3Extent, max, min } from "d3-array"; | ||
import * as PropTypes from "prop-types"; | ||
import * as React from "react"; | ||
import { clearCanvas, functor, head, identity, isDefined, isNotDefined, last, shallowEqual } from "./utils"; | ||
import { mouseBasedZoomAnchor } from "./zoom/zoomBehavior"; | ||
import { mouseBasedZoomAnchor } from "./zoom"; | ||
import { getChartConfigWithUpdatedYScales, getCurrentCharts, getCurrentItem, getNewChartConfig, } from "./utils/ChartDataUtil"; | ||
@@ -71,2 +59,24 @@ import { EventCapture } from "./EventCapture"; | ||
}; | ||
// eslint-disable-next-line @typescript-eslint/no-empty-function | ||
const noop = () => { }; | ||
export const chartCanvasContextDefaultValue = { | ||
amIOnTop: () => false, | ||
chartConfigs: [], | ||
chartId: 0, | ||
ratio: 0, | ||
displayXAccessor: () => 0, | ||
fullData: [], | ||
getMutableState: () => ({}), | ||
height: 0, | ||
margin: { top: 0, right: 0, bottom: 0, left: 0 }, | ||
plotData: [], | ||
setCursorClass: noop, | ||
subscribe: noop, | ||
unsubscribe: noop, | ||
redraw: noop, | ||
width: 0, | ||
xAccessor: () => 0, | ||
xScale: noop, | ||
}; | ||
export const ChartCanvasContext = React.createContext(chartCanvasContextDefaultValue); | ||
const getDimensions = (props) => { | ||
@@ -107,6 +117,6 @@ const { margin, height, width } = props; | ||
const dimensions = getDimensions(props); | ||
const chartConfig = getChartConfigWithUpdatedYScales(getNewChartConfig(dimensions, children), { plotData, xAccessor, displayXAccessor, fullData }, xScale.domain()); | ||
const chartConfigs = getChartConfigWithUpdatedYScales(getNewChartConfig(dimensions, children), { plotData, xAccessor, displayXAccessor, fullData }, xScale.domain()); | ||
return Object.assign(Object.assign({}, state), { xScale, | ||
plotData, | ||
chartConfig }); | ||
chartConfigs }); | ||
}; | ||
@@ -152,7 +162,7 @@ const updateChart = (newState, initialXScale, props, lastItemWasVisible, initialChartConfig) => { | ||
const plotData = postCalculator(initialPlotData); | ||
const chartConfig = getChartConfigWithUpdatedYScales(getNewChartConfig(dimensions, children, initialChartConfig), { plotData, xAccessor, displayXAccessor, fullData }, updatedXScale.domain()); | ||
const chartConfigs = getChartConfigWithUpdatedYScales(getNewChartConfig(dimensions, children, initialChartConfig), { plotData, xAccessor, displayXAccessor, fullData }, updatedXScale.domain()); | ||
return { | ||
xScale: updatedXScale, | ||
xAccessor, | ||
chartConfig, | ||
chartConfigs, | ||
plotData, | ||
@@ -164,3 +174,3 @@ fullData, | ||
const calculateState = (props) => { | ||
const { xAccessor: inputXAccesor, xExtents: xExtentsProp, data, padding, flipXScale } = props; | ||
const { xAccessor: inputXAccessor, xExtents: xExtentsProp, data, padding, flipXScale } = props; | ||
const direction = getXScaleDirection(flipXScale); | ||
@@ -170,6 +180,6 @@ const dimensions = getDimensions(props); | ||
? xExtentsProp(data) | ||
: d3Extent(xExtentsProp.map((d) => functor(d)).map((each) => each(data, inputXAccesor))); | ||
: d3Extent(xExtentsProp.map((d) => functor(d)).map((each) => each(data, inputXAccessor))); | ||
const { xAccessor, displayXAccessor, xScale, fullData, filterData } = calculateFullData(props); | ||
const updatedXScale = setXRange(xScale, dimensions, padding, direction); | ||
const { plotData, domain } = filterData(fullData, extent, inputXAccesor, updatedXScale); | ||
const { plotData, domain } = filterData(fullData, extent, inputXAccessor, updatedXScale); | ||
return { | ||
@@ -226,3 +236,3 @@ plotData, | ||
this.lastSubscriptionId = 0; | ||
this.mutableState = {}; | ||
this.mutableState = { mouseXY: [0, 0], currentCharts: [], currentItem: null }; | ||
this.panInProgress = false; | ||
@@ -233,5 +243,2 @@ this.subscriptions = []; | ||
}; | ||
this.getDataInfo = () => { | ||
return Object.assign(Object.assign({}, this.state), { fullData: this.fullData }); | ||
}; | ||
this.getCanvasContexts = () => { | ||
@@ -267,4 +274,4 @@ var _a; | ||
this.handleContextMenu = (mouseXY, e) => { | ||
const { xAccessor, chartConfig, plotData, xScale } = this.state; | ||
const currentCharts = getCurrentCharts(chartConfig, mouseXY); | ||
const { xAccessor, chartConfigs, plotData, xScale } = this.state; | ||
const currentCharts = getCurrentCharts(chartConfigs, mouseXY); | ||
const currentItem = getCurrentItem(xScale, xAccessor, mouseXY, plotData); | ||
@@ -278,5 +285,4 @@ this.triggerEvent("contextmenu", { | ||
this.calculateStateForDomain = (newDomain) => { | ||
const { xAccessor, displayXAccessor, xScale: initialXScale, chartConfig: initialChartConfig, plotData: initialPlotData, } = this.state; | ||
const { filterData } = this.state; | ||
const { fullData } = this; | ||
const { xAccessor, displayXAccessor, xScale: initialXScale, chartConfigs: initialChartConfig, plotData: initialPlotData, } = this.state; | ||
const { filterData, fullData } = this.state; | ||
const { postCalculator = ChartCanvas.defaultProps.postCalculator } = this.props; | ||
@@ -289,7 +295,7 @@ const { plotData: beforePlotData, domain } = filterData(fullData, newDomain, xAccessor, initialXScale, { | ||
const updatedScale = initialXScale.copy().domain(domain); | ||
const chartConfig = getChartConfigWithUpdatedYScales(initialChartConfig, { plotData, xAccessor, displayXAccessor, fullData }, updatedScale.domain()); | ||
const chartConfigs = getChartConfigWithUpdatedYScales(initialChartConfig, { plotData, xAccessor, displayXAccessor, fullData }, updatedScale.domain()); | ||
return { | ||
xScale: updatedScale, | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
}; | ||
@@ -299,4 +305,3 @@ }; | ||
const { xScale: initialPinchXScale } = initialPinch; | ||
const { xScale: initialXScale, chartConfig: initialChartConfig, plotData: initialPlotData, xAccessor, displayXAccessor, filterData, } = this.state; | ||
const { fullData } = this; | ||
const { xScale: initialXScale, chartConfigs: initialChartConfig, plotData: initialPlotData, xAccessor, displayXAccessor, filterData, fullData, } = this.state; | ||
const { postCalculator = ChartCanvas.defaultProps.postCalculator } = this.props; | ||
@@ -318,6 +323,6 @@ const { topLeft: iTL, bottomRight: iBR } = pinchCoordinates(initialPinch); | ||
const mouseXY = finalPinch.touch1Pos; | ||
const chartConfig = getChartConfigWithUpdatedYScales(initialChartConfig, { plotData, xAccessor, displayXAccessor, fullData }, updatedScale.domain()); | ||
const chartConfigs = getChartConfigWithUpdatedYScales(initialChartConfig, { plotData, xAccessor, displayXAccessor, fullData }, updatedScale.domain()); | ||
const currentItem = getCurrentItem(updatedScale, xAccessor, mouseXY, plotData); | ||
return { | ||
chartConfig, | ||
chartConfigs, | ||
xScale: updatedScale, | ||
@@ -327,2 +332,4 @@ plotData, | ||
currentItem, | ||
xAccessor, | ||
fullData, | ||
}; | ||
@@ -347,7 +354,6 @@ }; | ||
const state = this.pinchZoomHelper(initialPinch, this.finalPinch); | ||
const { xScale } = state; | ||
const { xScale, fullData } = state; | ||
this.triggerEvent("pinchzoom", state, e); | ||
this.finalPinch = undefined; | ||
this.clearThreeCanvas(); | ||
const { fullData } = this; | ||
const firstItem = head(fullData); | ||
@@ -378,5 +384,4 @@ const scale_start = head(xScale.domain()); | ||
} | ||
const { xAccessor, xScale: initialXScale, plotData: initialPlotData } = this.state; | ||
const { xAccessor, xScale: initialXScale, plotData: initialPlotData, fullData } = this.state; | ||
const { zoomMultiplier = ChartCanvas.defaultProps.zoomMultiplier, zoomAnchor = ChartCanvas.defaultProps.zoomAnchor, } = this.props; | ||
const { fullData } = this; | ||
const item = zoomAnchor({ | ||
@@ -394,5 +399,5 @@ xScale: initialXScale, | ||
.map((x) => initialXScale.invert(x)); | ||
const { xScale, plotData, chartConfig } = this.calculateStateForDomain(newDomain); | ||
const { xScale, plotData, chartConfigs } = this.calculateStateForDomain(newDomain); | ||
const currentItem = getCurrentItem(xScale, xAccessor, mouseXY, plotData); | ||
const currentCharts = getCurrentCharts(chartConfig, mouseXY); | ||
const currentCharts = getCurrentCharts(chartConfigs, mouseXY); | ||
this.clearThreeCanvas(); | ||
@@ -413,3 +418,3 @@ const firstItem = head(fullData); | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
mouseXY, | ||
@@ -424,3 +429,3 @@ currentCharts, | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
}, () => { | ||
@@ -440,6 +445,5 @@ if (scale_start < data_start) { | ||
this.xAxisZoom = (newDomain) => { | ||
const { xScale, plotData, chartConfig } = this.calculateStateForDomain(newDomain); | ||
const { xScale, plotData, chartConfigs } = this.calculateStateForDomain(newDomain); | ||
this.clearThreeCanvas(); | ||
const { xAccessor } = this.state; | ||
const { fullData } = this; | ||
const { xAccessor, fullData } = this.state; | ||
const firstItem = head(fullData); | ||
@@ -455,3 +459,3 @@ const scale_start = head(xScale.domain()); | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
}, () => { | ||
@@ -472,4 +476,4 @@ if (scale_start < data_start) { | ||
this.clearThreeCanvas(); | ||
const { chartConfig: initialChartConfig } = this.state; | ||
const chartConfig = initialChartConfig.map((each) => { | ||
const { chartConfigs: initialChartConfig } = this.state; | ||
const chartConfigs = initialChartConfig.map((each) => { | ||
if (each.id === chartId) { | ||
@@ -484,3 +488,3 @@ const { yScale } = each; | ||
this.setState({ | ||
chartConfig, | ||
chartConfigs, | ||
}); | ||
@@ -500,4 +504,3 @@ }; | ||
this.panHelper = (mouseXY, initialXScale, { dx, dy }, chartsToPan) => { | ||
const { xAccessor, displayXAccessor, chartConfig: initialChartConfig, filterData } = this.state; | ||
const { fullData } = this; | ||
const { xAccessor, displayXAccessor, chartConfigs: initialChartConfig, filterData, fullData } = this.state; | ||
const { postCalculator = ChartCanvas.defaultProps.postCalculator } = this.props; | ||
@@ -516,8 +519,8 @@ const newDomain = initialXScale | ||
const currentItem = getCurrentItem(updatedScale, xAccessor, mouseXY, plotData); | ||
const chartConfig = getChartConfigWithUpdatedYScales(initialChartConfig, { plotData, xAccessor, displayXAccessor, fullData }, updatedScale.domain(), dy, chartsToPan); | ||
const currentCharts = getCurrentCharts(chartConfig, mouseXY); | ||
const chartConfigs = getChartConfigWithUpdatedYScales(initialChartConfig, { plotData, xAccessor, displayXAccessor, fullData }, updatedScale.domain(), dy, chartsToPan); | ||
const currentCharts = getCurrentCharts(chartConfigs, mouseXY); | ||
return { | ||
xScale: updatedScale, | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
mouseXY, | ||
@@ -530,24 +533,25 @@ currentCharts, | ||
var _a, _b; | ||
if (!this.waitingForPanAnimationFrame) { | ||
this.waitingForPanAnimationFrame = true; | ||
this.hackyWayToStopPanBeyondBounds__plotData = | ||
(_a = this.hackyWayToStopPanBeyondBounds__plotData) !== null && _a !== void 0 ? _a : this.state.plotData; | ||
this.hackyWayToStopPanBeyondBounds__domain = | ||
(_b = this.hackyWayToStopPanBeyondBounds__domain) !== null && _b !== void 0 ? _b : this.state.xScale.domain(); | ||
const newState = this.panHelper(mousePosition, panStartXScale, dxdy, chartsToPan); | ||
this.hackyWayToStopPanBeyondBounds__plotData = newState.plotData; | ||
this.hackyWayToStopPanBeyondBounds__domain = newState.xScale.domain(); | ||
this.panInProgress = true; | ||
this.triggerEvent("pan", newState, e); | ||
this.mutableState = { | ||
mouseXY: newState.mouseXY, | ||
currentItem: newState.currentItem, | ||
currentCharts: newState.currentCharts, | ||
}; | ||
requestAnimationFrame(() => { | ||
this.waitingForPanAnimationFrame = false; | ||
this.clearBothCanvas(); | ||
this.draw({ trigger: "pan" }); | ||
}); | ||
if (this.waitingForPanAnimationFrame) { | ||
return; | ||
} | ||
this.waitingForPanAnimationFrame = true; | ||
this.hackyWayToStopPanBeyondBounds__plotData = | ||
(_a = this.hackyWayToStopPanBeyondBounds__plotData) !== null && _a !== void 0 ? _a : this.state.plotData; | ||
this.hackyWayToStopPanBeyondBounds__domain = | ||
(_b = this.hackyWayToStopPanBeyondBounds__domain) !== null && _b !== void 0 ? _b : this.state.xScale.domain(); | ||
const newState = this.panHelper(mousePosition, panStartXScale, dxdy, chartsToPan); | ||
this.hackyWayToStopPanBeyondBounds__plotData = newState.plotData; | ||
this.hackyWayToStopPanBeyondBounds__domain = newState.xScale.domain(); | ||
this.panInProgress = true; | ||
this.triggerEvent("pan", newState, e); | ||
this.mutableState = { | ||
mouseXY: newState.mouseXY, | ||
currentItem: newState.currentItem, | ||
currentCharts: newState.currentCharts, | ||
}; | ||
requestAnimationFrame(() => { | ||
this.waitingForPanAnimationFrame = false; | ||
this.clearBothCanvas(); | ||
this.draw({ trigger: "pan" }); | ||
}); | ||
}; | ||
@@ -559,7 +563,6 @@ this.handlePanEnd = (mousePosition, panStartXScale, dxdy, chartsToPan, e) => { | ||
this.panInProgress = false; | ||
const { xScale, plotData, chartConfig } = state; | ||
const { xScale, plotData, chartConfigs } = state; | ||
this.triggerEvent("panend", state, e); | ||
requestAnimationFrame(() => { | ||
const { xAccessor } = this.state; | ||
const { fullData } = this; | ||
const { xAccessor, fullData } = this.state; | ||
const firstItem = head(fullData); | ||
@@ -576,3 +579,3 @@ const scale_start = head(xScale.domain()); | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
}, () => { | ||
@@ -601,27 +604,28 @@ if (scale_start < data_start) { | ||
this.handleMouseMove = (mouseXY, _, e) => { | ||
if (!this.waitingForMouseMoveAnimationFrame) { | ||
this.waitingForMouseMoveAnimationFrame = true; | ||
const { chartConfig, plotData, xScale, xAccessor } = this.state; | ||
const currentCharts = getCurrentCharts(chartConfig, mouseXY); | ||
const currentItem = getCurrentItem(xScale, xAccessor, mouseXY, plotData); | ||
this.triggerEvent("mousemove", { | ||
show: true, | ||
mouseXY, | ||
// prevMouseXY is used in interactive components | ||
prevMouseXY: this.prevMouseXY, | ||
currentItem, | ||
currentCharts, | ||
}, e); | ||
this.prevMouseXY = mouseXY; | ||
this.mutableState = { | ||
mouseXY, | ||
currentItem, | ||
currentCharts, | ||
}; | ||
requestAnimationFrame(() => { | ||
this.clearMouseCanvas(); | ||
this.draw({ trigger: "mousemove" }); | ||
this.waitingForMouseMoveAnimationFrame = false; | ||
}); | ||
if (this.waitingForMouseMoveAnimationFrame) { | ||
return; | ||
} | ||
this.waitingForMouseMoveAnimationFrame = true; | ||
const { chartConfigs, plotData, xScale, xAccessor } = this.state; | ||
const currentCharts = getCurrentCharts(chartConfigs, mouseXY); | ||
const currentItem = getCurrentItem(xScale, xAccessor, mouseXY, plotData); | ||
this.triggerEvent("mousemove", { | ||
show: true, | ||
mouseXY, | ||
// prevMouseXY is used in interactive components | ||
prevMouseXY: this.prevMouseXY, | ||
currentItem, | ||
currentCharts, | ||
}, e); | ||
this.prevMouseXY = mouseXY; | ||
this.mutableState = { | ||
mouseXY, | ||
currentItem, | ||
currentCharts, | ||
}; | ||
requestAnimationFrame(() => { | ||
this.clearMouseCanvas(); | ||
this.draw({ trigger: "mousemove" }); | ||
this.waitingForMouseMoveAnimationFrame = false; | ||
}); | ||
}; | ||
@@ -637,4 +641,4 @@ this.handleMouseLeave = (e) => { | ||
this.handleDrag = ({ startPos, mouseXY }, e) => { | ||
const { chartConfig, plotData, xScale, xAccessor } = this.state; | ||
const currentCharts = getCurrentCharts(chartConfig, mouseXY); | ||
const { chartConfigs, plotData, xScale, xAccessor } = this.state; | ||
const currentCharts = getCurrentCharts(chartConfigs, mouseXY); | ||
const currentItem = getCurrentItem(xScale, xAccessor, mouseXY, plotData); | ||
@@ -675,5 +679,5 @@ this.triggerEvent("drag", { | ||
this.resetYDomain = (chartId) => { | ||
const { chartConfig } = this.state; | ||
const { chartConfigs } = this.state; | ||
let changed = false; | ||
const newChartConfig = chartConfig.map((each) => { | ||
const newChartConfig = chartConfigs.map((each) => { | ||
if ((isNotDefined(chartId) || each.id === chartId) && | ||
@@ -689,10 +693,46 @@ !shallowEqual(each.yScale.domain(), each.realYDomain)) { | ||
this.setState({ | ||
chartConfig: newChartConfig, | ||
chartConfigs: newChartConfig, | ||
}); | ||
} | ||
}; | ||
const _a = resetChart(props), { fullData } = _a, state = __rest(_a, ["fullData"]); | ||
this.state = state; | ||
this.fullData = fullData; | ||
this.state = resetChart(props); | ||
} | ||
static getDerivedStateFromProps(props, state) { | ||
var _a; | ||
const { chartConfigs: initialChartConfig, plotData, xAccessor, xScale } = state; | ||
const interaction = isInteractionEnabled(xScale, xAccessor, plotData); | ||
const shouldReset = shouldResetChart(state.lastProps || {}, props); | ||
let newState; | ||
if (!interaction || shouldReset || !shallowEqual((_a = state.lastProps) === null || _a === void 0 ? void 0 : _a.xExtents, props.xExtents)) { | ||
// do reset | ||
newState = resetChart(props); | ||
} | ||
else { | ||
const [start, end] = xScale.domain(); | ||
const prevLastItem = last(state.fullData); | ||
const calculatedState = calculateFullData(props); | ||
const { xAccessor } = calculatedState; | ||
const previousX = xAccessor(prevLastItem); | ||
const lastItemWasVisible = previousX <= end && previousX >= start; | ||
newState = updateChart(calculatedState, xScale, props, lastItemWasVisible, initialChartConfig); | ||
} | ||
return Object.assign(Object.assign({}, newState), { lastProps: props, propIteration: (state.propIteration || 0) + 1 }); | ||
} | ||
getSnapshotBeforeUpdate(prevProps, prevState) { | ||
// propIteration is incremented when the props change to differentiate between state updates | ||
// and prop updates | ||
if (prevState.propIteration !== this.state.propIteration && !this.panInProgress) { | ||
this.clearThreeCanvas(); | ||
} | ||
return null; | ||
} | ||
componentDidUpdate(prevProps) { | ||
if (prevProps.data !== this.props.data) { | ||
this.triggerEvent("dataupdated", { | ||
chartConfigs: this.state.chartConfigs, | ||
xScale: this.state.xScale, | ||
plotData: this.state.plotData, | ||
}); | ||
} | ||
} | ||
clearBothCanvas() { | ||
@@ -723,14 +763,16 @@ const canvases = this.getCanvasContexts(); | ||
this.subscriptions.forEach((each) => { | ||
const state = Object.assign(Object.assign({}, this.state), { fullData: this.fullData, subscriptions: this.subscriptions }); | ||
const state = Object.assign(Object.assign({}, this.state), { subscriptions: this.subscriptions }); | ||
each.listener(type, props, state, e); | ||
}); | ||
} | ||
getChildContext() { | ||
// TODO: Memoize this | ||
getContextValues() { | ||
const dimensions = getDimensions(this.props); | ||
return { | ||
fullData: this.fullData, | ||
chartId: -1, | ||
fullData: this.state.fullData, | ||
plotData: this.state.plotData, | ||
width: dimensions.width, | ||
height: dimensions.height, | ||
chartConfig: this.state.chartConfig, | ||
chartConfigs: this.state.chartConfigs, | ||
xScale: this.state.xScale, | ||
@@ -753,28 +795,2 @@ xAccessor: this.state.xAccessor, | ||
} | ||
UNSAFE_componentWillReceiveProps(nextProps) { | ||
const reset = shouldResetChart(this.props, nextProps); | ||
const { chartConfig: initialChartConfig, plotData, xAccessor, xScale } = this.state; | ||
const interaction = isInteractionEnabled(xScale, xAccessor, plotData); | ||
let newState; | ||
if (!interaction || reset || !shallowEqual(this.props.xExtents, nextProps.xExtents)) { | ||
// do reset | ||
newState = resetChart(nextProps); | ||
this.mutableState = {}; | ||
} | ||
else { | ||
const [start, end] = xScale.domain(); | ||
const prevLastItem = last(this.fullData); | ||
const calculatedState = calculateFullData(nextProps); | ||
const { xAccessor } = calculatedState; | ||
const previousX = xAccessor(prevLastItem); | ||
const lastItemWasVisible = previousX <= end && previousX >= start; | ||
newState = updateChart(calculatedState, xScale, nextProps, lastItemWasVisible, initialChartConfig); | ||
} | ||
const { fullData } = newState, state = __rest(newState, ["fullData"]); | ||
if (!this.panInProgress) { | ||
this.clearThreeCanvas(); | ||
this.setState(state); | ||
} | ||
this.fullData = fullData; | ||
} | ||
shouldComponentUpdate() { | ||
@@ -785,3 +801,3 @@ return !this.panInProgress; | ||
const { disableInteraction, disablePan, disableZoom, useCrossHairStyleCursor, onClick, onDoubleClick, height, width, margin = ChartCanvas.defaultProps.margin, className, zIndex = ChartCanvas.defaultProps.zIndex, defaultFocus, ratio, mouseMoveEvent, } = this.props; | ||
const { plotData, xScale, xAccessor, chartConfig } = this.state; | ||
const { plotData, xScale, xAccessor, chartConfigs } = this.state; | ||
const dimensions = getDimensions(this.props); | ||
@@ -791,14 +807,15 @@ const interaction = isInteractionEnabled(xScale, xAccessor, plotData); | ||
const cursor = getCursorStyle(); | ||
return (React.createElement("div", { style: { position: "relative", width, height }, className: className, onClick: onClick, onDoubleClick: onDoubleClick }, | ||
React.createElement(CanvasContainer, { ref: this.canvasContainerRef, ratio: ratio, width: width, height: height, style: { height, zIndex, width } }), | ||
React.createElement("svg", { className: className, width: width, height: height, style: { position: "absolute", zIndex: zIndex + 5 } }, | ||
cursor, | ||
React.createElement("defs", null, | ||
React.createElement("clipPath", { id: "chart-area-clip" }, | ||
React.createElement("rect", { x: "0", y: "0", width: dimensions.width, height: dimensions.height })), | ||
chartConfig.map((each, idx) => (React.createElement("clipPath", { key: idx, id: `chart-area-clip-${each.id}` }, | ||
React.createElement("rect", { x: "0", y: "0", width: each.width, height: each.height }))))), | ||
React.createElement("g", { transform: `translate(${margin.left + 0.5}, ${margin.top + 0.5})` }, | ||
React.createElement(EventCapture, { ref: this.eventCaptureRef, useCrossHairStyleCursor: cursorStyle, mouseMove: mouseMoveEvent && interaction, zoom: !disableZoom && interaction, pan: !disablePan && interaction, width: dimensions.width, height: dimensions.height, chartConfig: chartConfig, xScale: xScale, xAccessor: xAccessor, focus: defaultFocus, disableInteraction: disableInteraction, getAllPanConditions: this.getAllPanConditions, onContextMenu: this.handleContextMenu, onClick: this.handleClick, onDoubleClick: this.handleDoubleClick, onMouseDown: this.handleMouseDown, onMouseMove: this.handleMouseMove, onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave, onDragStart: this.handleDragStart, onDrag: this.handleDrag, onDragComplete: this.handleDragEnd, onZoom: this.handleZoom, onPinchZoom: this.handlePinchZoom, onPinchZoomEnd: this.handlePinchZoomEnd, onPan: this.handlePan, onPanEnd: this.handlePanEnd }), | ||
React.createElement("g", { className: "react-financial-charts-avoid-interaction" }, this.props.children))))); | ||
return (React.createElement(ChartCanvasContext.Provider, { value: this.getContextValues() }, | ||
React.createElement("div", { style: { position: "relative", width, height }, className: className, onClick: onClick, onDoubleClick: onDoubleClick }, | ||
React.createElement(CanvasContainer, { ref: this.canvasContainerRef, ratio: ratio, width: width, height: height, style: { height, zIndex, width } }), | ||
React.createElement("svg", { className: className, width: width, height: height, style: { position: "absolute", zIndex: zIndex + 5 } }, | ||
cursor, | ||
React.createElement("defs", null, | ||
React.createElement("clipPath", { id: "chart-area-clip" }, | ||
React.createElement("rect", { x: "0", y: "0", width: dimensions.width, height: dimensions.height })), | ||
chartConfigs.map((each, idx) => (React.createElement("clipPath", { key: idx, id: `chart-area-clip-${each.id}` }, | ||
React.createElement("rect", { x: "0", y: "0", width: each.width, height: each.height }))))), | ||
React.createElement("g", { transform: `translate(${margin.left + 0.5}, ${margin.top + 0.5})` }, | ||
React.createElement(EventCapture, { ref: this.eventCaptureRef, useCrossHairStyleCursor: cursorStyle, mouseMove: mouseMoveEvent && interaction, zoom: !disableZoom && interaction, pan: !disablePan && interaction, width: dimensions.width, height: dimensions.height, chartConfig: chartConfigs, xScale: xScale, xAccessor: xAccessor, focus: defaultFocus, disableInteraction: disableInteraction, getAllPanConditions: this.getAllPanConditions, onContextMenu: this.handleContextMenu, onClick: this.handleClick, onDoubleClick: this.handleDoubleClick, onMouseDown: this.handleMouseDown, onMouseMove: this.handleMouseMove, onMouseEnter: this.handleMouseEnter, onMouseLeave: this.handleMouseLeave, onDragStart: this.handleDragStart, onDrag: this.handleDrag, onDragComplete: this.handleDragEnd, onZoom: this.handleZoom, onPinchZoom: this.handlePinchZoom, onPinchZoomEnd: this.handlePinchZoomEnd, onPan: this.handlePan, onPanEnd: this.handlePanEnd }), | ||
React.createElement("g", { className: "react-financial-charts-avoid-interaction" }, this.props.children)))))); | ||
} | ||
@@ -828,43 +845,2 @@ } | ||
}; | ||
ChartCanvas.childContextTypes = { | ||
plotData: PropTypes.array, | ||
fullData: PropTypes.array, | ||
chartConfig: PropTypes.arrayOf(PropTypes.shape({ | ||
id: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, | ||
origin: PropTypes.arrayOf(PropTypes.number).isRequired, | ||
padding: PropTypes.oneOfType([ | ||
PropTypes.number, | ||
PropTypes.shape({ | ||
top: PropTypes.number, | ||
bottom: PropTypes.number, | ||
}), | ||
]), | ||
yExtents: PropTypes.arrayOf(PropTypes.func), | ||
yExtentsProvider: PropTypes.func, | ||
yScale: PropTypes.func.isRequired, | ||
mouseCoordinates: PropTypes.shape({ | ||
at: PropTypes.string, | ||
format: PropTypes.func, | ||
}), | ||
width: PropTypes.number.isRequired, | ||
height: PropTypes.number.isRequired, | ||
})).isRequired, | ||
xScale: PropTypes.func.isRequired, | ||
xAccessor: PropTypes.func.isRequired, | ||
displayXAccessor: PropTypes.func.isRequired, | ||
width: PropTypes.number.isRequired, | ||
height: PropTypes.number.isRequired, | ||
margin: PropTypes.object.isRequired, | ||
ratio: PropTypes.number.isRequired, | ||
getCanvasContexts: PropTypes.func, | ||
xAxisZoom: PropTypes.func, | ||
yAxisZoom: PropTypes.func, | ||
amIOnTop: PropTypes.func, | ||
redraw: PropTypes.func, | ||
subscribe: PropTypes.func, | ||
unsubscribe: PropTypes.func, | ||
setCursorClass: PropTypes.func, | ||
generateSubscriptionId: PropTypes.func, | ||
getMutableState: PropTypes.func, | ||
}; | ||
//# sourceMappingURL=ChartCanvas.js.map |
import { ScaleContinuousNumeric, ScaleTime } from "d3-scale"; | ||
import * as React from "react"; | ||
import { ChartConfig } from "./utils/ChartDataUtil"; | ||
interface EventCaptureProps { | ||
@@ -12,6 +13,3 @@ readonly mouseMove: boolean; | ||
readonly height: number; | ||
readonly chartConfig: { | ||
origin: number[]; | ||
height: number; | ||
}[]; | ||
readonly chartConfig: ChartConfig[]; | ||
readonly xAccessor: any; | ||
@@ -31,4 +29,4 @@ readonly xScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>; | ||
readonly onDrag?: (details: { | ||
startPos: number[]; | ||
mouseXY: number[]; | ||
startPos: [number, number]; | ||
mouseXY: [number, number]; | ||
}, event: React.MouseEvent) => void; | ||
@@ -38,4 +36,4 @@ readonly onDragComplete?: (details: { | ||
}, event: React.MouseEvent) => void; | ||
readonly onMouseDown?: (mouseXY: number[], currentCharts: string[], event: React.MouseEvent) => void; | ||
readonly onMouseMove?: (touchXY: number[], eventType: string, event: React.MouseEvent | React.TouchEvent) => void; | ||
readonly onMouseDown?: (mouseXY: [number, number], currentCharts: string[], event: React.MouseEvent) => void; | ||
readonly onMouseMove?: (touchXY: [number, number], eventType: string, event: React.MouseEvent | React.TouchEvent) => void; | ||
readonly onMouseEnter?: (event: React.MouseEvent) => void; | ||
@@ -59,7 +57,7 @@ readonly onMouseLeave?: (event: React.MouseEvent) => void; | ||
}, e: React.TouchEvent) => void; | ||
readonly onPan?: (mouseXY: number[], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, panOrigin: { | ||
readonly onPan?: (mouseXY: [number, number], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, panOrigin: { | ||
dx: number; | ||
dy: number; | ||
}, chartsToPan: string[], e: React.MouseEvent) => void; | ||
readonly onPanEnd?: (mouseXY: number[], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, panOrigin: { | ||
readonly onPanEnd?: (mouseXY: [number, number], panStartXScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, panOrigin: { | ||
dx: number; | ||
@@ -73,3 +71,3 @@ dy: number; | ||
dragInProgress?: boolean; | ||
dragStartPosition?: number[]; | ||
dragStartPosition?: [number, number]; | ||
panInProgress: boolean; | ||
@@ -135,5 +133,5 @@ panStart?: { | ||
handlePinchZoomEnd: (e: any) => void; | ||
setCursorClass: (cursorOverrideClass: string) => void; | ||
setCursorClass: (cursorOverrideClass: string | undefined | null) => void; | ||
render(): JSX.Element; | ||
} | ||
export {}; |
@@ -400,3 +400,3 @@ var __rest = (this && this.__rest) || function (s, e) { | ||
this.setState({ | ||
cursorOverrideClass, | ||
cursorOverrideClass: cursorOverrideClass === null ? undefined : cursorOverrideClass, | ||
}); | ||
@@ -470,9 +470,11 @@ } | ||
: "react-financial-charts-crosshair-cursor"; | ||
const interactionProps = disableInteraction || { | ||
onMouseDown: this.handleMouseDown, | ||
onClick: this.handleClick, | ||
onContextMenu: this.handleRightClick, | ||
onTouchStart: this.handleTouchStart, | ||
onTouchMove: this.handleTouchMove, | ||
}; | ||
const interactionProps = disableInteraction | ||
? undefined | ||
: { | ||
onMouseDown: this.handleMouseDown, | ||
onClick: this.handleClick, | ||
onContextMenu: this.handleRightClick, | ||
onTouchStart: this.handleTouchStart, | ||
onTouchMove: this.handleTouchMove, | ||
}; | ||
return (React.createElement("rect", Object.assign({ ref: this.ref, className: className, width: width, height: height, style: { opacity: 0 } }, interactionProps))); | ||
@@ -479,0 +481,0 @@ } |
@@ -1,2 +0,2 @@ | ||
import * as PropTypes from "prop-types"; | ||
/// <reference types="react" /> | ||
import { GenericComponent } from "./GenericComponent"; | ||
@@ -14,25 +14,3 @@ export declare class GenericChartComponent extends GenericComponent { | ||
}; | ||
static contextTypes: { | ||
width: PropTypes.Validator<number>; | ||
height: PropTypes.Validator<number>; | ||
margin: PropTypes.Validator<object>; | ||
chartId: PropTypes.Requireable<string | number>; | ||
getCanvasContexts: PropTypes.Requireable<(...args: any[]) => any>; | ||
xScale: PropTypes.Validator<(...args: any[]) => any>; | ||
xAccessor: PropTypes.Validator<(...args: any[]) => any>; | ||
displayXAccessor: PropTypes.Validator<(...args: any[]) => any>; | ||
plotData: PropTypes.Validator<any[]>; | ||
fullData: PropTypes.Validator<any[]>; | ||
chartConfig: PropTypes.Validator<object>; | ||
morePropsDecorator: PropTypes.Requireable<(...args: any[]) => any>; | ||
generateSubscriptionId: PropTypes.Requireable<(...args: any[]) => any>; | ||
getMutableState: PropTypes.Validator<(...args: any[]) => any>; | ||
amIOnTop: PropTypes.Validator<(...args: any[]) => any>; | ||
subscribe: PropTypes.Validator<(...args: any[]) => any>; | ||
unsubscribe: PropTypes.Validator<(...args: any[]) => any>; | ||
setCursorClass: PropTypes.Validator<(...args: any[]) => any>; | ||
canvasOriginX: PropTypes.Requireable<number>; | ||
canvasOriginY: PropTypes.Requireable<number>; | ||
ratio: PropTypes.Validator<number>; | ||
}; | ||
static contextType: import("react").Context<import("./Chart").ChartContextType>; | ||
constructor(props: any, context: any); | ||
@@ -39,0 +17,0 @@ preCanvasDraw(ctx: CanvasRenderingContext2D, moreProps: any): void; |
@@ -1,4 +0,4 @@ | ||
import * as PropTypes from "prop-types"; | ||
import { GenericComponent } from "./GenericComponent"; | ||
import { isDefined } from "./utils"; | ||
import { ChartContext } from "./Chart"; | ||
const ALWAYS_TRUE_TYPES = ["drag", "dragend"]; | ||
@@ -74,25 +74,3 @@ export class GenericChartComponent extends GenericComponent { | ||
GenericChartComponent.defaultProps = GenericComponent.defaultProps; | ||
GenericChartComponent.contextTypes = { | ||
width: PropTypes.number.isRequired, | ||
height: PropTypes.number.isRequired, | ||
margin: PropTypes.object.isRequired, | ||
chartId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), | ||
getCanvasContexts: PropTypes.func, | ||
xScale: PropTypes.func.isRequired, | ||
xAccessor: PropTypes.func.isRequired, | ||
displayXAccessor: PropTypes.func.isRequired, | ||
plotData: PropTypes.array.isRequired, | ||
fullData: PropTypes.array.isRequired, | ||
chartConfig: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired, | ||
morePropsDecorator: PropTypes.func, | ||
generateSubscriptionId: PropTypes.func, | ||
getMutableState: PropTypes.func.isRequired, | ||
amIOnTop: PropTypes.func.isRequired, | ||
subscribe: PropTypes.func.isRequired, | ||
unsubscribe: PropTypes.func.isRequired, | ||
setCursorClass: PropTypes.func.isRequired, | ||
canvasOriginX: PropTypes.number, | ||
canvasOriginY: PropTypes.number, | ||
ratio: PropTypes.number.isRequired, | ||
}; | ||
GenericChartComponent.contextType = ChartContext; | ||
//# sourceMappingURL=GenericChartComponent.js.map |
@@ -1,4 +0,4 @@ | ||
import * as PropTypes from "prop-types"; | ||
import * as React from "react"; | ||
import { ICanvasContexts } from "./CanvasContainer"; | ||
import { ChartCanvasContext } from "./ChartCanvas"; | ||
interface GenericComponentProps { | ||
@@ -47,22 +47,3 @@ readonly svgDraw?: (moreProps: any) => React.ReactNode; | ||
}; | ||
static contextTypes: { | ||
width: PropTypes.Validator<number>; | ||
height: PropTypes.Validator<number>; | ||
margin: PropTypes.Validator<object>; | ||
chartId: PropTypes.Requireable<string | number>; | ||
getCanvasContexts: PropTypes.Requireable<(...args: any[]) => any>; | ||
xScale: PropTypes.Validator<(...args: any[]) => any>; | ||
xAccessor: PropTypes.Validator<(...args: any[]) => any>; | ||
displayXAccessor: PropTypes.Validator<(...args: any[]) => any>; | ||
plotData: PropTypes.Validator<any[]>; | ||
fullData: PropTypes.Validator<any[]>; | ||
chartConfig: PropTypes.Validator<object>; | ||
morePropsDecorator: PropTypes.Requireable<(...args: any[]) => any>; | ||
generateSubscriptionId: PropTypes.Requireable<(...args: any[]) => any>; | ||
getMutableState: PropTypes.Validator<(...args: any[]) => any>; | ||
amIOnTop: PropTypes.Validator<(...args: any[]) => any>; | ||
subscribe: PropTypes.Validator<(...args: any[]) => any>; | ||
unsubscribe: PropTypes.Validator<(...args: any[]) => any>; | ||
setCursorClass: PropTypes.Validator<(...args: any[]) => any>; | ||
}; | ||
context: React.ContextType<typeof ChartCanvasContext>; | ||
moreProps: any; | ||
@@ -72,3 +53,3 @@ private dragInProgress; | ||
private iSetTheCursorClass; | ||
private suscriberId; | ||
private readonly subscriberId; | ||
constructor(props: GenericComponentProps, context: any); | ||
@@ -85,3 +66,3 @@ updateMoreProps(moreProps: any): void; | ||
}; | ||
draw({ trigger, force }?: { | ||
draw({ trigger, force }: { | ||
force: boolean; | ||
@@ -88,0 +69,0 @@ trigger: string; |
/* eslint-disable @typescript-eslint/no-unused-vars */ | ||
import * as PropTypes from "prop-types"; | ||
import * as React from "react"; | ||
import { functor, identity } from "./utils"; | ||
import { ChartCanvasContext } from "./ChartCanvas"; | ||
const aliases = { | ||
@@ -45,3 +45,3 @@ mouseleave: "mousemove", | ||
const { generateSubscriptionId } = context; | ||
this.suscriberId = generateSubscriptionId(); | ||
this.subscriberId = generateSubscriptionId(); | ||
this.state = { | ||
@@ -121,3 +121,3 @@ updateCount: 0, | ||
/* && !prevHover */ | ||
amIOnTop(this.suscriberId) && | ||
amIOnTop(this.subscriberId) && | ||
this.props.onHover !== undefined) { | ||
@@ -127,3 +127,3 @@ setCursorClass("react-financial-charts-pointer-cursor"); | ||
} | ||
else if (this.moreProps.hovering && this.props.selected && amIOnTop(this.suscriberId)) { | ||
else if (this.moreProps.hovering && this.props.selected && amIOnTop(this.subscriberId)) { | ||
setCursorClass(this.props.interactiveCursorClass); | ||
@@ -178,3 +178,3 @@ this.iSetTheCursorClass = true; | ||
const { amIOnTop } = this.context; | ||
if (amIOnTop(this.suscriberId)) { | ||
if (amIOnTop(this.subscriberId)) { | ||
this.dragInProgress = true; | ||
@@ -225,5 +225,3 @@ if (this.props.onDragStart !== undefined) { | ||
} | ||
// @ts-ignore | ||
draw({ trigger, force } = { force: false }) { | ||
// @ts-ignore | ||
draw({ trigger, force = false }) { | ||
const type = aliases[trigger] || trigger; | ||
@@ -247,3 +245,3 @@ const proceed = this.props.drawOn.indexOf(type) > -1; | ||
const { clip, edgeClip } = this.props; | ||
subscribe(this.suscriberId, { | ||
subscribe(this.subscriberId, { | ||
chartId, | ||
@@ -260,3 +258,3 @@ clip, | ||
const { unsubscribe } = this.context; | ||
unsubscribe(this.suscriberId); | ||
unsubscribe(this.subscriberId); | ||
if (this.iSetTheCursorClass) { | ||
@@ -302,7 +300,7 @@ const { setCursorClass } = this.context; | ||
getMoreProps() { | ||
const { xScale, plotData, chartConfig, morePropsDecorator, xAccessor, displayXAccessor, width, height, } = this.context; | ||
const { xScale, plotData, chartConfigs, morePropsDecorator, xAccessor, displayXAccessor, width, height } = this.context; | ||
const { chartId, fullData } = this.context; | ||
const moreProps = Object.assign({ xScale, | ||
plotData, | ||
chartConfig, | ||
chartConfigs, | ||
xAccessor, | ||
@@ -358,22 +356,3 @@ displayXAccessor, | ||
}; | ||
GenericComponent.contextTypes = { | ||
width: PropTypes.number.isRequired, | ||
height: PropTypes.number.isRequired, | ||
margin: PropTypes.object.isRequired, | ||
chartId: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), | ||
getCanvasContexts: PropTypes.func, | ||
xScale: PropTypes.func.isRequired, | ||
xAccessor: PropTypes.func.isRequired, | ||
displayXAccessor: PropTypes.func.isRequired, | ||
plotData: PropTypes.array.isRequired, | ||
fullData: PropTypes.array.isRequired, | ||
chartConfig: PropTypes.oneOfType([PropTypes.array, PropTypes.object]).isRequired, | ||
morePropsDecorator: PropTypes.func, | ||
generateSubscriptionId: PropTypes.func, | ||
getMutableState: PropTypes.func.isRequired, | ||
amIOnTop: PropTypes.func.isRequired, | ||
subscribe: PropTypes.func.isRequired, | ||
unsubscribe: PropTypes.func.isRequired, | ||
setCursorClass: PropTypes.func.isRequired, | ||
}; | ||
GenericComponent.contextType = ChartCanvasContext; | ||
export const getAxisCanvas = (contexts) => { | ||
@@ -380,0 +359,0 @@ return contexts.axes; |
@@ -1,6 +0,7 @@ | ||
export { ChartCanvas } from "./ChartCanvas"; | ||
export { ChartCanvas, ChartCanvasContext } from "./ChartCanvas"; | ||
export * from "./Chart"; | ||
export * from "./GenericChartComponent"; | ||
export * from "./GenericComponent"; | ||
export * from "./MoreProps"; | ||
export * from "./utils"; | ||
export * from "./zoom"; |
@@ -1,7 +0,8 @@ | ||
export { ChartCanvas } from "./ChartCanvas"; | ||
export { ChartCanvas, ChartCanvasContext } from "./ChartCanvas"; | ||
export * from "./Chart"; | ||
export * from "./GenericChartComponent"; | ||
export * from "./GenericComponent"; | ||
export * from "./MoreProps"; | ||
export * from "./utils"; | ||
export * from "./zoom"; | ||
//# sourceMappingURL=index.js.map |
import { ScaleContinuousNumeric, ScaleTime } from "d3-scale"; | ||
export interface ChartConfig { | ||
id: number | string; | ||
readonly origin: number[]; | ||
readonly padding: number | { | ||
top: number; | ||
bottom: number; | ||
}; | ||
readonly originalYExtentsProp?: number[] | ((data: any) => number) | ((data: any) => number[]); | ||
readonly yExtents?: number[] | ((data: any) => number) | ((data: any) => number[]); | ||
readonly yExtentsCalculator?: (options: { | ||
plotData: any[]; | ||
xDomain: any; | ||
xAccessor: any; | ||
displayXAccessor: any; | ||
fullData: any[]; | ||
}) => number[]; | ||
readonly flipYScale?: boolean; | ||
readonly yScale: ScaleContinuousNumeric<number, number>; | ||
readonly yPan: boolean; | ||
readonly yPanEnabled: boolean; | ||
readonly realYDomain?: number[]; | ||
readonly width: number; | ||
readonly height: number; | ||
mouseCoordinates?: { | ||
at: string; | ||
format: () => unknown; | ||
}; | ||
} | ||
export declare const ChartDefaultConfig: { | ||
flipYScale: boolean; | ||
id: number; | ||
origin: number[]; | ||
padding: number; | ||
yPan: boolean; | ||
yPanEnabled: boolean; | ||
yScale: import("d3-scale").ScaleLinear<number, number, never>; | ||
}; | ||
export declare function getChartOrigin(origin: any, contextWidth: number, contextHeight: number): any; | ||
@@ -8,6 +45,6 @@ export declare function getDimensions({ width, height }: any, chartProps: any): { | ||
}; | ||
export declare function getNewChartConfig(innerDimension: any, children: any, existingChartConfig?: any[]): any; | ||
export declare function getCurrentCharts(chartConfig: any, mouseXY: number[]): any; | ||
export declare function getChartConfigWithUpdatedYScales(chartConfig: any, { plotData, xAccessor, displayXAccessor, fullData }: any, xDomain: any, dy?: number, chartsToPan?: string[]): any[]; | ||
export declare function getNewChartConfig(innerDimension: any, children: any, existingChartConfig?: ChartConfig[]): any; | ||
export declare function getCurrentCharts(chartConfig: ChartConfig[], mouseXY: number[]): any[]; | ||
export declare function getChartConfigWithUpdatedYScales(chartConfig: ChartConfig[], { plotData, xAccessor, displayXAccessor, fullData }: any, xDomain: any, dy?: number, chartsToPan?: (string | number)[]): ChartConfig[]; | ||
export declare function getCurrentItem(xScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, xAccessor: any, mouseXY: number[], plotData: any[]): any; | ||
export declare function getXValue(xScale: ScaleContinuousNumeric<number, number> | ScaleTime<number, number>, xAccessor: any, mouseXY: number[], plotData: any[]): any; |
import { extent } from "d3-array"; | ||
import { scaleLinear } from "d3-scale"; | ||
import flattenDeep from "lodash.flattendeep"; | ||
import * as React from "react"; | ||
import { Chart } from "../Chart"; | ||
import { functor, getClosestItem, isDefined, isNotDefined, isObject, last, mapObject, shallowEqual, zipper, } from "./index"; | ||
import { functor, getClosestItem, isNotDefined, isObject, last, mapObject, shallowEqual, zipper } from "./index"; | ||
export const ChartDefaultConfig = { | ||
flipYScale: false, | ||
id: 0, | ||
origin: [0, 0], | ||
padding: 0, | ||
yPan: true, | ||
yPanEnabled: false, | ||
yScale: scaleLinear(), | ||
}; | ||
export function getChartOrigin(origin, contextWidth, contextHeight) { | ||
@@ -46,52 +55,52 @@ const originCoordinates = typeof origin === "function" ? origin(contextWidth, contextHeight) : origin; | ||
return React.Children.map(children, (each) => { | ||
if (each !== undefined && each !== null && isChartProps(each.props)) { | ||
const chartProps = Object.assign(Object.assign({}, Chart.defaultProps), each.props); | ||
const { id, origin, padding, yExtents: yExtentsProp, yScale: yScaleProp, flipYScale, yExtentsCalculator, } = chartProps; | ||
const yScale = yScaleProp.copy(); | ||
const { width, height, availableHeight } = getDimensions(innerDimension, chartProps); | ||
const { yPan } = chartProps; | ||
let { yPanEnabled } = chartProps; | ||
const yExtents = isDefined(yExtentsProp) | ||
? (Array.isArray(yExtentsProp) ? yExtentsProp : [yExtentsProp]).map(functor) | ||
: undefined; | ||
const prevChartConfig = existingChartConfig.find((d) => d.id === id); | ||
if (isArraySize2AndNumber(yExtentsProp)) { | ||
if (isDefined(prevChartConfig) && | ||
prevChartConfig.yPan && | ||
prevChartConfig.yPanEnabled && | ||
yPan && | ||
yPanEnabled && | ||
shallowEqual(prevChartConfig.originalYExtentsProp, yExtentsProp)) { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
} | ||
else { | ||
const [a, b] = yExtentsProp; | ||
yScale.domain([a, b]); | ||
} | ||
if (!each || !isChartProps(each.props)) { | ||
return undefined; | ||
} | ||
const chartProps = Object.assign(Object.assign({}, ChartDefaultConfig), each.props); | ||
const { id, origin, padding, yExtents: yExtentsProp, yScale: yScaleProp = ChartDefaultConfig.yScale, flipYScale, yExtentsCalculator, } = chartProps; | ||
const yScale = yScaleProp.copy(); | ||
const { width, height, availableHeight } = getDimensions(innerDimension, chartProps); | ||
const { yPan } = chartProps; | ||
let { yPanEnabled } = chartProps; | ||
const yExtents = yExtentsProp | ||
? (Array.isArray(yExtentsProp) ? yExtentsProp : [yExtentsProp]).map(functor) | ||
: undefined; | ||
const prevChartConfig = existingChartConfig.find((d) => d.id === id); | ||
if (isArraySize2AndNumber(yExtentsProp)) { | ||
if (!!prevChartConfig && | ||
prevChartConfig.yPan && | ||
prevChartConfig.yPanEnabled && | ||
yPan && | ||
yPanEnabled && | ||
shallowEqual(prevChartConfig.originalYExtentsProp, yExtentsProp)) { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
} | ||
else if (isDefined(prevChartConfig) && prevChartConfig.yPanEnabled) { | ||
if (isArraySize2AndNumber(prevChartConfig.originalYExtentsProp)) { | ||
// do nothing | ||
} | ||
else { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
yPanEnabled = true; | ||
} | ||
else { | ||
const [a, b] = yExtentsProp; | ||
yScale.domain([a, b]); | ||
} | ||
return { | ||
id, | ||
origin: functor(origin)(width, availableHeight), | ||
padding, | ||
originalYExtentsProp: yExtentsProp, | ||
yExtents, | ||
yExtentsCalculator, | ||
flipYScale, | ||
yScale, | ||
yPan, | ||
yPanEnabled, | ||
width, | ||
height, | ||
}; | ||
} | ||
return undefined; | ||
else if (!!prevChartConfig && prevChartConfig.yPanEnabled) { | ||
if (isArraySize2AndNumber(prevChartConfig.originalYExtentsProp)) { | ||
// do nothing | ||
} | ||
else { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
yPanEnabled = true; | ||
} | ||
} | ||
return { | ||
id, | ||
origin: functor(origin)(width, availableHeight), | ||
padding, | ||
originalYExtentsProp: yExtentsProp, | ||
yExtents, | ||
yExtentsCalculator, | ||
flipYScale, | ||
yScale, | ||
yPan, | ||
yPanEnabled, | ||
width, | ||
height, | ||
}; | ||
}).filter((each) => each !== undefined); | ||
@@ -135,3 +144,3 @@ } | ||
const yDomains = chartConfig.map(({ yExtentsCalculator, yExtents, yScale }) => { | ||
const realYDomain = isDefined(yExtentsCalculator) | ||
const realYDomain = yExtentsCalculator | ||
? yExtentsCalculator({ plotData, xDomain, xAccessor, displayXAccessor, fullData }) | ||
@@ -138,0 +147,0 @@ : yDomainFromYExtents(yExtents, yScale, plotData); |
@@ -1,2 +0,2 @@ | ||
/// <reference types="react" /> | ||
import React from "react"; | ||
export { default as zipper } from "./zipper"; | ||
@@ -32,3 +32,3 @@ export { default as slidingWindow } from "./slidingWindow"; | ||
export declare function last(array: any[], accessor?: any): any; | ||
export declare const isDefined: <T>(d: T) => boolean; | ||
export declare const isDefined: <T>(d: T) => d is NonNullable<T>; | ||
export declare function isNotDefined<T>(d: T): boolean; | ||
@@ -35,0 +35,0 @@ export declare function isObject(d: any): boolean; |
@@ -1,3 +0,3 @@ | ||
export declare type strokeDashTypes = "Solid" | "ShortDash" | "ShortDash2" | "ShortDot" | "ShortDashDot" | "ShortDashDotDot" | "Dot" | "Dash" | "LongDash" | "DashDot" | "LongDashDot" | "LongDashDotDot"; | ||
export declare const getStrokeDasharrayCanvas: (type?: strokeDashTypes | undefined) => number[]; | ||
export declare const getStrokeDasharray: (type?: strokeDashTypes | undefined) => "none" | "6, 2" | "6, 3" | "2, 2" | "6, 2, 2, 2" | "6, 2, 2, 2, 2, 2" | "2, 6" | "4, 6" | "16, 6" | "8, 6, 2, 6" | "16, 6, 2, 6" | "16, 6, 2, 6, 2, 6"; | ||
export type strokeDashTypes = "Solid" | "ShortDash" | "ShortDash2" | "ShortDot" | "ShortDashDot" | "ShortDashDotDot" | "Dot" | "Dash" | "LongDash" | "DashDot" | "LongDashDot" | "LongDashDotDot"; | ||
export declare const getStrokeDasharrayCanvas: (type?: strokeDashTypes) => number[]; | ||
export declare const getStrokeDasharray: (type?: strokeDashTypes) => "none" | "6, 2" | "6, 3" | "2, 2" | "6, 2, 2, 2" | "6, 2, 2, 2, 2, 2" | "2, 6" | "4, 6" | "16, 6" | "8, 6, 2, 6" | "16, 6, 2, 6" | "16, 6, 2, 6, 2, 6"; |
103
package.json
{ | ||
"name": "@react-financial-charts/core", | ||
"version": "1.3.1", | ||
"description": "Core code for react-financial-charts", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"type": "module", | ||
"main": "./lib/index.js", | ||
"typings": "./lib/index.d.ts", | ||
"files": [ | ||
"lib", | ||
"src" | ||
], | ||
"sideEffects": false, | ||
"author": "Reactive Markets", | ||
"keywords": [ | ||
"charts", | ||
"charting", | ||
"stockcharts", | ||
"finance", | ||
"financial", | ||
"finance-chart", | ||
"react", | ||
"d3" | ||
], | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/reactivemarkets/react-financial-charts.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/reactivemarkets/react-financial-charts/issues" | ||
}, | ||
"scripts": { | ||
"build": "npm run clean && npm run compile", | ||
"clean": "rimraf lib coverage", | ||
"compile": "tsc -p tsconfig.json", | ||
"test": "jest", | ||
"watch": "tsc -p tsconfig.json --watch --preserveWatchOutput" | ||
}, | ||
"dependencies": { | ||
"@types/d3-scale": "^3.2.2", | ||
"d3-array": "^2.9.1", | ||
"d3-scale": "^3.2.3", | ||
"d3-selection": "^2.0.0", | ||
"lodash.flattendeep": "^4.4.0", | ||
"prop-types": "^15.7.2" | ||
}, | ||
"peerDependencies": { | ||
"react": "^16.0.0 || ^17.0.0", | ||
"react-dom": "^16.0.0 || ^17.0.0" | ||
}, | ||
"gitHead": "403d8b776af90cbd787af7683a8d1537108b1b25" | ||
"name": "@react-financial-charts/core", | ||
"version": "2.0.0", | ||
"description": "Core code for react-financial-charts", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"main": "./lib/index.js", | ||
"typings": "./lib/index.d.ts", | ||
"files": [ | ||
"lib", | ||
"src" | ||
], | ||
"sideEffects": false, | ||
"author": "Reactive Markets", | ||
"keywords": [ | ||
"charts", | ||
"charting", | ||
"stockcharts", | ||
"finance", | ||
"financial", | ||
"finance-chart", | ||
"react", | ||
"d3" | ||
], | ||
"license": "MIT", | ||
"repository": { | ||
"type": "git", | ||
"url": "https://github.com/reactivemarkets/react-financial-charts.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/reactivemarkets/react-financial-charts/issues" | ||
}, | ||
"scripts": { | ||
"build": "npm run clean && npm run compile", | ||
"clean": "rimraf lib coverage", | ||
"compile": "tsc -p tsconfig.json", | ||
"watch": "tsc -p tsconfig.json --watch --preserveWatchOutput" | ||
}, | ||
"dependencies": { | ||
"@types/d3-scale": "^3.2.2", | ||
"d3-array": "^2.9.1", | ||
"d3-scale": "^3.2.3", | ||
"d3-selection": "^2.0.0", | ||
"lodash.flattendeep": "^4.4.0" | ||
}, | ||
"peerDependencies": { | ||
"react": "^16.0.0 || ^17.0.0 || ^18.0.0", | ||
"react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" | ||
}, | ||
"gitHead": "281943c4c71e8fb9e48caff017bcf0e431854bb2" | ||
} |
# Axes | ||
```bash | ||
npm i @react-finanical-charts/axes | ||
npm i @react-financial-charts/axes | ||
``` |
@@ -1,6 +0,7 @@ | ||
export { ChartCanvas } from "./ChartCanvas"; | ||
export { ChartCanvas, ChartCanvasContext } from "./ChartCanvas"; | ||
export * from "./Chart"; | ||
export * from "./GenericChartComponent"; | ||
export * from "./GenericComponent"; | ||
export * from "./MoreProps"; | ||
export * from "./utils"; | ||
export * from "./zoom"; |
import { extent } from "d3-array"; | ||
import { ScaleContinuousNumeric, ScaleTime } from "d3-scale"; | ||
import { ScaleContinuousNumeric, scaleLinear, ScaleTime } from "d3-scale"; | ||
import flattenDeep from "lodash.flattendeep"; | ||
import * as React from "react"; | ||
import type { ChartProps } from "../Chart"; | ||
import { Chart, ChartProps } from "../Chart"; | ||
import { functor, getClosestItem, isNotDefined, isObject, last, mapObject, shallowEqual, zipper } from "./index"; | ||
import { | ||
functor, | ||
getClosestItem, | ||
isDefined, | ||
isNotDefined, | ||
isObject, | ||
last, | ||
mapObject, | ||
shallowEqual, | ||
zipper, | ||
} from "./index"; | ||
export interface ChartConfig { | ||
id: number | string; | ||
// readonly origin: number[] | ((width: number, height: number) => number[]); | ||
readonly origin: number[]; | ||
readonly padding: number | { top: number; bottom: number }; | ||
readonly originalYExtentsProp?: number[] | ((data: any) => number) | ((data: any) => number[]); | ||
readonly yExtents?: number[] | ((data: any) => number) | ((data: any) => number[]); | ||
readonly yExtentsCalculator?: (options: { | ||
plotData: any[]; | ||
xDomain: any; | ||
xAccessor: any; | ||
displayXAccessor: any; | ||
fullData: any[]; | ||
}) => number[]; | ||
readonly flipYScale?: boolean; | ||
readonly yScale: ScaleContinuousNumeric<number, number>; | ||
readonly yPan: boolean; | ||
readonly yPanEnabled: boolean; | ||
readonly realYDomain?: number[]; | ||
readonly width: number; | ||
readonly height: number; | ||
mouseCoordinates?: { at: string; format: () => unknown }; | ||
} | ||
export const ChartDefaultConfig = { | ||
flipYScale: false, | ||
id: 0, | ||
origin: [0, 0], | ||
padding: 0, | ||
yPan: true, | ||
yPanEnabled: false, | ||
yScale: scaleLinear(), | ||
}; | ||
export function getChartOrigin(origin: any, contextWidth: number, contextHeight: number) { | ||
@@ -46,3 +69,3 @@ const originCoordinates = typeof origin === "function" ? origin(contextWidth, contextHeight) : origin; | ||
function isArraySize2AndNumber(yExtentsProp: any) { | ||
function isArraySize2AndNumber(yExtentsProp: any): yExtentsProp is [number, number] { | ||
if (Array.isArray(yExtentsProp) && yExtentsProp.length === 2) { | ||
@@ -69,77 +92,76 @@ const [a, b] = yExtentsProp; | ||
export function getNewChartConfig(innerDimension: any, children: any, existingChartConfig: any[] = []) { | ||
return React.Children.map(children, (each) => { | ||
if (each !== undefined && each !== null && isChartProps(each.props)) { | ||
const chartProps = { | ||
...Chart.defaultProps, | ||
...each.props, | ||
}; | ||
export function getNewChartConfig(innerDimension: any, children: any, existingChartConfig: ChartConfig[] = []) { | ||
return React.Children.map(children, (each): ChartConfig | undefined => { | ||
if (!each || !isChartProps(each.props)) { | ||
return undefined; | ||
} | ||
const chartProps = { | ||
...ChartDefaultConfig, | ||
...(each.props as ChartProps), | ||
}; | ||
const { | ||
id, | ||
origin, | ||
padding, | ||
yExtents: yExtentsProp, | ||
yScale: yScaleProp, | ||
flipYScale, | ||
yExtentsCalculator, | ||
} = chartProps; | ||
const { | ||
id, | ||
origin, | ||
padding, | ||
yExtents: yExtentsProp, | ||
yScale: yScaleProp = ChartDefaultConfig.yScale, | ||
flipYScale, | ||
yExtentsCalculator, | ||
} = chartProps; | ||
const yScale = yScaleProp.copy(); | ||
const { width, height, availableHeight } = getDimensions(innerDimension, chartProps); | ||
const yScale = yScaleProp.copy(); | ||
const { width, height, availableHeight } = getDimensions(innerDimension, chartProps); | ||
const { yPan } = chartProps; | ||
let { yPanEnabled } = chartProps; | ||
const yExtents = isDefined(yExtentsProp) | ||
? (Array.isArray(yExtentsProp) ? yExtentsProp : [yExtentsProp]).map(functor) | ||
: undefined; | ||
const { yPan } = chartProps; | ||
let { yPanEnabled } = chartProps; | ||
const yExtents = yExtentsProp | ||
? (Array.isArray(yExtentsProp) ? yExtentsProp : [yExtentsProp]).map(functor) | ||
: undefined; | ||
const prevChartConfig = existingChartConfig.find((d) => d.id === id); | ||
const prevChartConfig = existingChartConfig.find((d) => d.id === id); | ||
if (isArraySize2AndNumber(yExtentsProp)) { | ||
if ( | ||
isDefined(prevChartConfig) && | ||
prevChartConfig.yPan && | ||
prevChartConfig.yPanEnabled && | ||
yPan && | ||
yPanEnabled && | ||
shallowEqual(prevChartConfig.originalYExtentsProp, yExtentsProp) | ||
) { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
} else { | ||
const [a, b] = yExtentsProp; | ||
yScale.domain([a, b]); | ||
} | ||
} else if (isDefined(prevChartConfig) && prevChartConfig.yPanEnabled) { | ||
if (isArraySize2AndNumber(prevChartConfig.originalYExtentsProp)) { | ||
// do nothing | ||
} else { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
yPanEnabled = true; | ||
} | ||
if (isArraySize2AndNumber(yExtentsProp)) { | ||
if ( | ||
!!prevChartConfig && | ||
prevChartConfig.yPan && | ||
prevChartConfig.yPanEnabled && | ||
yPan && | ||
yPanEnabled && | ||
shallowEqual(prevChartConfig.originalYExtentsProp, yExtentsProp) | ||
) { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
} else { | ||
const [a, b] = yExtentsProp; | ||
yScale.domain([a, b]); | ||
} | ||
return { | ||
id, | ||
origin: functor(origin)(width, availableHeight), | ||
padding, | ||
originalYExtentsProp: yExtentsProp, | ||
yExtents, | ||
yExtentsCalculator, | ||
flipYScale, | ||
yScale, | ||
yPan, | ||
yPanEnabled, | ||
width, | ||
height, | ||
}; | ||
} else if (!!prevChartConfig && prevChartConfig.yPanEnabled) { | ||
if (isArraySize2AndNumber(prevChartConfig.originalYExtentsProp)) { | ||
// do nothing | ||
} else { | ||
yScale.domain(prevChartConfig.yScale.domain()); | ||
yPanEnabled = true; | ||
} | ||
} | ||
return undefined; | ||
return { | ||
id, | ||
origin: functor(origin)(width, availableHeight), | ||
padding, | ||
originalYExtentsProp: yExtentsProp, | ||
yExtents, | ||
yExtentsCalculator, | ||
flipYScale, | ||
yScale, | ||
yPan, | ||
yPanEnabled, | ||
width, | ||
height, | ||
}; | ||
}).filter((each: any) => each !== undefined); | ||
} | ||
export function getCurrentCharts(chartConfig: any, mouseXY: number[]) { | ||
export function getCurrentCharts(chartConfig: ChartConfig[], mouseXY: number[]) { | ||
const currentCharts = chartConfig | ||
.filter((eachConfig: any) => { | ||
.filter((eachConfig) => { | ||
const top = eachConfig.origin[1]; | ||
@@ -178,3 +200,3 @@ const bottom = top + eachConfig.height; | ||
const realYDomain = yScale.invert ? extent(allYValues) : [...new Set(allYValues).values()]; | ||
const realYDomain = yScale.invert ? (extent(allYValues) as [number, number]) : [...new Set(allYValues).values()]; | ||
@@ -185,10 +207,10 @@ return realYDomain; | ||
export function getChartConfigWithUpdatedYScales( | ||
chartConfig: any, | ||
chartConfig: ChartConfig[], | ||
{ plotData, xAccessor, displayXAccessor, fullData }: any, | ||
xDomain: any, | ||
dy?: number, | ||
chartsToPan?: string[], | ||
) { | ||
const yDomains = chartConfig.map(({ yExtentsCalculator, yExtents, yScale }: any) => { | ||
const realYDomain = isDefined(yExtentsCalculator) | ||
chartsToPan?: (string | number)[], | ||
): ChartConfig[] { | ||
const yDomains = chartConfig.map(({ yExtentsCalculator, yExtents, yScale }) => { | ||
const realYDomain = yExtentsCalculator | ||
? yExtentsCalculator({ plotData, xDomain, xAccessor, displayXAccessor, fullData }) | ||
@@ -211,18 +233,20 @@ : yDomainFromYExtents(yExtents, yScale, plotData); | ||
const combine = zipper().combine((config: any, { realYDomain, yDomainDY, prevYDomain }: any) => { | ||
const { id, padding, height, yScale, yPan, flipYScale, yPanEnabled = false } = config; | ||
const combine = zipper().combine( | ||
(config: ChartConfig, { realYDomain, yDomainDY, prevYDomain }: (typeof yDomains)[number]): ChartConfig => { | ||
const { id, padding, height, yScale, yPan, flipYScale, yPanEnabled = false } = config; | ||
const another = chartsToPan !== undefined ? chartsToPan.indexOf(id) > -1 : true; | ||
const domain = yPan && yPanEnabled ? (another ? yDomainDY : prevYDomain) : realYDomain; | ||
const another = chartsToPan !== undefined ? chartsToPan.indexOf(id) > -1 : true; | ||
const domain = yPan && yPanEnabled ? (another ? yDomainDY : prevYDomain) : realYDomain; | ||
const newYScale = setRange(yScale.copy().domain(domain), height, padding, flipYScale); | ||
const newYScale = setRange(yScale.copy().domain(domain), height, padding, flipYScale); | ||
return { | ||
...config, | ||
yScale: newYScale, | ||
realYDomain, | ||
}; | ||
}); | ||
return { | ||
...config, | ||
yScale: newYScale, | ||
realYDomain, | ||
}; | ||
}, | ||
); | ||
const updatedChartConfig = combine(chartConfig, yDomains); | ||
const updatedChartConfig = combine(chartConfig, yDomains) as ChartConfig[]; | ||
@@ -229,0 +253,0 @@ return updatedChartConfig; |
@@ -0,1 +1,2 @@ | ||
import React from "react"; | ||
export { default as zipper } from "./zipper"; | ||
@@ -103,3 +104,3 @@ export { default as slidingWindow } from "./slidingWindow"; | ||
export const isDefined = <T>(d: T) => { | ||
export const isDefined = <T>(d: T): d is NonNullable<T> => { | ||
return d !== null && d !== undefined; | ||
@@ -106,0 +107,0 @@ }; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
7
100
372263
6760
No
+ Addedreact@18.3.1(transitive)
+ Addedreact-dom@18.3.1(transitive)
+ Addedscheduler@0.23.2(transitive)
- Removedprop-types@^15.7.2
- Removedobject-assign@4.1.1(transitive)
- Removedprop-types@15.8.1(transitive)
- Removedreact@17.0.2(transitive)
- Removedreact-dom@17.0.2(transitive)
- Removedreact-is@16.13.1(transitive)
- Removedscheduler@0.20.2(transitive)