Charts: Comment modifier les valeurs de l'axe X Swift ?

Créé le 20 août 2016  ·  33Commentaires  ·  Source: danielgindi/Charts

Avec la nouvelle version, j'ai eu quelques problèmes pour créer des 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'essayais quelques heures mais je n'arrivais pas à trouver un moyen de modifier les valeurs de l'axe X, j'espère que quelqu'un pourra m'aider, merci !!

Commentaire le plus utile

J'avais un problème similaire. La documentation est trop courte, mais travailler avec l'axe x nécessite quelques lignes de code. En utilisant le code fourni par @ajmenezjulio , j'ai créé une extension de classe pour simplifier l'utilisation de BarChartView. Peut-être sera-t-il utile à quelqu'un.

extension BarChartView {

    private class BarChartFormatter: NSObject, IAxisValueFormatter {

        var labels: [String] = []

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

        init(labels: [String]) {
            super.init()
            self.labels = labels
        }
    }

    func setBarChartData(xValues: [String], yValues: [Double], label: String) {

        var dataEntries: [BarChartDataEntry] = []

        for i in 0..<yValues.count {
            let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
            dataEntries.append(dataEntry)
        }

        let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
        let chartData = BarChartData(dataSet: chartDataSet)

        let chartFormatter = BarChartFormatter(labels: xValues)
        let xAxis = XAxis()
        xAxis.valueFormatter = chartFormatter
        self.xAxis.valueFormatter = xAxis.valueFormatter

        self.data = chartData
    }
} 

Usage

func setChart(){
        let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
        let unitsSold = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]

        barChartView.setBarChartData(xValues: months, yValues: unitsSold, label: "Monthly Sales")
    } 

Tous les 33 commentaires

Je modifie la valeur de l'axe des abscisses dans le diagramme de dispersion et cela fonctionne maintenant.
J'ai trouvé 2 points :

1 : laissez dataEntry = BarChartDataEntry(x : Double(i+2), y:values[i], data : mois )
Utilisez ChartDataEntry(x,y) au lieu de la méthode BarChartDataEntry.

2 : laissez chartData = BarChartData() -> laissez chartData = BarChartData(ensemble de données)

J'espère que ça peut t'aider.

Merci NyoSeint, vous avez raison avec votre méthode, vous pouvez modifier l'axe des abscisses mais juste de manière numérique, j'essaie de mettre des chaînes dans ce cas des mois dans l'axe des abscisses

avez-vous vérifié le ChartsDemo ? Je crois qu'il y a des réponses.

Je cherche également une réponse à cela, j'ai ouvert un dossier plus tôt ici - https://github.com/danielgindi/Charts/issues/1331

Impossible de trouver une réponse dans les démos, s'il vous plaît laissez-moi savoir si vous trouvez une solution. Merci

J'ai trouvé la solution, peut-être qu'un autre peut mieux résoudre ce problème, sans créer de nouvelle classe, eh bien voici ce que j'ai trouvé :

Vous devez d'abord créer une nouvelle classe, qui sera votre classe de formateur 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'indice) et le second est l'axe où se trouve la valeur.

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 de formateur et une pour la classe d'axe :

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

Ensuite, continuez à la fin de la boucle for in et transmettez l'index et l'axe à votre variable de formatage :

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

Après la boucle, ajoutez le format à votre variable d'axe :

xaxis.valueFormatter = formato

La dernière étape consiste à ajouter le nouveau xaxisformatted au barChartView :

barChartView.xAxis.valueFormatter = xaxis.valueFormatter

Et ce sont toutes les autres lignes de la fonction setChart(), gardez-les là où elles sont, j'espère que cela pourra vous aider.

@ajmenezjulio C'est effectivement la bonne manière :-)

Nous utilisons maintenant des formateurs, en raison de valeurs x indépendantes. Ceci est bien sûr moins confortable pour ceux qui avaient l'habitude d'avoir un tableau d'index x simpliste, mais ouvre tout un monde de possibilités. Cela a supprimé la contrainte d'avoir à prédéfinir les index x avec leurs étiquettes.

Je suis sûr que nous trouverons de nouvelles façons d'écrire moins de code pour des situations simplistes comme celle-ci, à l'avenir.

S'il vous plaît, donnez-nous un moyen simple de personnaliser l'axe x.
La version précédente était tellement sympa pour ça ! (ou au moins un tutoriel pour Swift/Objc)

Merci.

Toute mise à jour ?

@dante20007 Désolé, vous ne pouvez pas tout avoir. Les gens veulent pouvoir ajouter des entrées à n'importe quel index x, pas seulement 0, 1, 2, mais aussi 0, 1.3, 2.7... Un tableau ne peut pas représenter des étiquettes pour de telles valeurs.

Et si on voulait que les mois soient affichés sur l'axe des X ? pas possible aussi ?

Merci.

Salut, j'essaie d'ajouter cette solution mais quand je me déplace vers la droite, l'index est hors plage, je sais que je n'ai que 12 mois

J'ai également besoin d'un moyen simple de personnaliser l'axe des x. Je suis revenu à la version précédente des graphiques à cause de cela.

C'est un moyen facile de personnaliser mon problème, c'est que lorsque je me déplace vers la droite, je recommence à rendre, donc je modifie la bibliothèque et je mets à ignorer si l'index lors du rendu

Désolé, je parlais de "Comment modifier les valeurs de l'axe X Swift?" utiliser des chaînes

Oui moi aussi. J'ai utilisé la même réponse de @ajmenezjulio

Je maintiens un projet qui est en Objective-C, et bien que j'ai réussi à reproduire la réponse de @ajmenezjulio , il ne compilerait pas: pour une raison quelconque, IAxisValueFormatter n'a jamais été reconnu.

J'avais un problème similaire. La documentation est trop courte, mais travailler avec l'axe x nécessite quelques lignes de code. En utilisant le code fourni par @ajmenezjulio , j'ai créé une extension de classe pour simplifier l'utilisation de BarChartView. Peut-être sera-t-il utile à quelqu'un.

extension BarChartView {

    private class BarChartFormatter: NSObject, IAxisValueFormatter {

        var labels: [String] = []

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

        init(labels: [String]) {
            super.init()
            self.labels = labels
        }
    }

    func setBarChartData(xValues: [String], yValues: [Double], label: String) {

        var dataEntries: [BarChartDataEntry] = []

        for i in 0..<yValues.count {
            let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
            dataEntries.append(dataEntry)
        }

        let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
        let chartData = BarChartData(dataSet: chartDataSet)

        let chartFormatter = BarChartFormatter(labels: xValues)
        let xAxis = XAxis()
        xAxis.valueFormatter = chartFormatter
        self.xAxis.valueFormatter = xAxis.valueFormatter

        self.data = chartData
    }
} 

Usage

func setChart(){
        let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
        let unitsSold = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]

        barChartView.setBarChartData(xValues: months, yValues: unitsSold, label: "Monthly Sales")
    } 

Hé, peut-on aussi avoir d'autres extensions de cartes ?

J'obtiens une erreur "BarChartFormatter n'est pas conforme au protocole IAxisValueFormatter.

Pourquoi as-tu fait cela? C'était si facile à utiliser dans Android Studio. Est-ce que QUELQU'UN sait comment obtenir un tableau ["J", "F", etc... dans l'axe X ? Je suis foutu ici. Ces "exemples sont au-dessus de mon niveau de compétence.

Existe-t-il une solution pour ObjC pour formater l'axe X avec des étiquettes personnalisées ?

dans YourViewControllerViewController déclarer var mois : [String] = Chaîne et définir les valeurs du mois dont vous avez besoin
extension YourViewControllerViewController : IAxisValueFormatter {
func stringForValue(_ valeur : Double, axe : AxisBase ?) -> Chaîne {
retourne mois[Int(valeur) % mois.compte]
}
}

Salut,
J'ai essayé d'ajouter la solution. Mais je reçois toujours une erreur "index hors plage"

Ouais, j'aimerais mieux comprendre comment stringForValue est appelé et comment votre personnalisation du graphique/des données change la façon dont il est appelé pour vos données. J'ai fait une partie de cette vérification pour éviter que l'index ne soit hors plage. Une sorte de pansement cependant 🤷‍♂️

       func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            let index = Int(value)
            if index < labels.count && index >= 0 {
                return labels[index]
            } else {
                return ""
            }
        }

Bouton Ouvrir

@robotsquidward - Moi aussi. Ce serait bien si la documentation expliquait comment cela fonctionnait ou, mieux encore, l'une des démos montrait comment le faire. J'imagine qu'il y a _beaucoup_ de personnes qui ont besoin d'utiliser des chaînes pour les étiquettes, mais il n'y a pas d'explication ou d'exemple clair que je puisse trouver qui aiderait. Je vois juste un tas de réponses qui disent look at stringForValue() . Soupir...

@AlexSmet
Merci beaucoup pour la rallonge ! Cela fonctionne très bien. J'utilise un graphique en courbes, j'ai donc modifié un peu le code. Cela fonctionne, mais j'ai un bug visuel. Avez-vous une idée de la raison pour laquelle les jours sur l'axe X ne sont pas alignés correctement ? Lundi et mercredi sont également affichés 2 fois de suite.
Voir capture d'écran : https://imgur.com/a/OG7OuSY

dataContent1 = ["LUN", "MAR", "MER", "JEU", "VEN"]
dataContent2 = [230, 320, 403, 430, 312]
chartView.setLineChartData(xValues : dataContent1, yValues : dataContent2, étiquette : "BTC")

@benzai
Vous devez définir un nombre d'étiquettes pour xAxis. Si vous utilisez du code comme dans mon extension, ajoutez simplement une chaîne dans votre fonction setLineChartData :
self.xAxis.setLabelCount(xValues.count, force: true)

@benzai J'ai trouvé que je devais modifier légèrement l'approche de @AlexSmet et définir force: false pour que mon graphique affiche correctement 12 mois :

barChartView.xAxis.setLabelCount(dataPoints.count, force: false)

Lorsque force était défini sur true, le graphique demandait des valeurs xAxis bizarres dans le délégué du formateur (par exemple -0,5 au lieu de 0,0) et les étiquettes n'étaient pas correctement alignées avec la yValue correspondante.

Le balisage de la documentation indique "si vrai, le nombre défini d'étiquettes y sera forcé", ce qui implique que cela concerne spécifiquement les étiquettes y, mais il semble que cela s'applique aux étiquettes des axes x et y, n'est-ce pas ?

Puis-je définir une étiquette de chaîne dans l'axe de gauche ?

Vers le graphique en courbes :

self.lineChart.xAxis.valueFormatter = IndexAxisValueFormatter(values: self.chartLabels)
self.lineChart.xAxis.avoidFirstLastClippingEnabled = true

Comment vas-tu aujourd'hui.
S'il vous plaît aidez-moi, je voudrais définir la valeur avec des graphiques à barres du projet Swift 4.

tE1U5
Je veux dessiner ce type de graphique linéaire.
Entre deux intervalles de temps, comment ajouter plusieurs points ? (Exemple, veut afficher plusieurs points entre 7 h et 8 h)

Cette page vous a été utile?
0 / 5 - 0 notes