Comment ajouter des chaînes sur L'axe X dans iOS-charts?

avec la nouvelle version j'ai eu quelques problèmes pour créer quelques graphiques le code précédent était:

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
}

vous pouvez passer les valeurs par exemple un tableau de mois en utilisant la ligne:

let chartData = BarChartData(xVals: months, dataSet: chartDataSet)

après la nouvelle version le code pour implémenter le même graphique est:

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
}

j'ai essayé quelques heures, mais je ne pouvais pas trouver un moyen de modifier les valeurs de l'axe X, j'espère que quelqu'un peut m'aider, merci!!

20
demandé sur Tobi 2016-08-20 03:00:09

4 réponses

j'ai trouvé la solution, peut-être qu'une autre peut résoudre ce problème d'une meilleure façon, sans créer une nouvelle classe, et bien c'est ce que j'ai trouvé:

tout D'abord vous devez créer une nouvelle classe, qui sera votre classe formatter et ajouter l'interface IAxisValueFormater, puis vous utilisez la méthode stringForValue pour personnaliser les nouvelles valeurs, il faut deux paramètres, le premier est la valeur réelle (vous pouvez le voir comme l'index) et le second est l'axe où la valeur être.

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

maintenant dans votre fichier au début de votre fonction setChart() vous devez créer deux variables une pour votre classe formatter et une pour la classe axis:

let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()

Ensuite, aller de l'avant à la fin de la pour les dans la boucle et passer l'indice et de l'axe à votre formateur de la variable:

formato.stringForValue(Double(i), axis: xaxis)

après la boucle ajouter le format à votre variable axis:

xaxis.valueFormatter = formato

la dernière étape est d'ajouter le nouveau xaxisformatted barChartView:

barChartView.xAxis.valueFormatter = xaxis.valueFormatter

Et c'est tous les autres lignes dans le setChart() la fonction il suffit de le garder là où ils sont, j'espère que cela peut vous aider.

11
répondu Julio Cesar Aguilar Jiménez 2016-12-13 10:10:08

Bonjour, récemment, j'ai rencontré le même problème et résolu de cette façon-

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

    }
}

À la fin il suffit d'ajouter l'extension pour le délégué

extension ViewController: IAxisValueFormatter {

    func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    return months[Int(value)]
    }
}

trouvé cette solution à travers ce lien https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk

10
répondu Harshit Goel 2018-06-25 08:27:51

une façon plus propre d'implémenter la suggestion ci-dessus si vous sous-classez un graph est d'implémenter IAxisValueFormatter protocole dans votre sous-classe elle-même

class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {}

comme ceci...

public func stringForValue(_ value: Double, axis: Charts.AxisBase?) -> String
{
    return "My X Axis Label Str";  // Return you label string, from an array perhaps.
}

Ensuite, dans ta fonction init()

self.xAxis.valueFormatter = self;
6
répondu RedHotPawn.com 2016-11-08 11:42:52

comme beaucoup de gens ont dit que vous pouvez créer une classe ou étendre avec le type IAxisValueFormatter, mais vous pouvez facilement utiliser la méthode suivante qui ne prend que 3 lignes :

self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
    return xStrings[Int(index)]
})

voici ma fonction setChart () au cas où certains d'entre vous trouveraient intéressante ma personnalisation :

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
}

entrée est une structure que j'ai créé :

struct entry {
    var timestamp: Int
    var temperature: Double
}
2
répondu Damien Bannerot 2017-02-24 00:33:41