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
xujunwen
2014-05-28 20:24:50 +0800
Browse Files
Options
Browse Files
Download
Email Patches
Plain Diff
Commit
0cb78e589023a4c6a680a9fcd4d9e3b4215717cd
0cb78e58
1 parent
a45ea1e6
PNLineChart's inflexion Point support two sharp, such as cycle, square
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
173 additions
and
24 deletions
PNChart/PNLineChart/PNLineChart.h
PNChart/PNLineChart/PNLineChart.m
PNChart/PNLineChart/PNLineChartData.h
PNChart/PNLineChart/PNLineChartData.m
PNChartDemo/PCChartsTableViewController.m
PNChart/PNLineChart/PNLineChart.h
View file @
0cb78e5
...
...
@@ -10,7 +10,6 @@
#import <QuartzCore/QuartzCore.h>
#import "PNChartDelegate.h"
@interface
PNLineChart
:
UIView
/**
...
...
@@ -48,8 +47,6 @@
@property
(
nonatomic
)
CGFloat
chartMargin
;
@property
(
nonatomic
)
BOOL
showLabel
;
...
...
PNChart/PNLineChart/PNLineChart.m
View file @
0cb78e5
...
...
@@ -18,9 +18,11 @@
//------------------------------------------------------------------------------------------------
@interface
PNLineChart
()
@property
(
nonatomic
)
NSMutableArray
*
chartLineArray
;
// Array[CAShapeLayer]
@property
(
nonatomic
)
NSMutableArray
*
chartLineArray
;
// Array[CAShapeLayer]
@property
(
nonatomic
)
NSMutableArray
*
chartPointArray
;
// Array[CAShapeLayer] save the point layer
@property
(
nonatomic
)
NSMutableArray
*
chartPath
;
//Array of line path, one for each line.
@property
(
nonatomic
)
NSMutableArray
*
chartPath
;
// Array of line path, one for each line.
@property
(
nonatomic
)
NSMutableArray
*
pointPath
;
// Array of point path, one for each line
-
(
void
)
setDefaultValues
;
...
...
@@ -182,18 +184,29 @@
-
(
void
)
strokeChart
{
_chartPath
=
[[
NSMutableArray
alloc
]
init
];
_pointPath
=
[[
NSMutableArray
alloc
]
init
];
//Draw each line
for
(
NSUInteger
lineIndex
=
0
;
lineIndex
<
self
.
chartData
.
count
;
lineIndex
++
)
{
PNLineChartData
*
chartData
=
self
.
chartData
[
lineIndex
];
CAShapeLayer
*
chartLine
=
(
CAShapeLayer
*
)
self
.
chartLineArray
[
lineIndex
];
CAShapeLayer
*
pointLayer
=
(
CAShapeLayer
*
)
self
.
chartPointArray
[
lineIndex
];
CGFloat
yValue
;
CGFloat
innerGrade
;
CGPoint
point
;
UIGraphicsBeginImageContext
(
self
.
frame
.
size
);
UIBezierPath
*
progressline
=
[
UIBezierPath
bezierPath
];
[
progressline
setLineWidth
:
chartData
.
lineWidth
];
[
progressline
setLineCapStyle
:
kCGLineCapRound
];
[
progressline
setLineJoinStyle
:
kCGLineJoinRound
];
UIBezierPath
*
pointPath
=
[
UIBezierPath
bezierPath
];
[
pointPath
setLineWidth
:
chartData
.
lineWidth
];
[
_chartPath
addObject
:
progressline
];
[
_pointPath
addObject
:
pointPath
];
if
(
!
_showLabel
)
{
_chartCavanHeight
=
self
.
frame
.
size
.
height
-
2
*
_yLabelHeight
;
...
...
@@ -203,23 +216,91 @@
}
NSMutableArray
*
linePointsArray
=
[[
NSMutableArray
alloc
]
init
];
[
progressline
setLineWidth
:
3
.
0
];
[
progressline
setLineCapStyle
:
kCGLineCapRound
];
[
progressline
setLineJoinStyle
:
kCGLineJoinRound
];
int
last_x
=
0
;
int
last_y
=
0
;
CGFloat
circle_diameter
=
chartData
.
inflexionPointWidth
;
for
(
NSUInteger
i
=
0
;
i
<
chartData
.
itemCount
;
i
++
)
{
yValue
=
chartData
.
getData
(
i
).
y
;
innerGrade
=
(
yValue
-
_yValueMin
)
/
(
_yValueMax
-
_yValueMin
);
point
=
CGPointMake
(
2
*
_chartMargin
+
(
i
*
_xLabelWidth
),
_chartCavanHeight
-
(
innerGrade
*
_chartCavanHeight
)
+
(
_yLabelHeight
/
2
));
if
(
i
!=
0
)
{
[
progressline
addLineToPoint
:
point
];
int
x
=
2
*
_chartMargin
+
(
i
*
_xLabelWidth
);
int
y
=
_chartCavanHeight
-
(
innerGrade
*
_chartCavanHeight
)
+
(
_yLabelHeight
/
2
);
// cycle style point
if
(
chartData
.
inflexionPointStyle
==
PNLineChartPointStyleCycle
)
{
CGRect
circleRect
=
CGRectMake
(
x
-
circle_diameter
/
2
,
y
-
circle_diameter
/
2
,
circle_diameter
,
circle_diameter
);
CGPoint
circleCenter
=
CGPointMake
(
circleRect
.
origin
.
x
+
(
circleRect
.
size
.
width
/
2
),
circleRect
.
origin
.
y
+
(
circleRect
.
size
.
height
/
2
));
[
pointPath
moveToPoint
:
CGPointMake
(
circleCenter
.
x
+
(
circle_diameter
/
2
),
circleCenter
.
y
)];
[
pointPath
addArcWithCenter
:
circleCenter
radius
:
circle_diameter
/
2
startAngle
:
0
endAngle
:
2
*
M_PI
clockwise
:
YES
];
if
(
i
!=
0
)
{
// calculate the point for line
float
distance
=
sqrt
(
pow
(
x
-
last_x
,
2
)
+
pow
(
y
-
last_y
,
2
)
);
float
last_x1
=
last_x
+
(
circle_diameter
/
2
)
/
distance
*
(
x
-
last_x
);
float
last_y1
=
last_y
+
(
circle_diameter
/
2
)
/
distance
*
(
y
-
last_y
);
float
x1
=
x
-
(
circle_diameter
/
2
)
/
distance
*
(
x
-
last_x
);
float
y1
=
y
-
(
circle_diameter
/
2
)
/
distance
*
(
y
-
last_y
);
[
progressline
moveToPoint
:
CGPointMake
(
last_x1
,
last_y1
)];
[
progressline
addLineToPoint
:
CGPointMake
(
x1
,
y1
)];
}
last_x
=
x
;
last_y
=
y
;
}
[
progressline
moveToPoint
:
point
];
[
linePointsArray
addObject
:[
NSValue
valueWithCGPoint
:
point
]];
// Square style point
else
if
(
chartData
.
inflexionPointStyle
==
PNLineChartPointStyleSquare
)
{
CGRect
squareRect
=
CGRectMake
(
x
-
circle_diameter
/
2
,
y
-
circle_diameter
/
2
,
circle_diameter
,
circle_diameter
);
CGPoint
squareCenter
=
CGPointMake
(
squareRect
.
origin
.
x
+
(
squareRect
.
size
.
width
/
2
),
squareRect
.
origin
.
y
+
(
squareRect
.
size
.
height
/
2
));
[
pointPath
moveToPoint
:
CGPointMake
(
squareCenter
.
x
-
(
circle_diameter
/
2
),
squareCenter
.
y
-
(
circle_diameter
/
2
))];
[
pointPath
addLineToPoint
:
CGPointMake
(
squareCenter
.
x
+
(
circle_diameter
/
2
),
squareCenter
.
y
-
(
circle_diameter
/
2
))];
[
pointPath
addLineToPoint
:
CGPointMake
(
squareCenter
.
x
+
(
circle_diameter
/
2
),
squareCenter
.
y
+
(
circle_diameter
/
2
))];
[
pointPath
addLineToPoint
:
CGPointMake
(
squareCenter
.
x
-
(
circle_diameter
/
2
),
squareCenter
.
y
+
(
circle_diameter
/
2
))];
[
pointPath
closePath
];
if
(
i
!=
0
)
{
// calculate the point for line
float
distance
=
sqrt
(
pow
(
x
-
last_x
,
2
)
+
pow
(
y
-
last_y
,
2
)
);
float
last_x1
=
last_x
+
(
circle_diameter
/
2
);
float
last_y1
=
last_y
+
(
circle_diameter
/
2
)
/
distance
*
(
y
-
last_y
);
float
x1
=
x
-
(
circle_diameter
/
2
);
float
y1
=
y
-
(
circle_diameter
/
2
)
/
distance
*
(
y
-
last_y
);
[
progressline
moveToPoint
:
CGPointMake
(
last_x1
,
last_y1
)];
[
progressline
addLineToPoint
:
CGPointMake
(
x1
,
y1
)];
}
last_x
=
x
;
last_y
=
y
;
}
// Triangle style point
else
if
(
chartData
.
inflexionPointStyle
==
PNLineChartPointStyleTriangle
)
{
if
(
i
!=
0
)
{
[
progressline
addLineToPoint
:
CGPointMake
(
x
,
y
)];
}
[
progressline
moveToPoint
:
CGPointMake
(
x
,
y
)];
}
else
{
if
(
i
!=
0
)
{
[
progressline
addLineToPoint
:
CGPointMake
(
x
,
y
)];
}
[
progressline
moveToPoint
:
CGPointMake
(
x
,
y
)];
}
[
linePointsArray
addObject
:[
NSValue
valueWithCGPoint
:
CGPointMake
(
x
,
y
)]];
}
[
_pathPoints
addObject
:[
linePointsArray
copy
]];
...
...
@@ -227,29 +308,42 @@
// setup the color of the chart line
if
(
chartData
.
color
)
{
chartLine
.
strokeColor
=
[
chartData
.
color
CGColor
];
pointLayer
.
strokeColor
=
[
chartData
.
color
CGColor
];
}
else
{
chartLine
.
strokeColor
=
[
PNGreen
CGColor
];
pointLayer
.
strokeColor
=
[
PNGreen
CGColor
];
}
[
progressline
stroke
];
chartLine
.
path
=
progressline
.
CGPath
;
pointLayer
.
path
=
pointPath
.
CGPath
;
[
CATransaction
begin
];
CABasicAnimation
*
pathAnimation
=
[
CABasicAnimation
animationWithKeyPath
:
@"strokeEnd"
];
pathAnimation
.
duration
=
1
.
0
;
pathAnimation
.
timingFunction
=
[
CAMediaTimingFunction
functionWithName
:
kCAMediaTimingFunctionEaseInEaseOut
];
pathAnimation
.
fromValue
=
@0.0f
;
pathAnimation
.
toValue
=
@1.0f
;
[
chartLine
addAnimation
:
pathAnimation
forKey
:
@"strokeEndAnimation"
];
[
chartLine
addAnimation
:
pathAnimation
forKey
:
@"strokeEndAnimation"
];
chartLine
.
strokeEnd
=
1
.
0
;
if
(
chartData
.
inflexionPointStyle
==
PNLineChartPointStyleCycle
)
{
[
pointLayer
addAnimation
:
pathAnimation
forKey
:
@"strokeEndAnimation"
];
}
[
CATransaction
setCompletionBlock
:
^
{
//pointLayer.strokeEnd = 1.0f; // stroken point when animation end
}];
[
CATransaction
commit
];
UIGraphicsEndImageContext
();
}
}
-
(
void
)
setChartData
:
(
NSArray
*
)
data
{
if
(
data
!=
_chartData
)
{
...
...
@@ -262,20 +356,36 @@
for
(
CALayer
*
layer
in
self
.
chartLineArray
)
{
[
layer
removeFromSuperlayer
];
}
for
(
CALayer
*
layer
in
self
.
chartPointArray
)
{
[
layer
removeFromSuperlayer
];
}
self
.
chartLineArray
=
[
NSMutableArray
arrayWithCapacity
:
data
.
count
];
self
.
chartPointArray
=
[
NSMutableArray
arrayWithCapacity
:
data
.
count
];
// set for point stoken
float
circle_stroke_width
=
2
.
f
;
float
line_width
=
3
.
0
f
;
for
(
PNLineChartData
*
chartData
in
data
)
{
// create as many chart line layers as there are data-lines
CAShapeLayer
*
chartLine
=
[
CAShapeLayer
layer
];
chartLine
.
lineCap
=
kCALineCapRound
;
chartLine
.
lineJoin
=
kCALineJoinBevel
;
chartLine
.
fillColor
=
[[
UIColor
whiteColor
]
CGColor
];
chartLine
.
lineWidth
=
3
.
0
;
chartLine
.
lineWidth
=
line_width
;
chartLine
.
strokeEnd
=
0
.
0
;
[
self
.
layer
addSublayer
:
chartLine
];
[
self
.
chartLineArray
addObject
:
chartLine
];
// create point
CAShapeLayer
*
pointLayer
=
[
CAShapeLayer
layer
];
pointLayer
.
strokeColor
=
[
chartData
.
color
CGColor
];
pointLayer
.
fillColor
=
nil
;
pointLayer
.
lineWidth
=
circle_stroke_width
;
[
self
.
layer
addSublayer
:
pointLayer
];
[
self
.
chartPointArray
addObject
:
pointLayer
];
for
(
NSUInteger
i
=
0
;
i
<
chartData
.
itemCount
;
i
++
)
{
yValue
=
chartData
.
getData
(
i
).
y
;
[
yLabelsArray
addObject
:[
NSString
stringWithFormat
:
@"%2f"
,
yValue
]];
...
...
@@ -385,7 +495,6 @@
+
(
float
)
heightOfString
:
(
NSString
*
)
text
withWidth
:
(
float
)
width
font
:
(
UIFont
*
)
font
{
NSInteger
ch
;
//设置字体
CGSize
size
=
CGSizeMake
(
width
,
MAXFLOAT
);
if
([
text
respondsToSelector
:
@selector
(
boundingRectWithSize
:
options
:
attributes
:
context
:
)])
{
...
...
@@ -399,7 +508,7 @@
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
size
=
[
text
sizeWithFont
:
font
constrainedToSize
:
size
lineBreakMode
:
NSLineBreakByCharWrapping
];
//ios7以上已经摒弃的这个方法
size
=
[
text
sizeWithFont
:
font
constrainedToSize
:
size
lineBreakMode
:
NSLineBreakByCharWrapping
];
#pragma clang diagnostic pop
}
ch
=
size
.
height
;
...
...
PNChart/PNLineChart/PNLineChartData.h
View file @
0cb78e5
...
...
@@ -5,14 +5,36 @@
#import <Foundation/Foundation.h>
/**
* not support PNLineChartPointStyleTriangle style recently
*/
typedef
NS_ENUM
(
NSUInteger
,
PNLineChartPointStyle
)
{
PNLineChartPointStyleNone
=
0
,
PNLineChartPointStyleCycle
,
PNLineChartPointStyleTriangle
,
PNLineChartPointStyleSquare
};
@class
PNLineChartDataItem
;
typedef
PNLineChartDataItem
*
(
^
LCLineChartDataGetter
)(
NSUInteger
item
);
@interface
PNLineChartData
:
NSObject
@property
(
strong
)
UIColor
*
color
;
@property
NSUInteger
itemCount
;
@property
(
copy
)
LCLineChartDataGetter
getData
;
@property
(
nonatomic
,
assign
)
PNLineChartPointStyle
inflexionPointStyle
;
/**
* if PNLineChartPointStyle is cycle, inflexionPointWidth equal cycle's diameter
* if PNLineChartPointStyle is square, that means the foundation is square with
* inflexionPointWidth long
*/
@property
(
nonatomic
,
assign
)
CGFloat
inflexionPointWidth
;
@property
(
nonatomic
,
assign
)
CGFloat
lineWidth
;
@end
...
...
PNChart/PNLineChart/PNLineChartData.m
View file @
0cb78e5
...
...
@@ -7,4 +7,22 @@
@implementation
PNLineChartData
-
(
id
)
init
{
self
=
[
super
init
];
if
(
self
)
{
[
self
setDefaultValues
];
}
return
self
;
}
-
(
void
)
setDefaultValues
{
_inflexionPointStyle
=
PNLineChartPointStyleNone
;
_inflexionPointWidth
=
6
.
f
;
_lineWidth
=
2
.
f
;
}
@end
...
...
PNChartDemo/PCChartsTableViewController.m
View file @
0cb78e5
...
...
@@ -64,12 +64,14 @@
lineChart
.
yLabelFormat
=
@"%1.1f"
;
lineChart
.
backgroundColor
=
[
UIColor
clearColor
];
[
lineChart
setXLabels
:@[
@"SEP 1"
,
@"SEP 2"
,
@"SEP 3"
,
@"SEP 4"
,
@"SEP 5"
,
@"SEP 6"
,
@"SEP 7"
]];
lineChart
.
showCoordinateAxis
=
YES
;
// Line Chart Nr.1
NSArray
*
data01Array
=
@[
@60.1
,
@160.1
,
@126.4
,
@262.2
,
@186.2
,
@127.2
,
@176.2
];
PNLineChartData
*
data01
=
[
PNLineChartData
new
];
data01
.
color
=
PNFreshGreen
;
data01
.
itemCount
=
lineChart
.
xLabels
.
count
;
data01
.
inflexionPointStyle
=
PNLineChartPointStyleCycle
;
data01
.
getData
=
^
(
NSUInteger
index
)
{
CGFloat
yValue
=
[
data01Array
[
index
]
floatValue
];
return
[
PNLineChartDataItem
dataItemWithY
:
yValue
];
...
...
@@ -80,6 +82,7 @@
PNLineChartData
*
data02
=
[
PNLineChartData
new
];
data02
.
color
=
PNTwitterColor
;
data02
.
itemCount
=
lineChart
.
xLabels
.
count
;
data02
.
inflexionPointStyle
=
PNLineChartPointStyleSquare
;
data02
.
getData
=
^
(
NSUInteger
index
)
{
CGFloat
yValue
=
[
data02Array
[
index
]
floatValue
];
return
[
PNLineChartDataItem
dataItemWithY
:
yValue
];
...
...
Please
register
or
login
to post a comment