2016-08-20 1 views
18

В новой версии я имел некоторые проблемы, чтобы создать несколько графиков предыдущий код был:Как добавить строки в X Axis в iOS-диаграммах?

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 
} 

Вы можете передать значения, например массив месяцев, используя строку:

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

После новый релиз код, реализующий тот же граф является:

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 
} 

Я пытался несколько часов, но я не мог найти способ изменить значение оси X, Я надеюсь, что кто-то может мне помочь, спасибо!

+0

I думаю, вы можете использовать форматировщик значений оси. barChartView.xAixs.valueFormatter = «Свой объект форматирования ценности» – Surely

+1

: О, спасибо rmaddy, я пытаюсь использовать «barChartView.xAxis.valueFormatter», но ему нужен «iAxisValueFormatter?», который является интерфейсом, m новичок и не знаете, как использовать этот тип, не могли бы вы дать мне несколько инструкций о том, как его использовать? –

+0

Привет, вы можете просто создать класс, реализующий интерфейс, затем создать объект класса, или вы можете просто реализовать интерфейс с вашим текущим классом и передать его себе. Это похоже на то, как вы реализуете методы делегата tableview. – Surely

ответ

12

Я нашел решение, может быть, еще один может решить эту проблему в лучшую сторону, без создания нового класса, а это то, что я нашел:

Сначала вы nedd создать новый класс, который будет ваш класс форматирования и добавьте интерфейс IAxisValueFormater, то вы используете метод stringForValue для настройки новых значений, он принимает два параметра, первое - это фактическое значение (вы можете видеть его как индекс), а второе - ось, где значение равно ,

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

Теперь в вашем файле в начале вашего setChart() функции, которые вы должны создать две переменные один для вашего класса форматировочной и один для класса оси:

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

Далее идти вперед в конец ибо в цикле и передать индекс и ось переменной форматировочной:

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

После цикла добавьте формат переменной оси:

xaxis.valueFormatter = formato 

Заключительный шаг, чтобы добавить новый xaxisformatted к barChartView:

barChartView.xAxis.valueFormatter = xaxis.valueFormatter 

И это все остальные строки в setChart() функция просто держать его там, где они есть, я надеюсь, что это может помочь вы.

+0

Это хорошо работает, но как бы передать значения месяца в класс, вместо того, чтобы иметь их настройку спереди (поскольку я пытаюсь получить эти значения из CoreData) –

+0

В вашем классе форматирования просто добавьте новый метод, например «setArray», и он принимает один массив в качестве параметра, а затем просто устанавливает ваш массив var, в данном случае «месяцев» и делает его равным вашему массиву, в вашем основном классе вы можете вызвать этот метод «setArray» и отправить массив, который вы хотите , –

+0

Отличный ответ на ваш вопрос! Но знаете ли вы, как устанавливать x-метки, когда вы устанавливаете другую ширину столбца в столбцы? –

6

уборщик способ реализовать предложение выше, если вы подклассы графика является реализацией IAxisValueFormatter протокола в подклассе самого

class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {} 

, как это ...

public func stringForValue(_ value: Double, axis: Charts.AxisBase?) -> String 
{ 
    return "My X Axis Label Str"; // Return you label string, from an array perhaps. 
} 

Затем в Init()

self.xAxis.valueFormatter = self; 
4

Здравствуйте недавно я получил stucked в нем, и я попытался это ПУТЬ

class ViewController: UIViewController { 

    var months: [String]! 
    var unitsSold = [Double]() 
    weak var axisFormatDelegate: IAxisValueFormatter? 

    @IBOutlet var viewForChart: BarChartView! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     axisFormatDelegate = self 
     months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 
     unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0] 

     // setChart(_ dataPoints:months,_ forY: unitsSold) 
     setChart(dataEntryX: months, dataEntryY: unitsSold) 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func setChart(dataEntryX forX:[String],dataEntryY forY: [Double]) { 
     viewForChart.noDataText = "You need to provide data for the chart." 
     var dataEntries:[BarChartDataEntry] = [] 
     for i in 0..<forX.count{ 
      // print(forX[i]) 
      // let dataEntry = BarChartDataEntry(x: (forX[i] as NSString).doubleValue, y: Double(unitsSold[i])) 
      let dataEntry = BarChartDataEntry(x: Double(i), y: Double(forY[i]) , data: months as AnyObject?) 
      print(dataEntry) 
      dataEntries.append(dataEntry) 
     } 
     let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units Sold") 
     let chartData = BarChartData(dataSet: chartDataSet) 
     viewForChart.data = chartData 
     let xAxisValue = viewForChart.xAxis 
     xAxisValue.valueFormatter = axisFormatDelegate 

    } 
} 

В конце только что добавили расширение для делегат

extension ViewController: IAxisValueFormatter { 

    func stringForValue(_ value: Double, axis: AxisBase?) -> String { 
    return months[Int(value)] 
    } 
} 

с th is link Я узнал https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk

29

Я думаю, что это более совершенное решение для установки меток оси x со строками без создания каких-либо классов, как показано ниже.

Раствор для этикеток X-оси в Swift 3.0: -

let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] 

barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values:months) 
//Also, you probably want to add: 

barChartView.xAxis.granularity = 1 

Вот так.

Подробнее см. here.

+3

самый полезный ответ для меня. Нет необходимости называть делегат оси. Но здесь нам еще нужно выяснить, как центрировать метку. –

+2

xaxis.centerAxisLabelsEnabled = true –

+1

Я бы выделил barChartView.xAxis.granularity = 1. Это помогло сопоставить значения xAxis с построенными данными –

1

Как и многие люди говорили, что вы можете создать класс или расширить с типом IAxisValueFormatter, но вы можете легко использовать следующий метод, который только принимать 3 линии:

self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in 
    return xStrings[Int(index)] 
}) 

вот моя функция setChart() в случае, если какой-то из вас найти некоторые из моих кастомизации интересных:

func setChartView(entriesData: [entry]) { 
    var chartEntries: [ChartDataEntry] = [] 
    var xStrings: [String] = [] 
    let sortedentriesData = entriesData.sorted { (s1: entry, s2: entry) -> Bool in 
     return s1.timestamp < s2.timestamp 
    } 
    for (i, entry) in sortedentriesData.enumerated() { 
     let newEntry = ChartDataEntry(x: Double(i), y: entry.temperature) 
     chartEntries.append(newEntry) 
     let dateFormatter = DateFormatter() 
     dateFormatter.timeStyle = .medium 
     dateFormatter.dateStyle = .none 
     xStrings.append("\(dateFormatter.string(from: Date.init(timeIntervalSince1970: TimeInterval(entry.timestamp))))") 
    } 
    let set: LineChartDataSet = LineChartDataSet(values: chartEntries, label: "°C") 
    set.setColor(NSUIColor.blue, alpha: CGFloat(1)) 
    set.circleColors = [NSUIColor.blue] 
    set.circleRadius = 3 
    set.mode = LineChartDataSet.Mode.cubicBezier 

    let data: LineChartData = LineChartData(dataSet: set) 
    self.chartView.xAxis.labelRotationAngle = -90 
    self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in 
     return xStrings[Int(index)] 
    }) 
    self.chartView.xAxis.setLabelCount(xStrings.count, force: true) 
    self.chartView.data = data 
} 

записи является структурой, я создал:

struct entry { 
    var timestamp: Int 
    var temperature: Double 
} 
+0

Это идеальное решение для меня благодарит за обмен. работает как шарм –