从数组中提取多个数据时如何使用iOS图表?

时间:2017-01-07 17:11:37

标签: ios swift charts ios-charts

过去几天我一直在学习使用iOS图表,并且在处理单个'单独'从API调用的数据。

但是我现在卡住了,因为我想从数组中提取多个数据。

我的目标是根据下面数组中每个winning_streak的{​​{1}}创建一个条形图:

user_name

这是我检索API的代码:

这是我需要帮助的地方 - 我是否需要制作某种循环? 在提供的答案中,图表中显示的用户数量已预先编程。

使用我当前的代码,它只会选出数组中的第一个对象。如何让它循环遍历数组并填充所需的变量?

["leagueStats": {
winningStreak =     (
            {
        id = 2;
        "user_name" = Dicky;
        "winning_streak" = 5;
    },
            {
        id = 6;
        "user_name" = G;
        "winning_streak" = 2;
    },
            {
        id = 5;
        "user_name" = Sultan;
        "winning_streak" = 0;
    }
);
}
]

但是,上面的代码只会从要使用的数组中的第一条记录中提取信息 if let dict = json?["leagueStats"] as? [String:AnyObject] { // WINNING STREAK if let dataWinStreak = dict["winningStreak"] as? [[String : AnyObject]] { let newdictWinStreak = dataWinStreak.first! // I'm guess this needs to be removed and this section re-structured? let tempWinStreakNumber = newdictWinStreak ["winning_streak"] as? String let tempWinStreakNewNumber = Int(tempWinStreakNumber!) let doubleWinStreak = Double(tempWinStreakNewNumber!) self.winStreak = doubleWinStreak self.winningStreak = ["Wins"] let games = [self.winStreak] self.setWinStreakChart(dataPoints: self.winningStreak, values: games) }

我希望能够生成3个不同的列5DickyG,其中包含Sultan5的相应值,以及2

这是我显示条形图的代码 - 目前只显示1列,显示0

5

这就是我所拥有的:

enter image description here

理想情况下,我想要的是标签&#39; Win Streak&#39;要成为API中的func setWinStreakChart(dataPoints: [String], values: [Double]){ let formato:WinningStreakFormatter = WinningStreakFormatter() let xaxis:XAxis = XAxis() winningStreakBarChart.noDataText = "you need to provide some data for the chart." var dataEntries: [BarChartDataEntry] = Array() for i in 0..<dataPoints.count { let dataEntry = BarChartDataEntry(x: Double(i), y: values[i]) dataEntries.append(dataEntry) formato.stringForValue (Double(i), axis: xaxis) } xaxis.valueFormatter = formato winningStreakBarChart.xAxis.valueFormatter = xaxis.valueFormatter let chartDataSet = BarChartDataSet(values: dataEntries, label: "Games Played") let chartData = BarChartData(dataSets: [chartDataSet]) chartData.addDataSet(chartDataSet) winningStreakBarChart.data = chartData winningStreakBarChart.xAxis.granularityEnabled = true winningStreakBarChart.xAxis.granularity = 1.0 self.winningStreakBarChart.xAxis.labelPosition = XAxis.LabelPosition.bottom } ,然后是user_name来说明Games _Played。在这个特定的实例中,我希望数组中的3个user_names有3列。

完成此操作后,作为次要目标,我想为Winning Streak添加另一个数据集,该数据集将按相同的Losing Streak进行分组。

有人可以告诉我该怎么做吗?谢谢

1 个答案:

答案 0 :(得分:3)

WinningStreakFormatter类用于格式化xAxis标签,这里我使用了一种重用图表对象数据的方法,因为结果WinningStreakFormatter对图表视图有弱引用。因此,使用此方法,我们可以通过图表视图保存数据,而不是使用WinningStreakFormatter

保留其他副本
import Foundation
import Charts

class WinningStreakFormatter: NSObject, IAxisValueFormatter {

    weak var _chartView : BarChartView!

    init(chartView : BarChartView) {
        self._chartView = chartView
    }

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        let barChartData : IChartDataSet = (self._chartView.barData?.dataSets.first)!
        let barChartDataEntry : ChartDataEntry = barChartData.entryForIndex(Int(value))!
        return barChartDataEntry.data as! String
    }
}

参考下面的代码以准备建议的图表,在下面的代码中,ChartView基本上是BarChartView类型的实例变量。此外,我使用了您在API中使用的相同数据结构,您只需将dataPoints替换为已解析的数据结构。

    self.chartView.drawBarShadowEnabled = false
    self.chartView.drawValueAboveBarEnabled = true
    self.chartView.chartDescription?.enabled = false

    let  xAxis : XAxis = self.chartView.xAxis;
    xAxis.labelFont = UIFont(name: "HelveticaNeue-Light", size: 10.0)! 
    xAxis.labelTextColor = UIColor.black
    xAxis.drawAxisLineEnabled = false
    xAxis.drawGridLinesEnabled = true
    xAxis.granularity = 1;
    xAxis.labelPosition = .bottom
    xAxis.valueFormatter = WinningStreakFormatter(chartView: self.chartView)

    let yAxisLeft : YAxis = self.chartView.leftAxis
    yAxisLeft.axisMinimum = 0.0

    let yAxisRight : YAxis = self.chartView.rightAxis
    yAxisRight.axisMinimum = 0.0

    let l : Legend = self.chartView.legend;
    l.horizontalAlignment = Legend.HorizontalAlignment.left
    l.verticalAlignment = Legend.VerticalAlignment.bottom
    l.orientation = Legend.Orientation.horizontal
    l.drawInside = false
    l.form = Legend.Form.square
    l.formSize = 9.0
    l.font = UIFont(name: "HelveticaNeue-Light", size: 11.0)!
    l.xEntrySpace = 4.0

    //Data Structure built for each user for winning streak, you can use your parsing logic to prepare the same
    let winningStreakDM1 : [String : Any] = [
        "id" : 2,
        "user_name" : "Dicky",
        "winning_streak" : 5
    ]

    let winningStreakDM2 : [String : Any] = [
        "id" : 6,
        "user_name" : "G",
        "winning_streak" : 2
    ]

    let winningStreakDM3 : [String : Any] = [
        "id" : 5,
        "user_name" : "Sultan",
        "winning_streak" : 0
    ]


    //Array of the each user winning streak dictionary.
    let dataPoints = [winningStreakDM1, winningStreakDM2, winningStreakDM3]

    var values = [BarChartDataEntry]()

    for i in 0..<dataPoints.count {
        let xValue = Double(i)
        let yValue = Double(dataPoints[i]["winning_streak"] as! Int)

        let barChartDataEntry = BarChartDataEntry(x: xValue, y: yValue, data: dataPoints[i]["user_name"] as AnyObject)
        values.append(barChartDataEntry)
    }

    let barChartDataSet = BarChartDataSet(values: values, label: "Winning Streak")
    barChartDataSet.colors = ChartColorTemplates.material()

    let barChartData = BarChartData(dataSet: barChartDataSet)
    barChartData.setValueFont(UIFont.systemFont(ofSize: 12.0))
    self.chartView.data = barChartData

Output of the above sample code.