过去几天我一直在学习使用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个不同的列5
,Dicky
,G
,其中包含Sultan
,5
的相应值,以及2
。
这是我显示条形图的代码 - 目前只显示1列,显示0
。
5
这就是我所拥有的:
理想情况下,我想要的是标签' Win Streak'要成为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
进行分组。
有人可以告诉我该怎么做吗?谢谢
答案 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