前提
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
class GraphViewController: UIViewController, ChartViewDelegate { @IBOutlet weak var tableView: UITableView! @IBOutlet weak var scrollView: UIScrollView! let realm = try! Realm() var post: Post! var percentPoints = try! Realm().objects(Post.self).sorted(byKeyPath: "date", ascending: true) var numSegments = 7 var currentItems: Results<Post>! var dataPoints = [Double]() var dateString: String! @IBAction func SegmentSelected(_ sender: UISegmentedControl) { switch sender.selectedSegmentIndex { case 0: numSegments = 7 case 1: numSegments = 30 default: numSegments = 12 } } override func viewDidLoad() { super.viewDidLoad() //dataPointsに値を代入する var i = 0 repeat{ dataPoints.append(Double(percentPoints[i].percent)!) i += 1 } while i < percentPoints.count //④lineChartViewにlineChartDataを詰める let lineChartView = createLineChartView(data: dataPoints) self.view.addSubview(lineChartView) 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) let contentsView = createContentsView(of: dataPoints, percentCountPerPage: numSegments) scrollView.addSubview(contentsView) scrollView.contentSize = contentsView.frame.size scrollView.isPagingEnabled = true } //ページをスクロールできるようにする func createContentsView(of data: [Double], percentCountPerPage: Int) -> UIView { //1ページあたりのデータ(配列) let itemsPerPage = stride(from: 0, to: data.count, by: percentCountPerPage).map { Array(data[$0 ..< min($0 + percentCountPerPage, data.count)]) } let contentsView = UIView(frame: CGRect(x: 0, y: 0, width: scrollView.frame.width * CGFloat(itemsPerPage.count), height: scrollView.frame.height)) for (i, data) in itemsPerPage.enumerated() { let lineChartView = createLineChartView(data: data) let percent = CGFloat(data.count) / CGFloat(itemsPerPage[0].count) lineChartView.frame = CGRect( x: scrollView.frame.width * CGFloat(i), y: 0, width: scrollView.frame.width * percent, height: scrollView.frame.height ) print(itemsPerPage[i]) contentsView.addSubview(lineChartView) } return contentsView } //dataPointsをもとにLineChartViewを作る func createLineChartView(data:[Double]) -> LineChartView{ let lineChartView = LineChartView() lineChartView.delegate = self //y軸の最大値・最小値 lineChartView.leftAxis.axisMaximum = 100 lineChartView.leftAxis.axisMinimum = -50 //y軸のラベルの数 lineChartView.leftAxis.labelCount = 7 //右側のラベルを非表示 lineChartView.rightAxis.enabled = false lineChartView.legend.enabled = false lineChartView.pinchZoomEnabled = false lineChartView.doubleTapToZoomEnabled = false lineChartView.extraTopOffset = 20 lineChartView.xAxis.labelPosition = .bottom //dataPointsを渡す lineChartView.data = createLineChartData(of: data) return lineChartView } func createLineChartData(of data: [Double]) -> LineChartData{ //①dataEntriesにデータを詰める var dataEntries = [ChartDataEntry]() for (xValue, yValue) in data.enumerated() { let dataEntry = ChartDataEntry(x: Double(Int(xValue)), y: yValue) dataEntries.append(dataEntry) } //②dataEntriesからlineChartDataSetを作成 let lineChartDataSet = LineChartDataSet(entries: dataEntries, label: "percentChart") lineChartDataSet.lineWidth = 5.0 lineChartDataSet.mode = .linear //③lineChartDataSetからLineChartDataを作成 let lineChartData = LineChartData(dataSet: lineChartDataSet) return lineChartData }
補足情報(FW/ツールのバージョンなど)
Xcodeのバージョンは最新です。
長文失礼しました。ご回答いただけますと幸いです。よろしくお願いいたします。
まだ回答がついていません
会員登録して回答してみよう