如何在 iOS 图表的 X 轴上添加字符串?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/39049188/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to add Strings on X Axis in iOS-charts?
提问by Julio Cesar Aguilar Jiménez
With the new release i had some troubles to create some graphs the previous code was:
在新版本中,我在创建一些图表时遇到了一些麻烦,以前的代码是:
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(yVals: dataEntries, label: "Units Sold")
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
barChartView.data = chartData
}
You can pass the values for example an array of months using the line:
您可以使用以下行传递值,例如月份数组:
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
After the new release the code to implement the same graph is:
在新版本之后,实现相同图的代码是:
func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [BarChartDataEntry] = []
for i in 0..<dataPoints.count {
let dataEntry = BarChartDataEntry(x: Double(i+2), y:values[i], data: months )
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units Sold")
let chartData = BarChartData()
chartData.addDataSet(chartDataSet)
barChartView.data = chartData
}
I was trying a few hours but i couldn't find a way to modify the X axis values, i hope someone can help me, thanks!!
我尝试了几个小时,但找不到修改 X 轴值的方法,希望有人能帮助我,谢谢!!
采纳答案by Julio Cesar Aguilar Jiménez
I found the solution, maybe another one can solve this problem in a better way, without create a new class, well this is what I found:
我找到了解决方案,也许另一个可以更好地解决这个问题,而无需创建新类,这就是我发现的:
First you nedd to create a new class, which will be your formatter class and add the IAxisValueFormater interface, then you use the method stringForValue to customize the new values, it takes two parameters, the first is the actual value (you can see it like the index) and second is the axis where the value is.
首先你需要创建一个新类,这将是你的格式化程序类并添加 IAxisValueFormater 接口,然后你使用方法 stringForValue 自定义新值,它需要两个参数,第一个是实际值(你可以看到它像索引),第二个是值所在的轴。
import UIKit
import Foundation
import Charts
@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter
{
var months: [String]! = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
public func stringForValue(value: Double, axis: AxisBase?) -> String
{
return months[Int(value)]
}
}
Now in your file at the begining of your setChart() function you have to create two variables one for your formatter class and one for the axis class:
现在,在 setChart() 函数开头的文件中,您必须创建两个变量,一个用于格式化程序类,另一个用于轴类:
let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
Next, go ahead at the end of the for in loop and pass the index and axis to your formatter variable:
接下来,在 for in 循环的末尾继续,并将索引和轴传递给格式化程序变量:
formato.stringForValue(Double(i), axis: xaxis)
After looping add the format to your axis variable:
循环后将格式添加到轴变量中:
xaxis.valueFormatter = formato
The final step is to add the new xaxisformatted to the barChartView:
最后一步是将新的 xaxisformatted 添加到 barChartView:
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
And that's all the other lines in the setChart() function just keep it where they are, I hope it can help you.
这就是 setChart() 函数中的所有其他行,只需将其保留在原处,我希望它可以帮助您。
回答by Harshit Goel
Hello recently I encountered the same problem and solved it this way-
您好最近我遇到了同样的问题并通过这种方式解决了它-
class ViewController: UIViewController {
var months: [String]!
var unitsSold = [Double]()
weak var axisFormatDelegate: IAxisValueFormatter?
@IBOutlet var viewForChart: BarChartView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
axisFormatDelegate = self
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
// setChart(_ dataPoints:months,_ forY: unitsSold)
setChart(dataEntryX: months, dataEntryY: unitsSold)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func setChart(dataEntryX forX:[String],dataEntryY forY: [Double]) {
viewForChart.noDataText = "You need to provide data for the chart."
var dataEntries:[BarChartDataEntry] = []
for i in 0..<forX.count{
// print(forX[i])
// let dataEntry = BarChartDataEntry(x: (forX[i] as NSString).doubleValue, y: Double(unitsSold[i]))
let dataEntry = BarChartDataEntry(x: Double(i), y: Double(forY[i]) , data: months as AnyObject?)
print(dataEntry)
dataEntries.append(dataEntry)
}
let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units Sold")
let chartData = BarChartData(dataSet: chartDataSet)
viewForChart.data = chartData
let xAxisValue = viewForChart.xAxis
xAxisValue.valueFormatter = axisFormatDelegate
}
}
At the end simply add the extension for the delegate
最后只需为委托添加扩展名
extension ViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return months[Int(value)]
}
}
Figured this solution out through this link https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk
通过此链接找到此解决方案 https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk
回答by Damien Bannerot
As many people said you can create a class or extend with the type IAxisValueFormatter, but you can easily use the following method which only take 3 lines :
正如许多人所说,您可以创建一个类或使用 IAxisValueFormatter 类型扩展,但您可以轻松使用以下方法,该方法只需要 3 行:
self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
return xStrings[Int(index)]
})
here's my setChart() function in case some of you find some of my customization interesting :
这是我的 setChart() 函数,以防你们中的一些人发现我的一些自定义很有趣:
func setChartView(entriesData: [entry]) {
var chartEntries: [ChartDataEntry] = []
var xStrings: [String] = []
let sortedentriesData = entriesData.sorted { (s1: entry, s2: entry) -> Bool in
return s1.timestamp < s2.timestamp
}
for (i, entry) in sortedentriesData.enumerated() {
let newEntry = ChartDataEntry(x: Double(i), y: entry.temperature)
chartEntries.append(newEntry)
let dateFormatter = DateFormatter()
dateFormatter.timeStyle = .medium
dateFormatter.dateStyle = .none
xStrings.append("\(dateFormatter.string(from: Date.init(timeIntervalSince1970: TimeInterval(entry.timestamp))))")
}
let set: LineChartDataSet = LineChartDataSet(values: chartEntries, label: "°C")
set.setColor(NSUIColor.blue, alpha: CGFloat(1))
set.circleColors = [NSUIColor.blue]
set.circleRadius = 3
set.mode = LineChartDataSet.Mode.cubicBezier
let data: LineChartData = LineChartData(dataSet: set)
self.chartView.xAxis.labelRotationAngle = -90
self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
return xStrings[Int(index)]
})
self.chartView.xAxis.setLabelCount(xStrings.count, force: true)
self.chartView.data = data
}
entry is a struct I created :
条目是我创建的结构:
struct entry {
var timestamp: Int
var temperature: Double
}
回答by RedHotPawn.com
A cleaner way to implement the suggestion above if you are subclassing a graph is to implement IAxisValueFormatterprotocol in your subclass itself
如果您对图形进行子类化,则实现上述建议的一种更简洁的方法是在子类本身中实现IAxisValueFormatter协议
class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {}
like this...
像这样...
public func stringForValue(_ value: Double, axis: Charts.AxisBase?) -> String
{
return "My X Axis Label Str"; // Return you label string, from an array perhaps.
}
Then in your init()
然后在你的 init()
self.xAxis.valueFormatter = self;
回答by Zoltan Vinkler
The most simple solution:
最简单的解决方法:
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
barChartView.xAxis.granularity = 1
回答by Narendra Jagne
I achieved this like that, I have date in "yyyy-MM-dd HH:mm" format and I want show "HH:mm" in the from of string in x-axis. Here is code,
我是这样实现的,我有“yyyy-MM-dd HH:mm”格式的日期,我想在 x 轴的字符串中显示“HH:mm”。这是代码,
I used Cubic Lines chart , first i set data on chart
我使用立方线图,首先我在图表上设置数据
func setDataCount() {
var dataEntries: [ChartDataEntry] = []
let formatter = CubicChartFormatter()
let xaxis:XAxis = XAxis()
if graphArray?.count ?? 0>0 {
for i in 0..<graphArray!.count {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm"
let date = dateFormatter.date(from:graphArray![i].writetime)
let formatingDate = getFormattedDate(date: date!, format: "HH:mm")
xDataPoints.append(formatingDate)
formatter.setValues(values: xDataPoints)
let dataEntry = ChartDataEntry(x: Double(i), y: Double(yVal)!, data: formatingDate)
dataEntries.append(dataEntry)
let set1 = LineChartDataSet(entries: dataEntries, label: "DataSet")
let data = LineChartData(dataSet: set1)
chartView.xAxis.valueFormatter = formatter
chartView.data = data
}
}
}
and Make format Class
并制作格式类
@objc(CubicChartFormatter)
public class CubicChartFormatter: NSObject, IAxisValueFormatter
{
var names = [String]()
public func stringForValue(_ value: Double, axis: AxisBase?) -> String
{
return names[Int(value)]
}
public func setValues(values: [String])
{
self.names = values
}
}