Charts: LineChart X-Axis - Como sempre exibir o primeiro e o último rótulo

Criado em 26 dez. 2016  ·  21Comentários  ·  Fonte: danielgindi/Charts

Em meu gráfico de linha, eu o configurei de forma que, se houver apenas uma entrada de dados, eu faça o ponto de dados aparecer no meio assim:

screen shot 2016-12-25 at 7 00 36 pm

Se houver mais entradas de dados, será mais parecido com isto:

screen shot 2016-12-25 at 7 00 50 pm

O problema que estou tendo é que o último rótulo do eixo X não está aparecendo. Esses são os dados dos últimos 30 dias, então gostaria que a última gravadora, 25 de dezembro, apareça. Existe uma maneira de fazer meu gráfico de linhas sempre exibir o primeiro e o último rótulo no eixo X? Não me importo como ele calcula ou ignora os rótulos intermediários.

bug

Comentários muito úteis

    lineChart?.xAxis.setLabelCount(arrOfMonth.count, force: true)

Isso ajudará a exibir o último valor do gráfico de linha - tentei e trabalhei para mim

Todos 21 comentários

tente avoidFirstLastClippingEnabled , o padrão é falso.

    /// if set to true, the chart will avoid that the first and last label entry in the chart "clip" off the edge of the chart
    open var avoidFirstLastClippingEnabled = false

@ cnowak7 Você conseguiu resolver o problema mencionado na 2ª imagem? Por favor, compartilhe a solução

avoidFirstLastClippingEnabled não ajuda. O último rótulo sempre é cortado

Se eu olhar para o código-fonte, as entradas do eixo são calculadas em AxisRendererBase.computeAxisValues e não há como impor o valor máximo a ser exibido. Eu acredito que esta funcionalidade foi suportada na versão anterior.

https://github.com/danielgindi/Charts/issues/2007 parece mesmo problema com este?
@ondrejhanslik por padrão, computeAxisValues ​​() usará os valores mínimo e máximo para calcular o intervalo. Portanto, os valores mínimo e máximo devem ser maiores do que o valor mínimo / máximo dos dados para conter todos os dados. Você verificou qual é o seu valor mínimo / máximo em computeAxisValues ​​() e qual é o valor mínimo / máximo dos seus dados?

@ liuxuan30 Eu uso a matriz String personalizada como valores do eixo X, ou seja, datas

Aqui está uma captura de tela do meu gráfico

untitled

Esta é a aparência do meu gráfico ao definir avoidFirstLastClippingEnabled como verdadeiro:

screen shot 2016-12-28 at 11 02 15 pm

Aqui está um código extra que estou usando para configurar meu eixo X:

private func setUpLineChartPreferences() {
        .
        .
        .
        // x-axis
        self.lineChart.xAxis.labelPosition = .bottom
        self.lineChart.xAxis.drawGridLinesEnabled = true
        self.lineChart.xAxis.granularity = 1.0
        .
        .
        .
}
private func setUpLineChart(withDataEntries entries: [ChartDataEntry]) {
        let entryCount = entries.count
        if entryCount > 0 {
            let dataSet = LineChartDataSet(values: entries, label: nil)
            dataSet.drawFilledEnabled = true
            dataSet.fillColor = .green
            dataSet.circleRadius = 5
            dataSet.drawValuesEnabled = false
            dataSet.setColor(.black)
            dataSet.highlightColor = .green
            dataSet.setCircleColor(.blue)
            let lineChartData = LineChartData(dataSet: dataSet)
            self.lineChart.data = lineChartData
            // SET UP X-AXIS
            self.lineChart.xAxis.valueFormatter = IndexAxisValueFormatter(values: self.chartLabels)
            self.lineChart.xAxis.avoidFirstLastClippingEnabled = true
            print("NOWAK: CHART LABELS THO - \(self.chartLabels)")
            if entryCount == 1 {
                self.lineChart.xAxis.axisMinimum = -1.0
                self.lineChart.xAxis.axisMaximum = 1.0
            } else {
                self.lineChart.xAxis.axisMinimum = 0.0
                self.lineChart.xAxis.axisMaximum = Double(self.chartLabels.count - 1)
            }
            print("X MIN IS \(self.lineChart.xAxis.axisMinimum) AND X MAX IS \(self.lineChart.xAxis.axisMaximum)")
        } else {
            self.lineChart.noDataText = "No Stats For The Past \(self.currentFilter.capitalized)"
            self.lineChart.setNeedsDisplay()
        }
        switch self.currentFilter {
        case "week":
            self.weekFilterButton.backgroundColor = .blue
            self.monthFilterButton.backgroundColor = .darkGray
            self.yearFilterButton.backgroundColor = .darkGray
        case "month":
            self.monthFilterButton.backgroundColor = .blue
            self.weekFilterButton.backgroundColor = .darkGray
            self.yearFilterButton.backgroundColor = .darkGray
        case "year":
            self.yearFilterButton.backgroundColor = .blue
            self.weekFilterButton.backgroundColor = .darkGray
            self.monthFilterButton.backgroundColor = .darkGray
        default:
            print("ERROR SETTING FILTER BUTTON BACKGROUND COLORS")
        }
        self.stopLoading()
}

A propósito, estou usando o Charts 3.0.1 :)

Mesmo aqui. Gráficos 3.0.1 , XCode 8.0 e Swift 3.0

Se uma solução não for possível para esta situação, acho que uma solução que provavelmente faria sentido seria, quando o gráfico for exibido, destacar o último valor (hoje) para que o "BalloonMarker" apareça exibindo o texto "Dez XX \ n500 ".

Do meu lado, obviamente :)

OK, eu verifiquei.

No gráfico 3.0, o eixo x se comporta como o eixo y, então você pode verificar os rótulos do eixo y, o maior rótulo do eixo y é menor do que o valor máximo dos dados, em
image

Em computeAxisValues() , ele lê o valor mínimo e máximo do valor mínimo / máximo do eixo (que é o valor mínimo / máximo dos dados) e calcula um intervalo para obter os rótulos do eixo x.

Por exemplo, em ChartsDemo - Line Chart Dual YAxis, se meus valores de x forem de 0 a 20,
computeAxisValues() leva 0, 20 como valor mínimo / máximo, então, meu labelCount é 6 por padrão, ele calcula rawInterval = (max - min) / labelCount e, posteriormente, o intervalo final será 3. Então ele começa em 0, para obter 7 (labelCount + 1) rótulos, que são 0,3,6,9,12,15,18. O último rótulo do eixo x é 18, não 20.

O motivo pelo qual isAvoidFirstLastClippingEnabled não funciona é porque ele controla quando o último rótulo está fora dos limites, portanto, é irrelevante para esse problema.

Se você quiser ter certeza de que o rótulo é o valor x dos seus dados, você deve ajustar computeAxisValues() para retornar os rótulos. Basta verificar computeAxisValues() para ver os detalhes e você poderá alterá-los.

@danielgindi, o que você acha desses casos de usuários?

@ liuxuan30 Não queremos ajustar computeAxisValues para retornar alguns rótulos específicos. Por exemplo, quando estou exibindo um gráfico sobre datas (por exemplo, os valores x são dias da semana, dias do mês ou meses do ano), preciso que o primeiro e o último rótulos sejam exibidos (por exemplo, segunda e domingo ou 1 / 1 e 31/1).

Eu primeiro gero os valores formatados (por exemplo, nomes de dias ou dias formatados) e, em seguida, os defino como:

    xAxis.axisMinimum = 0
    xAxis.axisMaximum = Double(xValues.count - 1)
    xAxis.valueFormatter = IndexAxisValueFormatter(values: xValues)

O que eu preciso é de um computeAxisValues mais inteligente que sempre exibirá o primeiro rótulo e o último rótulo e, em seguida , calculará os rótulos entre eles.

Este é um caso de uso muito básico e muito comum.

Eu entendo. Ainda existem erros sobre os rótulos do eixo x, por exemplo, sobreposição de rótulos.
A lógica atual é primeiro saber o valor mínimo / máximo, gerar intervalos a partir dele e acumular para obter os rótulos dos eixos. No entanto, o computeAxisValues() atual não garante que o valor máximo / último rótulo seja xAxis.axisMaximum. É disso que preciso da opinião de

Talvez eu deva usar 'override' em vez de 'tweak' para computeAxisValues ​​(). Você pode fornecer uma implementação para garantir que seu primeiro / último valor seja sempre exibido como uma solução alternativa. No entanto, isso pode causar problemas na etiqueta ou outros.

Outra maneira é, você pode tentar setLabelCount(count, forceLabelEnabled) igual a sua contagem de valores x ou metade para ver o resultado.
A lógica é bastante diferente então:

        // force label count
        if axis.isForceLabelsEnabled
        {
            interval = Double(range) / Double(labelCount - 1)

            // Ensure stops contains at least n elements.
            axis.entries.removeAll(keepingCapacity: true)
            axis.entries.reserveCapacity(labelCount)

            var v = yMin

            for _ in 0 ..< labelCount
            {
                axis.entries.append(v)
                v += interval
            }

            n = labelCount
        }

Não envolve o processo adicional, apenas matemática simples.

@ liuxuan30 E se os valores do eixo x estiverem no formato String? No meu caso, os valores do eixo x são datas no formato de string

@ vaibhav-varshaaweblabs eixo x agora está pegando double SOMENTE no Gráfico 3.x, então você pode usar valueFormatter para exibir o rótulo em vez de double. No entanto, o valueFormatter pode ser complicado, quando você precisa considerar o zoom / rolagem

Alguém encontrou uma solução para isso nos gráficos 3.0.2? Estou usando strings de data para meus rótulos do eixo x e vendo o último rótulo desaparecer ocasionalmente, mas estou tendo problemas para reproduzir. Isso é com isAvoidFirstLastClippingEnabled definido como true . Estou me perguntando se isso pode estar relacionado a # 2563?

@ vaibhav-varshaaweblabs @raudabaugh : Como vocês conseguiram plotar strings no eixo X, já que o método setDataCount espera valores inteiros ou duplos para X e Y.
Por favor, deixe-me saber, obrigado antecipadamente

bottomAxis.setLabelCount (entries.size (), true); e também definir a margem direita para tornar visível a última contagem.

    lineChart?.xAxis.setLabelCount(arrOfMonth.count, force: true)

Isso ajudará a exibir o último valor do gráfico de linha - tentei e trabalhei para mim

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

Questões relacionadas

deepumukundan picture deepumukundan  ·  3Comentários

anhltse03448 picture anhltse03448  ·  3Comentários

guanyanlin picture guanyanlin  ·  3Comentários

heumn picture heumn  ·  3Comentários

BrandonShega picture BrandonShega  ·  4Comentários