Как добавить несвязанный массив к меткам Datapoint в линейном графике iOS-диаграмм? - PullRequest
2 голосов
/ 30 октября 2019

Я прочитал Как добавить строки на оси X в iOS-диаграммах? , но это не отвечает на мой вопрос.

Я отрисовал линейную диаграмму с iOS-диаграммами безметки оси x / y, только метки точек данных, например . На этой диаграмме значения температуры в ChartDataEntry диаграммы представлены в виде Y с интервалами 0 ..

var temperaturevalues: [Double] = [47.0, 48.0, 49.0, 50.0, 51.0, 50.0, 49.0]

Однако я хочу добавить несвязанный массив раз к меткам точек данных со временем [i] сопоставление температурных значений в i.

var times: [String] = ["7 AM", "8 AM", "11 AM", "2 PM", "5 PM", "8 PM", "11 PM"]

Я расширил IValueFormatter в отдельном классе, например так:

class ChartsFormatterToDegrees: IValueFormatter {    
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
    return "\(Int(value))°"
}

, но он позволяет только настраивать dataPointпометить, используя значение в ChartDataEntry, которое является значением TemperatureValue, используемым для отображения Y в lineChart. Как я могу добавить другой массив в indexValue, чтобы метки dataPoints выглядели так?

    return """
    \(Int(value))°
    \(timesOfDay)
    """

Вот мой метод диаграмм:

private func setupChartView(temperatureValues: [Double], timesDataPoints: [String]) {
    var tempDataEntries: [ChartDataEntry] = []
    let chartsFormatterToDegrees = ChartsFormatterToDegrees(time: timeDataPoints)


    for eachTemp in 0..<temperatureValues.count {
        let tempEntry = ChartDataEntry(x: Double(eachTemp), y: temperatureValues[eachTemp])
        tempDataEntries.append(tempEntry)
    }

    let lineChartDataSet = LineChartDataSet(entries: tempDataEntries, label: "nil")
    lineChartDataSet.valueFormatter = chartsFormatterToDegrees

    let chartData = LineChartData(dataSets: [lineChartDataSet])
    chartData.addDataSet(lineChartDataSet)
    lineChartView.data = chartData
}

Как я понимаю, IValueFormatterРасширение позволяет только изменять значения, используемые для рисования диаграммы, но не добавлять дополнительные строковые массивы в индекс. Когда я попробовал описанное ниже, он только печатает timesOfDay в dataSetIndex, он печатает только timesOfDay[0] на всех метках dataPoint.

class ChartsFormatterToDegrees: IValueFormatter {
init(time: [String]) {
    timesOfDay = time
}
var timesOfDay = [String]()

func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
    return """
    \(Int(value))°
    \(timesOfDay[dataSetIndex])
    """
}
}

Вот мой самый обновленный метод с печатью:

class ChartsFormatterToDegrees: IValueFormatter {

     var timesOfDay = [String]()
     var values = [Double]()

     init(values: [Double], time: [String]) {
         timesOfDay = time
         //print(values, "are the values") //prints values correctly
     }

     func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
        //print(value, "at", dataSetIndex) //prints as 37.0 at 0, 39.0 at 0, 40.0 at 0 etc

          if let index = values.firstIndex(of: value) {
              return "\(Int(value))° \(timesOfDay[index])"
          }

        let i = values.firstIndex(of: value)
        //print(i as Any, "is index of where value shows up") //prints as nil is index of where value shows up for each i

          return "\(Int(value))°"
      }
    }

1 Ответ

1 голос
/ 30 октября 2019

Ваше предположение неверно. В IValueFormatter вы можете создать любую строку для соответствующего значения. Причина, по которой вы видите только значение или timeOfDay, заключается в том, что вы создаете String с нотацией """, которая добавляет несколько строк, в то время как метка, используемая для точки входа, может неправильно вычислять ее размер. Вы должны создать String, как показано ниже, и посмотреть, что у вас есть

class ChartsFormatterToDegrees: IValueFormatter {

     var timesOfDay = [String]()
     var values = [Double]()  

     init(values: [Double], time: [String]) {
         timesOfDay = time
         values = values
     }

     func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
          if let index = values.firstIndex(of: value) {
              return "\(Int(value))° \(timesOfDay[index])"
          }
          return "\(Int(value))°"
      }
}
...