DemoBaseViewController.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. //
  2. // DemoBaseViewController.swift
  3. // ChartsDemo-iOS
  4. //
  5. // Created by Jacob Christie on 2017-07-03.
  6. // Copyright © 2017 jc. All rights reserved.
  7. //
  8. #if canImport(UIKit)
  9. import UIKit
  10. #endif
  11. import Charts
  12. enum Option {
  13. case toggleValues
  14. case toggleIcons
  15. case toggleHighlight
  16. case animateX
  17. case animateY
  18. case animateXY
  19. case saveToGallery
  20. case togglePinchZoom
  21. case toggleAutoScaleMinMax
  22. case toggleData
  23. case toggleBarBorders
  24. // LineChart
  25. case toggleGradientLine
  26. // CandleChart
  27. case toggleShadowColorSameAsCandle
  28. case toggleShowCandleBar
  29. // CombinedChart
  30. case toggleLineValues
  31. case toggleBarValues
  32. case removeDataSet
  33. // CubicLineSampleFillFormatter
  34. case toggleFilled
  35. case toggleCircles
  36. case toggleCubic
  37. case toggleHorizontalCubic
  38. case toggleStepped
  39. // HalfPieChartController
  40. case toggleXValues
  41. case togglePercent
  42. case toggleHole
  43. case spin
  44. case drawCenter
  45. case toggleLabelsMinimumAngle
  46. // RadarChart
  47. case toggleXLabels
  48. case toggleYLabels
  49. case toggleRotate
  50. case toggleHighlightCircle
  51. var label: String {
  52. switch self {
  53. case .toggleValues: return "Toggle Y-Values"
  54. case .toggleIcons: return "Toggle Icons"
  55. case .toggleHighlight: return "Toggle Highlight"
  56. case .animateX: return "Animate X"
  57. case .animateY: return "Animate Y"
  58. case .animateXY: return "Animate XY"
  59. case .saveToGallery: return "Save to Camera Roll"
  60. case .togglePinchZoom: return "Toggle PinchZoom"
  61. case .toggleAutoScaleMinMax: return "Toggle auto scale min/max"
  62. case .toggleData: return "Toggle Data"
  63. case .toggleBarBorders: return "Toggle Bar Borders"
  64. // LineChart
  65. case .toggleGradientLine: return "Toggle Gradient Line"
  66. // CandleChart
  67. case .toggleShadowColorSameAsCandle: return "Toggle shadow same color"
  68. case .toggleShowCandleBar: return "Toggle show candle bar"
  69. // CombinedChart
  70. case .toggleLineValues: return "Toggle Line Values"
  71. case .toggleBarValues: return "Toggle Bar Values"
  72. case .removeDataSet: return "Remove Random Set"
  73. // CubicLineSampleFillFormatter
  74. case .toggleFilled: return "Toggle Filled"
  75. case .toggleCircles: return "Toggle Circles"
  76. case .toggleCubic: return "Toggle Cubic"
  77. case .toggleHorizontalCubic: return "Toggle Horizontal Cubic"
  78. case .toggleStepped: return "Toggle Stepped"
  79. // HalfPieChartController
  80. case .toggleXValues: return "Toggle X-Values"
  81. case .togglePercent: return "Toggle Percent"
  82. case .toggleHole: return "Toggle Hole"
  83. case .spin: return "Spin"
  84. case .drawCenter: return "Draw CenterText"
  85. case .toggleLabelsMinimumAngle: return "Toggle Labels Minimum Angle"
  86. // RadarChart
  87. case .toggleXLabels: return "Toggle X-Labels"
  88. case .toggleYLabels: return "Toggle Y-Labels"
  89. case .toggleRotate: return "Toggle Rotate"
  90. case .toggleHighlightCircle: return "Toggle highlight circle"
  91. }
  92. }
  93. }
  94. class DemoBaseViewController: UIViewController, ChartViewDelegate {
  95. private var optionsTableView: UITableView? = nil
  96. let parties = ["Party A", "Party B", "Party C", "Party D", "Party E", "Party F",
  97. "Party G", "Party H", "Party I", "Party J", "Party K", "Party L",
  98. "Party M", "Party N", "Party O", "Party P", "Party Q", "Party R",
  99. "Party S", "Party T", "Party U", "Party V", "Party W", "Party X",
  100. "Party Y", "Party Z"]
  101. @IBOutlet weak var optionsButton: UIButton!
  102. var options: [Option]!
  103. var shouldHideData: Bool = false
  104. required init?(coder aDecoder: NSCoder) {
  105. super.init(coder: aDecoder)
  106. self.initialize()
  107. }
  108. override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
  109. super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  110. self.initialize()
  111. }
  112. private func initialize() {
  113. self.edgesForExtendedLayout = []
  114. }
  115. func optionTapped(_ option: Option) {}
  116. func handleOption(_ option: Option, forChartView chartView: ChartViewBase) {
  117. switch option {
  118. case .toggleValues:
  119. for set in chartView.data! {
  120. set.drawValuesEnabled = !set.drawValuesEnabled
  121. }
  122. chartView.setNeedsDisplay()
  123. case .toggleIcons:
  124. for set in chartView.data! {
  125. set.drawIconsEnabled = !set.drawIconsEnabled
  126. }
  127. chartView.setNeedsDisplay()
  128. case .toggleHighlight:
  129. chartView.data!.isHighlightEnabled = !chartView.data!.isHighlightEnabled
  130. chartView.setNeedsDisplay()
  131. case .animateX:
  132. chartView.animate(xAxisDuration: 3)
  133. case .animateY:
  134. chartView.animate(yAxisDuration: 3)
  135. case .animateXY:
  136. chartView.animate(xAxisDuration: 3, yAxisDuration: 3)
  137. case .saveToGallery:
  138. UIImageWriteToSavedPhotosAlbum(chartView.getChartImage(transparent: false)!, nil, nil, nil)
  139. case .togglePinchZoom:
  140. let barLineChart = chartView as! BarLineChartViewBase
  141. barLineChart.pinchZoomEnabled = !barLineChart.pinchZoomEnabled
  142. chartView.setNeedsDisplay()
  143. case .toggleAutoScaleMinMax:
  144. let barLineChart = chartView as! BarLineChartViewBase
  145. barLineChart.autoScaleMinMaxEnabled = !barLineChart.isAutoScaleMinMaxEnabled
  146. chartView.notifyDataSetChanged()
  147. case .toggleData:
  148. shouldHideData = !shouldHideData
  149. updateChartData()
  150. case .toggleBarBorders:
  151. for set in chartView.data! {
  152. if let set = set as? BarChartDataSet {
  153. set.barBorderWidth = set.barBorderWidth == 1.0 ? 0.0 : 1.0
  154. }
  155. }
  156. chartView.setNeedsDisplay()
  157. default:
  158. break
  159. }
  160. }
  161. @IBAction func optionsButtonTapped(_ sender: Any) {
  162. if let optionsTableView = self.optionsTableView {
  163. optionsTableView.removeFromSuperview()
  164. self.optionsTableView = nil
  165. return
  166. }
  167. let optionsTableView = UITableView()
  168. optionsTableView.backgroundColor = UIColor(white: 0, alpha: 0.9)
  169. optionsTableView.delegate = self
  170. optionsTableView.dataSource = self
  171. optionsTableView.translatesAutoresizingMaskIntoConstraints = false
  172. self.optionsTableView = optionsTableView
  173. var constraints = [NSLayoutConstraint]()
  174. constraints.append(NSLayoutConstraint(item: optionsTableView,
  175. attribute: .leading,
  176. relatedBy: .equal,
  177. toItem: self.view,
  178. attribute: .leading,
  179. multiplier: 1,
  180. constant: 40))
  181. constraints.append(NSLayoutConstraint(item: optionsTableView,
  182. attribute: .trailing,
  183. relatedBy: .equal,
  184. toItem: sender as! UIView,
  185. attribute: .trailing,
  186. multiplier: 1,
  187. constant: 0))
  188. constraints.append(NSLayoutConstraint(item: optionsTableView,
  189. attribute: .top,
  190. relatedBy: .equal,
  191. toItem: sender,
  192. attribute: .bottom,
  193. multiplier: 1,
  194. constant: 5))
  195. self.view.addSubview(optionsTableView)
  196. constraints.forEach { $0.isActive = true }
  197. let constraint = NSLayoutConstraint(item: optionsTableView,
  198. attribute: .height,
  199. relatedBy: .equal,
  200. toItem: nil,
  201. attribute: .height,
  202. multiplier: 1,
  203. constant: 220)
  204. constraint.isActive = true
  205. }
  206. func updateChartData() {
  207. fatalError("updateChartData not overridden")
  208. }
  209. func setup(pieChartView chartView: PieChartView) {
  210. chartView.usePercentValuesEnabled = true
  211. chartView.drawSlicesUnderHoleEnabled = false
  212. chartView.holeRadiusPercent = 0.58
  213. chartView.transparentCircleRadiusPercent = 0.61
  214. chartView.chartDescription.enabled = false
  215. chartView.setExtraOffsets(left: 5, top: 10, right: 5, bottom: 5)
  216. chartView.drawCenterTextEnabled = true
  217. let paragraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
  218. paragraphStyle.lineBreakMode = .byTruncatingTail
  219. paragraphStyle.alignment = .center
  220. let centerText = NSMutableAttributedString(string: "Charts\nby Daniel Cohen Gindi")
  221. centerText.setAttributes([.font : UIFont(name: "HelveticaNeue-Light", size: 13)!,
  222. .paragraphStyle : paragraphStyle], range: NSRange(location: 0, length: centerText.length))
  223. centerText.addAttributes([.font : UIFont(name: "HelveticaNeue-Light", size: 11)!,
  224. .foregroundColor : UIColor.gray], range: NSRange(location: 10, length: centerText.length - 10))
  225. centerText.addAttributes([.font : UIFont(name: "HelveticaNeue-Light", size: 11)!,
  226. .foregroundColor : UIColor(red: 51/255, green: 181/255, blue: 229/255, alpha: 1)], range: NSRange(location: centerText.length - 19, length: 19))
  227. chartView.centerAttributedText = centerText;
  228. chartView.drawHoleEnabled = true
  229. chartView.rotationAngle = 0
  230. chartView.rotationEnabled = true
  231. chartView.highlightPerTapEnabled = true
  232. let l = chartView.legend
  233. l.horizontalAlignment = .right
  234. l.verticalAlignment = .top
  235. l.orientation = .vertical
  236. l.drawInside = false
  237. l.xEntrySpace = 7
  238. l.yEntrySpace = 0
  239. l.yOffset = 0
  240. // chartView.legend = l
  241. }
  242. func setup(radarChartView chartView: RadarChartView) {
  243. chartView.chartDescription.enabled = false
  244. }
  245. func setup(barLineChartView chartView: BarLineChartViewBase) {
  246. chartView.chartDescription.enabled = false
  247. chartView.dragEnabled = true
  248. chartView.setScaleEnabled(true)
  249. chartView.pinchZoomEnabled = false
  250. // ChartYAxis *leftAxis = chartView.leftAxis;
  251. let xAxis = chartView.xAxis
  252. xAxis.labelPosition = .bottom
  253. chartView.rightAxis.enabled = false
  254. }
  255. // TODO: Cannot override from extensions
  256. //extension DemoBaseViewController: ChartViewDelegate {
  257. func chartValueSelected(_ chartView: ChartViewBase, entry: ChartDataEntry, highlight: Highlight) {
  258. NSLog("chartValueSelected");
  259. }
  260. func chartValueNothingSelected(_ chartView: ChartViewBase) {
  261. NSLog("chartValueNothingSelected");
  262. }
  263. func chartScaled(_ chartView: ChartViewBase, scaleX: CGFloat, scaleY: CGFloat) {
  264. }
  265. func chartTranslated(_ chartView: ChartViewBase, dX: CGFloat, dY: CGFloat) {
  266. }
  267. }
  268. extension DemoBaseViewController: UITableViewDelegate, UITableViewDataSource {
  269. func numberOfSections(in tableView: UITableView) -> Int {
  270. if optionsTableView != nil {
  271. return 1
  272. }
  273. return 0
  274. }
  275. @available(iOS 2.0, *)
  276. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  277. if optionsTableView != nil {
  278. return options.count
  279. }
  280. return 0
  281. }
  282. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  283. if optionsTableView != nil {
  284. return 40.0;
  285. }
  286. return 44.0;
  287. }
  288. @available(iOS 2.0, *)
  289. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  290. var cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
  291. if cell == nil {
  292. cell = UITableViewCell(style: .default, reuseIdentifier: "Cell")
  293. cell?.backgroundView = nil
  294. cell?.backgroundColor = .clear
  295. cell?.textLabel?.textColor = .white
  296. }
  297. cell?.textLabel?.text = self.options[indexPath.row].label
  298. return cell!
  299. }
  300. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  301. if optionsTableView != nil {
  302. tableView.deselectRow(at: indexPath, animated: true)
  303. optionsTableView?.removeFromSuperview()
  304. self.optionsTableView = nil
  305. self.optionTapped(self.options[indexPath.row])
  306. }
  307. }
  308. }