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!!
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.
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
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;
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
}