|
| 1 | +// |
| 2 | +// BarsPlusMinusAndLinesExample.swift |
| 3 | +// SwiftCharts |
| 4 | +// |
| 5 | +// Created by ischuetz on 04/05/15. |
| 6 | +// Copyright (c) 2015 ivanschuetz. All rights reserved. |
| 7 | +// |
| 8 | + |
| 9 | +import UIKit |
| 10 | + |
| 11 | +class BarsPlusMinusAndLinesExample: UIViewController { |
| 12 | + |
| 13 | + private var chart: Chart? // arc |
| 14 | + |
| 15 | + override func viewDidLoad() { |
| 16 | + |
| 17 | + let labelSettings = ChartLabelSettings(font: ExamplesDefaults.labelFont) |
| 18 | + |
| 19 | + let barsData: [(title: String, min: CGFloat, max: CGFloat)] = [ |
| 20 | + ("A", -65, 40), |
| 21 | + ("B", -30, 50), |
| 22 | + ("C", -40, 35), |
| 23 | + ("D", -50, 40), |
| 24 | + ("E", -60, 30), |
| 25 | + ("F", -35, 47), |
| 26 | + ("G", -30, 60), |
| 27 | + ("H", -46, 48) |
| 28 | + ] |
| 29 | + |
| 30 | + let lineData: [(title: String, val: CGFloat)] = [ |
| 31 | + ("A", -10), |
| 32 | + ("B", 20), |
| 33 | + ("C", -20), |
| 34 | + ("D", 10), |
| 35 | + ("E", -20), |
| 36 | + ("F", 23), |
| 37 | + ("G", 10), |
| 38 | + ("H", 45) |
| 39 | + ] |
| 40 | + |
| 41 | + let alpha: CGFloat = 0.5 |
| 42 | + let posColor = UIColor.greenColor().colorWithAlphaComponent(alpha) |
| 43 | + let negColor = UIColor.redColor().colorWithAlphaComponent(alpha) |
| 44 | + let zero = ChartAxisValueFloat(0) |
| 45 | + let bars: [ChartPointsBar] = Array(enumerate(barsData)).flatMap {index, tuple in |
| 46 | + [ |
| 47 | + ChartPointsBar(constant: ChartAxisValueFloat(CGFloat(index)), axisValue1: zero, axisValue2: ChartAxisValueFloat(tuple.min), bgColor: negColor), |
| 48 | + ChartPointsBar(constant: ChartAxisValueFloat(CGFloat(index)), axisValue1: zero, axisValue2: ChartAxisValueFloat(tuple.max), bgColor: posColor) |
| 49 | + ] |
| 50 | + } |
| 51 | + |
| 52 | + let yValues = Array(stride(from: -80, through: 80, by: 20)).map {ChartAxisValueFloat($0, labelSettings: labelSettings)} |
| 53 | + let xValues = |
| 54 | + [ChartAxisValueString(order: -1)] + |
| 55 | + Array(enumerate(barsData)).map {index, tuple in ChartAxisValueString(tuple.0, order: index, labelSettings: labelSettings)} + |
| 56 | + [ChartAxisValueString(order: barsData.count)] |
| 57 | + |
| 58 | + |
| 59 | + let xModel = ChartAxisModel(axisValues: xValues, axisTitleLabel: ChartAxisLabel(text: "Axis title", settings: labelSettings)) |
| 60 | + let yModel = ChartAxisModel(axisValues: yValues, axisTitleLabel: ChartAxisLabel(text: "Axis title", settings: labelSettings)) |
| 61 | + let chartFrame = ExamplesDefaults.chartFrame(self.view.bounds) |
| 62 | + let coordsSpace = ChartCoordsSpaceLeftBottomSingleAxis(chartSettings: ExamplesDefaults.chartSettings, chartFrame: chartFrame, xModel: xModel, yModel: yModel) |
| 63 | + let (xAxis, yAxis, innerFrame) = (coordsSpace.xAxis, coordsSpace.yAxis, coordsSpace.chartInnerFrame) |
| 64 | + |
| 65 | + let barsLayer = ChartBarsLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, bars: bars, horizontal: false, barWidth: Env.iPad ? 40 : 25) |
| 66 | + |
| 67 | + // labels layer |
| 68 | + // create chartpoints for the top and bottom of the bars, where we will show the labels |
| 69 | + let labelChartPoints = bars.map {bar in |
| 70 | + ChartPoint(x: bar.constant, y: bar.axisValue2) |
| 71 | + } |
| 72 | + let formatter = NSNumberFormatter() |
| 73 | + formatter.maximumFractionDigits = 2 |
| 74 | + let labelsLayer = ChartPointsViewsLayer(axisX: xAxis, axisY: yAxis, innerFrame: innerFrame, chartPoints: labelChartPoints, viewGenerator: {(chartPointModel, layer, chart) -> UIView? in |
| 75 | + let label = HandlingLabel() |
| 76 | + let posOffset: CGFloat = 10 |
| 77 | + |
| 78 | + let pos = chartPointModel.chartPoint.y.scalar > 0 |
| 79 | + |
| 80 | + let yOffset = pos ? -posOffset : posOffset |
| 81 | + label.text = "\(formatter.stringFromNumber(chartPointModel.chartPoint.y.scalar)!)%" |
| 82 | + label.font = ExamplesDefaults.labelFont |
| 83 | + label.sizeToFit() |
| 84 | + label.center = CGPointMake(chartPointModel.screenLoc.x, pos ? innerFrame.origin.y : innerFrame.origin.y + innerFrame.size.height) |
| 85 | + label.alpha = 0 |
| 86 | + |
| 87 | + label.movedToSuperViewHandler = { |
| 88 | + UIView.animateWithDuration(0.3, animations: { |
| 89 | + label.alpha = 1 |
| 90 | + label.center.y = chartPointModel.screenLoc.y + yOffset |
| 91 | + }) |
| 92 | + } |
| 93 | + return label |
| 94 | + |
| 95 | + }, displayDelay: 0.5) // show after bars animation |
| 96 | + |
| 97 | + // line layer |
| 98 | + let lineChartPoints = Array(enumerate(lineData)).map {index, tuple in ChartPoint(x: ChartAxisValueFloat(CGFloat(index)), y: ChartAxisValueFloat(tuple.val))} |
| 99 | + let lineModel = ChartLineModel(chartPoints: lineChartPoints, lineColor: UIColor.blackColor(), lineWidth: 2, animDuration: 0.5, animDelay: 1) |
| 100 | + let lineLayer = ChartPointsLineLayer(axisX: xAxis, axisY: yAxis, innerFrame: innerFrame, lineModels: [lineModel]) |
| 101 | + |
| 102 | + let circleViewGenerator = {(chartPointModel: ChartPointLayerModel, layer: ChartPointsLayer, chart: Chart) -> UIView? in |
| 103 | + let color = UIColor(red: 0.7, green: 0.7, blue: 0.7, alpha: 1) |
| 104 | + return ChartPointCircleView(center: chartPointModel.screenLoc, size: CGSizeMake(7, 7), settings: ChartPointCircleViewSettings(animDuration: 0.3, cornerRadius: 3, borderColor: color, fillColor: color)) |
| 105 | + } |
| 106 | + let lineCirclesLayer = ChartPointsViewsLayer(axisX: xAxis, axisY: yAxis, innerFrame: innerFrame, chartPoints: lineChartPoints, viewGenerator: circleViewGenerator, displayDelay: 1.5, delayBetweenItems: 0.05) |
| 107 | + |
| 108 | + |
| 109 | + // show a gap between positive and negative bar |
| 110 | + let dummyZeroYChartPoint = ChartPoint(x: ChartAxisValueFloat(0), y: ChartAxisValueFloat(0)) |
| 111 | + let yZeroGapLayer = ChartPointsViewsLayer(axisX: xAxis, axisY: yAxis, innerFrame: innerFrame, chartPoints: [dummyZeroYChartPoint], viewGenerator: {(chartPointModel, layer, chart) -> UIView? in |
| 112 | + let height: CGFloat = 2 |
| 113 | + let v = UIView(frame: CGRectMake(innerFrame.origin.x + 2, chartPointModel.screenLoc.y - height / 2, innerFrame.origin.x + innerFrame.size.height, height)) |
| 114 | + v.backgroundColor = UIColor.whiteColor() |
| 115 | + return v |
| 116 | + }) |
| 117 | + |
| 118 | + let chart = Chart( |
| 119 | + frame: chartFrame, |
| 120 | + layers: [ |
| 121 | + xAxis, |
| 122 | + yAxis, |
| 123 | + barsLayer, |
| 124 | + labelsLayer, |
| 125 | + yZeroGapLayer, |
| 126 | + lineLayer, |
| 127 | + lineCirclesLayer |
| 128 | + ] |
| 129 | + ) |
| 130 | + |
| 131 | + self.view.addSubview(chart.view) |
| 132 | + self.chart = chart |
| 133 | + } |
| 134 | + |
| 135 | +} |
0 commit comments