Charts: LineChart X-Axis: cómo mostrar siempre la primera y la última etiqueta

Creado en 26 dic. 2016  ·  21Comentarios  ·  Fuente: danielgindi/Charts

En mi gráfico de líneas, lo tengo configurado de modo que si solo hay una entrada de datos, hago que el punto de datos aparezca en el medio de esta manera:

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

Si hay más entradas de datos, se verá más parecido a esto:

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

El problema que tengo es que la última etiqueta del eje X no aparece. Estos son datos de los últimos 30 días, por lo que me gustaría que apareciera la última etiqueta, el 25 de diciembre. ¿Hay alguna manera de hacer que mi gráfico de líneas siempre muestre la primera y la última etiqueta en el eje X? No me importa cómo calcule u omita las etiquetas intermedias.

bug

Comentario más útil

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

Esto ayudará a mostrar el último valor del gráfico de líneas: lo intenté y trabajé para mí

Todos 21 comentarios

intente avoidFirstLastClippingEnabled , el valor predeterminado es 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 ¿

avoidFirstLastClippingEnabled no ayuda. La última etiqueta siempre se corta

Si miro el código fuente, las entradas del eje se calculan en AxisRendererBase.computeAxisValues y no hay forma de hacer cumplir el valor máximo que se mostrará. Sin embargo, creo que esta funcionalidad fue compatible con la versión anterior.

https://github.com/danielgindi/Charts/issues/2007 parece el mismo problema con este?
@ondrejhanslik de forma predeterminada, computeAxisValues ​​() tomará el valor mínimo y máximo para calcular el rango. Por lo tanto, el valor mínimo y máximo debe ser mayor que el valor mínimo / máximo de los datos para contener todos los datos. ¿Ha comprobado cuál es su valor mínimo / máximo en computeAxisValues ​​() y cuál es el valor mínimo / máximo de sus datos?

@ liuxuan30 Uso una matriz de cadenas personalizada como valores del eje X, es decir, fechas

Aquí hay una captura de pantalla de mi gráfico.

untitled

Así es como se ve mi gráfico al establecer avoidFirstLastClippingEnabled en verdadero:

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

Aquí hay un código adicional que estoy usando para configurar mi eje 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()
}

Estoy usando Charts 3.0.1 por cierto :)

Aquí igual. Gráficos 3.0.1 , XCode 8.0 y Swift 3.0

Si no es posible una solución para esta situación, supongo que una solución alternativa que probablemente tendría sentido sería, cuando se muestre el gráfico, resaltar el último valor (hoy) para que el "BalloonMarker" aparezca mostrando el texto "Dec XX \ n500 ".

De mi lado obviamente :)

OK, lo comprobé.

En el gráfico 3.0, el eje x se comporta como el eje y, por lo que puede consultar las etiquetas del eje y, la etiqueta del eje y más grande es más pequeña que el valor máximo de los datos, en
image

En computeAxisValues() , lee el valor mínimo y máximo del valor mínimo / máximo del eje (que es el valor mínimo / máximo de los datos) y calcula un intervalo para obtener las etiquetas del eje x.

Por ejemplo, en ChartsDemo - Line Chart Dual YAxis, si mis valores x son de 0 a 20,
computeAxisValues() toma 0, 20 como valor mínimo / máximo, luego, mi labelCount es 6 por defecto, calculará rawInterval = (max - min) / labelCount , y luego el intervalo final será 3. Entonces comienza desde 0, para obtener 7 (labelCount + 1) etiquetas, que son 0,3,6,9,12,15,18. La última etiqueta del eje x es 18, no 20.

La razón por la que isAvoidFirstLastClippingEnabled no funciona es porque maneja cuando la última etiqueta está fuera del límite, por lo que es irrelevante para este problema.

Si desea asegurarse de la etiqueta que es el valor x de sus datos, debe ajustar computeAxisValues() para devolver las etiquetas. Simplemente consulte computeAxisValues() para ver los detalles y debería poder cambiarlo.

@danielgindi, ¿qué opinas de estos casos de usuarios?

@ liuxuan30 No queremos modificar computeAxisValues para devolver algunas etiquetas específicas. Por ejemplo, cuando visualizo un gráfico sobre fechas (p. Ej., Los valores x son días de una semana, días de un mes o meses de un año), necesito que se muestren la primera y la última etiqueta (p. Ej., Lunes y domingo o 1 / 1 y 31/1).

Primero genero los valores formateados (por ejemplo, nombres de días o días formateados) y luego los configuro como:

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

Lo que necesito es un computeAxisValues más inteligente que siempre muestre la primera etiqueta y la última etiqueta y luego calcule las etiquetas entre ellas.

Este es un caso de uso muy básico y muy común.

Entiendo. Todavía hay errores en las etiquetas del eje x, por ejemplo, superposición de etiquetas.
La lógica actual es primero conocer el valor mínimo / máximo, generar intervalos a partir de él y acumularlos para obtener las etiquetas de los ejes. Sin embargo, el computeAxisValues() actual @danielgindi sobre esto.

Tal vez debería usar 'anular' en lugar de 'modificar' para computeAxisValues ​​(). Puede proporcionar una implementación para asegurarse de que su primer / último valor siempre se muestre como solución alternativa. Sin embargo, esto podría causar que la etiqueta se salga del encuadernado u otros problemas.

Otra forma es, puede intentar que setLabelCount(count, forceLabelEnabled) igual a su recuento de valores x o la mitad para ver el resultado.
La lógica es bastante diferente entonces:

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

No implica el proceso adicional, solo matemáticas simples.

@ liuxuan30 ¿

El eje x de @ vaibhav-varshaaweblabs ahora está tomando el doble SOLAMENTE en el Gráfico 3.x, por lo que puede usar valueFormatter para mostrar la etiqueta en lugar del doble. Sin embargo, valueFormatter puede ser complicado, cuando necesita considerar hacer zoom / desplazarse

¿Alguien ha encontrado una solución para esto en Gráficos 3.0.2? Estoy usando cadenas de fecha para mis etiquetas del eje x y veo que la última etiqueta desaparece ocasionalmente, pero tengo problemas para reproducir. Esto es con isAvoidFirstLastClippingEnabled establecido en true . Me pregunto si esto podría estar relacionado con # 2563.

@ vaibhav-varshaaweblabs @raudabaugh : ¿Cómo lograron trazar cadenas en el eje X, ya que el método setDataCount espera valores int o dobles para X e Y?
Amablemente hágamelo saber, gracias de antemano

bottomAxis.setLabelCount (entradas.tamaño (), verdadero); y también establezca el margen derecho para hacer visible el último recuento.

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

Esto ayudará a mostrar el último valor del gráfico de líneas: lo intenté y trabajé para mí

¿Fue útil esta página
0 / 5 - 0 calificaciones