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
Kevin
2015-03-14 00:17:23 +0800
Browse Files
Options
Browse Files
Download
Plain Diff
Commit
8cf1b7c8003058313627bc09c3896a2cfd3b0da1
8cf1b7c8
2 parents
fb079043
a5352435
Merge pull request #176 from sanandrea/master
Interactive Pie
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
138 additions
and
54 deletions
PNChart/PNChartDelegate.h
PNChart/PNGenericChart.h
PNChart/PNGenericChart.m
PNChart/PNLineChart.m
PNChart/PNPieChart.h
PNChart/PNPieChart.m
PNChartDemo/PCChartViewController.m
PNChart/PNChartDelegate.h
View file @
8cf1b7c
...
...
@@ -27,4 +27,7 @@
*/
-
(
void
)
userClickedOnBarAtIndex
:(
NSInteger
)
barIndex
;
-
(
void
)
userClickedOnPieIndexItem
:(
NSInteger
)
pieIndex
;
-
(
void
)
didUnselectPieItem
;
@end
...
...
PNChart/PNGenericChart.h
View file @
8cf1b7c
...
...
@@ -25,6 +25,7 @@ typedef NS_ENUM(NSUInteger, PNLegendItemStyle) {
@property
(
assign
,
nonatomic
)
BOOL
hasLegend
;
@property
(
assign
,
nonatomic
)
PNLegendPosition
legendPosition
;
@property
(
assign
,
nonatomic
)
PNLegendItemStyle
legendStyle
;
@property
(
assign
,
nonatomic
)
NSUInteger
labelRowsInSerialMode
;
@property
(
assign
,
nonatomic
)
CGFloat
legendFontSize
;
/**
...
...
@@ -37,4 +38,6 @@ typedef NS_ENUM(NSUInteger, PNLegendItemStyle) {
*/
-
(
UIView
*
)
getLegendWithMaxWidth
:(
CGFloat
)
mWidth
;
-
(
void
)
setupDefaultValues
;
@end
...
...
PNChart/PNGenericChart.m
View file @
8cf1b7c
...
...
@@ -24,37 +24,11 @@
}
*/
-
(
UIView
*
)
drawLegend
{
return
nil
;
}
-
(
id
)
initWithCoder
:
(
NSCoder
*
)
coder
{
self
=
[
super
initWithCoder
:
coder
];
if
(
self
)
{
[
self
setupDefaultValues
];
}
return
self
;
}
-
(
id
)
initWithFrame
:
(
CGRect
)
frame
{
self
=
[
super
initWithFrame
:
frame
];
if
(
self
)
{
[
self
setupDefaultValues
];
}
return
self
;
}
-
(
void
)
setupDefaultValues
{
self
.
hasLegend
=
YES
;
self
.
legendPosition
=
PNLegendPositionBottom
;
self
.
legendStyle
=
PNLegendItemStyleStacked
;
self
.
labelRowsInSerialMode
=
1
;
}
...
...
@@ -67,6 +41,13 @@
return
nil
;
}
-
(
void
)
setLabelRowsInSerialMode
:
(
NSUInteger
)
num
{
if
(
self
.
legendStyle
==
PNLegendItemStyleSerial
)
{
_labelRowsInSerialMode
=
num
;
}
else
{
_labelRowsInSerialMode
=
1
;
}
}
@end
...
...
PNChart/PNLineChart.m
View file @
8cf1b7c
...
...
@@ -66,7 +66,6 @@
_yChartLabels
=
[
NSMutableArray
new
];
}
#warning modify origin
if
(
yStep
==
0
.
0
)
{
PNChartLabel
*
minLabel
=
[[
PNChartLabel
alloc
]
initWithFrame
:
CGRectMake
(
0
.
0
,
(
NSInteger
)
_chartCavanHeight
,
(
NSInteger
)
_chartMargin
,
(
NSInteger
)
_yLabelHeight
)];
minLabel
.
text
=
[
NSString
stringWithFormat
:
yLabelFormat
,
0
.
0
];
...
...
@@ -197,7 +196,6 @@
for
(
int
index
=
0
;
index
<
xLabels
.
count
;
index
++
)
{
labelText
=
xLabels
[
index
];
#warning modify origin
NSInteger
x
=
2
*
_chartMargin
+
(
index
*
_xLabelWidth
)
-
(
_xLabelWidth
/
2
);
NSInteger
y
=
_chartMargin
+
_chartCavanHeight
;
...
...
@@ -403,7 +401,6 @@
CGFloat
offSetX
=
(
_chartCavanWidth
)
/
(
chartData
.
itemCount
);
#warning modify chart path
int
x
=
2
*
_chartMargin
+
(
i
*
offSetX
);
int
y
=
_chartCavanHeight
-
(
innerGrade
*
_chartCavanHeight
)
+
(
_yLabelHeight
/
2
);
...
...
@@ -652,7 +649,6 @@
-
(
void
)
drawRect
:
(
CGRect
)
rect
{
if
(
self
.
isShowCoordinateAxis
)
{
#warning modify
CGFloat
yAxisOffset
=
10
.
f
;
CGContextRef
ctx
=
UIGraphicsGetCurrentContext
();
...
...
@@ -726,6 +722,7 @@
-
(
void
)
setupDefaultValues
{
[
super
setupDefaultValues
];
// Initialization code
self
.
backgroundColor
=
[
UIColor
whiteColor
];
self
.
clipsToBounds
=
YES
;
...
...
@@ -807,15 +804,15 @@
CGFloat
x
=
0
;
CGFloat
y
=
0
;
/* accumulated width and height */
CGFloat
totalWidth
=
0
;
/* accumulated height */
CGFloat
totalHeight
=
0
;
NSMutableArray
*
legendViews
=
[[
NSMutableArray
alloc
]
init
];
NSUInteger
numLabelsPerRow
=
ceil
((
float
)[
self
.
chartData
count
]
/
self
.
labelRowsInSerialMode
);
/* Determine the max width of each legend item */
CGFloat
maxLabelWidth
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
(
mWidth
-
legendLineWidth
)
:
(
mWidth
/
[
self
.
chartData
count
]
-
legendLineWidth
);
CGFloat
maxLabelWidth
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
(
mWidth
-
legendLineWidth
)
:
(
mWidth
/
numLabelsPerRow
-
legendLineWidth
);
/* this is used when labels wrap text and the line
* should be in the middle of the first row */
...
...
@@ -823,6 +820,9 @@
withWidth
:
MAXFLOAT
font
:
[
UIFont
systemFontOfSize
:
self
.
legendFontSize
]].
height
;
NSUInteger
counter
=
0
;
NSUInteger
rowMaxHeight
=
0
;
for
(
PNLineChartData
*
pdata
in
self
.
chartData
)
{
/* Expected label size*/
CGSize
labelsize
=
[
PNLineChart
sizeOfString
:
pdata
.
dataTitle
...
...
@@ -831,6 +831,11 @@
/* draw lines */
if
(
counter
!=
0
&&
counter
%
numLabelsPerRow
==
0
)
{
x
=
0
;
y
+=
rowMaxHeight
;
rowMaxHeight
=
0
;
}
/* If there is inflection decorator, the line is composed of two lines
* and this is the space that separates two lines in order to put inflection
...
...
@@ -872,16 +877,18 @@
label
.
font
=
[
UIFont
systemFontOfSize
:
self
.
legendFontSize
];
label
.
lineBreakMode
=
NSLineBreakByWordWrapping
;
label
.
numberOfLines
=
0
;
rowMaxHeight
=
fmaxf
(
rowMaxHeight
,
labelsize
.
height
);
x
+=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
0
:
labelsize
.
width
+
legendLineWidth
;
y
+=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
labelsize
.
height
:
0
;
totalWidth
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
fmaxf
(
totalWidth
,
labelsize
.
width
+
legendLineWidth
)
:
totalWidth
+
labelsize
.
width
+
legendLineWidth
;
totalHeight
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
fmaxf
(
totalHeight
,
labelsize
.
height
)
:
totalHeight
+
labelsize
.
height
;
[
legendViews
addObject
:
label
];
totalHeight
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
fmaxf
(
totalHeight
,
rowMaxHeight
+
y
)
:
totalHeight
+
labelsize
.
height
;
[
legendViews
addObject
:
label
];
counter
++
;
}
UIView
*
legend
=
[[
UIView
alloc
]
initWithFrame
:
CGRectMake
(
0
,
0
,
total
Width
,
totalHeight
)];
UIView
*
legend
=
[[
UIView
alloc
]
initWithFrame
:
CGRectMake
(
0
,
0
,
m
Width
,
totalHeight
)];
for
(
UIView
*
v
in
legendViews
)
{
[
legend
addSubview
:
v
];
...
...
PNChart/PNPieChart.h
View file @
8cf1b7c
...
...
@@ -9,6 +9,7 @@
#import <UIKit/UIKit.h>
#import "PNPieChartDataItem.h"
#import "PNGenericChart.h"
#import "PNChartDelegate.h"
@interface
PNPieChart
:
PNGenericChart
...
...
@@ -34,10 +35,11 @@
/** Show only values, this is useful when legend is present */
@property
(
nonatomic
)
BOOL
showOnlyValues
;
/** Show absolute values not relative i.e. percentages */
@property
(
nonatomic
)
BOOL
showAbsoluteValues
;
@property
(
nonatomic
,
weak
)
id
<
PNChartDelegate
>
delegate
;
-
(
void
)
strokeChart
;
@end
...
...
PNChart/PNPieChart.m
View file @
8cf1b7c
...
...
@@ -21,7 +21,7 @@
@property
(
nonatomic
)
UIView
*
contentView
;
@property
(
nonatomic
)
CAShapeLayer
*
pieLayer
;
@property
(
nonatomic
)
NSMutableArray
*
descriptionLabels
;
@property
(
strong
,
nonatomic
)
CAShapeLayer
*
sectorHighlight
;
-
(
void
)
loadDefault
;
...
...
@@ -57,6 +57,7 @@
_descriptionTextShadowOffset
=
CGSizeMake
(
0
,
1
);
_duration
=
1
.
0
;
[
super
setupDefaultValues
];
[
self
loadDefault
];
}
...
...
@@ -101,6 +102,7 @@
CGFloat
radius
=
_innerCircleRadius
+
(
_outerCircleRadius
-
_innerCircleRadius
)
/
2
;
CGFloat
borderWidth
=
_outerCircleRadius
-
_innerCircleRadius
;
CAShapeLayer
*
currentPieLayer
=
[
self
newCircleLayerWithRadius
:
radius
borderWidth
:
borderWidth
fillColor
:
[
UIColor
clearColor
]
...
...
@@ -251,13 +253,78 @@
}];
}
-
(
void
)
didTouchAt
:
(
CGPoint
)
touchLocation
{
CGPoint
circleCenter
=
CGPointMake
(
_contentView
.
bounds
.
size
.
width
/
2
,
_contentView
.
bounds
.
size
.
height
/
2
);
CGFloat
distanceFromCenter
=
sqrtf
(
powf
((
touchLocation
.
y
-
circleCenter
.
y
),
2
)
+
powf
((
touchLocation
.
x
-
circleCenter
.
x
),
2
));
if
(
distanceFromCenter
<
_innerCircleRadius
)
{
if
([
self
.
delegate
respondsToSelector
:
@selector
(
didUnselectPieItem
)])
{
[
self
.
delegate
didUnselectPieItem
];
}
[
self
.
sectorHighlight
removeFromSuperlayer
];
return
;
}
CGFloat
percentage
=
[
self
findPercentageOfAngleInCircle
:
circleCenter
fromPoint
:
touchLocation
];
int
index
=
0
;
while
(
percentage
>
[
self
endPercentageForItemAtIndex
:
index
])
{
index
++
;
}
if
([
self
.
delegate
respondsToSelector
:
@selector
(
userClickedOnPieIndexItem
:)])
{
[
self
.
delegate
userClickedOnPieIndexItem
:
index
];
}
if
(
self
.
sectorHighlight
)
{
[
self
.
sectorHighlight
removeFromSuperlayer
];
}
PNPieChartDataItem
*
currentItem
=
[
self
dataItemForIndex
:
index
];
CGFloat
red
,
green
,
blue
,
alpha
;
UIColor
*
old
=
currentItem
.
color
;
[
old
getRed
:
&
red
green
:
&
green
blue
:&
blue
alpha
:&
alpha
];
alpha
/=
2
;
UIColor
*
newColor
=
[
UIColor
colorWithRed
:
red
green
:
green
blue
:
blue
alpha
:
alpha
];
CGFloat
startPercnetage
=
[
self
startPercentageForItemAtIndex
:
index
];
CGFloat
endPercentage
=
[
self
endPercentageForItemAtIndex
:
index
];
self
.
sectorHighlight
=
[
self
newCircleLayerWithRadius
:
_outerCircleRadius
+
5
borderWidth
:
10
fillColor
:
[
UIColor
clearColor
]
borderColor
:
newColor
startPercentage
:
startPercnetage
endPercentage
:
endPercentage
];
[
_contentView
.
layer
addSublayer
:
self
.
sectorHighlight
];
}
-
(
void
)
touchesBegan
:
(
NSSet
*
)
touches
withEvent
:
(
UIEvent
*
)
event
{
for
(
UITouch
*
touch
in
touches
)
{
CGPoint
touchLocation
=
[
touch
locationInView
:
_contentView
];
[
self
didTouchAt
:
touchLocation
];
}
}
-
(
CGFloat
)
findPercentageOfAngleInCircle
:
(
CGPoint
)
center
fromPoint
:
(
CGPoint
)
reference
{
//Find angle of line Passing In Reference And Center
CGFloat
angleOfLine
=
atanf
((
reference
.
y
-
center
.
y
)
/
(
reference
.
x
-
center
.
x
));
CGFloat
percentage
=
(
angleOfLine
+
M_PI
/
2
)
/
(
2
*
M_PI
);
return
(
reference
.
x
-
center
.
x
)
>
0
?
percentage
:
percentage
+
.
5
;
}
-
(
UIView
*
)
getLegendWithMaxWidth
:
(
CGFloat
)
mWidth
{
if
([
self
.
items
count
]
<
1
)
{
return
nil
;
}
/* This is a small circle that refers to the chart data */
CGFloat
legendCircle
=
10
;
CGFloat
legendCircle
=
16
;
CGFloat
hSpacing
=
0
;
CGFloat
beforeLabel
=
legendCircle
+
hSpacing
;
/* x and y are the coordinates of the starting point of each legend item */
CGFloat
x
=
0
;
...
...
@@ -269,9 +336,13 @@
NSMutableArray
*
legendViews
=
[[
NSMutableArray
alloc
]
init
];
/* Determine the max width of each legend item */
CGFloat
maxLabelWidth
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
(
mWidth
-
legendCircle
)
:
(
mWidth
/
[
self
.
items
count
]
-
legendCircle
);
CGFloat
maxLabelWidth
;
if
(
self
.
legendStyle
==
PNLegendItemStyleStacked
)
{
maxLabelWidth
=
mWidth
-
beforeLabel
;
}
else
{
maxLabelWidth
=
MAXFLOAT
;
}
/* this is used when labels wrap text and the line
* should be in the middle of the first row */
...
...
@@ -279,29 +350,45 @@
withWidth
:
MAXFLOAT
font
:
[
UIFont
systemFontOfSize
:
self
.
legendFontSize
]].
height
;
NSUInteger
counter
=
0
;
NSUInteger
rowWidth
=
0
;
NSUInteger
rowMaxHeight
=
0
;
for
(
PNPieChartDataItem
*
pdata
in
self
.
items
)
{
/* Expected label size*/
CGSize
labelsize
=
[
PNLineChart
sizeOfString
:
pdata
.
textDescription
withWidth
:
maxLabelWidth
font
:
[
UIFont
systemFontOfSize
:
self
.
legendFontSize
]];
if
((
rowWidth
+
labelsize
.
width
+
beforeLabel
>
mWidth
)
&&
(
self
.
legendStyle
==
PNLegendItemStyleSerial
))
{
rowWidth
=
0
;
x
=
0
;
y
+=
rowMaxHeight
;
rowMaxHeight
=
0
;
}
rowWidth
+=
labelsize
.
width
+
beforeLabel
;
totalWidth
=
self
.
legendStyle
==
PNLegendItemStyleSerial
?
fmaxf
(
rowWidth
,
totalWidth
)
:
fmaxf
(
totalWidth
,
labelsize
.
width
+
beforeLabel
);
// Add inflexion type
[
legendViews
addObject
:[
self
drawInflexion
:
legendCircle
*
.
8
[
legendViews
addObject
:[
self
drawInflexion
:
legendCircle
*
.
6
center
:
CGPointMake
(
x
+
legendCircle
/
2
,
y
+
singleRowHeight
/
2
)
andColor
:
pdata
.
color
]];
UILabel
*
label
=
[[
UILabel
alloc
]
initWithFrame
:
CGRectMake
(
x
+
legendCircle
,
y
,
maxLabelWidth
,
labelsize
.
height
)];
UILabel
*
label
=
[[
UILabel
alloc
]
initWithFrame
:
CGRectMake
(
x
+
beforeLabel
,
y
,
labelsize
.
width
,
labelsize
.
height
)];
label
.
text
=
pdata
.
textDescription
;
label
.
font
=
[
UIFont
systemFontOfSize
:
self
.
legendFontSize
];
label
.
lineBreakMode
=
NSLineBreakByWordWrapping
;
label
.
numberOfLines
=
0
;
x
+=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
0
:
labelsize
.
width
+
legendCircle
;
rowMaxHeight
=
fmaxf
(
rowMaxHeight
,
labelsize
.
height
);
x
+=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
0
:
labelsize
.
width
+
beforeLabel
;
y
+=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
labelsize
.
height
:
0
;
totalWidth
=
self
.
legendStyle
==
PNLegendItemStyleStacked
?
fmaxf
(
totalWidth
,
labelsize
.
width
+
legendCircle
)
:
totalWidth
+
labelsize
.
width
+
legendCircle
;
totalHeight
=
self
.
legendStyle
==
PNLegendItemStyleS
tacked
?
fmaxf
(
totalHeight
,
labelsize
.
height
)
:
totalHeight
+
labelsize
.
height
;
totalHeight
=
self
.
legendStyle
==
PNLegendItemStyleS
erial
?
fmaxf
(
totalHeight
,
rowMaxHeight
+
y
)
:
totalHeight
+
labelsize
.
height
;
[
legendViews
addObject
:
label
];
counter
++
;
}
UIView
*
legend
=
[[
UIView
alloc
]
initWithFrame
:
CGRectMake
(
0
,
0
,
totalWidth
,
totalHeight
)];
...
...
PNChartDemo/PCChartViewController.m
View file @
8cf1b7c
...
...
@@ -20,6 +20,7 @@
self
.
rightSwitch
.
hidden
=
YES
;
self
.
leftLabel
.
hidden
=
YES
;
self
.
rightLabel
.
hidden
=
YES
;
self
.
changeValueButton
.
hidden
=
YES
;
if
([
self
.
title
isEqualToString
:
@"Line Chart"
])
{
...
...
@@ -67,7 +68,7 @@
data02
.
color
=
PNTwitterColor
;
data02
.
alpha
=
0
.
5
f
;
data02
.
itemCount
=
data02Array
.
count
;
data02
.
inflexionPointStyle
=
PNLineChartPointStyle
Non
e
;
data02
.
inflexionPointStyle
=
PNLineChartPointStyle
Circl
e
;
data02
.
getData
=
^
(
NSUInteger
index
)
{
CGFloat
yValue
=
[
data02Array
[
index
]
floatValue
];
return
[
PNLineChartDataItem
dataItemWithY
:
yValue
];
...
...
@@ -79,11 +80,11 @@
[
self
.
view
addSubview
:
self
.
lineChart
];
self
.
lineChart
.
legendStyle
=
PNLegendItemStyleS
tacked
;
self
.
lineChart
.
legendStyle
=
PNLegendItemStyleS
erial
;
self
.
lineChart
.
legendFontSize
=
12
.
0
;
UIView
*
legend
=
[
self
.
lineChart
getLegendWithMaxWidth
:
20
0
];
[
legend
setFrame
:
CGRectMake
(
100
,
40
0
,
legend
.
frame
.
size
.
width
,
legend
.
frame
.
size
.
width
)];
UIView
*
legend
=
[
self
.
lineChart
getLegendWithMaxWidth
:
32
0
];
[
legend
setFrame
:
CGRectMake
(
30
,
34
0
,
legend
.
frame
.
size
.
width
,
legend
.
frame
.
size
.
width
)];
[
self
.
view
addSubview
:
legend
];
}
else
if
([
self
.
title
isEqualToString
:
@"Bar Chart"
])
...
...
@@ -156,7 +157,7 @@
self
.
pieChart
.
legendFontSize
=
12
.
0
;
UIView
*
legend
=
[
self
.
pieChart
getLegendWithMaxWidth
:
200
];
[
legend
setFrame
:
CGRectMake
(
1
00
,
400
,
legend
.
frame
.
size
.
width
,
legend
.
frame
.
size
.
width
)];
[
legend
setFrame
:
CGRectMake
(
1
30
,
350
,
legend
.
frame
.
size
.
width
,
legend
.
frame
.
size
.
height
)];
[
self
.
view
addSubview
:
legend
];
[
self
.
view
addSubview
:
self
.
pieChart
];
...
...
Please
register
or
login
to post a comment