Added semi-circle Pie and Donut charts

This commit is contained in:
Abhinandan Kushwaha 2022-01-28 04:17:45 +05:30
parent 165ba66160
commit 1f01917b6b
4 changed files with 204 additions and 89 deletions

162
App.js
View File

@ -2,7 +2,7 @@ import React, {useEffect, useState} from 'react';
import {TouchableOpacity} from 'react-native';
import {Alert} from 'react-native';
import {View, Text, StyleSheet} from 'react-native';
import {BarChart, LineChart} from './src';
import {BarChart, LineChart, PieChart} from './src';
const App = () => {
const [toggle, setToggle] = useState(true);
@ -486,9 +486,9 @@ const App = () => {
);
};
const ndd = [
{label: 'Jan', value: 30},
{label: 'Feb', value: 10},
{label: 'Mar', value: 20},
{value: 30, color: 'rgb(84,219,234)'},
{value: 40, color: 'lightgreen'},
{value: 20, color: 'orange'},
];
const [data, setData] = useState([
{value: 15, label: 'Jan'},
@ -532,44 +532,115 @@ const App = () => {
{value: 30, label: 'Dec'},
]);
const renderLegend = (text, color) => {
return (
<View style={{flexDirection: 'row', marginBottom: 12}}>
<View
style={{
height: 18,
width: 18,
marginRight: 10,
borderRadius: 4,
backgroundColor: color || 'white',
}}
/>
<Text style={{color: 'white', fontSize: 16}}>{text || ''}</Text>
</View>
);
};
const barData = [
{
value: 15,
label: 'Mon',
},
{value: 30, label: 'Tue'},
{value: 26, label: 'Wed'},
// {value: 40, label: 'Thu'},
{value: 16, label: 'Wed'},
{value: 40, label: 'Thu'},
];
return (
<View>
<View
style={{
marginVertical: 100,
paddingVertical: 50,
// backgroundColor: '#414141',
marginLeft: 6,
}}>
<BarChart hideOrigin data={ndd} yAxisLabelTexts={['0', '£10', '£20']} />
{/* <LineChart
isAnimated
thickness={3}
color="#07BAD1"
maxValue={600}
noOfSections={3}
animateOnDataChange
animationDuration={1000}
onDataChangeAnimationDuration={300}
areaChart
yAxisTextStyle={{color: 'lightgray'}}
data={currentData}
// curved
hideDataPoints
startFillColor={'rgb(84,219,234)'}
endFillColor={'rgb(84,219,234)'}
startOpacity={0.4}
endOpacity={0.1}
spacing={22}
backgroundColor="#414141"
rulesColor="gray"
rulesType="solid"
initialSpacing={10}
yAxisColor="lightgray"
xAxisColor="lightgray"
dataPointsHeight={20}
dataPointsWidth={20}
/> */}
{/* <BarChart backgroundColor={'green'} data={barData} /> */}
<PieChart
backgroundColor={'red'}
maxValue={40}
data={barData}
height={140}
radius={170}
donut={true}
showText={true}
showValuesAsLabels={true}
semiCircle={true}
isThreeD={true}
// shiftInnerCenterY={100}
shadow={true}
strokeWidth={5}
innerCircleBorderColor={'gray'}
// showTextBackground={true}
/>
{/* <View
style={{
marginVertical: 100,
marginHorizontal: 30,
borderRadius: 10,
paddingVertical: 50,
backgroundColor: '#414141',
justifyContent: 'center',
alignItems: 'center',
}}>
<Text
style={{
color: 'white',
fontSize: 32,
fontWeight: 'bold',
marginBottom: 12,
}}>
Quarterly Sales
</Text>
<PieChart
strokeColor="white"
strokeWidth={4}
donut
data={[
{value: 30, color: 'rgb(84,219,234)'},
{value: 40, color: 'lightgreen'},
{value: 20, color: 'orange'},
]}
innerCircleColor="#414141"
innerCircleBorderWidth={4}
innerCircleBorderColor={'white'}
showValuesAsLabels={true}
showText
textSize={18}
showTextBackground={true}
centerLabelComponent={() => {
return (
<View>
<Text style={{color: 'white', fontSize: 36}}>90</Text>
<Text style={{color: 'white', fontSize: 18}}>Total</Text>
</View>
);
}}
/>
<View
style={{
width: '100%',
flexDirection: 'row',
justifyContent: 'space-evenly',
marginTop: 20,
}}>
{renderLegend('Jan', 'rgb(84,219,234)')}
{renderLegend('Feb', 'lightgreen')}
{renderLegend('Mar', 'orange')}
</View>
</View> */}
{/* <TouchableOpacity
onPress={() => setCurrentData(latestData)}
@ -597,13 +668,15 @@ const App = () => {
<Text>Straight</Text>
</TouchableOpacity> */}
{/* {!toggle ? (
<BarChart
{/* {true ? (
<LineChart
isThreeD
key={'xyz'}
height={300}
height={320}
maxValue={360}
showLine
hideOrigin
// animationDuration={000}
initialSpacing={30}
// showVerticalLines
lineConfig={{
@ -619,12 +692,17 @@ const App = () => {
shiftY: 25,
curved: true,
}}
yAxisLabelPrefix={'$'}
yAxisLabelSuffix={'.0'}
barWidth={32}
// width={190}
data={[
{
value: 270,
value: 70,
label: 'Jan',
topLabelComponent: () => {
return <Text>30</Text>;
},
},
{value: 250, label: 'Feb'},
{value: 200, label: 'Mar'},
@ -672,8 +750,8 @@ const App = () => {
capColor={'rgb(78, 0, 142)'}
capThickness={4}
// barWidth={35}
frontColor={'rgba(200, 100, 244,0.2)'}
gradientColor={'rgba(78, 0, 142,1)'}
gradientColor={'rgba(200, 100, 244,0.2)'}
frontColor={'rgba(78, 0, 142,1)'}
// rulesType="dashed"
// rulesColor={'rgba(0,200,0,0.5)'}
// rulesThickness={1}

View File

@ -1,7 +1,7 @@
# Pie Chart props
| Prop | Type | Description | Default value |
| -------------------- | -------------- | -------------------------------------------------------------------------------- | --------------- |
| -------------------- | -------------- | --------------------------------------------------------------------------------------------------------- | --------------- |
| data | Array of items | An item object represents a section in the Pie chart. Descibed in the next table | \_ |
| radius | number | Radius of the Pie chart | 120 |
| isThreeD | Boolean | If set to true, it rotates and translates the chart to give it a 3D effect | false |
@ -22,6 +22,7 @@
| textBackgroundRadius | number | Radius for the background of the text labels | textSize |
| showValuesAsLabels | Boolean | When set to true, the values of the Pie sections are displayed as labels | false |
| centerLabelComponent | Function | Component to be rendered at the center of the Pie chart | \_ |
| semiCircle | Boolean | When set to true, renders the Pie Chart in a semi-circle. donut semiCircle charts look like a speed-meter | false |
### Item description

View File

@ -1,6 +1,6 @@
{
"name": "react-native-gifted-charts",
"version": "0.2.9",
"version": "1.0.0",
"description": "The most complete library for Bar, Line, Area, Pie and Donut charts in React Native. Allows 2D, 3D, gradient, animations and live data updates.",
"main": "src/index.tsx",
"files": [

View File

@ -2,8 +2,6 @@ import React from 'react';
import {ColorValue, View} from 'react-native';
import Canvas from 'react-native-canvas';
const pi = Math.PI;
type propTypes = {
radius?: number;
isThreeD?: Boolean;
@ -21,6 +19,7 @@ type propTypes = {
strokeColor?: string;
backgroundColor?: string;
data: Array<itemType>;
semiCircle?: Boolean;
showText?: Boolean;
textColor?: string;
@ -59,6 +58,7 @@ export const PieChart = (props: propTypes) => {
const backgroundColor = props.backgroundColor || 'white';
const shadowColor = props.shadowColor || 'lightgray';
let total = 0;
let pi = Math.PI;
const shadow = props.shadow || false;
const donut = props.donut || false;
const innerRadius = props.innerRadius || radius / 2;
@ -79,7 +79,7 @@ export const PieChart = (props: propTypes) => {
const showTextBackground = props.showTextBackground || false;
const showValuesAsLabels = props.showValuesAsLabels || false;
const semiCircle = props.semiCircle || false;
const fontStyleList = ['normal', 'italic', 'oblique'];
const fontWeightList = [
'normal',
@ -105,6 +105,10 @@ export const PieChart = (props: propTypes) => {
}
});
if (semiCircle) {
pi = Math.PI / 2;
}
const canvasHeight = isThreeD ? radius * 2.5 + 60 : radius * 2 + 60;
const canvasWidth = radius * 2 + 60;
@ -125,7 +129,7 @@ export const PieChart = (props: propTypes) => {
const initialValue = 30;
/****************** SHADOW ***************/
if (isThreeD && shadow) {
if (!semiCircle && isThreeD && shadow) {
ctx.beginPath();
ctx.moveTo(initialValue, radius + initialValue);
ctx.lineTo(initialValue, shadowWidth + initialValue);
@ -230,7 +234,7 @@ export const PieChart = (props: propTypes) => {
radius + initialValue + shiftY,
);
ctx.fillStyle = dataItem.color || colors[i++ % 8];
ctx.fillStyle = dataItem.color || colors[i++ % 9];
ctx.fill();
// Stroke at the end again
@ -297,29 +301,41 @@ export const PieChart = (props: propTypes) => {
// console.log('semisum==>>', semiSum);
// console.log('sin(semisum)==>>', Math.sin(semiSum));
if (semiCircle) {
if (semiSum > 0 && semiSum <= pi / 2) {
xx -= 40;
yy -= 10;
yy -= 6;
} else if (semiSum > pi / 2 && semiSum <= pi) {
xx += 10;
yy -= 10;
} else if (semiSum > pi && semiSum <= 1.5 * pi) {
xx += 10;
yy += 24;
yy -= 20;
} else {
xx -= 40;
yy += 24;
xx += 25;
yy -= 8;
}
} else {
if (semiSum > 0 && semiSum <= pi / 2) {
xx -= 20;
} else if (semiSum > pi && semiSum <= 1.5 * pi) {
xx += 10;
yy += 16;
} else if (semiSum > 1.5 * pi) {
xx -= 16;
yy += 16;
}
}
if (showTextBackground && (dataItem.text || showValuesAsLabels)) {
let textBackgroundX =
xx +
xx -
(semiCircle ? 18 : 0) +
(props.textBackgroundRadius ||
dataItem.textBackgroundRadius ||
textSize) /
2;
let textBackgroundY =
yy -
yy +
(semiCircle ? 8 : 0) -
(props.textBackgroundRadius ||
dataItem.textBackgroundRadius ||
textSize) /
@ -332,7 +348,7 @@ export const PieChart = (props: propTypes) => {
dataItem.textBackgroundRadius ||
textSize,
0,
2 * pi,
2 * Math.PI,
false,
);
ctx.fillStyle =
@ -345,13 +361,21 @@ export const PieChart = (props: propTypes) => {
xx += shiftTextX;
yy += shiftTextY;
ctx.fillStyle = dataItem.textColor || textColor || colors[i++ % 8];
ctx.fillStyle = dataItem.textColor || textColor || colors[i++ % 9];
let labelText = dataItem.text || '';
if (showValuesAsLabels && !labelText) {
labelText = dataItem.value.toString();
}
if (semiCircle) {
ctx.translate(xx, yy);
ctx.rotate(Math.PI);
ctx.fillText(labelText, 4, 4);
ctx.rotate(Math.PI);
ctx.translate(-xx, -yy);
} else {
ctx.fillText(labelText, xx, yy);
}
}
/****************************************************************************************/
@ -361,7 +385,10 @@ export const PieChart = (props: propTypes) => {
return total === 0 ? null : (
<View style={{transform: [{scaleY: tilt}]}}>
<Canvas ref={handleCanvas} />
<Canvas
style={semiCircle && {transform: [{rotate: '180deg'}]}}
ref={handleCanvas}
/>
{(props.centerLabelComponent || (donut && !isDataShifted)) && (
<View
style={[
@ -375,7 +402,8 @@ export const PieChart = (props: propTypes) => {
top:
canvasHeight / 2 -
innerRadius * (isThreeD ? 1.5 : 1) +
shiftInnerCenterY,
shiftInnerCenterY +
(isThreeD && semiCircle ? radius / 2 : 0),
borderWidth: innerCircleBorderWidth,
borderColor: innerCircleBorderColor,
backgroundColor: innerCircleColor,
@ -388,6 +416,14 @@ export const PieChart = (props: propTypes) => {
? innerCircleBorderWidth * 2
: innerCircleBorderWidth,
},
semiCircle && {
borderTopWidth: isThreeD
? innerCircleBorderWidth * 5
: innerCircleBorderWidth,
borderLeftWidth: 0.001,
borderBottomWidth: 0,
borderRightWidth: 0.001,
},
]}>
{props.centerLabelComponent ? props.centerLabelComponent() : null}
</View>