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

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

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

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

Xcode

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

Swift

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

Q&A

解決済

1回答

1666閲覧

swift: ios-charts xAxisについて

退会済みユーザー

退会済みユーザー

総合スコア0

iOS

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

Xcode

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

Swift

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

0グッド

0クリップ

投稿2018/08/05 13:59

swift

1import UIKit 2import Charts 3 4class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { 5 6 @IBOutlet weak var weight: UITextField! 7 @IBOutlet weak var bodyfat: UITextField! 8 @IBOutlet weak var chtChart: LineChartView! 9 @IBOutlet weak var chartssegment: UISegmentedControl! 10 @IBOutlet weak var mytableView: UITableView! 11 var numbers : [Double] = [] 12 var bfpnumbers : [Double] = [] 13 var item = String() 14 15 var dete = NSDate() 16 17 @IBAction func okBtr(_ sender: Any) { 18 let input = Double(weight.text!) 19 let output = Double(bodyfat.text!) 20 21 numbers.append(input!) //here we add the data to the array. 22 bfpnumbers.append(output!) 23 24 updateGraph() 25 item.append("(numbers)" + "(bfpnumbers)") 26 mytableView.reloadData() 27 weight.text = "" 28 bodyfat.text = "" 29 } 30 31 func updateGraph(){ 32 var lineChartEntry = [ChartDataEntry]()//ここが折れ線グラフのキー 33 var lineChartEntry2 = [ChartDataEntry]() 34 35 for i in 0..<numbers.count { 36 37 let value = ChartDataEntry(x: Double(i), y: numbers[i]) 38 } 39 40 for i in 0..<bfpnumbers.count { 41 42 let value2 = ChartDataEntry(x: Double(i), y: bfpnumbers[i]) 43 44 lineChartEntry2.append(value2) 45 46 } 47 48 let line1 = LineChartDataSet(values: lineChartEntry, label: "円相場") 49 line1.colors = [NSUIColor.blue] 50 51 let line2 = LineChartDataSet(values: lineChartEntry2, label: "ドル相場") 52 line2.colors = [NSUIColor.red] 53 54 line1.axisDependency = .left 55 line2.axisDependency = .right 56 57 line1.circleRadius = 6 58 line1.circleColors = [UIColor.red] 59 60 61 line2.circleRadius = 5 62 line2.circleColors = [UIColor.blue] 63 64 let dateFormatter = DateFormatter() 65 dateFormatter.locale = NSLocale(localeIdentifier: "en_US") as Locale? // ロケールの設定 66 dateFormatter.dateFormat = "yyyy/MM/dd"//:ss" // 日付フォーマットの設定 67 68 let dateString = dateFormatter.string(from: dete as Date) 69 print(dateString) // -> 2014/06/25 02:13:18 70 71 let xAxis = chtChart.xAxis 72 xAxis.valueFormatter = IndexAxisValueFormatter(values:[dateString]) 73 xAxis.labelPosition = .bottom 74 xAxis.labelCount = line1.entryCount 75 xAxis.drawLabelsEnabled = true 76 xAxis.drawLimitLinesBehindDataEnabled = true 77 xAxis.avoidFirstLastClippingEnabled = true 78 79 chtChart.xAxis.spaceMin = 0.5 80 chtChart.xAxis.spaceMax = 0.5 81 chtChart.xAxis.drawGridLinesEnabled = false //x軸のグリッド表示(今回は表示しない) 82 83 chtChart.leftAxis.axisMaximum = 150 //y左軸最大値 84 chtChart.leftAxis.axisMinimum = 30 //y左軸最小値 85 86 chtChart.rightAxis.axisMaximum = 50 //y左軸最大値 87 chtChart.rightAxis.axisMinimum = 0 //y左軸最小値 88 89 chtChart.rightAxis.drawGridLinesEnabled = false 90 91 let data = LineChartData() 92 data.addDataSet(line1) 93 data.addDataSet(line2) 94 95 chtChart.data = data 96 chtChart.chartDescription?.text = "My awesome chart" 97 98 } 99 100 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 101 return numbers.count 102 } 103 104 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 105 let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) 106 107 let dateFormatter = DateFormatter() 108 dateFormatter.locale = NSLocale(localeIdentifier: "en_US") as Locale? // ロケールの設定 109 dateFormatter.dateFormat = "yyyy/MM/dd "//:ss" // 日付フォーマットの設定 110 111 let dateString = dateFormatter.string(from: dete as Date) 112 print(dateString) // -> 2014/06/25 02:13:18*/ 113 114 let str = String("(numbers)" + "(bfpnumbers)") 115 116 cell.textLabel?.text = dateString + ("(numbers[indexPath.row]) " + "¥ " + "(bfpnumbers[indexPath.row])") + " $"//str.description 117 118 print(str) 119 return cell 120 } 121 122 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 123 return 40 124 } 125 126 func tableView(_ tableView: UITableView, 127 trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { 128 guard indexPath.row % 2 == 0 else { return UISwipeActionsConfiguration(actions: []) } 129 130 let deleteAction = UIContextualAction(style: .destructive, title: "Delete") 131 { action, view, completionHandler in 132 self.numbers.remove(at: indexPath.row) 133 self.bfpnumbers.remove(at: indexPath.row) 134 self.mytableView.reloadData() 135 completionHandler(true) 136 } 137 138 let edit = UIContextualAction(style: .normal,title: "edit", handler: 139 { (action: UIContextualAction, view: UIView, success :(Bool) -> Void) in 140 //self.showTextFieldAlert(.titleEdit, index: indexPath.section) 141 success(true) 142 }) 143 144 edit.backgroundColor = .blue 145 let config = UISwipeActionsConfiguration(actions: [deleteAction,edit]) 146 config.performsFirstActionWithFullSwipe = false 147 return config 148 } 149 150 override func viewDidLoad() { 151 super.viewDidLoad() 152 153 mytableView.delegate = self 154 mytableView.dataSource = self 155 //mytableView.separatorColor = UIColor.clear 156 makeKeybord() 157 self.weight.keyboardType = UIKeyboardType.decimalPad 158 self.bodyfat.keyboardType = UIKeyboardType.decimalPad 159 160 } 161 //入力画面を閉じる時 162 func makeKeybord(){ 163 // 仮のサイズでツールバー生成 164 let kbToolBar = UIToolbar(frame: CGRect(x: 0, y: 0, width: 320, height: 40)) 165 kbToolBar.barStyle = UIBarStyle.default // スタイルを設定 166 167 kbToolBar.sizeToFit() // 画面幅に合わせてサイズを変更 168 169 // スペーサー 170 let spacer = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: self, action: nil) 171 172 // 閉じるボタン 173 let commitButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(ViewController.commitButtonTapped)) 174 175 kbToolBar.items = [spacer, commitButton] 176 weight.inputAccessoryView = kbToolBar 177 bodyfat.inputAccessoryView = kbToolBar 178 } 179 180 @objc func commitButtonTapped (){ 181 self.view.endEditing(true) 182 } 183}

現状の結果

理想のイメージ

実現したい事

横軸の日付を各点に表示させたい。
縦軸に関しては追加されるデーターに対し80ならば最高点が83点最低点が76と自動的に縦軸が割り振られるようにしたい。

現状で出来ていることと困っていること

大まかにはイメージした折れ線グラフを作る事は出来たが縦軸・横軸ともに見辛い、出来てない箇所がある。
縦軸に関しては現状では事前に入力される範囲を予想し設定してるがそれだと範囲が広すぎて見づらくなっている。
理想として入力されるされたデータの+3-3の縦軸にしたい。
横軸に関しては一番初めの入力に限り入力された時の日付を取得し、横軸に表示させる事が出来たが以降の入力の際には横軸に反映させる事が出来なくて困っています。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

let dateString = dateFormatter.string(from: dete as Date) print(dateString) // -> 2014/06/25 02:13:18 let xAxis = chtChart.xAxis xAxis.valueFormatter = IndexAxisValueFormatter(values:[dateString])

としているので常にひとつの値しかx軸に表示されないです。表示したい値の配列を渡す必要があるのでこんな感じでしょうか。

class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource { @IBOutlet weak var weight: UITextField! @IBOutlet weak var bodyfat: UITextField! @IBOutlet weak var chtChart: LineChartView! @IBOutlet weak var chartssegment: UISegmentedControl! @IBOutlet weak var mytableView: UITableView! var numbers : [Double] = [] var bfpnumbers : [Double] = [] var item = String() var dete = NSDate() var dateStrings : [String] = [] // 省略 let dateString = dateFormatter.string(from: dete as Date) print(dateString) // -> 2014/06/25 02:13:18 dateStrings.append(dateString) let xAxis = chtChart.xAxis xAxis.valueFormatter = IndexAxisValueFormatter(values:dateStrings)

データの+3-3はそれぞれの最大値と最小値を取ってaxisMaximumなどに設定するだけだと思いますので

var minNum = 0.0 var maxNum = 0.0 for num in numbers { if num < minNum || minNum == 0.0 { minNum = num } if num > maxNum { maxNum = num } } var minBfpNum = 0.0 var maxBfpNum = 0.0 for bfpNum in bfpnumbers { if bfpNum < minBfpNum || minBfpNum == 0.0 { minBfpNum = bfpNum } if bfpNum > maxBfpNum { maxBfpNum = bfpNum } } chtChart.leftAxis.axisMaximum = maxNum + 3.0 //y左軸最大値 chtChart.leftAxis.axisMinimum = minNum - 3.0 //y左軸最小値 chtChart.rightAxis.axisMaximum = maxBfpNum + 3.0 //y左軸最大値 chtChart.rightAxis.axisMinimum = minBfpNum - 3.0 //y左軸最小値

のようになると思いますが、これだと変化率に応じず一律+-3で最大値、最小値が決定されてしまうため、例えば、片方のグラフが最小値が100、最大値が1000。もう片方が最小値10、最大値20のようなグラフだと。始めの方は補正(プラスマイナス3)がほとんど効かない状態、逆に最初の方は補正がかなり効いている状態になると思います。なので、それぞれのグラフでの補正値は変化させる必要があるかもしれません。

ちなみにavoidFirstLastClippingEnabled = trueにしていると最初のxラベルがずれた状態になってしまっています。

コメントへの回答追記:
entryCountの個数分表示するのでentryCountの数が増えているのであれば問題ありません。
真ん中の例のようにvar dateStrings : [String] = []を外で持たせて
それにappendするようにしていますでしょうか?valuesに渡す値が複数になっていないと複数表示されません。

// 省略 numbers = [100.0, 110.0, 105.0, 120.0] bfpnumbers = [30.0, 20.0, 25.0, 15.0] // 省略 dateStrings = ["08/05", "08/06", "08/07", "08/09"] let xAxis = chtChart.xAxis xAxis.valueFormatter = IndexAxisValueFormatter(values:dateStrings)

まず上記のように固定値で配列を持たせて複数表示されるか確認していただいてもよろしいでしょうか。

投稿2018/08/06 05:14

編集2018/08/06 07:25
razuma

総合スコア1313

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/08/06 06:56

懇切に教えて頂きありがとうございます。 縦軸に関してはイメージした通りになりました。 横軸に関して試して見たのですがどうしても日付が一つしか反映されませんでした。 恐らくなのですがxAxis.labelCount = line1.entryCount に問題があるのかなと思うのですが line1.entryCountで合っているのでしょうか?
退会済みユーザー

退会済みユーザー

2018/08/06 07:29

固定値を持たせると各点ごとに横軸が追加されました。 なので、xAxis.labelCount自体には問題はありませんでした。
退会済みユーザー

退会済みユーザー

2018/08/06 07:32

今固定値で確認出来たので再度dateStrings = [dateString]にしたところ出来ました。
razuma

2018/08/06 07:36

変数名がわかりにくかったですかね? 単純にvalues:dateStringsとして渡した配列で横軸の値が決まっていくので let dateString = dateFormatter.string(from: dete as Date) print(dateString) // -> 2014/06/25 02:13:18 [dateString]で渡してしまうと必ずひとつの配列しか渡らないので1個しか表示されないので dateStringを追加していった配列を渡す必要があると言うことです。
退会済みユーザー

退会済みユーザー

2018/08/06 07:53

私の理解力不足でおお手数をお掛けしてすいませんでした。 それでなんですが参考程度に例えば入力しなかった時の横軸も表記させたい場合はどのようにすればいいのでしょうか? もし良ければ教えて頂けないでしょう?
razuma

2018/08/06 08:47

とりあえず、全て何も入力しなかった場合でも下ラベルを表示させると言う意味では xAxis.axisMinimum = 0.0 xAxis.axisMaximum = 4.0 のようにx軸に対してもmin、max設定することで表示させることができます。 任意の箇所のみ表示をしない、x軸に関して任意の点でラベルを表示したいと言うと標準の機能でできるかはちょっとわかりません(あまりChartsに詳しくないので。カスタムでポイントを設定できるような機能を追加する必要があるかもしれません)
退会済みユーザー

退会済みユーザー

2018/08/06 15:22

なるほど。そういうやり方があるのですね。 最後にお聞きしたい事があるのですが現状のグラフでは値を追加すると真ん中から追加されていくのですがそれを左端から追加していく形にしたいのですがグラフの値の左寄せや点と点の幅を決める方法はあるのでしょうか? もしお分かりでしたら教えて頂けると嬉しいです。
razuma

2018/08/07 02:46

x軸もまた表示するべきポイントの数によって位置がきまってきます。どの位置から表示したいかによりますが、例えば5ポイントぐらいで表示したいとすると numbers = [100.0] bfpnumbers = [30.0] dateStrings = ["08/01"] xAxis.axisMinimum = -0.5 // axisMinimumで設定するとspaceがきかないようなので0.5でスペースをあけてみる xAxis.axisMaximum = 4.0 こんな感じでminとmaxを決めてあげて入れるのは1個だけにすると左から追加されているように表示されると思います。
退会済みユーザー

退会済みユーザー

2018/08/07 11:56

なるほど。分かりました。 懇切に色々教えていただきありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問