質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
87.20%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

解決済

【Swift-Charts】SegmentedControlの値に応じて1ページあたりのデータ数を変え、スクロールできるようにしたいです

miyuki
miyuki

総合スコア5

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

1回答

0評価

0クリップ

261閲覧

投稿2022/03/30 09:35

前提

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のバージョンは最新です。
長文失礼しました。ご回答いただけますと幸いです。よろしくお願いいたします。

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
87.20%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。