mirror of
https://github.com/status-im/react-native-gifted-charts.git
synced 2025-02-23 00:58:11 +00:00
Added semi-circle Pie and Donut charts
This commit is contained in:
parent
165ba66160
commit
1f01917b6b
162
App.js
162
App.js
@ -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}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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": [
|
||||
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user