Charts: Como modificar os valores do eixo X Swift?

Criado em 20 ago. 2016  ·  33Comentários  ·  Fonte: danielgindi/Charts

Com a nova versão tive alguns problemas para criar alguns gráficos, o código anterior era:

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
}

Você pode passar os valores, por exemplo, uma matriz de meses usando a linha:

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

Após a nova versão o código para implementar o mesmo gráfico é:

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

}

Fiquei tentando algumas horas mas não consegui encontrar uma maneira de modificar os valores do eixo X, espero que alguém possa me ajudar, obrigado!!

Comentários muito úteis

Eu tive um problema parecido. A documentação é muito curta, mas trabalhar com x Axis requer algumas linhas de código. Usando o código fornecido por @ajimenezjulio , fiz extensão de classe para simplificar o uso do BarChartView. Talvez seja útil para alguém.

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

Uso

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

Todos 33 comentários

Eu modifico o valor do eixo x no gráfico de dispersão e está funcionando agora.
Achei 2 pontos:

1: let dataEntry = BarChartDataEntry(x: Double(i+2), y:values[i], data: months)
Use ChartDataEntry(x,y) em vez do método BarChartDataEntry.

2: deixe chartData = BarChartData() -> let chartData = BarChartData(dataset)

Espero que isso possa ajudar-lhe.

Obrigado NyoSeint, você está certo com seu método, você pode modificar o eixo x, mas apenas de maneira numérica, estou tentando colocar Strings neste caso meses no eixo x

você verificou o ChartsDemo? Acredito que existam respostas.

Também estou procurando uma resposta para isso, abri um caso anteriormente aqui - https://github.com/danielgindi/Charts/issues/1331

Não foi possível encontrar uma resposta nas demonstrações, por favor, deixe-me saber se você encontrar uma solução. obrigado

Encontrei a solução, talvez outro possa resolver esse problema de uma maneira melhor, sem criar uma nova classe, bem, foi isso que encontrei:

Primeiro você precisa criar uma nova classe, que será sua classe de formatador e adicionar a interface IAxisValueFormater, então você usa o método stringForValue para customizar os novos valores, são necessários dois parâmetros, o primeiro é o valor real (você pode ver como o índice) e o segundo é o eixo onde está o valor.

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

}

Agora em seu arquivo no início de sua função setChart() você tem que criar duas variáveis ​​uma para sua classe formatadora e outra para a classe axis:

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

Em seguida, vá em frente no final do loop for in e passe o índice e o eixo para a variável do formatador:

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

Após o loop, adicione o formato à sua variável de eixo:

xaxis.valueFormatter = formato

A etapa final é adicionar o novo xaxisformatted ao barChartView:

barChartView.xAxis.valueFormatter = xaxis.valueFormatter

E essas são todas as outras linhas na função setChart() apenas mantenha-as onde estão, espero que possa ajudá-lo.

@ajimenezjulio Esta é a maneira correta :-)

Estamos usando formatadores agora, devido a valores x independentes. Obviamente, isso é menos confortável para aqueles que costumavam ter uma matriz x-index simplista, mas abre um mundo inteiro de possibilidades. Isso removeu a restrição de ter que predefinir os índices x com seus rótulos.

Tenho certeza de que vamos encontrar novas maneiras de escrever menos código para situações simplistas como essa, no futuro.

Por favor, devolva-nos uma maneira fácil de personalizar o xaxis.
A versão anterior era tão boa para isso! (ou pelo menos um tutorial para Swift/Objc)

THX.

Qualquer atualização ?

@dante20007 Desculpe, você não pode ter tudo. As pessoas querem poder adicionar entradas em qualquer índice x, não apenas 0, 1, 2, mas também 0, 1.3, 2.7... Um array não pode representar rótulos para esses valores.

E se quisermos que os meses sejam exibidos no eixo X? não é possível também?

THX.

Oi, tento adicionar esta solução, mas quando me movo para a direita, diz índice fora do intervalo, sei que tenho apenas 12 meses

Eu também preciso de uma maneira fácil de personalizar o eixo x. Voltei para a versão anterior dos gráficos por causa disso.

Esta é uma maneira fácil de customizar meu problema foi que quando eu me movo para a direita começo a renderizar novamente então eu modifico a lib e coloco para ignorar se o index ao renderizar

Desculpe, eu estava falando sobre "Como modificar os valores do eixo X Swift?" usando Strings

Sim eu também. Usei a mesma resposta de @ajimenezjulio

Estou mantendo um projeto que está em Objective-C, e apesar de ter conseguido reproduzir a resposta de @ajimenezjulio ele não compilava: por algum motivo o IAxisValueFormatter nunca foi reconhecido.

Eu tive um problema parecido. A documentação é muito curta, mas trabalhar com x Axis requer algumas linhas de código. Usando o código fornecido por @ajimenezjulio , fiz extensão de classe para simplificar o uso do BarChartView. Talvez seja útil para alguém.

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

Uso

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

Ei, pode ter outra extensão de gráficos também?

Estou recebendo um erro "BarChartFormatter não está em conformidade com o protocolo IAxisValueFormatter.

Por que você fez isso? Foi tão fácil de usar no Android Studio. ALGUÉM sabe como colocar um array ["J", "F", etc... no eixo X? Estou ferrado aqui. Esses "exemplos estão acima do meu nível de habilidade.

Existe uma solução para ObjC formatar o eixo X com rótulos personalizados?

em YourViewControllerViewController declare var months: [String] = String e defina os valores do mês que você precisa
extensão YourViewControllerViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
retornar meses[Int(valor) % meses.conta]
}
}

Oi,
Tentei adicionar a solução. Mas estou sempre recebendo um erro 'índice fora do intervalo'

Sim, eu gostaria de entender mais como stringForValue é chamado e como sua personalização do gráfico/dados altera a forma como ele é chamado para seus dados. Eu fiz algumas dessas verificações para evitar o índice fora do intervalo. Uma espécie de band-aid 🤷‍♂️

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

Botão Abrir

@robotsquidward - Eu também. Seria bom se a documentação explicasse como funcionava ou, melhor ainda, uma das demos mostrasse como fazê-lo. Imagino que existam muitas pessoas que precisam usar strings para rótulos, mas não há explicação ou exemplo claro que eu possa encontrar que ajude. Acabei de ver um monte de respostas que dizem look at stringForValue() . Suspirar...

@AlexSmet
Muito obrigado pela extensão! Funciona muito bem. Estou usando um gráfico de linhas, então modifiquei um pouco o código. Funciona, porém estou tendo um bug visual. Alguma idéia de por que os dias no eixo X não estão alinhados corretamente? Também segunda e quarta-feira estão sendo exibidos 2 vezes seguidas.
Veja a captura de tela: https://imgur.com/a/OG7OuSY

dataContent1 = ["SEG", "TER", "QUA", "QUI", "SEX"]
dataContent2 = [230, 320, 403, 430, 312]
chartView.setLineChartData(xValues: dataContent1, yValues: dataContent2, label: "BTC")

@benzai
Você precisa definir uma contagem de rótulos para xAxis. Se você usar código como na extensão mine, basta adicionar uma string na sua função setLineChartData:
self.xAxis.setLabelCount(xValues.count, force: true)

@benzai , descobri que precisava ajustar um pouco a abordagem do @AlexSmet e definir force: false para que meu gráfico exibisse 12 meses corretamente:

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

Quando force era definido como true, o gráfico solicitava valores excêntricos de xAxis no delegado do formatador (por exemplo, -0,5 em vez de 0,0) e os rótulos não eram alinhados corretamente com o yValue correspondente.

A marcação da documentação diz 'se verdadeiro, o número definido de rótulos y será forçado', o que implica que isso é especificamente para os rótulos y, mas parece que se aplica aos rótulos dos eixos x e y, correto?

Posso definir o rótulo String no eixo esquerdo?

Para LineChart:

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

Como você está hoje.
Por favor me ajude, gostaria de definir o valor com gráficos de barras do projeto Swift 4.

tE1U5
Eu quero desenhar esse tipo de gráfico de linhas.
Entre dois intervalos de tempo, como adicionar vários pontos? (Exemplo, deseja exibir vários pontos entre 7h e 8h)

Esta página foi útil?
0 / 5 - 0 avaliações