mirror of
https://github.com/status-im/react-native-gifted-charts.git
synced 2025-02-23 00:58:11 +00:00
Added Svg Pie and Donut charts!!
This commit is contained in:
parent
588703b8c9
commit
f64a7a59e4
204
App.js
204
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',
|
||||
}}>
|
||||
|
||||
{/* <MyPattern/> */}
|
||||
<LineChart
|
||||
data={lineData1}
|
||||
areaChart
|
||||
{/* <PieChart
|
||||
data={lineData2.reverse()}
|
||||
// initialAngle={Math.PI}
|
||||
showText
|
||||
showValuesAsLabels
|
||||
/> */}
|
||||
<SvgPie
|
||||
// backgroundColor='black'
|
||||
donut
|
||||
// isThreeD
|
||||
// shiftInnerCenterX={20}
|
||||
semiCircle
|
||||
shadow
|
||||
radius={150}
|
||||
// shadow
|
||||
// innerCircleBorderWidth={4}
|
||||
showText
|
||||
showValuesAsLabels
|
||||
textSize={10}
|
||||
fontWeight='bold'
|
||||
// font='monospace'
|
||||
// labelsPosition="inward"
|
||||
data={[{value: 500}, {value: 20}, {value: 40}, {value: 80}, {value: 30}]}
|
||||
/>
|
||||
{/* <PieChart donut innerCircleBorderWidth={3} innerCircleBorderColor='lightgray' shiftInnerCenterX={15} shadow data={[{value:50},{value:20},{value:40},{value:80},{value:30}]} /> */}
|
||||
{/* <BarChart
|
||||
data={lineData2}
|
||||
showText
|
||||
showValuesAsLabels
|
||||
// horizontalRulesStyle={{zIndex:100}}
|
||||
// backgroundColor='black'
|
||||
// color='white'
|
||||
// dataPointsColor1='red'
|
||||
// rotateLabel
|
||||
labelsExtraHeight={100}
|
||||
// areaChart
|
||||
// barMarginBottom={10}
|
||||
// isAnimated
|
||||
curved
|
||||
dataPointsShape='rectangular'
|
||||
// isThreeD
|
||||
// showGradient
|
||||
cappedBars
|
||||
capColor={'red'}
|
||||
// curved
|
||||
// dataPointsShape="rectangular"
|
||||
// cappedBars
|
||||
// yAxisSide='right'
|
||||
// pressEnabled
|
||||
// showStripOnPress
|
||||
// pointerConfig={{pointerStripColor: 'blue'}}
|
||||
initialSpacing={0}
|
||||
hideRules
|
||||
// initialSpacing={0}
|
||||
// hideRules
|
||||
// scrollToEnd
|
||||
// horizontalRulesStyle={{zIndex:1}}
|
||||
// backgroundColor='rgba(255,0,0,0.8)'
|
||||
// yAxisLabelContainerStyle={{zIndex:100000,elevation:1,textAlign:'left'}}
|
||||
// yAxisTextStyle={{fontWeight:'bold',marginRight:-110,zIndex:10000,textAlign:'left'}}
|
||||
// spacing={30}
|
||||
/>
|
||||
/> */}
|
||||
{/* <BarChart
|
||||
data={ldt}
|
||||
maxValue={80}
|
||||
stepValue={20}
|
||||
noOfSections={4}
|
||||
minValue={-60}
|
||||
noOfSectionsBelowXAxis={3}
|
||||
areaChart
|
||||
// maxValue={80}
|
||||
// stepValue={20}
|
||||
// noOfSections={4}
|
||||
// minValue={-60}
|
||||
frontColor={'yellow'}
|
||||
yAxisThickness={5}
|
||||
width={260}
|
||||
yAxisSide='right'
|
||||
yAxisTextStyle={{left:40}}
|
||||
// yAxisLabelContainerStyle={{zIndex:20,elevation:10}}
|
||||
// noOfSectionsBelowXAxis={3}
|
||||
showReferenceLine1
|
||||
referenceLine1Position={40}
|
||||
referenceLine1Config={{
|
||||
labelText: 'hello',
|
||||
labelTextStyle: {left:100,top:-10},
|
||||
type: 'solid'
|
||||
}}
|
||||
showReferenceLine2
|
||||
referenceLine2Position={60}
|
||||
referenceLine2Config={{
|
||||
color:'red',
|
||||
labelText: 'hello',
|
||||
labelTextStyle: {left:100,top:-10},
|
||||
type: 'solid'
|
||||
}}
|
||||
// width={190}
|
||||
// hideRules
|
||||
/> */}
|
||||
{/* <LineChart
|
||||
areaChart
|
||||
@ -891,7 +1019,7 @@ const App = () => {
|
||||
</View> */}
|
||||
{/* <PieChart data={[]} isThreeD shadow donut/> */}
|
||||
|
||||
<LineChart
|
||||
{/* <LineChart
|
||||
data={lineData}
|
||||
initialSpacing={0}
|
||||
spacing={12}
|
||||
@ -904,7 +1032,7 @@ const App = () => {
|
||||
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 (
|
||||
<View>
|
||||
<Text style={{color:'yellow',fontWeight:'bold'}}>{item.value}</Text>
|
||||
<Text style={{color: 'yellow', fontWeight: 'bold'}}>
|
||||
{item.value}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
},
|
||||
}}
|
||||
/>
|
||||
/> */}
|
||||
|
||||
{/* <LineChart
|
||||
curved={true}
|
||||
|
306
src/SvgPie/index.tsx
Normal file
306
src/SvgPie/index.tsx
Normal file
@ -0,0 +1,306 @@
|
||||
import React from 'react';
|
||||
import {ColorValue, View, Text} from 'react-native';
|
||||
import Svg, {
|
||||
Path,
|
||||
LinearGradient,
|
||||
Stop,
|
||||
Circle,
|
||||
Rect,
|
||||
Text as CanvasText,
|
||||
Line,
|
||||
} from 'react-native-svg';
|
||||
import {svgPath, bezierCommand} from '../utils';
|
||||
|
||||
type propTypes = {
|
||||
radius?: number;
|
||||
isThreeD?: Boolean;
|
||||
donut?: Boolean;
|
||||
innerRadius?: number;
|
||||
shadow?: Boolean;
|
||||
innerCircleColor?: ColorValue;
|
||||
innerCircleBorderWidth?: number;
|
||||
innerCircleBorderColor?: ColorValue;
|
||||
shiftInnerCenterX?: number;
|
||||
shiftInnerCenterY?: number;
|
||||
shadowColor?: string;
|
||||
shadowWidth?: number;
|
||||
strokeWidth?: number;
|
||||
strokeColor?: string;
|
||||
backgroundColor?: string;
|
||||
data: Array<itemType>;
|
||||
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 (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
backgroundColor: backgroundColor,
|
||||
height: canvasHeight,
|
||||
width: canvasWidth,
|
||||
},
|
||||
isThreeD && {transform: [{rotateX: '55deg'}]},
|
||||
]}>
|
||||
<Svg>
|
||||
{isThreeD && shadow && !semiCircle && (
|
||||
<Circle
|
||||
cx={cx}
|
||||
cy={shadowWidth}
|
||||
r={radius}
|
||||
stroke={shadowColor}
|
||||
strokeWidth="1.5"
|
||||
fill={shadowColor}
|
||||
/>
|
||||
)}
|
||||
{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 (
|
||||
<Path
|
||||
d={`M ${cx} ${cy} L ${sx} ${sy} A ${radius} ${radius} 0 ${
|
||||
semiCircle ? 0 : data[index].value > 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 (
|
||||
<>
|
||||
{/* <Line x1={mx} x2={cx} y1={my} y2={cy} stroke="black" /> */}
|
||||
<Circle
|
||||
cx={x}
|
||||
cy={y - (item.textSize || textSize) / 4}
|
||||
r={
|
||||
item.textBackgroundRadius ||
|
||||
props.textBackgroundRadius ||
|
||||
item.textSize ||
|
||||
textSize
|
||||
}
|
||||
fill={item.textBackgroundColor || textBackgroundColor}
|
||||
/>
|
||||
<CanvasText
|
||||
fill={item.textColor || textColor || colors[(index + 2) % 9]}
|
||||
fontSize={item.textSize || textSize}
|
||||
fontFamily={item.font || props.font}
|
||||
fontWeight={item.fontWeight || props.fontWeight}
|
||||
x={x + (item.shiftTextX || 0) - (item.textSize || textSize)/1.8}
|
||||
y={y + (item.shiftTextY || 0)}>
|
||||
{item.text || (showValuesAsLabels ? item.value + '' : '')}
|
||||
</CanvasText>
|
||||
</>
|
||||
);
|
||||
})}
|
||||
</Svg>
|
||||
{(props.centerLabelComponent || (donut && !isDataShifted)) && (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
height: innerRadius * 2,
|
||||
width: innerRadius * 2,
|
||||
borderRadius: innerRadius,
|
||||
position: 'absolute',
|
||||
zIndex: 100,
|
||||
alignSelf: 'center',
|
||||
backgroundColor: innerCircleColor,
|
||||
left: canvasWidth / 2 - innerRadius + shiftInnerCenterX,
|
||||
top:
|
||||
canvasHeight / 2 -
|
||||
innerRadius +
|
||||
shiftInnerCenterY -
|
||||
(isThreeD ? radius / 5 : 0),
|
||||
borderWidth: innerCircleBorderWidth,
|
||||
borderColor: innerCircleBorderColor,
|
||||
justifyContent: 'center',
|
||||
alignItems: 'center',
|
||||
},
|
||||
isThreeD && {
|
||||
borderTopWidth: innerCircleBorderWidth * 5,
|
||||
borderLeftWidth: shiftInnerCenterX
|
||||
? innerCircleBorderWidth * 2
|
||||
: innerCircleBorderWidth,
|
||||
},
|
||||
semiCircle && {
|
||||
borderTopWidth: isThreeD
|
||||
? innerCircleBorderWidth * 5
|
||||
: innerCircleBorderWidth,
|
||||
borderLeftWidth: 0.5,
|
||||
borderLeftColor: innerCircleColor,
|
||||
borderBottomWidth: 0,
|
||||
borderRightWidth: 0.5,
|
||||
borderRightColor: innerCircleColor,
|
||||
},
|
||||
]}>
|
||||
{props.centerLabelComponent ? props.centerLabelComponent() : null}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user