2017-01-18 4 views
2

Ich habe Schwierigkeiten, Bibliothek Charts (von Daniel Gindi) von Version 2 (Swift 2.3) zu 3 (Swift 3) zu migrieren.ios Charts 3.0 - Ausrichten x Etiketten (Daten) mit Plots

Grundsätzlich kann ich die X-Etiketten (Daten) nicht korrekt mit den entsprechenden Plots ausgerichtet haben.

Dies ist, was ich in der Version 2 vor hatte:

In Version 2 hatte ich Werte für Tage 7, 8, 10 und 11 So einen Tag in der Mitte ich fehlte, aber die Etiketten wurden korrekt mit den Plots abgestimmt. Charts 2


Und hier ist das, was ich in der Version haben 3:

In der Version 3 sind die "Etiketten" in der x-Achse sind nun durch einen Doppelklick (Termine ersetzt worden, es ist ein TimeInterval seit 1970) und über einen Formatierer formatiert. Also ist der Graph jetzt zweifellos "korrekter", da das Diagramm den Wert für den 9. korrekt extrapoliert, aber ich finde nicht, wie man die Beschriftungen unter die entsprechenden Plots stellt. Charts 3

Dies ist mein Code für die x-Achse:

let chartView = LineChartView() 
... 
let xAxis = chartView.xAxis 
xAxis.labelPosition = .bottom 
xAxis.labelCount = entries.count 
xAxis.drawLabelsEnabled = true 
xAxis.drawLimitLinesBehindDataEnabled = true 
xAxis.avoidFirstLastClippingEnabled = true 

// Set the x values date formatter 
let xValuesNumberFormatter = ChartXAxisFormatter() 
xValuesNumberFormatter.dateFormatter = dayNumberAndShortNameFormatter // e.g. "wed 26" 
xAxis.valueFormatter = xValuesNumberFormatter 

Hier ist die ChartXAxisFormatter Klasse I erstellt:

import Foundation 
import Charts 

class ChartXAxisFormatter: NSObject { 
    var dateFormatter: DateFormatter? 
} 

extension ChartXAxisFormatter: IAxisValueFormatter { 

    func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
     if let dateFormatter = dateFormatter { 

      let date = Date(timeIntervalSince1970: value) 
      return dateFormatter.string(from: date) 
     } 

     return "" 
    } 

} 

die Werte hier also richtig sind, wird die Formatierung korrekt ist, Die Form des Diagramms ist korrekt, aber die Ausrichtung der Beschriftungen mit den entsprechenden Plots ist nicht gut. Danke für Ihre Hilfe

+0

Ich konnte mit Charts 3.0.0 und Charts 3.0.1 reproduzieren. Zur gleichen Zeit habe ich Code mit Charts 3.0.0 in einem separaten Projekt, das nicht unter diesen Problemen leidet. Vielleicht liegt eine gewisse Kombination von Diagrammeinstellungen an diesem Fehler? – Alex

+0

Ich hatte eine Antwort des Charts Github Repo: anscheinend geschieht dies, wenn ** Zeitintervalle ** auf der x-Achse verwendet wird, weil Charts eine Interpolation verwendet, um zu bestimmen, welche Labels angezeigt werden sollen. –

Antwort

7

OK, hab es geschafft!

Sie müssen ein Referenzzeit-Intervall definieren (die "0" für die X-Achse). Und dann berechnen Sie das zusätzliche Zeitintervall für jeden x-Wert.

Die ChartXAxisFormatter wird:

import Foundation 
import Charts 

class ChartXAxisFormatter: NSObject { 
    fileprivate var dateFormatter: DateFormatter? 
    fileprivate var referenceTimeInterval: TimeInterval? 

    convenience init(referenceTimeInterval: TimeInterval, dateFormatter: DateFormatter) { 
     self.init() 
     self.referenceTimeInterval = referenceTimeInterval 
     self.dateFormatter = dateFormatter 
    } 
} 


extension ChartXAxisFormatter: IAxisValueFormatter { 

    func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
     guard let dateFormatter = dateFormatter, 
     let referenceTimeInterval = referenceTimeInterval 
     else { 
      return "" 
     } 

     let date = Date(timeIntervalSince1970: value * 3600 * 24 + referenceTimeInterval) 
     return dateFormatter.string(from: date) 
    } 

} 

Und dann, wenn ich meine Dateneinträge zu erstellen, funktioniert es wie so:

// (objects is defined as an array of struct with date and value) 

// Define the reference time interval 
var referenceTimeInterval: TimeInterval = 0 
if let minTimeInterval = (objects.map { $0.date.timeIntervalSince1970 }).min() { 
     referenceTimeInterval = minTimeInterval 
    } 


    // Define chart xValues formatter 
    let formatter = DateFormatter() 
    formatter.dateStyle = .short 
    formatter.timeStyle = .none 
    formatter.locale = Locale.current 

    let xValuesNumberFormatter = ChartXAxisFormatter(referenceTimeInterval: referenceTimeInterval, dateFormatter: xValuesFormatter) 



    // Define chart entries 
    var entries = [ChartDataEntry]() 
    for object in objects { 
     let timeInterval = object.date.timeIntervalSince1970 
     let xValue = (timeInterval - referenceTimeInterval)/(3600 * 24) 

     let yValue = object.value 
     let entry = ChartDataEntry(x: xValue, y: yValue) 
     entries.append(entry) 
    } 

// Pass these entries and the formatter to the Chart ... 

Das Ergebnis viel schöner ist (ich übrigens cubic entfernt): enter image description here

+0

Bitte teilen Sie Demo-Code als Referenz. – TKutal

+0

Ich denke es ist was ich gemacht habe –

+0

Was ist xValuesFormatter? –

Verwandte Themen