diff --git a/demo/src/index.js b/demo/src/index.js
index ed47fc9fad..a90343bdc8 100644
--- a/demo/src/index.js
+++ b/demo/src/index.js
@@ -267,6 +267,9 @@ module.exports = {
get Pinterest() {
return require('./screens/realExamples/Pinterest').default;
},
+ get PieChartScreen() {
+ return require('./screens/componentScreens/PieChartScreen.tsx').default;
+ },
get ListActionsScreen() {
return require('./screens/realExamples/ListActions/ListActionsScreen').default;
},
diff --git a/demo/src/screens/MenuStructure.js b/demo/src/screens/MenuStructure.js
index 3b2bfbe003..c755c44436 100644
--- a/demo/src/screens/MenuStructure.js
+++ b/demo/src/screens/MenuStructure.js
@@ -104,6 +104,12 @@ export const navigationData = {
{title: 'SortableGridList', tags: 'sort grid list drag', screen: 'unicorn.components.SortableGridListScreen'}
]
},
+ Charts: {
+ title: 'Charts',
+ screens: [
+ {title: 'PieChart', tags: 'pie chart data', screen: 'unicorn.components.PieChartScreen'}
+ ]
+ },
LayoutsAndTemplates: {
title: 'Layouts & Templates',
screens: [
diff --git a/demo/src/screens/componentScreens/PieChartScreen.tsx b/demo/src/screens/componentScreens/PieChartScreen.tsx
new file mode 100644
index 0000000000..f057536432
--- /dev/null
+++ b/demo/src/screens/componentScreens/PieChartScreen.tsx
@@ -0,0 +1,101 @@
+import React from 'react';
+import {ScrollView} from 'react-native';
+import {View, PieChart, Card, Text, Badge, PieChartSegmentProps, Colors} from 'react-native-ui-lib';
+
+const SEGMENTS: PieChartSegmentProps[] = [
+ {
+ percentage: 40,
+ color: Colors.blue30
+ },
+ {
+ percentage: 30,
+ color: Colors.red30
+ },
+ {
+ percentage: 20,
+ color: Colors.green30
+ },
+ {
+ percentage: 10,
+ color: Colors.purple30
+ }
+];
+
+const MONOCHROME_SEGMENTS: PieChartSegmentProps[] = [
+ {
+ percentage: 40,
+ color: Colors.blue70
+ },
+ {
+ percentage: 30,
+ color: Colors.blue50
+ },
+ {
+ percentage: 20,
+ color: Colors.blue30
+ },
+ {
+ percentage: 10,
+ color: Colors.blue10
+ }
+];
+
+const NOT_FULL_PIECHART: PieChartSegmentProps[] = [
+ {
+ percentage: 30,
+ color: Colors.blue30
+ },
+ {
+ percentage: 40,
+ color: Colors.red30
+ }
+];
+
+const PieChartScreen = () => {
+ const renderSegmentLabel = (segment: PieChartSegmentProps, text: string) => {
+ const {percentage, color} = segment;
+ return (
+
+
+
+ {text}
+ {percentage}%
+
+
+ );
+ };
+
+ const renderPieChartCard = (segments: PieChartSegmentProps[]) => {
+ return (
+
+
+
+
+
+ {segments.map((segment, index) => renderSegmentLabel(segment, `Value ${index + 1}`))}
+
+
+ );
+ };
+
+ return (
+
+
+
+ PieChart
+
+ {renderPieChartCard(SEGMENTS)}
+
+ Monochrome colors
+
+ {renderPieChartCard(MONOCHROME_SEGMENTS)}
+
+ Not Full PieChart
+
+ {renderPieChartCard(NOT_FULL_PIECHART)}
+
+
+ );
+};
+
+export default PieChartScreen;
diff --git a/demo/src/screens/componentScreens/index.js b/demo/src/screens/componentScreens/index.js
index 4805496025..3007fb4bfd 100644
--- a/demo/src/screens/componentScreens/index.js
+++ b/demo/src/screens/componentScreens/index.js
@@ -1,5 +1,6 @@
export function registerScreens(registrar) {
registrar('unicorn.components.ActionSheetScreen', () => require('./ActionSheetScreen').default);
+ registrar('unicorn.components.PieChartScreen', () => require('./PieChartScreen').default);
registrar('unicorn.components.ActionBarScreen', () => require('./ActionBarScreen').default);
registrar('unicorn.components.AvatarsScreen', () => require('./AvatarsScreen').default);
registrar('unicorn.components.AnimatedImageScreen', () => require('./AnimatedImageScreen').default);
diff --git a/src/components/pieChart/PieChart.api.json b/src/components/pieChart/PieChart.api.json
new file mode 100644
index 0000000000..de940a3dfb
--- /dev/null
+++ b/src/components/pieChart/PieChart.api.json
@@ -0,0 +1,15 @@
+{
+ "name": "PieChart",
+ "category": "charts",
+ "description": "Pie Chart",
+ "example": "https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/PieChartScreen.tsx",
+ "props": [
+ {"name": "segments", "type": "PieChartSegmentProps[]", "description": "Pie chart segments array"},
+ {"name": "diameter", "type": "number", "description": "Pie chart diameter"},
+ {"name": "dividerWidth", "type": "number", "description": "The width of the divider between the segments"},
+ {"name": "dividerColor", "type": "ColorValue", "description": "The color of the divider between the segments"}
+ ],
+ "snippet": [
+ ""
+ ]
+}
diff --git a/src/components/pieChart/PieSegment.tsx b/src/components/pieChart/PieSegment.tsx
new file mode 100644
index 0000000000..b6ee707228
--- /dev/null
+++ b/src/components/pieChart/PieSegment.tsx
@@ -0,0 +1,106 @@
+import React from 'react';
+import {ColorValue, StyleSheet} from 'react-native';
+import View from '../view';
+import {SvgPackage} from '../../optionalDependencies';
+import {Colors} from '../../style';
+const {Svg, Path} = SvgPackage;
+
+export type PieSegmentProps = {
+ /**
+ * The percentage of pie the segment should cover
+ */
+ percentage: number;
+ /**
+ * The radius of the containing pie
+ */
+ radius: number;
+ /**
+ * The color of the segment
+ */
+ color: string;
+ /**
+ * The start angle of the segment
+ */
+ startAngle?: number;
+ /**
+ * The padding between the segments and the container of the pie.
+ */
+ padding?: number;
+ /**
+ * The width of the divider between the segments
+ */
+ dividerWidth?: number;
+ /**
+ * The color of the divider between the segments
+ */
+ dividerColor?: ColorValue;
+};
+
+const PieSegment = (props: PieSegmentProps) => {
+ const {
+ percentage,
+ radius,
+ color,
+ startAngle = 0,
+ padding = 0,
+ dividerWidth = 4,
+ dividerColor = Colors.$backgroundDefault
+ } = props;
+
+ const actualRadius = radius - padding;
+ const centerXAndY = radius;
+ const amountToCover = (percentage / 100) * 360;
+ const angleFromTop = startAngle - 90;
+
+ const startRad = (angleFromTop * Math.PI) / 180;
+ const endRad = startRad + (amountToCover * Math.PI) / 180;
+
+ const startX = centerXAndY + Math.cos(startRad) * actualRadius;
+ const startY = centerXAndY + Math.sin(startRad) * actualRadius;
+ const endX = centerXAndY + Math.cos(endRad) * actualRadius;
+ const endY = centerXAndY + Math.sin(endRad) * actualRadius;
+
+ const largeArcFlag = amountToCover > 180 ? 1 : 0;
+ const sweepFlag = 1;
+
+ const arcPath = `
+ M ${centerXAndY} ${centerXAndY}
+ L ${startX} ${startY}
+ A ${actualRadius} ${actualRadius} 0 ${largeArcFlag} ${sweepFlag} ${endX} ${endY}
+ Z
+ `;
+ const startBorderLine = `M ${centerXAndY} ${centerXAndY} L ${startX} ${startY}`;
+ const endBorderLine = `M ${centerXAndY} ${centerXAndY} L ${endX} ${endY}`;
+
+ const arc = ;
+ const borders = (
+
+ );
+ const totalSize = radius * 2 + padding;
+
+ return (
+
+
+
+ );
+};
+
+export default PieSegment;
+
+const styles = StyleSheet.create({
+ container: {
+ position: 'absolute'
+ },
+ svg: {
+ position: 'absolute'
+ }
+});
diff --git a/src/components/pieChart/index.tsx b/src/components/pieChart/index.tsx
new file mode 100644
index 0000000000..adda6fae1a
--- /dev/null
+++ b/src/components/pieChart/index.tsx
@@ -0,0 +1,48 @@
+import React from 'react';
+import View from '../view';
+import PieSegment, {PieSegmentProps} from './PieSegment';
+import {SvgPackage} from '../../optionalDependencies';
+const {Svg, Path} = SvgPackage;
+
+export type PieChartSegmentProps = Pick;
+
+export type PieChartProps = {
+ /**
+ * Pie chart segments array
+ */
+ segments: PieChartSegmentProps[];
+ /**
+ * Pie chart diameter
+ */
+ diameter?: number;
+} & Pick;
+
+const DEFAULT_DIAMETER = 144;
+
+const PieChart = (props: PieChartProps) => {
+ const {segments, diameter = DEFAULT_DIAMETER, ...others} = props;
+
+ if (!Svg || !Path) {
+ console.error(`RNUILib PieChart requires installing "@react-native-svg" dependency`);
+ return null;
+ }
+
+ const renderPieSegments = () => {
+ let currentStartAngle = 0;
+
+ return segments.map((segment, index) => {
+ const startAngle = currentStartAngle;
+ currentStartAngle += (segment.percentage / 100) * 360;
+ return (
+
+ );
+ });
+ };
+ return (
+
+ {renderPieSegments()}
+
+ );
+};
+
+export default PieChart;
diff --git a/src/index.ts b/src/index.ts
index db833aea08..b2b3cc845c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -123,6 +123,7 @@ export {
PickerItemsListProps,
PickerMethods
} from './components/picker';
+export {default as PieChart, PieChartSegmentProps} from './components/pieChart';
export {default as ProgressBar, ProgressBarProps} from './components/progressBar';
export {default as ProgressiveImage, ProgressiveImageProps} from './components/progressiveImage';
export {default as RadioButton, RadioButtonProps} from './components/radioButton';