Подтвердить что ты не робот

Как добавить строки в X Axis в iOS-диаграммах?

С новым выпуском у меня возникли проблемы с созданием некоторых графиков, которые были в предыдущем коде:

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, я надеюсь, что кто-то может мне помочь, спасибо!

4b9b3361

Ответ 1

Я нашел решение, возможно, другой может решить эту проблему лучше, не создавая новый класс, ну вот что я нашел:

Сначала вы создали новый класс, который будет вашим классом форматирования и добавит интерфейс 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() вам необходимо создать две переменные для вашего класса форматирования и одну для класса осей:

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() просто сохраняют его там, где они есть, я надеюсь, что это может вам помочь.

Ответ 2

Я думаю, что это более совершенное решение для установки меток оси x со строками без создания каких-либо классов, как показано ниже.

Решение для меток X-Axis в Swift 3.0: -

let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:months)
//Also, you probably want to add:

barChartView.xAxis.granularity = 1

Что это.

Подробнее см. здесь.

Ответ 3

Более чистый способ реализовать вышеприведенное предложение, если вы подклассифицируете граф, заключается в реализации протокола 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;

Ответ 4

Привет, недавно я тоже застрял в нем, и я пробовал этот путь -

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

из этой ссылки я узнал https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk

Ответ 5

Как многие говорили, вы можете создать класс или расширить его с помощью типа IAxisValueFormatter, но вы можете легко использовать следующий метод, который принимает только три строки:

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
}