iT邦幫忙

0

ios 實作折線圖顯示json資料

各位大哥先進晚安!清明連假快樂!
小弟正在撰寫一支簡單的ios app 目前實作的功能是讀取api json data 並且以折線圖呈現
格式如下

{
Elc_5min: [
{
Data: "2019-02-23T00:00:00",
Time: "11:54:00",
XElc_A_Vrs: 119.2,
XElc_A_Vst: 117.1,
XElc_A_Vtr: 118,
XElc_A_Ir: 11,
XElc_A_Is: 14,
XElc_A_It: 9,
Elc_A_KWH: 1001,
XElc_B_Vrs: 221.3,
XElc_B_Vst: 221.9,
XElc_B_Vtr: 220.9,
XElc_B_Ir: 25,
XElc_B_Is: 27,
XElc_B_It: 23,
Elc_B_KWH: 20004
},
{
Data: "2019-02-23T00:00:00",
Time: "11:59:00",
XElc_A_Vrs: 119.1,
XElc_A_Vst: 118.3,
XElc_A_Vtr: 117.9,
XElc_A_Ir: 10,
XElc_A_Is: 15,
XElc_A_It: 11,
Elc_A_KWH: 1013,
XElc_B_Vrs: 220.1,
XElc_B_Vst: 222.3,
XElc_B_Vtr: 221.1,
XElc_B_Ir: 23,
XElc_B_Is: 29,
XElc_B_It: 23,
Elc_B_KWH: 20011
},
{
Data: "2019-02-23T00:00:00",
Time: "12:04:00",
XElc_A_Vrs: 118.9,
XElc_A_Vst: 118.5,
XElc_A_Vtr: 118.1,
XElc_A_Ir: 13,
XElc_A_Is: 13,
XElc_A_It: 12,
Elc_A_KWH: 1021,
XElc_B_Vrs: 221.4,
XElc_B_Vst: 221.8,
XElc_B_Vtr: 220.7,
XElc_B_Ir: 24,
XElc_B_Is: 26,
XElc_B_It: 21,
Elc_B_KWH: 20019
},
{
Data: "2019-02-23T00:00:00",
Time: "12:09:00",
XElc_A_Vrs: 117.8,
XElc_A_Vst: 117.4,
XElc_A_Vtr: 119.5,
XElc_A_Ir: 12,
XElc_A_Is: 15,
XElc_A_It: 10,
Elc_A_KWH: 1025,
XElc_B_Vrs: 220.3,
XElc_B_Vst: 221.4,
XElc_B_Vtr: 222,
XElc_B_Ir: 20,
XElc_B_Is: 23,
XElc_B_It: 25,
Elc_B_KWH: 20025
},
{
Data: "2019-02-23T00:00:00",
Time: "12:14:00",
XElc_A_Vrs: 117.9,
XElc_A_Vst: 117.8,
XElc_A_Vtr: 117.6,
XElc_A_Ir: 14,
XElc_A_Is: 12,
XElc_A_It: 14,
Elc_A_KWH: 1033,
XElc_B_Vrs: 221.4,
XElc_B_Vst: 221.6,
XElc_B_Vtr: 221.1,
XElc_B_Ir: 25,
XElc_B_Is: 29,
XElc_B_It: 30,
Elc_B_KWH: 20039
},
{
Data: "2019-02-23T00:00:00",
Time: "12:19:00",
XElc_A_Vrs: 118.1,
XElc_A_Vst: 118.5,
XElc_A_Vtr: 118.9,
XElc_A_Ir: 14,
XElc_A_Is: 13,
XElc_A_It: 19,
Elc_A_KWH: 1041,
XElc_B_Vrs: 220.8,
XElc_B_Vst: 220.6,
XElc_B_Vtr: 221.1,
XElc_B_Ir: 28,
XElc_B_Is: 27,
XElc_B_It: 25,
Elc_B_KWH: 20047
},
{
Data: "2019-02-23T00:00:00",
Time: "12:24:00",
XElc_A_Vrs: 119.3,
XElc_A_Vst: 119.1,
XElc_A_Vtr: 119.8,
XElc_A_Ir: 11,
XElc_A_Is: 15,
XElc_A_It: 12,
Elc_A_KWH: 1057,
XElc_B_Vrs: 221.3,
XElc_B_Vst: 221.9,
XElc_B_Vtr: 221.3,
XElc_B_Ir: 23,
XElc_B_Is: 24,
XElc_B_It: 21,
Elc_B_KWH: 20051
},
{
Data: "2019-02-23T00:00:00",
Time: "12:29:00",
XElc_A_Vrs: 118.3,
XElc_A_Vst: 118.1,
XElc_A_Vtr: 119.3,
XElc_A_Ir: 15,
XElc_A_Is: 12,
XElc_A_It: 15,
Elc_A_KWH: 1063,
XElc_B_Vrs: 220.1,
XElc_B_Vst: 220.5,
XElc_B_Vtr: 220.3,
XElc_B_Ir: 23,
XElc_B_Is: 21,
XElc_B_It: 28,
Elc_B_KWH: 20064
},
{
Data: "2019-02-23T00:00:00",
Time: "12:34:00",
XElc_A_Vrs: 111.6,
XElc_A_Vst: 113.1,
XElc_A_Vtr: 111.9,
XElc_A_Ir: 12,
XElc_A_Is: 18,
XElc_A_It: 17,
Elc_A_KWH: 1070,
XElc_B_Vrs: 221.2,
XElc_B_Vst: 223.1,
XElc_B_Vtr: 222.6,
XElc_B_Ir: 20,
XElc_B_Is: 25,
XElc_B_It: 26,
Elc_B_KWH: 20069
},
{
Data: "2019-02-23T00:00:00",
Time: "12:39:00",
XElc_A_Vrs: 114.1,
XElc_A_Vst: 115.2,
XElc_A_Vtr: 114.9,
XElc_A_Ir: 17,
XElc_A_Is: 16,
XElc_A_It: 20,
Elc_A_KWH: 1085,
XElc_B_Vrs: 220.4,
XElc_B_Vst: 220.9,
XElc_B_Vtr: 220.1,
XElc_B_Ir: 21,
XElc_B_Is: 22,
XElc_B_It: 23,
Elc_B_KWH: 20081
},
{
Data: "2019-02-23T00:00:00",
Time: "12:44:00",
XElc_A_Vrs: 114.1,
XElc_A_Vst: 115.2,
XElc_A_Vtr: 114.9,
XElc_A_Ir: 17,
XElc_A_Is: 16,
XElc_A_It: 20,
Elc_A_KWH: 77,
XElc_B_Vrs: 88,
XElc_B_Vst: 66.6,
XElc_B_Vtr: 99.6,
XElc_B_Ir: 5.6,
XElc_B_Is: 78.87,
XElc_B_It: 87.887,
Elc_B_KWH: 44558
}
]
}

實作功能的swift code如下

@objc func getchat(){
        //折線圖func
        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..<elc_5mins.count
        {
            
            let y = elc_5mins[i].XElc_B_Ir
            let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
            dataEntries1.append(entry)
            
        }
        let chartDataSet1 = LineChartDataSet(entries: dataEntries1, label: "R")
        chartDataSet1.colors = [NSUIColor.red]
        //產生第一條折線圖,並載入數據-----------------
        //產生第二條折線圖,並載入數據
        var dataEntries2 = [ChartDataEntry]()
        for i in 0..<elc_5mins.count
        {
            let y = elc_5mins[i].XElc_B_Is
            let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
            dataEntries2.append(entry)
        }
        let chartDataSet2 = LineChartDataSet(entries: dataEntries2, label: "S")
        chartDataSet2.colors = [NSUIColor.black]
        //------3折線圖
        var dataEntries3 = [ChartDataEntry]()
        for i in 0..<elc_5mins.count
        {
            let y = elc_5mins[i].XElc_B_It
            let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
            dataEntries3.append(entry)
        }
        let chartDataSet3 = LineChartDataSet(entries: dataEntries3, label: "T")
        let chartData = LineChartData(dataSets: [chartDataSet1, chartDataSet2, chartDataSet3]) //有三條折線圖
        //X軸顯示溫濕度時間
        //在X軸上方新增加TIME顯示
        var labels: [String] = []
        for i in 0..<elc_5mins.count
        {
            let y = elc_5mins[i].XElc_B_Ir
            let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
            dataEntries1.append(entry)
            labels.append(elc_5mins[i].Time)
        }
        //設定X軸上方資料 = json data "Time"
        chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: labels)
        //顯示折線圖數據
        chartView.data = chartData
    }

稍作說明:code中elc_5mins是解析json data 之後存的array

實作結果
https://ithelp.ithome.com.tw/upload/images/20190403/20115582qurI8wnh9C.png

目前遇到一個問題,考量到未來資料量大(破百、千筆)
想加入僅顯示最新幾筆資料
自己嘗試更改四個for迴圈,想讓只抓最後三筆資料

0..<elc_5mins.count
//改成
elc_5mins.count - 3..<elc_5mins.count

改完後折線圖的數據是正常的,但是X軸上方的時間卻顯示不出來,我檢查了我的

chartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: labels)

最後三筆json的"Time"是有傳入labels的,但是卻顯示不出在line chart中

如下圖
https://ithelp.ithome.com.tw/upload/images/20190403/20115582gZ1NtMRCQs.png

麻煩高手們指點迷津了!

1 個回答

0
海綿寶寶
iT邦超人 1 級 ‧ 2019-04-03 23:44:04

應該是 LineChartView 的使用方法的原因

//原來的資料 LineChartView X 軸就只顯示「一半」的資料了
//表示 LineChartView 有自己的顯示規則(一半或挑個區間...)
0..<elc_5mins.count
//改成多一筆(四筆),變成偶數筆資料試試看
elc_5mins.count - 4..<elc_5mins.count
//又看了一下,原本是11筆,也是奇數
//那就從 10,9,8,7,6,5,4 每個筆數都試試看囉...

另外有個地方我看不太懂

//X軸顯示溫濕度時間
//在X軸上方新增加TIME顯示
var labels: [String] = []
for i in 0..<elc_5mins.count
{
    //vvvvvvvv這三列是否沒必要了?vvvvvvvvvvvvvvv
    let y = elc_5mins[i].XElc_B_Ir
    let entry = ChartDataEntry.init(x: Double(i), y: Double(y))
    dataEntries1.append(entry)
    //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    labels.append(elc_5mins[i].Time)
}
看更多先前的回應...收起先前的回應...

對不起,是我成果圖片示範的不好,他不是只顯示一半的時間,他有全部顯示,因為資料量多,所以他會壓縮X軸,在手機上縮放就會顯示出來了

確實那三列是多餘的,因為X軸資料是之後加上去的,就一起複製修改了

https://ithelp.ithome.com.tw/upload/images/20190404/20115582cdmqgMZURF.png
補上縮放後的圖片

我沒用過 LineChartView
所以只能瞎猜

就上圖來看
「每筆資料都對應自己的一條直線(X軸)」
而在你只保留最後三筆資料的圖表
卻有九條直線
故推測
你前面的資料迴圈有改成只保留三筆
而最後X軸的迴圈仍然是完整的筆數
才會有「X軸labels和資料筆數不符」的情況發生

不,上面的圖是一般顯示所有資料的圖,沒有取幾筆的問題

我改成只讀取3筆的話,我的labels確實是有把最後三筆的時間傳入,但是問題就在於沒有顯示出來!所以有擷取到最後三筆是沒有問題的

我的意思(猜測)是
前面三個 dataEntries1,2,3都有改迴圈

0..<elc_5mins.count
//改成
elc_5mins.count - 3..<elc_5mins.count

只有最後一個沒改到

//X軸顯示溫濕度時間
//在X軸上方新增加TIME顯示
var labels: [String] = []
for i in 0..<elc_5mins.count
{

所以才會
X軸有9條線
而資料點數只有3筆

對,我懂你的意思,但確認過迴圈都是正常的,數據都有正常顯示,唯獨最後一個回圈的time顯示不出來/images/emoticon/emoticon02.gif

如果是這樣
就是「同樣的程式,11筆資料可以正常顯示,3筆資料就不能顯示」
那我只能說是清明節的原因
見鬼了
/images/emoticon/emoticon17.gif

https://ithelp.ithome.com.tw/upload/images/20190405/20115582YlilwbliPI.png

最後一個迴圈(設定X軸資料)labels確定有抓到最後四筆的time
但就是在圖表上沒有輸出出來/images/emoticon/emoticon02.gif

https://ithelp.ithome.com.tw/upload/images/20190405/20115582s6QZjp3593.png

做個比對,左邊是資料全抓,右邊只抓最後四筆,唯獨X軸時間不見了

我還是對這點耿耿於懷
左邊的圖表「九筆資料九條直線」
右邊的圖表「四筆資料七條直線」
/images/emoticon/emoticon06.gif

有試過一次減少一筆資料看看會如何嗎?
11,10,9,8,...

右邊的四筆三條線呀,沒有七條線,有,我試過結果都一樣!

我有嘗試11-1之間每一次回傳的數據都正常..跪異的是,X軸資料每次回傳(傳到labels中)都是正常的,唯獨顯示有問題!11-1的資料區間每一種都有不同結果..例如我傳9筆資料的話,他第一第二資料跑掉了,從第三筆開始,我傳7筆,X軸只有前三筆,而且數據是錯誤的,傳10筆的話,X軸前9筆都有顯示,只有最後一筆不見了,每種資料量都有不同的錯誤,非常奇怪!/images/emoticon/emoticon02.gif
這會是swift line chart函式庫的bug嗎?

剛剛多測試,如果數據每一個都只抓最後9筆elc_5mins.count - 9..<elc_5mins.count

X軸時間抓最後11筆elc_5mins.count - 11..<elc_5mins.count
那麼所有資料包含時間部份竟然都正常,

我說的是這 7 條直線(以紅色標示)
https://ithelp.ithome.com.tw/upload/images/20190405/20001787DDnN6y0Fg8.png

那個內建的,與數據無關,也可以讓他消失!

我要發表回答

立即登入回答