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
andi
2015-03-04 08:53:34 +0100
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
865bd3b5a3c331cbd6120aac76fa5d8cbb38a66b
865bd3b5
2 parents
a2dc6a6d
22e9eb78
merge
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
137 additions
and
40 deletions
PNChart/PNCircleChart.m
PNChart/PNLineChart.m
PNChart/PNPieChart.m
PNChart/PNPieChartDataItem.m
PNChart/PNScatterChart.m
README.md
PNChart/PNCircleChart.m
View file @
865bd3b
...
...
@@ -157,7 +157,7 @@ displayCountingLabel:(BOOL)displayCountingLabel
[
_circle
addAnimation
:
pathAnimation
forKey
:
@"strokeEndAnimation"
];
_circle
.
strokeEnd
=
[
_current
floatValue
]
/
[
_total
floatValue
];
[
_countingLabel
countFrom
:
0
to
:[
_current
floatValue
]
withDuration
:
self
.
duration
];
[
_countingLabel
countFrom
:
0
to
:[
_current
floatValue
]
/
([
_total
floatValue
]
/
100
.
0
)
withDuration
:
self
.
duration
];
// Check if user wants to add a gradient from the start color to the bar color
...
...
PNChart/PNLineChart.m
View file @
865bd3b
...
...
@@ -104,6 +104,20 @@
}
}
-
(
CGFloat
)
computeEqualWidthForXLabels
:(
NSArray
*
)
xLabels
{
CGFloat
xLabelWidth
;
if
(
_showLabel
)
{
xLabelWidth
=
_chartCavanWidth
/
[
xLabels
count
];
}
else
{
xLabelWidth
=
(
self
.
frame
.
size
.
width
)
/
[
xLabels
count
];
}
return
xLabelWidth
;
}
-
(
void
)
setXLabels
:(
NSArray
*
)
xLabels
{
CGFloat
xLabelWidth
;
...
...
PNChart/PNPieChart.m
View file @
865bd3b
...
...
@@ -12,9 +12,8 @@
@interface
PNPieChart
()
@property
(
nonatomic
,
readwrite
)
NSArray
*
items
;
@property
(
nonatomic
)
CGFloat
total
;
@property
(
nonatomic
)
CGFloat
currentTotal
;
@property
(
nonatomic
)
NSArray
*
items
;
@property
(
nonatomic
)
NSArray
*
endPercentages
;
@property
(
nonatomic
)
CGFloat
outerCircleRadius
;
@property
(
nonatomic
)
CGFloat
innerCircleRadius
;
...
...
@@ -23,10 +22,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
...
...
@@ -45,8 +48,8 @@
self
=
[
self
initWithFrame
:
frame
];
if
(
self
){
_items
=
[
NSArray
arrayWithArray
:
items
];
_outerCircleRadius
=
CGRectGetWidth
(
self
.
bounds
)
/
2
;
_innerCircleRadius
=
CGRectGetWidth
(
self
.
bounds
)
/
6
;
_outerCircleRadius
=
CGRectGetWidth
(
self
.
bounds
)
/
2
;
_innerCircleRadius
=
CGRectGetWidth
(
self
.
bounds
)
/
6
;
_descriptionTextColor
=
[
UIColor
whiteColor
];
_descriptionTextFont
=
[
UIFont
fontWithName
:
@"Avenir-Medium"
size
:
18
.
0
];
...
...
@@ -60,15 +63,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
];
...
...
@@ -80,39 +91,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
];
}
}
...
...
@@ -120,11 +122,9 @@
-
(
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
;
NSString
*
titleValue
;
...
...
@@ -132,7 +132,7 @@
if
(
self
.
showAbsoluteValues
)
{
titleValue
=
[
NSString
stringWithFormat
:
@"%.0f"
,
currentDataItem
.
value
];
}
else
{
titleValue
=
[
NSString
stringWithFormat
:
@"%.0f%%"
,
currentDataItem
.
value
/
_total
*
100
];
titleValue
=
[
NSString
stringWithFormat
:
@"%.0f%%"
,
[
self
ratioForItemAtIndex
:
index
]
*
100
];
}
if
(
!
titleText
||
self
.
showOnlyValues
){
descriptionLabel
.
text
=
titleValue
;
...
...
@@ -147,8 +147,7 @@
descriptionLabel
.
font
=
_descriptionTextFont
;
CGSize
labelSize
=
[
descriptionLabel
.
text
sizeWithAttributes
:@{
NSFontAttributeName
:
descriptionLabel
.
font
}];
descriptionLabel
.
frame
=
CGRectMake
(
descriptionLabel
.
frame
.
origin
.
x
,
descriptionLabel
.
frame
.
origin
.
y
,
descriptionLabel
.
frame
=
CGRectMake
(
descriptionLabel
.
frame
.
origin
.
x
,
descriptionLabel
.
frame
.
origin
.
y
,
descriptionLabel
.
frame
.
size
.
width
,
labelSize
.
height
);
descriptionLabel
.
numberOfLines
=
0
;
descriptionLabel
.
textColor
=
_descriptionTextColor
;
...
...
@@ -165,6 +164,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
...
...
@@ -190,13 +205,14 @@
circle
.
lineWidth
=
borderWidth
;
circle
.
path
=
path
.
CGPath
;
return
circle
;
}
-
(
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
...
...
@@ -213,13 +229,16 @@
[
maskLayer
addAnimation
:
animation
forKey
:
@"circleAnimation"
];
}
-
(
void
)
createArcAnimationForLayer
:
(
CAShapeLayer
*
)
layer
ForKey
:
(
NSString
*
)
key
fromValue
:
(
NSNumber
*
)
from
toValue
:
(
NSNumber
*
)
to
Delegate
:
(
id
)
delegate
{
-
(
void
)
createArcAnimationForLayer
:
(
CAShapeLayer
*
)
layer
forKey
:
(
NSString
*
)
key
fromValue
:
(
NSNumber
*
)
from
toValue
:
(
NSNumber
*
)
to
delegate
:
(
id
)
delegate
{
CABasicAnimation
*
arcAnimation
=
[
CABasicAnimation
animationWithKeyPath
:
key
];
arcAnimation
.
fromValue
=
@0
;
[
arcAnimation
setToValue
:
to
]
;
[
arcAnimation
setDelegate
:
delegate
]
;
[
arcAnimation
setTimingFunction
:[
CAMediaTimingFunction
functionWithName
:
kCAMediaTimingFunctionDefault
]
];
arcAnimation
.
toValue
=
to
;
arcAnimation
.
delegate
=
delegate
;
arcAnimation
.
timingFunction
=
[
CAMediaTimingFunction
functionWithName
:
kCAMediaTimingFunctionDefault
];
[
layer
addAnimation
:
arcAnimation
forKey
:
key
];
[
layer
setValue
:
to
forKey
:
key
];
}
...
...
PNChart/PNPieChartDataItem.m
View file @
865bd3b
...
...
@@ -27,4 +27,11 @@
return
item
;
}
-
(
void
)
setValue
:(
CGFloat
)
value
{
NSAssert
(
value
>=
0
,
@"value should >= 0"
);
if
(
value
!=
_value
){
_value
=
value
;
}
}
@end
...
...
PNChart/PNScatterChart.m
View file @
865bd3b
...
...
@@ -156,6 +156,24 @@
}
}
-
(
NSArray
*
)
getAxisMinMax
:
(
NSArray
*
)
xValues
{
float
min
=
[
xValues
[
0
]
floatValue
];
float
max
=
[
xValues
[
0
]
floatValue
];
for
(
NSNumber
*
number
in
xValues
)
{
if
([
number
floatValue
]
>
max
)
max
=
[
number
floatValue
];
if
([
number
floatValue
]
<
min
)
min
=
[
number
floatValue
];
}
NSArray
*
result
=
@[[
NSNumber
numberWithFloat
:
min
],
[
NSNumber
numberWithFloat
:
max
]];
return
result
;
}
-
(
void
)
setAxisXLabel
:
(
NSArray
*
)
array
{
if
(
array
.
count
==
++
_AxisX_partNumber
){
[
_axisX_labels
removeAllObjects
];
...
...
README.md
View file @
865bd3b
...
...
@@ -64,7 +64,6 @@ data02.getData = ^(NSUInteger index) {
lineChart.chartData = @[data01, data02];
[lineChart strokeChart];
```
[

](https://dl.dropboxusercontent.com/u/1599662/bar.png)
...
...
@@ -150,6 +149,46 @@ CGPoint end = CGPointMake(80, 45);
scatterChart.delegate = self;
```
#### Legend
Legend has been added to PNChart for Line and Pie Charts. Legend items position can be stacked or in series.
[](https://dl.dropboxusercontent.com/u/4904447/pnchart_legend_1.png)
[](https://dl.dropboxusercontent.com/u/4904447/pnchart_legend_2.png)
```
objective-c
#import "PNChart.h"
//For Line Chart
//Add Line Titles for the Legend
data01.dataTitle = @"Alpha";
data02.dataTitle = @"Beta Beta Beta Beta";
//Build the legend
self.lineChart.legendStyle = PNLegendItemStyleSerial;
self.lineChart.legendFontSize = 12.0;
UIView
*
legend =
[
self.lineChart getLegendWithMaxWidth:320
]
;
//Move legend to the desired position and add to view
[
legend setFrame:CGRectMake(100, 400, legend.frame.size.width, legend.frame.size.height)
]
;
[
self.view addSubview:legend
]
;
//For Pie Chart
//Build the legend
self.pieChart.legendStyle = PNLegendItemStyleStacked;
self.pieChart.legendFontSize = 12.0;
UIView
*
legend =
[
self.pieChart getLegendWithMaxWidth:200
]
;
//Move legend to the desired position and add to view
[
legend setFrame:CGRectMake(130, 350, legend.frame.size.width, legend.frame.size.height)
]
;
[
self.view addSubview:legend
]
;
```
#### Update Value
Now it's easy to update value in real time
...
...
Please
register
or
login
to post a comment