如何在 iOS 图表的 X 轴上添加字符串?
How to add Strings on X Axis in iOS-charts?
对于新版本,我在创建一些图表时遇到了一些麻烦,之前的代码是:
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
}
您可以使用以下行传递值,例如月份数组:
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
新版本发布后实现相同图表的代码为:
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
}
我尝试了几个小时,但找不到修改 X 轴值的方法,希望有人能帮助我,谢谢!!
我找到了解决方案,也许另一个可以更好地解决这个问题,而无需创建新的 class,这就是我找到的:
首先你需要创建一个新的class,这将是你的格式化程序class并添加 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)]
}
}
现在,在您的文件中,在 setChart() 函数的开头,您必须创建两个变量,一个用于格式化程序 class,一个用于轴 class:
let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
接下来,在 for in 循环的末尾继续并将索引和轴传递给格式化程序变量:
formato.stringForValue(Double(i), axis: xaxis)
循环后将格式添加到轴变量:
xaxis.valueFormatter = formato
最后一步是将新的 xaxisformatted 添加到 barChartView:
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
这就是 setChart() 函数中的所有其他行,请将其保留在原处,希望对您有所帮助。
如果您对图进行子类化,则实施上述建议的一种更简洁的方法是在您的子类本身中实施 IAxisValueFormatter 协议
class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {}
像这样...
public func stringForValue(_ value: Double, axis: Charts.AxisBase?) -> String
{
return "My X Axis Label Str"; // Return you label string, from an array perhaps.
}
然后在你的 init()
self.xAxis.valueFormatter = self;
你好,最近遇到了同样的问题,是这样解决的-
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
}
}
最后简单地添加委托的扩展
extension ViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return months[Int(value)]
}
}
通过这个 link 想出了这个解决方案
https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk
正如许多人所说,您可以创建一个 class 或使用 IAxisValueFormatter 类型进行扩展,但您可以轻松地使用以下仅需要 3 行的方法:
self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
return xStrings[Int(index)]
})
这是我的 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
}
条目是我创建的结构:
struct entry {
var timestamp: Int
var temperature: Double
}
最简单的解决方案:
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
barChartView.xAxis.granularity = 1
我是这样实现的,
我有 "yyyy-MM-dd HH:mm" 格式的日期,我想在 x 轴的字符串中显示 "HH:mm"。这是代码,
我使用立方线图表,首先我在图表上设置数据
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
}
}
}
并制作格式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
}
}
对于新版本,我在创建一些图表时遇到了一些麻烦,之前的代码是:
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
}
您可以使用以下行传递值,例如月份数组:
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
新版本发布后实现相同图表的代码为:
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
}
我尝试了几个小时,但找不到修改 X 轴值的方法,希望有人能帮助我,谢谢!!
我找到了解决方案,也许另一个可以更好地解决这个问题,而无需创建新的 class,这就是我找到的:
首先你需要创建一个新的class,这将是你的格式化程序class并添加 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)]
}
}
现在,在您的文件中,在 setChart() 函数的开头,您必须创建两个变量,一个用于格式化程序 class,一个用于轴 class:
let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
接下来,在 for in 循环的末尾继续并将索引和轴传递给格式化程序变量:
formato.stringForValue(Double(i), axis: xaxis)
循环后将格式添加到轴变量:
xaxis.valueFormatter = formato
最后一步是将新的 xaxisformatted 添加到 barChartView:
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
这就是 setChart() 函数中的所有其他行,请将其保留在原处,希望对您有所帮助。
如果您对图进行子类化,则实施上述建议的一种更简洁的方法是在您的子类本身中实施 IAxisValueFormatter 协议
class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {}
像这样...
public func stringForValue(_ value: Double, axis: Charts.AxisBase?) -> String
{
return "My X Axis Label Str"; // Return you label string, from an array perhaps.
}
然后在你的 init()
self.xAxis.valueFormatter = self;
你好,最近遇到了同样的问题,是这样解决的-
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
}
}
最后简单地添加委托的扩展
extension ViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return months[Int(value)]
}
}
通过这个 link 想出了这个解决方案 https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk
正如许多人所说,您可以创建一个 class 或使用 IAxisValueFormatter 类型进行扩展,但您可以轻松地使用以下仅需要 3 行的方法:
self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
return xStrings[Int(index)]
})
这是我的 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
}
条目是我创建的结构:
struct entry {
var timestamp: Int
var temperature: Double
}
最简单的解决方案:
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
barChartView.xAxis.granularity = 1
我是这样实现的, 我有 "yyyy-MM-dd HH:mm" 格式的日期,我想在 x 轴的字符串中显示 "HH:mm"。这是代码,
我使用立方线图表,首先我在图表上设置数据
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
}
}
}
并制作格式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
}
}