0

I am trying to design an ios app to display json data in a line chart.

First of all, this is my json data.

{
TH_5min: [
{
Data: "2019-02-23T00:00:00",
Time: "11:00:00",
XTP_A: 10.5, //temperature 1
XHP_A: 11.5, //humidity 1
XTP_B: 33.5,
XHP_B: 44.6,
XTP_C: 88.9,
XHP_C: 66.6,
XTP_D: 77.9,
XHP_D: 99.6,
XTP_E: 87.87,
XHP_E: 66.66
},
{
Data: "2019-02-23T00:00:00",
Time: "11:05:00",
XTP_A: 55.2,  //temperature 1
XHP_A: 44.3,  //humidity 1
XTP_B: 66.6,
XHP_B: 77.87,
XTP_C: 87.77,
XHP_C: 87.87,
XTP_D: 8.87,
XHP_D: 78.78,
XTP_E: 87.78,
XHP_E: 87.87
}
]
}

This is my implementation of the swift code showing json data.

override func viewDidLoad() {
        super.viewDidLoad()
      apiip = APIip
        getlatestTh_5min()
    @objc func getlatestTh_5min(){
        guard let th_5minUrl = URL(string: "http://" + apiip + "/api/Th_5min") else{
            return
        }
        let request = URLRequest(url: th_5minUrl)
        let task = URLSession.shared.dataTask(with: request, completionHandler: {(data,response,error) -> Void in
            if let error = error {
                print(error)
                return
            }
            if let data = data {
                self.th_5mins = self.pardrJsonData(data: data)
                self.getchat()
            }
        })
        task.resume()
        //getchat()
    }
    func pardrJsonData(data: Data) -> [Th_5min]{
        var th_5mins = [Th_5min]()
        do {
            let jsonResult = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
            let jsonTh_5mins = jsonResult?["TH_5min"] as! [AnyObject]
            print(jsonTh_5mins)
            print(th_5mins.count)
            for jsonTh_5min in jsonTh_5mins{
                var th_5min = Th_5min()
                th_5min.Data = jsonTh_5min["Data"] as! String
                th_5min.Time = jsonTh_5min["Time"] as! String
                th_5min.XTP_A = jsonTh_5min["XTP_A"] as! Double
                th_5min.XHP_A = jsonTh_5min["XHP_A"] as! Double
                print(th_5min)
                th_5mins.append(th_5min)
                //getchat()
            }        }catch{
                print(error)
        }
        //getchat()
        return th_5mins

    }

This is how I draw the line chart, using swift code.

@objc func getchat(){

        chartView = LineChartView()  
        chartView.frame = CGRect(x: 20, y: 80, width: self.view.bounds.width-20,height: self.view.bounds.height-100)
        self.view.addSubview(chartView)
        var dataEntries1 = [ChartDataEntry]()
        for i in 0..<th_5mins.count {
            chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: [th_5mins[i].Time])
            let y = th_5mins[i].XTP_A
            let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
            dataEntries1.append(entry)
        }
        let chartDataSet1 = LineChartDataSet(entries: dataEntries1, label: "temperature")

        chartDataSet1.colors = [NSUIColor.red]

        var dataEntries2 = [ChartDataEntry]()
        for i in 0..<th_5mins.count {
            chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: [th_5mins[i].Time])
            let y = th_5mins[i].XHP_A
            let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
            dataEntries2.append(entry)

        }
        let chartDataSet2 = LineChartDataSet(entries: dataEntries2, label: "humidity")
        chartDataSet2.colors = [NSUIColor.black]

        let chartData = LineChartData(dataSets: [chartDataSet1, chartDataSet2])

        chartView.data = chartData
    }
}

This is the result of my work.

enter image description here

Although the json data is successfully displayed, I don't know why it is loading for a long time, and I hope that the "time" in my json data can be displayed on the X axis above, marked with my temperature and humidity, and cannot be successful. I also hope that my line chart view can be implemented as a layout.

1

1 Answer 1

0
  1. "I don't know why it is loading for a long time". Do you mean that the graph does not load immediately upon opening the view? This is because the data is loading asynchronously from a remote source (correctly now, well done). It may well take a few seconds for your JSON to download over the web. That is ok. You can test the endpoint in a browser and see how long the response takes.

  2. "I hope that the 'time' in my json data can be displayed on the X axis above". Yes. You can take the assignation of IndexAxisValueFormatter outside of the loop and you should pass all labels as values into the constructor. Try this code, replacing the equivalent loop:-

    var labels: [String] = []
    for i in 0..<th_5mins.count {
        let y = th_5mins[i].XTP_A
        let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
        dataEntries1.append(entry)
        labels.append(th_5mins[i].Time)
    }
    chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: labels)
    

Note that the method you use for plotting against dates will result in an evenly spread graph, irrespective of your time gaps (e.g. if readings are 5 mins apart between the first two, but 5 years apart for the next two, they will still appear with even gaps between them.

Sign up to request clarification or add additional context in comments.

18 Comments

Thank you for your patience and explanation, but I still don't understand how to adjust my swift code, how do I use this new class?
Where have you defined IndexAxisValueFormatter? You are using it in your code already. Replace it with mine.
for i in 0..<th_5mins.count { class IndexAxisValueFormatter: NSObject, IndexAxisValueFormatter { func stringforvalue(value: Double , axis: AxisBase?) -> String { let i = round(Double) return th_5mins[i].Time } } //chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: [th_5mins[i].Time]) let y = th_5mins[i].XTP_A let entry = ChartDataEntry.init(x: Double(i), y: Double(y)) dataEntries1.append(entry) } . I
I just replace chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: [th_5mins[i].Time]) to class IndexAxisValueFormatter: NSObject, IndexAxisValueFormatter { func stringforvalue(value: Double , axis: AxisBase?) -> String { let i = round(Double) return th_5mins[i].Time } }
No. Revert to your code as above. Hold Command and click on IndexAxisValueFormatter. Go to definition. You must have defined it somewhere. Replace its definition - not its usage - with mine. If not, put the definition I gave outside of your getchat function. Change the chartView.xAxis.valueFormatter = line exactly as I've shown you in the answer.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.