前提
Realmのデータをもとにグラフを描画し、それをScrollViewを使ってスクロールできるようにしています。
https://bombrary.github.io/blog/posts/iphone-barchart-ioscharts/
こちらの記事を参考にしました。
実現したいこと
SegmentedControlの値に応じて、1ページに描画するデータの数を変え、またX軸の座標はページをスクロールするとX軸の値が0からやり直しになってしまうエラーを解消したいです。
最終的には下記画像のようにX軸の値を日付にして、またSegmentedControlで1週間・1ヶ月・1年ごとのデータをグラフに描画できるようにしたいです。(例えば「1週間」を選んだ場合、1ページに1週間分のデータが描画され、スクロールすることで別の週のグラフを見ることができる、といったイメージです)
発生している問題・エラーメッセージ
このようにX軸のグリッドの数と1ページあたりのデータの数が等しい時は正しくX軸の座標が表示されるのですが、
X軸のグリッドの数と1ページあたりのデータの数が異なる時、このようにX軸の座標が表示されてしまいます。またこの画像はスクロールして2枚目のグラフなのですが、X軸の値が0からスタートしてしまっています。
該当のソースコード
Swift
1class GraphViewController: UIViewController, ChartViewDelegate { 2 3 @IBOutlet weak var tableView: UITableView! 4 @IBOutlet weak var scrollView: UIScrollView! 5 6 let realm = try! Realm() 7 var post: Post! 8 var percentPoints = try! Realm().objects(Post.self).sorted(byKeyPath: "date", ascending: true) 9 var numSegments = 7 10 11 var currentItems: Results<Post>! 12 var dataPoints = [Double]() 13 var dateString: String! 14 15 @IBAction func SegmentSelected(_ sender: UISegmentedControl) { 16 switch sender.selectedSegmentIndex { 17 case 0: 18 numSegments = 7 19 case 1: 20 numSegments = 30 21 default: 22 numSegments = 12 23 } 24 } 25 26 override func viewDidLoad() { 27 super.viewDidLoad() 28 29 //dataPointsに値を代入する 30 var i = 0 31 repeat{ 32 dataPoints.append(Double(percentPoints[i].percent)!) 33 i += 1 34 } while i < percentPoints.count 35 36 //④lineChartViewにlineChartDataを詰める 37 let lineChartView = createLineChartView(data: dataPoints) 38 self.view.addSubview(lineChartView) 39 40 scrollView.frame = CGRect(x: (UIScreen.main.bounds.size.width - UIScreen.main.bounds.size.width * 0.8) / 2, y: 70, width: UIScreen.main.bounds.size.width * 0.8, height: UIScreen.main.bounds.size.width * 0.7) 41 42 let contentsView = createContentsView(of: dataPoints, percentCountPerPage: numSegments) 43 scrollView.addSubview(contentsView) 44 scrollView.contentSize = contentsView.frame.size 45 scrollView.isPagingEnabled = true 46 } 47 48 //ページをスクロールできるようにする 49 func createContentsView(of data: [Double], percentCountPerPage: Int) -> UIView { 50 //1ページあたりのデータ(配列) 51 let itemsPerPage = stride(from: 0, to: data.count, by: percentCountPerPage).map { 52 Array(data[$0 ..< min($0 + percentCountPerPage, data.count)]) 53 } 54 let contentsView = UIView(frame: CGRect(x: 0, y: 0, width: scrollView.frame.width * CGFloat(itemsPerPage.count), height: scrollView.frame.height)) 55 for (i, data) in itemsPerPage.enumerated() { 56 let lineChartView = createLineChartView(data: data) 57 let percent = CGFloat(data.count) / CGFloat(itemsPerPage[0].count) 58 lineChartView.frame = CGRect( 59 x: scrollView.frame.width * CGFloat(i), 60 y: 0, 61 width: scrollView.frame.width * percent, 62 height: scrollView.frame.height 63 ) 64 print(itemsPerPage[i]) 65 contentsView.addSubview(lineChartView) 66 } 67 return contentsView 68 } 69 70 //dataPointsをもとにLineChartViewを作る 71 func createLineChartView(data:[Double]) -> LineChartView{ 72 let lineChartView = LineChartView() 73 lineChartView.delegate = self 74 //y軸の最大値・最小値 75 lineChartView.leftAxis.axisMaximum = 100 76 lineChartView.leftAxis.axisMinimum = -50 77 //y軸のラベルの数 78 lineChartView.leftAxis.labelCount = 7 79 //右側のラベルを非表示 80 lineChartView.rightAxis.enabled = false 81 lineChartView.legend.enabled = false 82 lineChartView.pinchZoomEnabled = false 83 lineChartView.doubleTapToZoomEnabled = false 84 lineChartView.extraTopOffset = 20 85 lineChartView.xAxis.labelPosition = .bottom 86 87 //dataPointsを渡す 88 lineChartView.data = createLineChartData(of: data) 89 return lineChartView 90 } 91 92 func createLineChartData(of data: [Double]) -> LineChartData{ 93 //①dataEntriesにデータを詰める 94 var dataEntries = [ChartDataEntry]() 95 for (xValue, yValue) in data.enumerated() { 96 let dataEntry = ChartDataEntry(x: Double(Int(xValue)), y: yValue) 97 dataEntries.append(dataEntry) 98 } 99 //②dataEntriesからlineChartDataSetを作成 100 let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "percentChart") 101 lineChartDataSet.lineWidth = 5.0 102 lineChartDataSet.mode = .linear 103 //③lineChartDataSetからLineChartDataを作成 104 let lineChartData = LineChartData(dataSet: lineChartDataSet) 105 return lineChartData 106 }
補足情報(FW/ツールのバージョンなど)
Xcodeのバージョンは最新です。
長文失礼しました。ご回答いただけますと幸いです。よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2022/04/01 14:06 編集