From f64a7a59e4b6b259802778ea4886aa12ec594185 Mon Sep 17 00:00:00 2001 From: Abhinandan-Kushwaha Date: Mon, 18 Apr 2022 03:33:22 +0530 Subject: [PATCH] Added Svg Pie and Donut charts!! --- App.js | 204 +++++++++++++++++++++++------ src/SvgPie/index.tsx | 306 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 473 insertions(+), 37 deletions(-) create mode 100644 src/SvgPie/index.tsx diff --git a/App.js b/App.js index 059c8bc..504de94 100644 --- a/App.js +++ b/App.js @@ -5,6 +5,7 @@ import {View, Text, StyleSheet} from 'react-native'; import {MyPattern} from './src/pattern'; import {BarChart, LineChart, PieChart} from './src'; import {Path, Pattern} from 'react-native-svg'; +import {SvgPie} from './src/SvgPie'; const App = () => { const [toggle, setToggle] = useState(true); @@ -551,11 +552,11 @@ const App = () => { ); }; - const styleObject = { - marginLeft: -95, - paddingLeft: 120, - transform: [{rotate: '90deg'}], - }; + // const styleObject = { + // marginLeft: -95, + // paddingLeft: 120, + // transform: [{rotate: '90deg'}], + // }; const ddtt = [ { value: 10, @@ -682,7 +683,7 @@ const App = () => { {value: 0.85, label: '15'}, ]; const lineData = [ - {value: 8,pointerShiftX:10,pointerShiftY:-10}, + {value: 8, pointerShiftX: 10, pointerShiftY: -10}, {value: 10}, {value: 12}, {value: 8}, @@ -734,21 +735,85 @@ const App = () => { // {value: 85, dataPointText: '85'}, // ]; + const styleObject = { + marginLeft: -95, + paddingLeft: 110, + transform: [{rotate: '90deg'}], + // backgroundColor: 'red', + }; + const lineData1 = [ - {value: 20,pointerShiftX:10}, - {value: 40}, - {value: 48, onPress:(item)=>Alert.alert(item.value+'')}, - {value: 50}, - {value: 56}, - {value: 70}, - {value: 90}, - {value: 95}, - {value: 70}, - {value: 90}, - {value: 95}, + { + value: 10000, + barMarginBottom: 20, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 40000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 48000, + onPress: item => Alert.alert(item.value + ''), + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 50000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 56000, + barMarginBottom: 40, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 70000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 90000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 95000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 70000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 90000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, + { + value: 95000, + label: 'hello world', + labelTextStyle: styleObject, + labelWidth: 130, + }, ]; const lineData2 = [ - {value: 0}, {value: 5}, {value: 8}, {value: 18}, @@ -817,36 +882,99 @@ const App = () => { style={{ // flex: 1, paddingVertical: 100, - backgroundColor: 'black', + paddingLeft:20, + // backgroundColor: 'black', }}> - {/* */} - */} + + {/* */} + {/* + /> */} {/* */} {/* { */} {/* */} - { hideRules xAxisColor="white" yAxisColor="white" - yAxisTextStyle={{color:'white'}} + yAxisTextStyle={{color: 'white'}} height={250} pointerConfig={{ color: 'white', @@ -913,12 +1041,14 @@ const App = () => { pointerLabelComponent: item => { return ( - {item.value} + + {item.value} + ); }, }} - /> + /> */} {/* ; + semiCircle?: Boolean; + + showText?: Boolean; + textColor?: string; + textSize?: number; + fontStyle?: string; + fontWeight?: string; + font?: string; + showTextBackground?: Boolean; + textBackgroundColor?: string; + textBackgroundRadius?: number; + showValuesAsLabels?: Boolean; + + centerLabelComponent?: Function; + tilt?: number; + initialAngle?: number; + labelsPosition?: 'outward' | 'inward' | 'mid'; +}; +type itemType = { + value: number; + shiftX?: number; + shiftY?: number; + color?: string; + text?: string; + textColor?: string; + textSize?: number; + fontStyle?: string; + fontWeight?: string; + font?: string; + textBackgroundColor?: string; + textBackgroundRadius?: number; + shiftTextX?: number; + shiftTextY?: number; +}; + +export const SvgPie = (props: propTypes) => { + const {data, isThreeD} = props; + const radius = props.radius || 120; + const canvasWidth = radius * 2; + const canvasHeight = isThreeD ? radius * 2.3 : radius * 2; + const shadowWidth = props.shadowWidth || (6 * radius) / 5; + const backgroundColor = props.backgroundColor || 'transparent'; + const shadowColor = props.shadowColor || 'lightgray'; + const semiCircle = props.semiCircle || false; + let pi = Math.PI; + const initialAngle = props.initialAngle || (semiCircle ? pi / -2 : 0); + const shadow = props.shadow || false; + const donut = props.donut || false; + const innerRadius = props.innerRadius || radius / 2; + const innerCircleColor = + props.innerCircleColor || props.backgroundColor || 'white'; + const innerCircleBorderWidth = + props.innerCircleBorderWidth || (props.innerCircleBorderColor ? 5 : 0); + const innerCircleBorderColor = props.innerCircleBorderColor || 'lightgray'; + const shiftInnerCenterX = props.shiftInnerCenterX || 0; + const shiftInnerCenterY = props.shiftInnerCenterY || 0; + const strokeWidth = props.strokeWidth || 0; + const strokeColor = + props.strokeColor || (strokeWidth ? 'gray' : 'transparent'); + + const showText = props.showText || false; + const textColor = props.textColor || ''; + const textSize = props.textSize ? Math.min(props.textSize, radius / 5) : 16; + const tilt = props.tilt ? Math.min(props.tilt, 1) : props.isThreeD ? 0.5 : 1; + const labelsPosition = props.labelsPosition + ? props.labelsPosition + : donut + ? 'outward' + : 'mid'; + + const showTextBackground = props.showTextBackground || false; + const textBackgroundColor = props.textBackgroundColor || 'white'; + const showValuesAsLabels = props.showValuesAsLabels || false; + const fontStyleList = ['normal', 'italic', 'oblique']; + const fontWeightList = [ + 'normal', + 'bold', + 'bolder', + 'lighter', + '100', + '200', + '300', + '400', + '500', + '600', + '700', + '800', + '900', + ]; + + const colors = [ + 'cyan', + 'green', + 'orange', + 'purple', + 'yellow', + 'red', + 'blue', + 'pink', + ]; + let isDataShifted = false; + data.forEach((item: any) => { + total += item.value; + if (item.shiftX || item.shiftY) { + isDataShifted = true; + } + }); + + if (semiCircle) { + pi = Math.PI / 2; + } + + let cx = radius, + cy = radius; + + let total = data.map(item => item.value).reduce((v, a) => v + a); + console.log('total ------->', total); + let acc = 0; + let pData = data.map(item => { + acc += item.value / total; + return acc; + }); + acc = 0; + let mData = data.map(item => { + let pAcc = acc; + acc += item.value / total; + return pAcc + (acc - pAcc) / 2; + }); + pData = [0, ...pData]; + // mData = [0, ...mData]; + console.log('pdata----....----....---->>>>', pData); + + return ( + + + {isThreeD && shadow && !semiCircle && ( + + )} + {data.map((item, index) => { + console.log('index', index); + let nextItem; + if (index === pData.length - 1) nextItem = pData[0]; + else nextItem = pData[index + 1]; + let sx = cx * (1 + Math.sin(2 * pi * pData[index] + initialAngle)); + let sy = cy * (1 - Math.cos(2 * pi * pData[index] + initialAngle)); + let ax = cx * (1 + Math.sin(2 * pi * nextItem + initialAngle)); + let ay = cy * (1 - Math.cos(2 * pi * nextItem + initialAngle)); + + // console.log('sx', sx); + // console.log('sy', sy); + // console.log('ax', ax); + // console.log('ay', ay); + return ( + total / 2 ? 1 : 0 + } 1 ${ax} ${ay} L ${cx} ${cy}`} + stroke={strokeColor} + strokeWidth={strokeWidth} + fill={item.color || colors[index % 9]} + /> + ); + })} + + {showText && + data.map((item, index) => { + console.log('index', index); + + let mx = cx * (1 + Math.sin(2 * pi * mData[index] + initialAngle)); + let my = cy * (1 - Math.cos(2 * pi * mData[index] + initialAngle)); + + let midx = (mx + cx) / 2; + let midy = (my + cy) / 2; + + let x = midx, + y = midy; + + if (labelsPosition === 'outward') { + x = (midx + mx) / 2; + y = (midy + my) / 2; + } else if (labelsPosition === 'inward') { + x = (midx + cx) / 2; + y = (midy + cy) / 2; + } + + // console.log('sx', sx); + // console.log('sy', sy); + // console.log('ax', ax); + // console.log('ay', ay); + return ( + <> + {/* */} + + + {item.text || (showValuesAsLabels ? item.value + '' : '')} + + + ); + })} + + {(props.centerLabelComponent || (donut && !isDataShifted)) && ( + + {props.centerLabelComponent ? props.centerLabelComponent() : null} + + )} + + ); +};