Toggle navigation
Toggle navigation
This project
Loading...
Sign in
iOS
/
PNChart
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Pipelines
Graphs
Issues
0
Merge Requests
0
Wiki
Network
Create a new issue
Builds
Commits
Authored by
Zhang Hang
2015-03-01 18:38:04 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0a28c9c51246ba9daff1da8cf2eaa7aea250f81b
0a28c9c5
1 parent
3f666b10
PieChart divides equally when all value of data items are 0
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
46 additions
and
29 deletions
PNChart/PNPieChart.m
PNChart/PNPieChart.m
View file @
0a28c9c
...
...
@@ -11,8 +11,7 @@
@interface
PNPieChart
()
@property
(
nonatomic
,
readwrite
)
NSArray
*
items
;
@property
(
nonatomic
)
CGFloat
total
;
@property
(
nonatomic
)
CGFloat
currentTotal
;
@property
(
nonatomic
)
NSArray
*
endPercentages
;
@property
(
nonatomic
)
CGFloat
outerCircleRadius
;
@property
(
nonatomic
)
CGFloat
innerCircleRadius
;
...
...
@@ -21,11 +20,14 @@
@property
(
nonatomic
)
CAShapeLayer
*
pieLayer
;
@property
(
nonatomic
)
NSMutableArray
*
descriptionLabels
;
-
(
void
)
loadDefault
;
-
(
UILabel
*
)
descriptionLabelForItemAtIndex
:(
NSUInteger
)
index
;
-
(
PNPieChartDataItem
*
)
dataItemForIndex
:(
NSUInteger
)
index
;
-
(
CGFloat
)
startPercentageForItemAtIndex
:(
NSUInteger
)
index
;
-
(
CGFloat
)
endPercentageForItemAtIndex
:(
NSUInteger
)
index
;
-
(
CGFloat
)
ratioForItemAtIndex
:(
NSUInteger
)
index
;
-
(
CAShapeLayer
*
)
newCircleLayerWithRadius
:(
CGFloat
)
radius
borderWidth
:(
CGFloat
)
borderWidth
fillColor
:(
UIColor
*
)
fillColor
...
...
@@ -58,15 +60,23 @@
return
self
;
}
-
(
void
)
loadDefault
{
_currentTotal
=
0
;
_total
=
0
;
__block
CGFloat
currentTotal
=
0
;
CGFloat
total
=
[[
self
.
items
valueForKeyPath
:
@"@sum.value"
]
floatValue
];
NSMutableArray
*
endPercentages
=
[
NSMutableArray
new
];
[
_items
enumerateObjectsUsingBlock
:
^
(
PNPieChartDataItem
*
item
,
NSUInteger
idx
,
BOOL
*
stop
)
{
if
(
total
==
0
){
[
endPercentages
addObject
:
@
(
1
.
0
/
_items
.
count
*
(
idx
+
1
))];
}
else
{
currentTotal
+=
item
.
value
;
[
endPercentages
addObject
:
@
(
currentTotal
/
total
)];
}
}];
self
.
endPercentages
=
[
endPercentages
copy
];
[
_contentView
removeFromSuperview
];
_contentView
=
[[
UIView
alloc
]
initWithFrame
:
self
.
bounds
];
[
self
addSubview
:
_contentView
];
[
_descriptionLabels
removeAllObjects
];
_descriptionLabels
=
[
NSMutableArray
new
];
_pieLayer
=
[
CAShapeLayer
layer
];
...
...
@@ -78,39 +88,30 @@
-
(
void
)
strokeChart
{
[
self
loadDefault
];
[
self
.
items
enumerateObjectsUsingBlock
:
^
(
id
obj
,
NSUInteger
idx
,
BOOL
*
stop
)
{
_total
+=
((
PNPieChartDataItem
*
)
obj
).
value
;
}];
PNPieChartDataItem
*
currentItem
;
CGFloat
currentValue
=
0
;
for
(
int
i
=
0
;
i
<
_items
.
count
;
i
++
)
{
currentItem
=
[
self
dataItemForIndex
:
i
];
CGFloat
startPercnetage
=
currentValue
/
_total
;
CGFloat
endPercentage
=
(
currentValue
+
currentItem
.
value
)
/
_total
;
CGFloat
startPercnetage
=
[
self
startPercentageForItemAtIndex
:
i
]
;
CGFloat
endPercentage
=
[
self
endPercentageForItemAtIndex
:
i
]
;
CAShapeLayer
*
currentPieLayer
=
[
self
newCircleLayerWithRadius
:
_innerCircleRadius
+
(
_outerCircleRadius
-
_innerCircleRadius
)
/
2
borderWidth
:
_outerCircleRadius
-
_innerCircleRadius
CGFloat
radius
=
_innerCircleRadius
+
(
_outerCircleRadius
-
_innerCircleRadius
)
/
2
;
CGFloat
borderWidth
=
_outerCircleRadius
-
_innerCircleRadius
;
CAShapeLayer
*
currentPieLayer
=
[
self
newCircleLayerWithRadius
:
radius
borderWidth
:
borderWidth
fillColor
:
[
UIColor
clearColor
]
borderColor
:
currentItem
.
color
startPercentage
:
startPercnetage
endPercentage
:
endPercentage
];
[
_pieLayer
addSublayer
:
currentPieLayer
];
currentValue
+=
currentItem
.
value
;
}
[
self
maskChart
];
currentValue
=
0
;
for
(
int
i
=
0
;
i
<
_items
.
count
;
i
++
)
{
currentItem
=
[
self
dataItemForIndex
:
i
];
UILabel
*
descriptionLabel
=
[
self
descriptionLabelForItemAtIndex
:
i
];
[
_contentView
addSubview
:
descriptionLabel
];
currentValue
+=
currentItem
.
value
;
[
_descriptionLabels
addObject
:
descriptionLabel
];
}
}
...
...
@@ -118,19 +119,17 @@
-
(
UILabel
*
)
descriptionLabelForItemAtIndex
:
(
NSUInteger
)
index
{
PNPieChartDataItem
*
currentDataItem
=
[
self
dataItemForIndex
:
index
];
CGFloat
distance
=
_innerCircleRadius
+
(
_outerCircleRadius
-
_innerCircleRadius
)
/
2
;
CGFloat
centerPercentage
=
(
_currentTotal
+
currentDataItem
.
value
/
2
)
/
_total
;
CGFloat
centerPercentage
=
([
self
startPercentageForItemAtIndex
:
index
]
+
[
self
endPercentageForItemAtIndex
:
index
])
/
2
;
CGFloat
rad
=
centerPercentage
*
2
*
M_PI
;
_currentTotal
+=
currentDataItem
.
value
;
UILabel
*
descriptionLabel
=
[[
UILabel
alloc
]
initWithFrame
:
CGRectMake
(
0
,
0
,
100
,
80
)];
NSString
*
titleText
=
currentDataItem
.
textDescription
;
if
(
!
titleText
){
titleText
=
[
NSString
stringWithFormat
:
@"%.0f%%"
,
currentDataItem
.
value
/
_total
*
100
];
titleText
=
[
NSString
stringWithFormat
:
@"%.0f%%"
,
[
self
ratioForItemAtIndex
:
index
]
*
100
];
descriptionLabel
.
text
=
titleText
;
}
else
{
NSString
*
str
=
[
NSString
stringWithFormat
:
@"%.0f%%
\n
"
,
currentDataItem
.
value
/
_total
*
100
];
NSString
*
str
=
[
NSString
stringWithFormat
:
@"%.0f%%
\n
"
,
[
self
ratioForItemAtIndex
:
index
]
*
100
];
str
=
[
str
stringByAppendingString
:
titleText
];
descriptionLabel
.
text
=
str
;
}
...
...
@@ -158,6 +157,22 @@
return
self
.
items
[
index
];
}
-
(
CGFloat
)
startPercentageForItemAtIndex
:
(
NSUInteger
)
index
{
if
(
index
==
0
){
return
0
;
}
return
[
_endPercentages
[
index
-
1
]
floatValue
];
}
-
(
CGFloat
)
endPercentageForItemAtIndex
:
(
NSUInteger
)
index
{
return
[
_endPercentages
[
index
]
floatValue
];
}
-
(
CGFloat
)
ratioForItemAtIndex
:
(
NSUInteger
)
index
{
return
[
self
endPercentageForItemAtIndex
:
index
]
-
[
self
startPercentageForItemAtIndex
:
index
];
}
#pragma mark private methods
-
(
CAShapeLayer
*
)
newCircleLayerWithRadius
:
(
CGFloat
)
radius
...
...
@@ -188,8 +203,10 @@
}
-
(
void
)
maskChart
{
CAShapeLayer
*
maskLayer
=
[
self
newCircleLayerWithRadius
:
_innerCircleRadius
+
(
_outerCircleRadius
-
_innerCircleRadius
)
/
2
borderWidth
:
_outerCircleRadius
-
_innerCircleRadius
CGFloat
radius
=
_innerCircleRadius
+
(
_outerCircleRadius
-
_innerCircleRadius
)
/
2
;
CGFloat
borderWidth
=
_outerCircleRadius
-
_innerCircleRadius
;
CAShapeLayer
*
maskLayer
=
[
self
newCircleLayerWithRadius
:
radius
borderWidth
:
borderWidth
fillColor
:
[
UIColor
clearColor
]
borderColor
:
[
UIColor
blackColor
]
startPercentage
:
0
...
...
Please
register
or
login
to post a comment