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

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

ただいまの
回答率

87.78%

JSONデータをChartsを使ってグラフ表示したい

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,956

score 9

前提・実現したいこと

JSONを使ってGoogleスプレッドシートのデータを取得し、それをグラフ表示するiOSアプリ作っています。

発生している問題・エラーメッセージ

このページリンク内容を参考にさせてもらい、データの代入部分は自分で作ったJSONデータを取得するクラスに変えて、コンパイルは通るのですが、"Thread 1: signal SIGABRT"のエラーが出てアプリが動きません。
また、横軸の配列の型をDouble型ではなく、String型に変更したいのですが、どうすれば良いのかご教授いただければ幸いです。
以下、当該のソースコードです。

該当のソースコード

/*ViewController.swift*/

import UIKit
import Charts

class ViewController: UIViewController {

    var chart: CombinedChartView!
    var lineDataSet: LineChartDataSet!
    var bubbleDataSet: BubbleChartDataSet!

    override func viewDidLoad() {
        super.viewDidLoad()

        //combinedDataを結合グラフに設定する
        let combinedData = CombinedChartData()

        //結合グラフに線グラフのデータ読み出し
        combinedData.lineData = generateLineData()

        //グラフのサイズ設定、座標設定
        chart = CombinedChartView(frame: CGRect(x: 0, y: 20, width: self.view.frame.width , height: self.view.frame.height - 20))

        //chartのデータにcombinedDataを挿入する
        chart.data = combinedData

        //chartを出力
        self.view.addSubview(chart)

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    func generateLineData() -> LineChartData
    {

        //リストを作り、グラフのデータを追加する方法(GitHubにあったCombinedChartViewとかMPAndroidChartのwikiを参考にしている
        //データを入れていく、多重配列ではないため別々にデータは追加していく
        let values: [Double] = GetFarmData().DateArray
        let date : [Double]  = GetFarmData().TempArray
        //DataSetを行うために必要なEntryの変数を作る データによって入れるデータが違うため複数のentriesが必要になる?
        var entries: [ChartDataEntry] = Array()
        for (i, value) in values.enumerated(){
            entries.append(ChartDataEntry(x: date[i], y: value, icon: UIImage(named: "icon", in: Bundle(for: self.classForCoder), compatibleWith: nil)))
        }

        //データを送るためのDataSet変数をリストで作る
        var linedata:  [LineChartDataSet] = Array()

        //リストにデータを入れるためにデータを成形している
        //データの数値と名前を決める
        lineDataSet = LineChartDataSet(values: entries, label: "Line chart unit test data")
        lineDataSet.drawIconsEnabled = false
        //グラフの線の色とマルの色を変えている
        lineDataSet.colors = [NSUIColor.red]
        lineDataSet.circleColors = [NSUIColor.red]
        //上で作ったデータをリストにappendで入れる
        linedata.append(lineDataSet)

        //データを返す。
        return LineChartData(dataSets: linedata)
    }

}
/*GetFarmData/swift*/

import UIKit

class GetFarmData {

    struct FarmData : Codable{
        var Date : [String]
        var Temp : [Double]
    }

    var DateArray:[String] = []
    var TempArray:[Double] = []


    func GetData() {
        let UrlString = "https://script.googleusercontent.com/macros/echo?user_content_key=Ay52NkEmsTwP9m_g-4Nv7bfyqPzORn1CtkPpDI45PJKbmJkTErIIrLunc4oeUQRCd5toyTRnpgETSjloFsDHd0HfqGkKwZ5dm5_BxDlH2jW0nuo2oDemN9CCS2h10ox_1xSncGQajx_ryfhECjZEnLoHBjeqZZOS6uDdoVZbaErJG4ILXd2YeBoAJC8FsHjBLhCJb1CRC6P4G-VDNPWQFw&lib=Mt8YZ4DmL8BZYB77Ydcy6Qd3x1ejDTiej" //WebアプリのURL

        if let url = URL(string: UrlString){
            URLSession.shared.dataTask(with: url) { data, response, error in
                if let data = data{
                    do{
                        let FarmInfo = try JSONDecoder().decode(FarmData.self, from: data)
                        DispatchQueue.main.async {
                                self.DateArray = FarmInfo.Date
                                self.TempArray = FarmInfo.Temp
                        }
                    }catch let error{
                        print(error)
                        print(data)
                    }
                }
                }.resume()
        }
        // Do any additional setup after loading the view, typically from a nib.
    }

}

試したこと

普通のDouble型配列の代入はできたのですが、JSONから引っ張ってきたデータを代入することができません。
DateArrayに関してはString型なので、エラーが出るのは当然なのですが、Double型の配列にして実行した時でも、最初に述べた"Thread 1: signal SIGABRT"のエラーが出てしまいます。
また、GetFarmData.swiftのDateArrayとTempArrayにわざわざ一度代入しなくてもできるような気がするのですが、どうなのでしょうか。
お手数ですが、ご回答いただけると幸いです。よろしくお願いします。

補足情報(FW/ツールのバージョンなど)

Xcode 10.1
Swift4

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

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

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

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

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

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

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

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

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • takabosoft

    2018/12/27 17:49 編集

    ちょっと気がかりなのですが、ソース中にuser_content_keyのキーが含まれているようですが、これって他人に使われても大丈夫なキーですか?もし情報漏えいしているようなら質問自体の削除依頼を出したほうが良いです(編集しても編集履歴に残るので)問題無ければ無視してください。

    キャンセル

回答 1

checkベストアンサー

0

まだこちらの回答を探しているようならですが、
いくつかのブロックに分けて考えてみましょう。

1。jsonのファイルの読み取り、
2。データの作成
3。グラフへの表示

用意したDouble型配列の代入はグラフにできるということは、
1→2において、どこかに問題があるのではないですか?
自分が用意したDouble型配列と、jsonファイルを読み取ったものの配列に
違いがないか、printで表示して、確認してみてください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/04 18:41

    返信が遅くなってしまい申し訳ありません。
    ご回答ありがとうございます。
    ご指摘の通り、JSONファイルを受け取っている間にデータの作成が行われていました。
    JSOファイルを受け取っている間データ作成を待つような処理をしなければならないことがわかったのですが、どのように書けばいいのかわからず、困っております。
    よろしければ、それについてもご教授していただけないでしょうか?

    キャンセル

  • 2019/01/04 18:57

    JSONファイルは、ネットからDLしている?とかですかね?
    通常使うべきセオリーとしては、非同期処理(JSONのDL、分解とか)の時に必要となる、
    GCD(Grand Central Dispatch)というものです。
    使い方は下記参照。概念はググってもっと調べてみてください。
    https://qiita.com/shtnkgm/items/d9b78365a12b08d5bde1

    しかし、自分にはGCDの概念?がまだ完全理解できていなくて、
    自分はこのGCDを使ってない(使い切れていない)です。
    (きっと使えれば便利なんだろうなといつも思っていますが。。。)
    苦肉の策として使用しているのが、
    変数+定数を一つずつ追加して、回数を数える方法です。

    例えば、MapKitのMKLocalSearchや、
    Firebase/FirestoreからのDLデータが
    全部DLされてからの処理をしたい場合、
    はじめに全部のデータの個数を定数に保存。
    繰り返し文(for)などでデータを分解して、処理していく際に
    その回数を変数でカウントして、
    最初に取得した全体の個数に達した時を条件にif文を作成し、
    完了のタイミングを取得しています。

    どうでしょう?きっと、そんなの邪道だ、GCDを使えと
    怒られそうな気もしますが、自分はそうしてます。
    ご参考までに。。。

    キャンセル

  • 2019/01/08 14:48

    ご回答ありがとうございます!
    教えていただいたページなどを参考にしながらやったところ思った動作ができるようになりました。
    DispatchQueue.main.asyncのところをDispatchSemaphoreを使うことでできました。
    ご丁寧に教えていただき本当にありがとうございます!

    キャンセル

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

  • ただいまの回答率 87.78%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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