-
-
Save ivnsch/f6e285eb0c86bb831510 to your computer and use it in GitHub Desktop.
// NOTE: you may have to set the module in the storyboard to "SwiftCharts", otherwise the view may not be recognized correctly, which leads to axis, labels and guidelines not showing | |
class HelloWorld: UIViewController { | |
private var chart: Chart? // arc | |
@IBOutlet weak var chartView: ChartBaseView! | |
private var didLayout: Bool = false | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil) | |
} | |
override func viewDidLayoutSubviews() { | |
super.viewDidLayoutSubviews() | |
if !self.didLayout { | |
self.didLayout = true | |
self.initChart() | |
} | |
} | |
private func initChart() { | |
// map model data to chart points | |
let chartPoints: [ChartPoint] = [(2, 2), (4, 4), (6, 6), (8, 10), (12, 14)].map{ChartPoint(x: ChartAxisValueInt($0.0), y: ChartAxisValueInt($0.1))} | |
let labelSettings = ChartLabelSettings(font: ExamplesDefaults.labelFont) | |
// define x and y axis values (quick-demo way, see other examples for generation based on chartpoints) | |
let xValues = stride(from: 0, through: 16, by: 2).map {ChartAxisValueInt($0, labelSettings: labelSettings)} | |
let yValues = stride(from: 0, through: 16, by: 2).map {ChartAxisValueInt($0, labelSettings: labelSettings)} | |
// create axis models with axis values and axis title | |
let xModel = ChartAxisModel(axisValues: xValues, axisTitleLabel: ChartAxisLabel(text: "Axis title", settings: labelSettings)) | |
let yModel = ChartAxisModel(axisValues: yValues, axisTitleLabel: ChartAxisLabel(text: "Axis title", settings: labelSettings.defaultVertical())) | |
let chartFrame = self.chartView.frame | |
// generate axes layers and calculate chart inner frame, based on the axis models | |
let coordsSpace = ChartCoordsSpaceLeftBottomSingleAxis(chartSettings: ExamplesDefaults.chartSettings, chartFrame: chartFrame, xModel: xModel, yModel: yModel) | |
let (xAxis, yAxis, innerFrame) = (coordsSpace.xAxis, coordsSpace.yAxis, coordsSpace.chartInnerFrame) | |
// create layer with guidelines | |
let guidelinesLayerSettings = ChartGuideLinesDottedLayerSettings(linesColor: UIColor.black, linesWidth: ExamplesDefaults.guidelinesWidth) | |
let guidelinesLayer = ChartGuideLinesDottedLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, settings: guidelinesLayerSettings) | |
// view generator - this is a function that creates a view for each chartpoint | |
let viewGenerator = {(chartPointModel: ChartPointLayerModel, layer: ChartPointsViewsLayer, chart: Chart) -> UIView? in | |
let viewSize: CGFloat = Env.iPad ? 30 : 20 | |
let center = chartPointModel.screenLoc | |
let label = UILabel(frame: CGRect(x: center.x - viewSize / 2, y: center.y - viewSize / 2, width: viewSize, height: viewSize)) | |
label.backgroundColor = UIColor.green | |
label.textAlignment = NSTextAlignment.center | |
label.text = "\(chartPointModel.chartPoint.y.description)" | |
label.font = ExamplesDefaults.labelFont | |
return label | |
} | |
// create layer that uses viewGenerator to display chartpoints | |
let chartPointsLayer = ChartPointsViewsLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, chartPoints: chartPoints, viewGenerator: viewGenerator) | |
// create chart instance with frame and layers | |
let chart = Chart( | |
view: self.chartView!, | |
layers: [ | |
coordsSpace.xAxis, | |
coordsSpace.yAxis, | |
guidelinesLayer, | |
chartPointsLayer | |
] | |
) | |
self.chart = chart | |
} | |
func rotated() { | |
for view in self.chartView.subviews { | |
view.removeFromSuperview() | |
} | |
self.initChart() | |
} | |
} |
Hey there - I'm using this sample code in my app and if I call initChart after the view is rendered (after getting some data from a server) only the curve layer is displayed (the axis are not) - any idea of what I'm doing wrong?
here is how you can repro the issue using latest sample code:
- add a UIView to the iPhone storyboard in DetailView Controller/View
-> call view chartView and make it an outlet to the Detail class - update (aka hack) DetailViewController.swift as follow (mainly using the sample code from above)
//
// DetailViewController.swift
// SwiftCharts
//
// Created by ischuetz on 20/04/15.
// Copyright (c) 2015 ivanschuetz. All rights reserved.
//
import UIKit
import SwiftCharts
class DetailViewController: UIViewController, UISplitViewControllerDelegate {
@IBOutlet weak var detailDescriptionLabel: UILabel!
@IBOutlet weak var chartView: ChartBaseView!
// lazy var chartFrame: CGRect! = {
// CGRectMake(0, 80, self.view.frame.size.width, self.view.frame.size.height - 80)
// }()
var detailItem: Example? {
didSet {
self.configureView()
//initChart()
}
}
override func viewDidLoad() {
super.viewDidLoad()
var timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: "initChart", userInfo: nil, repeats: false)
}
func initChart() {
// map model data to chart points
let chartPoints: [ChartPoint] = [(2, 2), (4, 4), (6, 6), (8, 10), (12, 14)].map{ChartPoint(x: ChartAxisValueInt($0.0), y: ChartAxisValueInt($0.1))}
let labelSettings = ChartLabelSettings(font: ExamplesDefaults.labelFont)
// define x and y axis values (quick-demo way, see other examples for generation based on chartpoints)
let xValues = 0.stride( through: 16, by: 2).map {ChartAxisValueInt($0, labelSettings: labelSettings)}
let yValues = 0.stride( through: 16, by: 2).map {ChartAxisValueInt($0, labelSettings: labelSettings)}
// create axis models with axis values and axis title
let xModel = ChartAxisModel(axisValues: xValues, axisTitleLabel: ChartAxisLabel(text: "Axis title", settings: labelSettings))
let yModel = ChartAxisModel(axisValues: yValues, axisTitleLabel: ChartAxisLabel(text: "Axis title", settings: labelSettings.defaultVertical()))
let chartFrame = self.chartView.frame
// generate axes layers and calculate chart inner frame, based on the axis models
let coordsSpace = ChartCoordsSpaceLeftBottomSingleAxis(chartSettings: ExamplesDefaults.chartSettings, chartFrame: chartFrame, xModel: xModel, yModel: yModel)
let (xAxis, yAxis, innerFrame) = (coordsSpace.xAxis, coordsSpace.yAxis, coordsSpace.chartInnerFrame)
// create layer with guidelines
let guidelinesLayerSettings = ChartGuideLinesDottedLayerSettings(linesColor: UIColor.blackColor(), linesWidth: ExamplesDefaults.guidelinesWidth)
let guidelinesLayer = ChartGuideLinesDottedLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, settings: guidelinesLayerSettings)
// view generator - this is a function that creates a view for each chartpoint
let viewGenerator = {(chartPointModel: ChartPointLayerModel, layer: ChartPointsViewsLayer, chart: Chart) -> UIView? in
let viewSize: CGFloat = Env.iPad ? 30 : 20
let center = chartPointModel.screenLoc
let label = UILabel(frame: CGRectMake(center.x - viewSize / 2, center.y - viewSize / 2, viewSize, viewSize))
label.backgroundColor = UIColor.greenColor()
label.textAlignment = NSTextAlignment.Center
label.text = "\(chartPointModel.chartPoint.y)"
label.font = ExamplesDefaults.labelFont
return label
}
// create layer that uses viewGenerator to display chartpoints
let chartPointsLayer = ChartPointsViewsLayer(xAxis: xAxis, yAxis: yAxis, innerFrame: innerFrame, chartPoints: chartPoints, viewGenerator: viewGenerator)
// create chart instance with frame and layers
let chart = Chart(
view: self.chartView!,
layers: [
coordsSpace.xAxis,
coordsSpace.yAxis,
guidelinesLayer,
chartPointsLayer
]
)
self.chartView.setNeedsDisplay()
//self.chart = chart
}
var currentExampleController: UIViewController?
func configureView() {
if let example: Example = self.detailItem {
switch example {
case .HelloWorld:
self.setSplitSwipeEnabled(true)
self.showExampleController(HelloWorld())
case .Bars:
self.setSplitSwipeEnabled(true)
self.showExampleController(BarsExample())
case .StackedBars:
self.setSplitSwipeEnabled(true)
self.showExampleController(StackedBarsExample())
case .BarsPlusMinus:
self.setSplitSwipeEnabled(true)
self.showExampleController(BarsPlusMinusWithGradientExample())
case .GroupedBars:
self.setSplitSwipeEnabled(true)
self.showExampleController(GroupedBarsExample())
case .BarsStackedGrouped:
self.setSplitSwipeEnabled(true)
self.showExampleController(GroupedAndStackedBarsExample())
case .Scatter:
self.setSplitSwipeEnabled(true)
self.showExampleController(ScatterExample())
case .Notifications:
self.setSplitSwipeEnabled(true)
self.showExampleController(NotificationsExample())
case .Target:
self.setSplitSwipeEnabled(true)
self.showExampleController(TargetExample())
case .Areas:
self.setSplitSwipeEnabled(true)
self.showExampleController(AreasExample())
case .Bubble:
self.setSplitSwipeEnabled(true)
self.showExampleController(BubbleExample())
case .Combination:
self.setSplitSwipeEnabled(true)
self.showExampleController(BarsPlusMinusAndLinesExample())
case .Scroll:
self.setSplitSwipeEnabled(false)
self.automaticallyAdjustsScrollViewInsets = false
self.showExampleController(ScrollExample())
case .Coords:
self.setSplitSwipeEnabled(true)
self.showExampleController(CoordsExample())
case .Tracker:
self.setSplitSwipeEnabled(false)
self.showExampleController(TrackerExample())
case .EqualSpacing:
self.setSplitSwipeEnabled(true)
self.showExampleController(EqualSpacingExample())
case .CustomUnits:
self.setSplitSwipeEnabled(true)
self.showExampleController(CustomUnitsExample())
case .Multival:
self.setSplitSwipeEnabled(true)
self.showExampleController(MultipleLabelsExample())
case .MultiAxis:
self.setSplitSwipeEnabled(true)
self.showExampleController(MultipleAxesExample())
case .MultiAxisInteractive:
self.setSplitSwipeEnabled(true)
self.showExampleController(MultipleAxesInteractiveExample())
case .CandleStick:
self.setSplitSwipeEnabled(true)
self.showExampleController(CandleStickExample())
case .Cubiclines:
self.setSplitSwipeEnabled(true)
self.showExampleController(CubicLinesExample())
case .NotNumeric:
self.setSplitSwipeEnabled(true)
self.showExampleController(NotNumericExample())
case .CandleStickInteractive:
self.setSplitSwipeEnabled(false)
self.showExampleController(CandleStickInteractiveExample())
case .Trendline:
self.setSplitSwipeEnabled(true)
self.showExampleController(TrendlineExample())
}
}
}
private func showExampleController(controller: UIViewController) {
if let currentExampleController = self.currentExampleController {
currentExampleController.removeFromParentViewController()
currentExampleController.view.removeFromSuperview()
}
self.addChildViewController(controller)
//self.view.addSubview(controller.view)
self.currentExampleController = controller
}
private func setSplitSwipeEnabled(enabled: Bool) {
if UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Pad {
let splitViewController = UIApplication.sharedApplication().delegate?.window!!.rootViewController as! UISplitViewController
splitViewController.presentsWithGesture = enabled
}
}
}
results: click on any example, details view is shown - results: after 2 sec the graph is shown but the axis layers are not shown... self.chartView.setNeedsDisplay seems to have no effect - Any idea of what I'm missing? Thanks!
Hi! How can I add this: "@IBOutlet weak var chartView: ChartBaseView!" ? I not see ChartBaseView when i drag UIView to the class and I can't convert my UIView to ChartBaseView. Can somebody please help me? Thanks!
Hi, I tried to rewrite UIView to ChartBaseView to IBOutlet and I have the same problem as reivax (axis are missing). Did you resolve this? Thank you!
Genius! That's amazing. Now rotation works perfectly 👍
I'm sorry, I don't like using betas so I didn't know about swift2.0 and the change in Array(stride:) definition.
How can I quote your library in my App?