Closed zgordon01 closed 4 years ago
looks awesome 👍
Not at all different than what you have done here but tried to make it more readable
import React from 'react';
import PropTypes from 'prop-types';
import { Platform } from 'react-native';
import { Surface, Shape, Path, Group } from '@react-native-community/art';
function createPath(cx, cy, r, startAngle, arcAngle) {
const p = new Path();
p.path.push(0, cx + r * Math.cos(startAngle), cy + r * Math.sin(startAngle));
p.path.push(4, cx, cy, r, startAngle, startAngle + arcAngle, 1);
return p;
}
const ArcShape = ({ radius, width, color, strokeCap, startAngle, arcAngle }) => {
const path = createPath(
radius,
radius,
radius - width / 2,
startAngle / 180 * Math.PI,
arcAngle / 180 * Math.PI,
);
return <Shape d={path} stroke={color} strokeWidth={width} strokeCap={strokeCap} />;
};
const getPercentage = (percentage) => (percentage < 6 ? percentage + (6 - percentage) : percentage);
const _renderArc = ({ sections, width, radius, backgroundColor, strokeCap, dividerSize }) => {
const hasValidPercentage = sections.every(({ percentage }) => percentage !== 100);
const shouldShowRoundDividers = !!dividerSize && strokeCap === 'round' && hasValidPercentage;
let startValue = 0;
let arcArray = [];
let dividerColorOverlayArray = [];
let dividerArray = [];
sections.forEach((section, index) => {
const { percentage, color } = section;
const calculatedPercentage = shouldShowRoundDividers ? getPercentage(percentage) : percentage;
const startAngle = startValue / 100 * 360;
const arcAngle = calculatedPercentage / 100 * 360;
startValue += calculatedPercentage;
arcArray.push(<ArcShape
key={index}
radius={radius}
width={width}
color={color}
startAngle={startAngle + dividerSize}
arcAngle={arcAngle - dividerSize}
strokeCap={strokeCap}
/>);
if (shouldShowRoundDividers) {
dividerArray.push(<ArcShape
key={index}
radius={radius}
width={width}
color={backgroundColor}
startAngle={startAngle - dividerSize / 2}
arcAngle={dividerSize}
strokeCap={strokeCap}
/>);
dividerColorOverlayArray.push(<ArcShape
key={index}
radius={radius}
width={width}
color={color}
startAngle={startAngle + arcAngle - dividerSize / 2 - 1}
arcAngle={1}
strokeCap={strokeCap}
/>);
}
});
return [...arcArray, ...dividerArray, ...dividerColorOverlayArray];
}
const Pie = ({ sections, radius, innerRadius, backgroundColor, strokeCap, dividerSize }) => {
const width = radius - innerRadius;
const backgroundPath = createPath(radius, radius, radius - width / 2, 0, 360);
return (
<Surface width={radius * 2} height={radius * 2}>
<Group rotation={-90} originX={radius} originY={radius}>
<Shape
d={backgroundPath}
stroke={backgroundColor}
strokeWidth={width}
/>
<ArcShape radius={radius} width={width} color={backgroundColor} startAngle={0} arcAngle={360} />
{_renderArc({ sections, width, radius, backgroundColor, strokeCap, dividerSize })}
</Group>
</Surface>
);
};
Pie.propTypes = {
sections: PropTypes.arrayOf(
PropTypes.exact({
percentage: PropTypes.number.isRequired,
color: PropTypes.string.isRequired,
}),
).isRequired,
radius: PropTypes.number.isRequired,
innerRadius: PropTypes.number,
backgroundColor: PropTypes.string,
strokeCap: PropTypes.oneOf(['butt', 'square', 'round']),
dividerSize: PropTypes.number,
};
Pie.defaultProps = {
dividerSize: 0,
innerRadius: 0,
backgroundColor: '#FFFFFF',
strokeCap: 'butt',
};
export default Pie;
I have also added code here to handle the percentage < 6, which will break when we are displaying round
divider.
Removed web part from createPath
since this library is specifically for Native
Seems like we can remove this from the readme based on my above comments:
On android there is a ring shape drawing issue in React Native, I've made a PR to resolve it https://github.com/facebook/react-native/pull/15042, I also made a warkarond for this compoent https://github.com/nihgwu/react-native-pie/commit/86adf51339854ef3dc50df8cef6d12afb9df7b82, and will remove it when that PR is shipped with a stable release
@nihgwu do you know what RN version that was shipped in so I can add a clause to the readme?
@zgordon01
seems it's 0.50.0-rc.0
@nihgwu @milindagrawal check now. I did a docs update based on some discussion with the ring shape drawing issue, as well as addressed code comments
Thanks 👍
v1.1.0 released
BTW, what's your username for npm? I'll invite you as the admin
BTW, what's your username for npm? I'll invite you as the admin
zgordon01, same as github
@zgordon01 invited
Release 1.1.0
Description
An option to include dividers between the pie sections. Supports
round
andbutt
strokeCap. RemovingRingShape
workaroundUpdated readme to include strokeCap. Updating readme examples with new images.