Skip to content
This repository has been archived by the owner on Feb 19, 2022. It is now read-only.

Export helper methods as named exports #168

Merged
merged 7 commits into from
Feb 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
316 changes: 157 additions & 159 deletions src/components/helper-methods.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,168 +4,166 @@ import * as d3Shape from "d3-shape";

import { Helpers, Data, Style } from "victory-core";

export default {
degreesToRadians(degrees) {
return degrees * (Math.PI / 180);
},

checkForValidText(text) {
if (text === undefined || text === null) {
return text;
} else {
return `${text}`;
}
},

getSliceStyle(datum, index, calculatedValues) {
const { style, colors } = calculatedValues;
const fill = this.getColor(style, colors, index);
const dataStyles = omit(datum, ["_x", "_y", "x", "y", "label"]);
return defaults({}, dataStyles, { fill }, style.data);
},

getBaseProps(props, fallbackProps) {
props = Helpers.modifyProps(props, fallbackProps, "pie");
const calculatedValues = this.getCalculatedValues(props);
const { slices, style, pathFunction, data, origin } = calculatedValues;
const childProps = {
parent: {
standalone: props.standalone, slices, pathFunction,
width: props.width, height: props.height, style: style.parent
}
};
const degreesToRadians = (degrees) => {
return degrees * (Math.PI / 180);
};

for (let index = 0, len = slices.length; index < len; index++) {
const slice = slices[index];
const datum = data[index];
const eventKey = datum.eventKey || index;
const dataProps = {
index, slice, pathFunction, datum, data, origin,
style: this.getSliceStyle(datum, index, calculatedValues)
};

childProps[eventKey] = {
data: dataProps,
labels: this.getLabelProps(props, dataProps, calculatedValues)
};
}
return childProps;
},

getLabelProps(props, dataProps, calculatedValues) {
const { index, datum, data, slice } = dataProps;
const { style, radius, origin } = calculatedValues;
const labelStyle = Helpers.evaluateStyle(
assign({ padding: 0 }, style.labels), datum, props.active
);
const labelRadius = Helpers.evaluateProp(props.labelRadius, datum);
const labelPosition = this.getLabelPosition(radius, labelRadius, labelStyle);
const position = labelPosition.centroid(slice);
const orientation = this.getLabelOrientation(slice);
return {
index, datum, data, slice, orientation,
style: labelStyle,
x: Math.round(position[0]) + origin.x,
y: Math.round(position[1]) + origin.y,
text: this.getLabelText(props, datum, index),
textAnchor: labelStyle.textAnchor || this.getTextAnchor(orientation),
verticalAnchor: labelStyle.verticalAnchor || this.getVerticalAnchor(orientation),
angle: labelStyle.angle
};
},

getCalculatedValues(props) {
const { theme, colorScale, width, height } = props;
const styleObject = theme && theme.pie && theme.pie.style ? theme.pie.style : {};
const style = Helpers.getStyles(props.style, styleObject, "auto", "100%");
const colors = Array.isArray(colorScale) ? colorScale : Style.getColorScale(colorScale);
const padding = Helpers.getPadding(props);
const radius = this.getRadius(props, padding);
const offsetWidth = ((radius + padding.left) + (width - radius - padding.right)) / 2;
const offsetHeight = ((radius + padding.top) + (height - radius - padding.bottom)) / 2;
const origin = { x: offsetWidth, y: offsetHeight };
const data = Data.getData(props);
const slices = this.getSlices(props, data);
const pathFunction = d3Shape.arc()
.cornerRadius(props.cornerRadius)
.outerRadius(radius)
.innerRadius(props.innerRadius);
return { style, colors, padding, radius, data, slices, pathFunction, origin };
},

getColor(style, colors, index) {
if (style && style.data && style.data.fill) {
return style.data.fill;
}
return colors && colors[index % colors.length];
},

getRadius(props, padding) {
return Math.min(
props.width - padding.left - padding.right,
props.height - padding.top - padding.bottom
) / 2;
},

getLabelPosition(radius, labelRadius, style) {
const padding = style && style.padding || 0;
const arcRadius = labelRadius || radius + padding;
return d3Shape.arc()
.outerRadius(arcRadius)
.innerRadius(arcRadius);
},

getLabelOrientation(slice) {
const radiansToDegrees = (radians) => {
return radians * (180 / Math.PI);
};
const start = radiansToDegrees(slice.startAngle);
const end = radiansToDegrees(slice.endAngle);
const degree = start + (end - start) / 2;
if (degree < 45 || degree > 315) {
return "top";
} else if (degree >= 45 && degree < 135) {
return "right";
} else if (degree >= 135 && degree < 225) {
return "bottom";
} else {
return "left";
}
},
const checkForValidText = (text) => {
if (text === undefined || text === null) {
return text;
} else {
return `${text}`;
}
};

getTextAnchor(orientation) {
if (orientation === "top" || orientation === "bottom") {
return "middle";
}
return orientation === "right" ? "start" : "end";
},
const getColor = (style, colors, index) => {
if (style && style.data && style.data.fill) {
return style.data.fill;
}
return colors && colors[index % colors.length];
};

getVerticalAnchor(orientation) {
if (orientation === "left" || orientation === "right") {
return "middle";
}
return orientation === "bottom" ? "start" : "end";
},

getLabelText(props, datum, index) {
let text;
if (datum.label) {
text = datum.label;
} else if (Array.isArray(props.labels)) {
text = props.labels[index];
} else {
text = isFunction(props.labels) ? props.labels(datum) : datum.xName || datum._x;
const getRadius = (props, padding) => {
return Math.min(
props.width - padding.left - padding.right,
props.height - padding.top - padding.bottom
) / 2;
};

const getSlices = (props, data) => {
const layoutFunction = d3Shape.pie()
.sort(null)
.startAngle(degreesToRadians(props.startAngle))
.endAngle(degreesToRadians(props.endAngle))
.padAngle(degreesToRadians(props.padAngle))
.value((datum) => { return datum._y; });
return layoutFunction(data);
};

const getCalculatedValues = (props) => {
const { theme, colorScale, width, height } = props;
const styleObject = theme && theme.pie && theme.pie.style ? theme.pie.style : {};
const style = Helpers.getStyles(props.style, styleObject, "auto", "100%");
const colors = Array.isArray(colorScale) ? colorScale : Style.getColorScale(colorScale);
const padding = Helpers.getPadding(props);
const radius = getRadius(props, padding);
const offsetWidth = ((radius + padding.left) + (width - radius - padding.right)) / 2;
const offsetHeight = ((radius + padding.top) + (height - radius - padding.bottom)) / 2;
const origin = { x: offsetWidth, y: offsetHeight };
const data = Data.getData(props);
const slices = getSlices(props, data);
const pathFunction = d3Shape.arc()
.cornerRadius(props.cornerRadius)
.outerRadius(radius)
.innerRadius(props.innerRadius);
return { style, colors, padding, radius, data, slices, pathFunction, origin };
};

const getSliceStyle = (datum, index, calculatedValues) => {
const { style, colors } = calculatedValues;
const fill = getColor(style, colors, index);
const dataStyles = omit(datum, ["_x", "_y", "x", "y", "label"]);
return defaults({}, dataStyles, { fill }, style.data);
};

const getLabelText = (props, datum, index) => {
let text;
if (datum.label) {
text = datum.label;
} else if (Array.isArray(props.labels)) {
text = props.labels[index];
} else {
text = isFunction(props.labels) ? props.labels(datum) : datum.xName || datum._x;
}
return checkForValidText(text);
};

const getLabelPosition = (radius, labelRadius, style) => {
const padding = style && style.padding || 0;
const arcRadius = labelRadius || radius + padding;
return d3Shape.arc()
.outerRadius(arcRadius)
.innerRadius(arcRadius);
};

const getLabelOrientation = (slice) => {
const radiansToDegrees = (radians) => {
return radians * (180 / Math.PI);
};
const start = radiansToDegrees(slice.startAngle);
const end = radiansToDegrees(slice.endAngle);
const degree = start + (end - start) / 2;
if (degree < 45 || degree > 315) {
return "top";
} else if (degree >= 45 && degree < 135) {
return "right";
} else if (degree >= 135 && degree < 225) {
return "bottom";
} else {
return "left";
}
};

const getTextAnchor = (orientation) => {
if (orientation === "top" || orientation === "bottom") {
return "middle";
}
return orientation === "right" ? "start" : "end";
};

const getVerticalAnchor = (orientation) => {
if (orientation === "left" || orientation === "right") {
return "middle";
}
return orientation === "bottom" ? "start" : "end";
};

const getLabelProps = (props, dataProps, calculatedValues) => {
const { index, datum, data, slice } = dataProps;
const { style, radius, origin } = calculatedValues;
const labelStyle = Helpers.evaluateStyle(
assign({ padding: 0 }, style.labels), datum, props.active
);
const labelRadius = Helpers.evaluateProp(props.labelRadius, datum);
const labelPosition = getLabelPosition(radius, labelRadius, labelStyle);
const position = labelPosition.centroid(slice);
const orientation = getLabelOrientation(slice);
return {
index, datum, data, slice, orientation,
style: labelStyle,
x: Math.round(position[0]) + origin.x,
y: Math.round(position[1]) + origin.y,
text: getLabelText(props, datum, index),
textAnchor: labelStyle.textAnchor || getTextAnchor(orientation),
verticalAnchor: labelStyle.verticalAnchor || getVerticalAnchor(orientation),
angle: labelStyle.angle
};
};

export const getBaseProps = (props, fallbackProps) => {
props = Helpers.modifyProps(props, fallbackProps, "pie");
const calculatedValues = getCalculatedValues(props);
const { slices, style, pathFunction, data, origin } = calculatedValues;
const childProps = {
parent: {
standalone: props.standalone, slices, pathFunction,
width: props.width, height: props.height, style: style.parent
}
return this.checkForValidText(text);
},

getSlices(props, data) {
const layoutFunction = d3Shape.pie()
.sort(null)
.startAngle(this.degreesToRadians(props.startAngle))
.endAngle(this.degreesToRadians(props.endAngle))
.padAngle(this.degreesToRadians(props.padAngle))
.value((datum) => { return datum._y; });
return layoutFunction(data);
};

for (let index = 0, len = slices.length; index < len; index++) {
const slice = slices[index];
const datum = data[index];
const eventKey = datum.eventKey || index;
const dataProps = {
index, slice, pathFunction, datum, data, origin,
style: getSliceStyle(datum, index, calculatedValues)
};

childProps[eventKey] = {
data: dataProps,
labels: getLabelProps(props, dataProps, calculatedValues)
};
}
return childProps;
};
4 changes: 2 additions & 2 deletions src/components/victory-pie.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
addEvents, Helpers, Data, PropTypes as CustomPropTypes, Slice,
VictoryContainer, VictoryLabel, VictoryTheme
} from "victory-core";
import PieHelpers from "./helper-methods";
import { getBaseProps } from "./helper-methods";

const fallbackProps = {
endAngle: 360,
Expand Down Expand Up @@ -160,7 +160,7 @@ class VictoryPie extends React.Component {
theme: VictoryTheme.grayscale
};

static getBaseProps = partialRight(PieHelpers.getBaseProps.bind(PieHelpers), fallbackProps);
static getBaseProps = partialRight(getBaseProps, fallbackProps);
static getData = Data.getData.bind(Data);
static expectedComponents = [
"dataComponent", "labelComponent", "groupComponent", "containerComponent"
Expand Down