本文讲的是iOS 开源图形库 Core Plot 使用教程,
入门
安装 Core Plot
pod 'CorePlot', '~> 2.1'
创建饼图
1
|
import CorePlot
|
1
|
@IBOutlet weak var hostView: CPTGraphHostingView!
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
extension PieChartViewController: CPTPieChartDataSource, CPTPieChartDelegate {
func numberOfRecordsForPlot(plot: CPTPlot) ->
UInt {
return
0
}
func numberForPlot(plot: CPTPlot, field fieldEnum:
UInt, recordIndex idx:
UInt) -> AnyObject? {
return
0
}
func dataLabelForPlot(plot: CPTPlot, recordIndex idx:
UInt) -> CPTLayer? {
return
nil
}
func sliceFillForPieChart(pieChart: CPTPieChart, recordIndex idx:
UInt) -> CPTFill? {
return
nil
}
func legendTitleForPieChart(pieChart: CPTPieChart, recordIndex idx:
UInt) -> String? {
return
nil
}
}
|
建立图表托管视图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
initPlot()
}
func initPlot() {
configureHostView()
configureGraph()
configureChart()
configureLegend()
}
func configureHostView() {
}
func configureGraph() {
}
func configureChart() {
}
func configureLegend() {
}
|
1
|
hostView.allowPinchScaling =
false
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 1 -
Create
and configure the graph
let graph = CPTXYGraph(frame: hostView.bounds)
hostView.hostedGraph = graph
graph.paddingLeft =
0.0
graph.paddingTop =
0.0
graph.paddingRight =
0.0
graph.paddingBottom =
0.0
graph.axisSet = nil
//
2 -
Create
text style
let textStyle: CPTMutableTextStyle = CPTMutableTextStyle()
textStyle.color = CPTColor.blackColor()
textStyle.fontName =
"HelveticaNeue-Bold"
textStyle.fontSize =
16.0
textStyle.textAlignment = .Center
//
3 -
Set graph title
and
text style
graph.title =
"\(base.name) exchange rates\n\(rate.date)"
graph.titleTextStyle = textStyle
graph.titlePlotAreaFrameAnchor = CPTRectAnchor.Top
|
绘制饼图
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// 1 - Get a reference to the graph
let graph = hostView.hostedGraph!
// 2 -
Create the chart
let pieChart = CPTPieChart()
pieChart.delegate =
self
pieChart.dataSource =
self
pieChart.pieRadius = (
min(hostView.bounds.size.width, hostView.bounds.size.height) *
0.7) /
2
pieChart.identifier = graph.title
pieChart.startAngle = CGFloat(M_PI_4)
pieChart.sliceDirection = .Clockwise
pieChart.labelOffset =
-0.6 * pieChart.pieRadius
//
3 - Configure border
style
let borderStyle = CPTMutableLineStyle()
borderStyle.lineColor = CPTColor.whiteColor()
borderStyle.lineWidth =
2.0
pieChart.borderLineStyle = borderStyle
//
4 - Configure
text
style
let textStyle = CPTMutableTextStyle()
textStyle.color = CPTColor.whiteColor()
textStyle.textAlignment = .Center
pieChart.labelTextStyle = textStyle
//
3 -
Add chart
to graph
graph.addPlot(pieChart)
``
`
|
1
2
3
|
func numberOfRecordsForPlot(plot: CPTPlot) ->
UInt {
return
UInt(symbols.count) ??
0
}
|
1
2
3
4
5
|
func numberForPlot(plot: CPTPlot, field fieldEnum: UInt, recordIndex idx: UInt) -> AnyObject? {
let symbol = symbols[Int(idx)]
let currencyRate = rate.rates[symbol.name]!.floatValue
return
1.0 / currencyRate
}
|
1
2
3
4
5
6
|
func dataLabelForPlot(plot: CPTPlot, recordIndex idx: UInt) -> CPTLayer? {
let
value = rate.rates[symbols[Int(idx)].name]!.floatValue
let layer = CPTTextLayer(text: String(format:
"\(symbols[Int(idx)].name)\n%.2f",
value))
layer.textStyle = plot.labelTextStyle
return layer
}
|
1
2
3
4
5
6
7
8
|
func sliceFillForPieChart(pieChart: CPTPieChart, recordIndex idx:
UInt) -> CPTFill? {
switch idx {
case
0:
return CPTFill(color: CPTColor(componentRed:
0.92, green:
0.28, blue:
0.25, alpha:
1.00))
case
1:
return CPTFill(color: CPTColor(componentRed:
0.06, green:
0.80, blue:
0.48, alpha:
1.00))
case
2:
return CPTFill(color: CPTColor(componentRed:
0.22, green:
0.33, blue:
0.49, alpha:
1.00))
default:
return
nil
}
}
|
等一下…图例呢!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
func
configureLegend() {
// 1 - Get graph instance
guard
let graph = hostView.hostedGraph
else {
return }
// 2 - Create legend
let theLegend = CPTLegend(graph: graph)
// 3 - Configure legend
theLegend.numberOfColumns = 1
theLegend.fill = CPTFill(color: CPTColor.whiteColor())
let textStyle = CPTMutableTextStyle()
textStyle.fontSize = 18
theLegend.textStyle = textStyle
// 4 - Add legend to graph
graph.legend = theLegend
if view.bounds.width > view.bounds.height {
graph.legendAnchor = .Right
graph.legendDisplacement = CGPoint(x: -20, y: 0.0)
}
else {
graph.legendAnchor = .BottomRight
graph.legendDisplacement = CGPoint(x: -8.0, y: 8.0)
}
}
|
1
2
3
|
func legendTitleForPieChart(pieChart: CPTPieChart, recordIndex idx: UInt) -> String? {
return symbols[Int(idx)].name
}
|
创建柱状图
1
|
import CorePlot
|
1
|
@IBOutlet var hostView: CPTGraphHostingView!
|
1
2
3
|
var plot1: CPTBarPlot!
var plot2: CPTBarPlot!
var plot3: CPTBarPlot!
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
extension BarGraphViewController: CPTBarPlotDataSource, CPTBarPlotDelegate {
func numberOfRecordsForPlot(plot: CPTPlot) ->
UInt {
return
0
}
func numberForPlot(plot: CPTPlot, field fieldEnum:
UInt, recordIndex idx:
UInt) -> AnyObject? {
return
0
}
func barPlot(plot: CPTBarPlot, barWasSelectedAtRecordIndex idx:
UInt, withEvent event:
UIEvent) {
}
}
|
再次配置图表托管视图
绘制柱状图
1
2
|
let BarWidth = 0.25
let BarInitialX = 0.25
|
1
2
3
4
5
6
7
|
func highestRateValue() -> Double {
var maxRate = DBL_MIN
for rate
in rates {
maxRate = max(maxRate, rate.maxRate().doubleValue)
}
return maxRate
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
initPlot()
}
func initPlot() {
configureHostView()
configureGraph()
configureChart()
configureAxes()
}
func configureHostView() {
}
func configureGraph() {
}
func configureChart() {
}
func configureAxes() {
}
|
1
|
hostView.allowPinchScaling =
false
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
// 1 - Create the graph
let graph = CPTXYGraph(frame: hostView.bounds)
graph.plotAreaFrame?.masksToBorder = false
hostView.hostedGraph = graph
// 2 - Configure the graph
graph.applyTheme(CPTTheme(named: kCPTPlainWhiteTheme))
graph.fill = CPTFill(color: CPTColor.clearColor())
graph.paddingBottom = 30.0
graph.paddingLeft = 30.0
graph.paddingTop = 0.0
graph.paddingRight = 0.0
// 3 - Set up styles
let titleStyle = CPTMutableTextStyle()
titleStyle.color = CPTColor.blackColor()
titleStyle.fontName =
"HelveticaNeue-Bold"
titleStyle.fontSize = 16.0
titleStyle.textAlignment = .Center
graph.titleTextStyle = titleStyle
let title =
"\(base.name) exchange rates\n\(rates.first!.date) - \(rates.last!.date)"
graph.title = title
graph.titlePlotAreaFrameAnchor = .Top
graph.titleDisplacement = CGPointMake(0.0, -16.0)
// 4 - Set up plot space
let xM
in = 0.0
let xMax = Double(rates.count)
let yM
in = 0.0
let yMax = 1.4 * highestRateValue()
guard
let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace
else {
return }
plotSpace.xRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(xM
in), lengthDecimal: CPTDecimalFromDouble(xMax - xM
in))
plotSpace.yRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(yM
in), lengthDecimal: CPTDecimalFromDouble(yMax - yM
in))
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
// 1 -
Set up the three plots
plot1 = CPTBarPlot()
plot1.fill = CPTFill(color: CPTColor(componentRed:
0.92, green:
0.28, blue:
0.25, alpha:
1.00))
plot2 = CPTBarPlot()
plot2.fill = CPTFill(color: CPTColor(componentRed:
0.06, green:
0.80, blue:
0.48, alpha:
1.00))
plot3 = CPTBarPlot()
plot3.fill = CPTFill(color: CPTColor(componentRed:
0.22, green:
0.33, blue:
0.49, alpha:
1.00))
//
2 -
Set up line style
let barLineStyle = CPTMutableLineStyle()
barLineStyle.lineColor = CPTColor.lightGrayColor()
barLineStyle.lineWidth =
0.5
//
3 -
Add plots
to graph
guard let graph = hostView.hostedGraph
else {
return }
var barX = BarInitialX
let plots = [plot1, plot2, plot3]
for plot: CPTBarPlot
in plots {
plot.dataSource =
self
plot.delegate =
self
plot.barWidth = BarWidth
plot.barOffset = barX
plot.lineStyle = barLineStyle
graph.addPlot(plot, toPlotSpace: graph.defaultPlotSpace)
barX += BarWidth
}
|
1
|
return
UInt(rates.count ??
0)
|
1
2
3
4
5
6
7
8
9
10
11
12
|
if fieldEnum ==
UInt(CPTBarPlotField.BarTip.rawValue) {
if plot == plot1 {
return
1.0
}
if plot == plot2 {
return rates[Int(idx)].rates[symbols[
0].name]!.floatValue
}
if plot == plot3 {
return rates[Int(idx)].rates[symbols[
1].name]!.floatValue
}
}
return idx
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
// 1 - Configure styles
let axisLineStyle = CPTMutableLineStyle()
axisLineStyle.lineWidth = 2.0
axisLineStyle.lineColor = CPTColor.blackColor()
// 2 - Get the graph's axis set
guard let axisSet = hostView.hostedGraph?.axisSet as? CPTXYAxisSet else { return }
// 3 - Configure the x-axis
if let xAxis = axisSet.xAxis {
xAxis.labelingPolicy = .None
xAxis.majorIntervalLength = 1
xAxis.axisLineStyle = axisLineStyle
var majorTickLocations = Set<nsnumber>()
var axisLabels = Set<cptaxislabel>()
for (idx, rate) in rates.enumerate() {
majorTickLocations.insert(idx)
let label = CPTAxisLabel(text: "\(rate.date)", textStyle: CPTTextStyle())
label.tickLocation = idx
label.offset = 5.0
label.alignment = .Left
axisLabels.insert(label)
}
xAxis.majorTickLocations = majorTickLocations
xAxis.axisLabels = axisLabels
}
// 4 - Configure the y-axis
if let yAxis = axisSet.yAxis {
yAxis.labelingPolicy = .FixedInterval
yAxis.labelOffset = -10.0
yAxis.minorTicksPerInterval = 3
yAxis.majorTickLength = 30
let majorTickLineStyle = CPTMutableLineStyle()
majorTickLineStyle.lineColor = CPTColor.blackColor().colorWithAlphaComponent(0.1)
yAxis.majorTickLineStyle = majorTickLineStyle
yAxis.minorTickLength = 20
let minorTickLineStyle = CPTMutableLineStyle()
minorTickLineStyle.lineColor = CPTColor.blackColor().colorWithAlphaComponent(0.05)
yAxis.minorTickLineStyle = minorTickLineStyle
yAxis.axisLineStyle = axisLineStyle
}</cptaxislabel></nsnumber>
|
功能化坐标轴
1
|
var priceAnnotation: CPTPlotSpaceAnnotation?
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
// 1 - Is the plot hidden?
if plot.hidden ==
true {
return
}
// 2 - Create style,
if necessary
let style = CPTMutableTextStyle()
style.fontSize = 12.0
style.fontName =
"HelveticaNeue-Bold"
// 3 - Create annotation
guard
let price = numberForPlot(plot,
field: UInt(CPTBarPlotField.BarTip.rawValue),
recordIndex: idx) as? CGFloat
else {
return }
priceAnnotation?.annotationHostLayer?.removeAnnotation(priceAnnotation)
priceAnnotation = CPTPlotSpaceAnnotation(plotSpace: plot.plotSpace!, anchorPlotPoint: [0,0])
// 4 - Create number formatter
let formatter = NSNumberFormatter()
formatter.maximumFractionDigits = 2
// 5 - Create text layer
for annotation
let priceValue = formatter.stringFromNumber(price)!
let textLayer = CPTTextLayer(text: priceValue, style: style)
priceAnnotation!.contentLayer = textLayer
// 6 - Get plot index
var plotIndex: Int = 0
if plot == plot1 {
plotIndex = 0
}
else
if plot == plot2 {
plotIndex = 1
}
else
if plot == plot3 {
plotIndex = 2
}
// 7 - Get the anchor point
for annotation
let x = CGFloat(idx) + CGFloat(BarInitialX) + (CGFloat(plotIndex) * CGFloat(BarWidth))
let y = CGFloat(price) + 0.05
priceAnnotation!.anchorPlotPoint = [x, y]
// 8 - Add the annotation
guard
let plotArea = plot.graph?.plotAreaFrame?.plotArea
else {
return }
plotArea.addAnnotation(priceAnnotation)
|
隐藏和查找
1
2
3
4
5
6
7
8
9
|
func hideAnnotation(graph: CPTGraph) {
guard
let plotArea = graph.plotAreaFrame?.plotArea,
priceAnnotation = priceAnnotation
else {
return
}
plotArea.removeAnnotation(priceAnnotation)
self.priceAnnotation = nil
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@
IBAction func switch1Changed(sender: UISwitch) {
let
on = sender.
on
if !
on {
hideAnnotation(plot1.graph!)
}
plot1.hidden = !
on
}
@
IBAction func switch2Changed(sender: UISwitch) {
let
on = sender.
on
if !
on {
hideAnnotation(plot2.graph!)
}
plot2.hidden = !
on
}
@
IBAction func switch3Changed(sender: UISwitch) {
let
on = sender.
on
if !
on {
hideAnnotation(plot3.graph!)
}
plot3.hidden = !
on
}
|
接下来干点啥?
原文发布时间为:2016年07月20日
本文来自云栖社区合作伙伴掘金,了解相关信息可以关注掘金网站。