import React from "react";
import {
Datum,
Rect,
VictoryContainer,
VictoryContainerProps,
VictoryEventHandler,
} from "victory-core";
import { SelectionHelpers } from "./selection-helpers";
export interface VictorySelectionContainerProps extends VictoryContainerProps {
activateSelectedData?: boolean;
allowSelection?: boolean;
disable?: boolean;
onSelection?: (
points: {
childName?: string | string[];
eventKey?: string | number;
data?: Datum[];
}[],
bounds: {
x: number | Date;
y: number | Date;
}[],
props: VictorySelectionContainerProps,
) => void;
horizontal?: boolean;
onSelectionCleared?: (props: VictorySelectionContainerProps) => void;
selectionBlacklist?: string[];
selectionComponent?: React.ReactElement;
selectionDimension?: "x" | "y";
selectionStyle?: React.CSSProperties;
}
export const VICTORY_SELECTION_CONTAINER_DEFAULT_PROPS = {
activateSelectedData: true,
allowSelection: true,
selectionComponent: ,
selectionStyle: {
stroke: "transparent",
fill: "black",
fillOpacity: 0.1,
},
};
interface VictorySelectionContainerMutatedProps
extends VictorySelectionContainerProps {
x1: number;
x2: number;
y1: number;
y2: number;
}
export const useVictorySelectionContainer = (
initialProps: VictorySelectionContainerProps,
) => {
const props = {
...VICTORY_SELECTION_CONTAINER_DEFAULT_PROPS,
...(initialProps as VictorySelectionContainerMutatedProps),
};
const { x1, x2, y1, y2, selectionStyle, selectionComponent, children, name } =
props;
const width = Math.abs(x2 - x1) || 1;
const height = Math.abs(y2 - y1) || 1;
const x = Math.min(x1, x2);
const y = Math.min(y1, y2);
const shouldRenderRect = y1 && y2 && x1 && x2;
return {
props,
children: [
children,
shouldRenderRect &&
React.cloneElement(selectionComponent, {
key: `${name}-selection`,
x,
y,
width,
height,
style: selectionStyle,
}),
] as React.ReactElement[],
};
};
export const VictorySelectionContainer = (
initialProps: VictorySelectionContainerProps,
) => {
const { props, children } = useVictorySelectionContainer(initialProps);
return {children};
};
VictorySelectionContainer.role = "container";
VictorySelectionContainer.defaultEvents = (
initialProps: VictorySelectionContainerProps,
) => {
const props = {
...VICTORY_SELECTION_CONTAINER_DEFAULT_PROPS,
...initialProps,
};
const createEventHandler =
(handler: VictoryEventHandler, disabled?: boolean): VictoryEventHandler =>
// eslint-disable-next-line max-params
(event, targetProps, eventKey, context) =>
disabled || props.disable
? {}
: handler(event, { ...props, ...targetProps }, eventKey, context);
return [
{
target: "parent",
eventHandlers: {
onMouseDown: createEventHandler(SelectionHelpers.onMouseDown),
onTouchStart: createEventHandler(SelectionHelpers.onMouseDown),
onMouseMove: createEventHandler(SelectionHelpers.onMouseMove),
onTouchMove: createEventHandler(SelectionHelpers.onMouseMove),
onMouseUp: createEventHandler(SelectionHelpers.onMouseUp),
onTouchEnd: createEventHandler(SelectionHelpers.onMouseUp),
},
},
];
};