Skip to content

Commit

Permalink
Merge pull request #1375 from FormidableLabs/experiment/evaluation-order
Browse files Browse the repository at this point in the history
ensure some props are evaluated before others for ease of functional …
  • Loading branch information
boygirl authored Aug 23, 2019
2 parents 7a556d7 + 626e8e9 commit 3082c43
Show file tree
Hide file tree
Showing 7 changed files with 193 additions and 138 deletions.
36 changes: 22 additions & 14 deletions packages/victory-bar/src/bar.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ const getPolarBarPath = (props, cornerRadius) => {
return getVerticalPolarBarPath(props, cornerRadius);
};

const getBarWidth = (props, style) => {
const { scale, data, barWidth, defaultBarWidth } = props;
const getBarWidth = (barWidth, props) => {
const { scale, data, defaultBarWidth, style } = props;
if (barWidth) {
return isFunction(barWidth) ? Helpers.evaluateProp(barWidth, props) : barWidth;
} else if (style.width) {
Expand All @@ -39,8 +39,7 @@ const getBarWidth = (props, style) => {
return Math.max(1, defaultWidth);
};

const getCornerRadiusFromObject = (props) => {
const { cornerRadius } = props;
const getCornerRadiusFromObject = (cornerRadius, props) => {
const realCornerRadius = { topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 0 };
const updateCornerRadius = (corner, fallback) => {
if (!isNil(cornerRadius[corner])) {
Expand All @@ -56,31 +55,40 @@ const getCornerRadiusFromObject = (props) => {
return realCornerRadius;
};

const getCornerRadius = (props) => {
const { cornerRadius } = props;
const getCornerRadius = (cornerRadius, props) => {
const realCornerRadius = { topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 0 };
if (!cornerRadius) {
return realCornerRadius;
}
if (isPlainObject(cornerRadius)) {
return getCornerRadiusFromObject(props);
return getCornerRadiusFromObject(cornerRadius, props);
} else {
realCornerRadius.topLeft = Helpers.evaluateProp(cornerRadius, props);
realCornerRadius.topRight = Helpers.evaluateProp(cornerRadius, props);
return realCornerRadius;
}
};

const Bar = (props) => {
const { origin, polar } = props;
const stroke = (props.style && props.style.fill) || "black";
const getStyle = (style = {}, props) => {
const stroke = style.fill || "black";
const baseStyle = { fill: "black", stroke };
const style = Helpers.evaluateStyle(assign(baseStyle, props.style), props);
const width = getBarWidth(props, style);
const cornerRadius = getCornerRadius(props);
return Helpers.evaluateStyle(assign(baseStyle, style), props);
};

const evaluateProps = (props) => {
// Potential evaluated props are 1) `style`, 2) `barWidth` and 3) `cornerRadius`
const style = getStyle(props.style, props);
const barWidth = getBarWidth(props.barWidth, assign({}, props, { style }));
const cornerRadius = getCornerRadius(props.cornerRadius, assign({}, props, { style, barWidth }));
return assign({}, props, { style, barWidth, cornerRadius });
};

const Bar = (props) => {
props = evaluateProps(props);
const { polar, origin, style, barWidth, cornerRadius } = props;
const path = polar
? getPolarBarPath(props, cornerRadius)
: getBarPath(props, width, cornerRadius);
: getBarPath(props, barWidth, cornerRadius);
const defaultTransform = polar && origin ? `translate(${origin.x}, ${origin.y})` : undefined;

return React.cloneElement(props.pathComponent, {
Expand Down
4 changes: 1 addition & 3 deletions packages/victory-bar/src/path-helper-methods.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { Helpers } from "victory-core";
import * as d3Shape from "d3-shape";

import { circle, point } from "./geometry-helper-methods";
Expand Down Expand Up @@ -224,8 +223,7 @@ export const getHorizontalBarPath = (props, width, cornerRadius) => {
};

export const getVerticalPolarBarPath = (props, cornerRadius) => {
const { datum, scale, index, alignment } = props;
const style = Helpers.evaluateStyle(props.style, props);
const { datum, scale, index, alignment, style } = props;
const r1 = scale.y(datum._y0 || 0);
const r2 = scale.y(datum._y1 !== undefined ? datum._y1 : datum._y);
const currentAngle = scale.x(datum._x1 !== undefined ? datum._x1 : datum._x);
Expand Down
19 changes: 13 additions & 6 deletions packages/victory-candlestick/src/candle.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import PropTypes from "prop-types";
import { Helpers, CommonProps, Line, Rect } from "victory-core";
import { assign, defaults, isFunction } from "lodash";

const getCandleWidth = (props, style) => {
const { candleWidth } = props;
const getCandleWidth = (candleWidth, props) => {
const { style } = props;
if (candleWidth) {
return isFunction(candleWidth) ? Helpers.evaluateProp(candleWidth, props) : candleWidth;
} else if (style.width) {
Expand All @@ -15,8 +15,7 @@ const getCandleWidth = (props, style) => {
};

const getCandleProps = (props, style) => {
const { id, x, close, open, horizontal } = props;
const candleWidth = getCandleWidth(props, style);
const { id, x, close, open, horizontal, candleWidth } = props;
const candleLength = Math.abs(close - open);
return {
key: `${id}-candle`,
Expand Down Expand Up @@ -52,7 +51,15 @@ const getLowWickProps = (props, style) => {
};
};

const evaluateProps = (props) => {
// Potential evaluated props are 1) `style`, 2) `candleWidth`
const style = Helpers.evaluateStyle(assign({ stroke: "black" }, props.style), props);
const candleWidth = getCandleWidth(props.candleWidth, assign({}, props, { style }));
return assign({}, props, { style, candleWidth });
};

const Candle = (props) => {
props = evaluateProps(props);
const {
events,
groupComponent,
Expand All @@ -63,9 +70,9 @@ const Candle = (props) => {
shapeRendering,
className,
wickStrokeWidth,
transform
transform,
style
} = props;
const style = Helpers.evaluateStyle(assign({ stroke: "black" }, props.style), props);
const wickStyle = defaults({ strokeWidth: wickStrokeWidth }, style);
const sharedProps = { role, shapeRendering, className, transform, clipPath, ...events };
const candleProps = assign(getCandleProps(props, style), sharedProps);
Expand Down
69 changes: 39 additions & 30 deletions packages/victory-core/src/victory-label/victory-label.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,30 +43,30 @@ const getFontSize = (style) => {
return defaultStyles.fontSize;
};

const getStyle = (props, style) => {
style = style ? defaults({}, style, defaultStyles) : defaultStyles;
const baseStyles = Helpers.evaluateStyle(style, props);
return assign({}, baseStyles, { fontSize: getFontSize(baseStyles) });
};

const getStyles = (props) => {
return Array.isArray(props.style) && !isEmpty(props.style)
? props.style.map((style) => getStyle(props, style))
: [getStyle(props, props.style)];
const getStyles = (style, props) => {
const getSingleStyle = (s) => {
s = s ? defaults({}, s, defaultStyles) : defaultStyles;
const baseStyles = Helpers.evaluateStyle(s, props);
return assign({}, baseStyles, { fontSize: getFontSize(baseStyles) });
};

return Array.isArray(style) && !isEmpty(style)
? style.map((s) => getSingleStyle(s))
: [getSingleStyle(style)];
};

const getHeight = (props, type) => {
return Helpers.evaluateProp(props[type], props);
};

const getContent = (props) => {
if (props.text === undefined || props.text === null) {
const getContent = (text, props) => {
if (text === undefined || text === null) {
return undefined;
}
if (Array.isArray(props.text)) {
return props.text.map((line) => Helpers.evaluateProp(line, props));
if (Array.isArray(text)) {
return text.map((line) => Helpers.evaluateProp(line, props));
}
const child = Helpers.evaluateProp(props.text, props);
const child = Helpers.evaluateProp(text, props);
if (child === undefined || child === null) {
return undefined;
}
Expand All @@ -80,13 +80,12 @@ const checkLineHeight = (lineHeight, val, fallbackVal) => {
return lineHeight;
};

//eslint-disable-next-line max-params
const getDy = (props, style, content, lineHeight) => {
style = Array.isArray(style) ? style[0] : style;
const getDy = (props, lineHeight) => {
const style = Array.isArray(props.style) ? props.style[0] : props.style;
lineHeight = checkLineHeight(lineHeight, lineHeight[0], 1);
const fontSize = style.fontSize;
const dy = props.dy ? Helpers.evaluateProp(props.dy, props) : 0;
const length = content.length;
const length = props.text.length;
const capHeight = getHeight(props, "capHeight");
const verticalAnchor = style.verticalAnchor || props.verticalAnchor;
const anchor = verticalAnchor ? Helpers.evaluateProp(verticalAnchor, props) : "middle";
Expand All @@ -100,8 +99,8 @@ const getDy = (props, style, content, lineHeight) => {
}
};

const getTransform = (props, style) => {
const { x, y, polar } = props;
const getTransform = (props) => {
const { x, y, polar, style } = props;
const defaultAngle = polar ? LabelHelpers.getPolarAngle(props) : 0;
const baseAngle = style.angle === undefined ? props.angle : style.angle;
const angle = baseAngle === undefined ? defaultAngle : baseAngle;
Expand All @@ -111,18 +110,17 @@ const getTransform = (props, style) => {
return transformPart || angle ? Style.toTransformString(transformPart, rotatePart) : undefined;
};

const renderElements = (props, content) => {
const { inline, className, title, desc, events, direction } = props;
const style = getStyles(props);
const renderElements = (props) => {
const { inline, className, title, desc, events, direction, text, style } = props;
const lineHeight = getHeight(props, "lineHeight");
const textAnchor = props.textAnchor ? Helpers.evaluateProp(props.textAnchor, props) : "start";
const dx = props.dx ? Helpers.evaluateProp(props.dx, props) : 0;
const dy = getDy(props, style, content, lineHeight);
const transform = getTransform(props, style);
const dy = getDy(props, lineHeight);
const transform = getTransform(props);
const x = props.x !== undefined ? props.x : getPosition(props, "x");
const y = props.y !== undefined ? props.y : getPosition(props, "y");

const textChildren = content.map((line, i) => {
const textChildren = text.map((line, i) => {
const currentStyle = style[i] || style[0];
const lastStyle = style[i - 1] || style[0];
const fontSize = (currentStyle.fontSize + lastStyle.fontSize) / 2;
Expand Down Expand Up @@ -161,12 +159,23 @@ const renderElements = (props, content) => {
);
};

const evaluateProps = (props) => {
/* Potential evaluated props are
1) text
2) style
3) everything else
*/
const text = getContent(props.text, props);
const style = getStyles(props.style, assign({}, props, { text }));
return assign({}, props, { style, text });
};

const VictoryLabel = (props) => {
const content = getContent(props);
if (content === null || content === undefined) {
props = evaluateProps(props);
if (props.text === null || props.text === undefined) {
return null;
}
const label = renderElements(props, content);
const label = renderElements(props);
return props.renderInPortal ? <VictoryPortal>{label}</VictoryPortal> : label;
};

Expand Down
22 changes: 9 additions & 13 deletions packages/victory-pie/src/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -136,22 +136,17 @@ const getVerticalAnchor = (orientation) => {

const getLabelProps = (text, dataProps, calculatedValues) => {
const { index, datum, data, slice } = dataProps;
const {
style,
defaultRadius,
origin,
width,
height,
labelRadius,
labelPosition
} = calculatedValues;
const evaluatedRadius = Helpers.evaluateProp(labelRadius, assign({ text }, dataProps));
const { style, defaultRadius, origin, width, height, labelPosition } = calculatedValues;
const labelRadius = Helpers.evaluateProp(
calculatedValues.labelRadius,
assign({ text }, dataProps)
);
const labelStyle = assign({ padding: 0 }, style.labels);
const evaluatedStyle = Helpers.evaluateStyle(
labelStyle,
assign({ evaluatedRadius, text }, dataProps)
assign({ labelRadius, text }, dataProps)
);
const labelArc = getLabelArc(defaultRadius, evaluatedRadius, evaluatedStyle);
const labelArc = getLabelArc(defaultRadius, labelRadius, evaluatedStyle);
const position = getLabelPosition(labelArc, slice, labelPosition);
const orientation = getLabelOrientation(slice);
return {
Expand Down Expand Up @@ -221,7 +216,8 @@ export const getBaseProps = (props, fallbackProps) => {
};
const text = getLabelText(props, datum, index);
if ((text !== undefined && text !== null) || (labels && (events || sharedEvents))) {
childProps[eventKey].labels = getLabelProps(text, dataProps, calculatedValues);
const evaluatedText = Helpers.evaluateProp(text, dataProps);
childProps[eventKey].labels = getLabelProps(evaluatedText, dataProps, calculatedValues);
}
return childProps;
}, initialChildProps);
Expand Down
22 changes: 17 additions & 5 deletions packages/victory-pie/src/slice.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import React from "react";
import PropTypes from "prop-types";
import { Helpers, CommonProps, Path } from "victory-core";
import { defaults, isFunction } from "lodash";
import { defaults, isFunction, assign } from "lodash";
import * as d3Shape from "d3-shape";

const getPath = (props) => {
const { slice } = props;
const { slice, radius, innerRadius } = props;
if (isFunction(props.pathFunction)) {
return props.pathFunction(slice);
}
const cornerRadius = Helpers.evaluateProp(props.cornerRadius, props);
const innerRadius = Helpers.evaluateProp(props.innerRadius, props);
const radius = Helpers.evaluateProp(props.radius, props);
const padAngle = Helpers.degreesToRadians(Helpers.evaluateProp(props.padAngle, props));
const startAngle = Helpers.degreesToRadians(Helpers.evaluateProp(props.sliceStartAngle, props));
const endAngle = Helpers.degreesToRadians(Helpers.evaluateProp(props.sliceEndAngle, props));
Expand All @@ -23,14 +21,28 @@ const getPath = (props) => {
return pathFunction(defaults({ startAngle, endAngle, padAngle }, slice));
};

const evaluateProps = (props) => {
/* Potential evaluated props are
1) style
2) radius
3) innerRadius
4) everything else
*/
const style = Helpers.evaluateStyle(props.style, props);
const radius = Helpers.evaluateProp(props.radius, assign({}, props, { style }));
const innerRadius = Helpers.evaluateProp(props.innerRadius, assign({}, props, { style, radius }));
return assign({}, props, { style, radius, innerRadius });
};

const Slice = (props) => {
props = evaluateProps(props);
const defaultTransform = props.origin
? `translate(${props.origin.x}, ${props.origin.y})`
: undefined;
return React.cloneElement(props.pathComponent, {
...props.events,
d: getPath(props),
style: Helpers.evaluateStyle(props.style, props),
style: props.style,
transform: props.transform || defaultTransform,
className: props.className,
role: props.role,
Expand Down
Loading

0 comments on commit 3082c43

Please sign in to comment.