从数组中提取多个数据时如何使用 iOS 图表?
How to use iOS Charts when pulling in multiple data from an array?
过去几天我一直在学习使用 iOS 图表,并在处理从 API 调用的 'single' 数据时成功地使用了它们。
但是我现在卡住了,因为我想从一个数组中提取多个数据。
我的目标是根据下面数组中每个 user_name
的 winning_streak
创建一个条形图:
["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;
}
);
}
]
这是我检索 API:
的代码
这是我需要帮助的地方 - 我需要生成某种循环吗?
在提供的答案中,图表中出现的用户数量是预先编程的。
在我当前的代码下面,它只挑选出数组中的第一个对象。我如何让它循环遍历数组并填充所需的变量?
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)
}
然而,上面的代码仅从数组中的第一条记录中提取信息以供使用,5
。
我希望能够生成 3 个不同的列,Dicky
、G
、Sultan
,对应的值为 5
、2
, 和 0
.
这是我用于显示条形图的代码 - 目前仅显示 1 列,显示 5
。
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
}
这是我的:
理想情况下,我想要的是标签 'Win Streak' 是 API 中的 user_name
,然后是图例 Games _Played
表示 Winning Streak
。在这个特定的例子中,我想要数组中的 3 user_names 的 3 列。
完成后,作为辅助 objective 我想为 Losing Streak
添加另一个数据集,它将按相同的 user_name
.
分组
有人可以告诉我怎么做吗?谢谢
WinningStreakFormatter
class 用于格式化 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 中相同的数据结构,您可以简单地将数据点替换为已解析的数据结构。
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
过去几天我一直在学习使用 iOS 图表,并在处理从 API 调用的 'single' 数据时成功地使用了它们。
但是我现在卡住了,因为我想从一个数组中提取多个数据。
我的目标是根据下面数组中每个 user_name
的 winning_streak
创建一个条形图:
["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;
}
);
}
]
这是我检索 API:
的代码这是我需要帮助的地方 - 我需要生成某种循环吗? 在提供的答案中,图表中出现的用户数量是预先编程的。
在我当前的代码下面,它只挑选出数组中的第一个对象。我如何让它循环遍历数组并填充所需的变量?
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)
}
然而,上面的代码仅从数组中的第一条记录中提取信息以供使用,5
。
我希望能够生成 3 个不同的列,Dicky
、G
、Sultan
,对应的值为 5
、2
, 和 0
.
这是我用于显示条形图的代码 - 目前仅显示 1 列,显示 5
。
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
}
这是我的:
理想情况下,我想要的是标签 'Win Streak' 是 API 中的 user_name
,然后是图例 Games _Played
表示 Winning Streak
。在这个特定的例子中,我想要数组中的 3 user_names 的 3 列。
完成后,作为辅助 objective 我想为 Losing Streak
添加另一个数据集,它将按相同的 user_name
.
有人可以告诉我怎么做吗?谢谢
WinningStreakFormatter
class 用于格式化 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 中相同的数据结构,您可以简单地将数据点替换为已解析的数据结构。
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