如何在iOS图表的X轴上添加字符串?

如何在iOS图表的X轴上添加字符串?,ios,swift,ios-charts,Ios,Swift,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)

在新版本中,我在创建一些图表时遇到了一些麻烦,以前的代码是:

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
}
新版本发布后,实现相同图形的代码为:

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
}
func集合图表(数据点:[String],值:[Double]){
var数据项:[BarChartDataEntry]=[]

对于0中的i.我找到了解决方案,也许另一个可以以更好的方式解决这个问题,而无需创建新类,这就是我发现的:

首先,您需要创建一个新类,它将是您的格式化程序类并添加IAXISValueFormatter接口,然后使用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()函数开头的文件中,您必须创建两个变量,一个用于格式化程序类,另一个用于axis类:

let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
接下来,在for in循环的末尾继续,并将索引和轴传递给格式化程序变量:

formato.stringForValue(Double(i), axis: xaxis)
xaxis.valueFormatter = formato
循环后,将格式添加到轴变量:

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()中


您好,最近我遇到了同样的问题,并通过这种方式解决了它-

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

    }
}
通过这个链接找到了这个解决方案

正如许多人所说,您可以使用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
}

最简单的解决方案:

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
        }
    }
}

我认为您可以使用axis value formatter.barChartView.xAixs.valueFormatter=“您的值格式化程序对象”:O,谢谢您,rmaddy,我正在尝试使用“barChartView.xAxis.valueFormatter”,但它需要“iAxisValueFormatter?”,这是一个接口,我是一个初学者,不知道如何使用这种类型,你能给我一些关于如何使用它的说明吗?嗨,你可以创建一个实现接口的类,然后创建一个类的对象,或者你可以用你当前的类实现接口并将自己传递给它。这类似于u实现tableview委托方法。谢谢,现在一切都很好!这很好,但是我如何将月份值传递到类中,而不是在格式化程序类中预先设置它们(因为我试图从CoreData获取这些值),只需添加一个新方法,例如“setArray”,它将一个数组作为参数,然后只需设置数组变量,在本例中为“months”,并使其与数组相等,在主类中,您可以将此方法称为“setArray”然后发送你想要的数组。修复了它。问题是x轴显示1个小数点,显示的每个小数点都被替换为日期。通过添加这行修复了它-希望能帮助其他人:barChartView.xAxis.decimals=0我能在Objective C中得到答案吗?@Wodjefer,我解决了这个问题。详细信息是.Xcode 8+,ObjectiveC、 ios Charts
V3.0.1
这非常适合我,谢谢分享。就像Charm谢谢你!这正是我想要的我必须移动让xAxisValue=viewForChart.xAxisValue.valueFormatter=AxisFormatter=AxisFormatter在viewForChart.data=chartData上面运行。。。
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
barChartView.xAxis.granularity = 1
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
        }
    }
}
@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
   } 
}