Skip to content

Commit

Permalink
Merge pull request #1558 from FormidableLabs/task/add-chart-backgroun…
Browse files Browse the repository at this point in the history
…d-primitive

VictoryChart: adds an option for adding background for chart area
  • Loading branch information
boygirl authored May 11, 2020
2 parents 8c08a31 + ee88dbd commit c439d67
Show file tree
Hide file tree
Showing 12 changed files with 241 additions and 38 deletions.
17 changes: 14 additions & 3 deletions demo/js/components/victory-chart-demo.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,19 +180,30 @@ class App extends React.Component {
alignItems: "center",
justifyContent: "center"
};
const chartStyle = { parent: { border: "1px solid #ccc", margin: "2%", maxWidth: "40%" } };
const chartStyle = {
parent: { border: "1px solid #ccc", margin: "2%", maxWidth: "40%" }
};
const axisStyle = {
grid: { stroke: "grey", strokeWidth: 1 },
axis: { stroke: "transparent" },
ticks: { stroke: "transparent" },
tickLabels: { fill: "none" }
};

const bgStyle = {
background: { fill: "#e6e6ff" }
};

return (
<div className="demo">
<h1>VictoryChart</h1>
<div style={containerStyle}>
<VictoryChart style={chartStyle}>
<VictoryScatter data={[{ x: -3, y: -3 }]} />
<VictoryChart style={chartStyle} polar>
<VictoryScatter />
</VictoryChart>

<VictoryChart style={assign({}, chartStyle, bgStyle)}>
<VictoryScatter data={[{ x: -3, y: -3 }, { x: -2, y: 2 }, { x: 1, y: -1 }]} />
</VictoryChart>

<VictoryChart style={chartStyle} theme={dependentAxisTheme}>
Expand Down
21 changes: 17 additions & 4 deletions demo/ts/components/victory-chart-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,19 +208,32 @@ class VictoryChartDemo extends React.Component<any, VictoryChartDemoState> {
alignItems: "center",
justifyContent: "center"
};
const chartStyle = { parent: { border: "1px solid #ccc", margin: "2%", maxWidth: "40%" } };
const axisStyle = {

const chartStyle: { [key: string]: React.CSSProperties } = {
parent: { border: "1px solid #ccc", margin: "2%", maxWidth: "40%" }
};

const axisStyle: { [key: string]: React.CSSProperties } = {
grid: { stroke: "grey", strokeWidth: 1 },
axis: { stroke: "transparent" },
ticks: { stroke: "transparent" },
tickLabels: { fill: "none" }
};

const bgStyle: { [key: string]: React.CSSProperties } = {
background: { fill: "#e6e6ff" }
};

return (
<div className="demo">
<h1>VictoryChart</h1>
<div style={containerStyle}>
<VictoryChart style={chartStyle}>
<VictoryScatter data={[{ x: -3, y: -3 }]} />
<VictoryChart style={chartStyle} polar>
<VictoryScatter />
</VictoryChart>

<VictoryChart style={assign({}, chartStyle, bgStyle)}>
<VictoryScatter data={[{ x: -3, y: -3 }, { x: -2, y: 2 }, { x: 1, y: -1 }]} />
</VictoryChart>

<VictoryChart style={chartStyle} theme={dependentAxisTheme}>
Expand Down
4 changes: 2 additions & 2 deletions demo/ts/components/victory-polar-axis-demo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { VictoryScatter } from "@packages/victory-scatter";
import { VictoryZoomContainer } from "@packages/victory-zoom-container";
import { VictoryVoronoiContainer } from "@packages/victory-voronoi-container";
import { random, range, keys } from "lodash";
import { VictoryTheme, VictoryLabel, VictoryStyleInterface } from "@packages/victory-core";
import { VictoryTheme, VictoryLabel } from "@packages/victory-core";

type multiAxisDataListType = {
strength?: number;
Expand Down Expand Up @@ -115,7 +115,7 @@ class App extends React.Component<any, VictoryPolarAxisState> {
justifyContent: "center"
};

const chartStyle: VictoryStyleInterface = {
const chartStyle: { [key: string]: React.CSSProperties } = {
parent: { border: "1px solid #ccc", margin: "2%", maxWidth: "40%" }
};

Expand Down
65 changes: 52 additions & 13 deletions packages/victory-chart/src/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,40 @@ function getAxisProps(child, props, calculatedProps) {
};
}

function getBackgroundWithProps(props, calculatedProps) {
const backgroundElement = props.backgroundComponent;

const height = props.polar
? calculatedProps.range.y[1]
: calculatedProps.range.y[0] - calculatedProps.range.y[1];
const width = calculatedProps.range.x[1] - calculatedProps.range.x[0];

const xScale = props.horizontal
? calculatedProps.scale.y.range()[0]
: calculatedProps.scale.x.range()[0];
const yScale = props.horizontal
? calculatedProps.scale.x.range()[1]
: calculatedProps.scale.y.range()[1];

const xCoordinate = props.polar ? calculatedProps.origin.x : xScale;
const yCoordinate = props.polar ? calculatedProps.origin.y : yScale;

const backgroundProps = {
height,
polar: props.polar,
scale: calculatedProps.scale,
style: props.style.background,
x: xCoordinate,
y: yCoordinate,
width
};

return React.cloneElement(
backgroundElement,
defaults({}, backgroundElement.props, backgroundProps)
);
}

function getChildProps(child, props, calculatedProps) {
const axisChild = Axis.findAxisComponents([child]);
if (axisChild.length > 0) {
Expand All @@ -47,6 +81,7 @@ function getChildProps(child, props, calculatedProps) {

function getStyles(props) {
const styleProps = props.style && props.style.parent;

return {
parent: defaults({}, styleProps, {
height: "100%",
Expand Down Expand Up @@ -129,6 +164,7 @@ function getChildren(props, childComponents, calculatedProps) {
const { height, polar, theme, width } = props;
const { origin, horizontal } = calculatedProps;
const parentName = props.name || "chart";

return childComponents.map((child, index) => {
const role = child.type && child.type.role;
const style = Array.isArray(child.props.style)
Expand Down Expand Up @@ -158,21 +194,24 @@ function getChildren(props, childComponents, calculatedProps) {

const getChildComponents = (props, defaultAxes) => {
const childComponents = React.Children.toArray(props.children);
if (childComponents.length === 0) {
return [defaultAxes.independent, defaultAxes.dependent];
}
let newChildComponents = [...childComponents];

const axisComponents = {
dependent: Axis.getAxisComponentsWithParent(childComponents, "dependent"),
independent: Axis.getAxisComponentsWithParent(childComponents, "independent")
};
if (childComponents.length === 0) {
newChildComponents.push(defaultAxes.independent, defaultAxes.dependent);
} else {
const axisComponents = {
dependent: Axis.getAxisComponentsWithParent(childComponents, "dependent"),
independent: Axis.getAxisComponentsWithParent(childComponents, "independent")
};

if (axisComponents.dependent.length === 0 && axisComponents.independent.length === 0) {
return props.prependDefaultAxes
? [defaultAxes.independent, defaultAxes.dependent].concat(childComponents)
: childComponents.concat([defaultAxes.independent, defaultAxes.dependent]);
if (axisComponents.dependent.length === 0 && axisComponents.independent.length === 0) {
newChildComponents = props.prependDefaultAxes
? [defaultAxes.independent, defaultAxes.dependent].concat(newChildComponents)
: newChildComponents.concat([defaultAxes.independent, defaultAxes.dependent]);
}
}
return childComponents;

return newChildComponents;
};

const getDomain = (props, axis, childComponents) => {
Expand Down Expand Up @@ -252,4 +291,4 @@ const createStringMap = (props, childComponents) => {
return { x, y };
};

export { getChildren, getCalculatedProps, getChildComponents };
export { getBackgroundWithProps, getChildren, getCalculatedProps, getChildComponents };
15 changes: 8 additions & 7 deletions packages/victory-chart/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
import * as React from "react";
import {
CategoryPropType,
EventPropTypeInterface,
DomainPropType,
EventPropTypeInterface,
StringOrNumberOrCallback,
VictoryCommonProps,
VictoryStyleInterface
VictoryStyleInterface,
VictoryStyleObject
} from "victory-core";

export type AxesType = {
independent?: React.ReactElement;
dependent?: React.ReactElement;
independent?: React.ReactElement;
};

export interface VictoryChartProps extends VictoryCommonProps {
defaultAxes?: AxesType;
defaultPolarAxes?: AxesType;
categories?: CategoryPropType;
children?: React.ReactNode | React.ReactNode[];
defaultAxes?: AxesType;
defaultPolarAxes?: AxesType;
domain?: DomainPropType;
endAngle?: number;
events?: EventPropTypeInterface<string, string[] | number[] | string | number>[];
eventKey?: StringOrNumberOrCallback;
events?: EventPropTypeInterface<string, string[] | number[] | string | number>[];
innerRadius?: number;
prependDefaultAxes?: boolean;
startAngle?: number;
style?: Pick<VictoryStyleInterface, "parent">;
style?: Pick<VictoryStyleInterface, "parent"> & { background?: VictoryStyleObject };
}

export class VictoryChart extends React.Component<VictoryChartProps, any> {}
22 changes: 20 additions & 2 deletions packages/victory-chart/src/victory-chart.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { defaults, assign, isEmpty } from "lodash";
import PropTypes from "prop-types";
import React from "react";
import {
Background,
Helpers,
VictoryContainer,
VictoryTheme,
Expand All @@ -12,7 +13,12 @@ import {
import { VictorySharedEvents } from "victory-shared-events";
import { VictoryAxis } from "victory-axis";
import { VictoryPolarAxis } from "victory-polar-axis";
import { getChildComponents, getCalculatedProps, getChildren } from "./helper-methods";
import {
getBackgroundWithProps,
getChildComponents,
getCalculatedProps,
getChildren
} from "./helper-methods";
import isEqual from "react-fast-compare";

const fallbackProps = {
Expand All @@ -26,6 +32,7 @@ export default class VictoryChart extends React.Component {

static propTypes = {
...CommonProps.baseProps,
backgroundComponent: PropTypes.element,
children: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.node), PropTypes.node]),
defaultAxes: PropTypes.shape({
independent: PropTypes.element,
Expand All @@ -42,6 +49,7 @@ export default class VictoryChart extends React.Component {
};

static defaultProps = {
backgroundComponent: <Background />,
containerComponent: <VictoryContainer />,
defaultAxes: {
independent: <VictoryAxis />,
Expand Down Expand Up @@ -84,10 +92,19 @@ export default class VictoryChart extends React.Component {
getNewChildren(props, childComponents, calculatedProps) {
const children = getChildren(props, childComponents, calculatedProps);
const getAnimationProps = Wrapper.getAnimationProps.bind(this);
return children.map((child, index) => {

const newChildren = children.map((child, index) => {
const childProps = assign({ animate: getAnimationProps(props, child, index) }, child.props);
return React.cloneElement(child, childProps);
});

if (props.style && props.style.background) {
const backgroundComponent = getBackgroundWithProps(props, calculatedProps);

newChildren.unshift(backgroundComponent);
}

return newChildren;
}

renderContainer(containerComponent, props) {
Expand Down Expand Up @@ -134,6 +151,7 @@ export default class VictoryChart extends React.Component {
? this.renderContainer(containerComponent, containerProps)
: groupComponent;
const events = Wrapper.getAllEvents(props);

if (!isEmpty(events)) {
return (
<VictorySharedEvents
Expand Down
11 changes: 11 additions & 0 deletions packages/victory-core/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -660,6 +660,17 @@ export class VictoryPortal extends React.Component<VictoryPortalProps, any> {}

// #region Victory Primitives

export interface BackgroundProps extends VictoryCommonPrimitiveProps {
circleComponent?: React.ReactElement;
height?: number;
rectComponent?: React.ReactElement;
width?: number;
x?: number;
y?: number;
}

export class Background extends React.Component<BackgroundProps> {}

export interface VictoryPointProps extends VictoryCommonPrimitiveProps {
datum?: any;
getPath?: Function;
Expand Down
1 change: 1 addition & 0 deletions packages/victory-core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export { default as VictoryTheme } from "./victory-theme/victory-theme";
export { default as VictoryPortal } from "./victory-portal/victory-portal";
export { default as Portal } from "./victory-portal/portal";
export { default as Arc } from "./victory-primitives/arc";
export { default as Background } from "./victory-primitives/background";
export { default as Border, default as Box } from "./victory-primitives/border";
export { default as ClipPath } from "./victory-primitives/clip-path";
export { default as LineSegment } from "./victory-primitives/line-segment";
Expand Down
47 changes: 47 additions & 0 deletions packages/victory-core/src/victory-primitives/background.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from "react";
import PropTypes from "prop-types";
import CommonProps from "../victory-util/common-props";
import Rect from "./rect";
import Circle from "./circle";

const Background = (props) => {
return props.polar
? React.cloneElement(props.circleComponent, {
...props.events,
style: props.style,
role: props.role,
shapeRendering: props.shapeRendering,
cx: props.x,
cy: props.y,
r: props.height
})
: React.cloneElement(props.rectComponent, {
...props.events,
style: props.style,
role: props.role,
shapeRendering: props.shapeRendering,
x: props.x,
y: props.y,
width: props.width,
height: props.height
});
};

Background.propTypes = {
...CommonProps.primitiveProps,
circleComponent: PropTypes.element,
height: PropTypes.number,
rectComponent: PropTypes.element,
width: PropTypes.number,
x: PropTypes.number,
y: PropTypes.number
};

Background.defaultProps = {
circleComponent: <Circle />,
rectComponent: <Rect />,
role: "presentation",
shapeRendering: "auto"
};

export default Background;
2 changes: 2 additions & 0 deletions packages/victory/src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

declare module "victory" {
import {
Background,
// Border,
// Box,
// ClipPath,
Expand Down Expand Up @@ -115,6 +116,7 @@ declare module "victory" {

export {
// Area,
Background,
// Bar,
// Border,
// Box,
Expand Down
2 changes: 2 additions & 0 deletions packages/victory/src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {
Background,
Border,
Box,
ClipPath,
Expand Down Expand Up @@ -87,6 +88,7 @@ import { VictoryPolarAxis } from "victory-polar-axis";

export {
Area,
Background,
Bar,
Border,
Box,
Expand Down
Loading

0 comments on commit c439d67

Please sign in to comment.