2016-08-20 34 views
18

隨着新版本我遇到了一些麻煩,以創建一些圖表前面的代碼是:如何在iOS圖表的X軸上添加字符串?

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

我認爲你可以使用軸值格式化程序。 barChartView.xAixs.valueFormatter =「你的值格式化對象」 – Surely

+1

:O,謝謝你rmaddy,我試圖使用「barChartView.xAxis.valueFormatter」,但它需要一個「iAxisValueFormatter?」,這是一個接口,初學者,不知道如何使用這種類型,請給我一些關於如何使用它的說明? –

+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:

​​

而這在setChart所有其他線路()函數,只要保持他們在哪裏,我希望它可以幫助您。

+0

這很好,但我如何將月份值傳遞到類中,而不是必須讓它們在前面設置(因爲我試圖從CoreData中獲取這些值) –

+0

在您的格式化程序類中,只需添加一個新方法「setArray」,並且它需要一個數組作爲參數,然後在你的主類中設置數組var,在本例中爲「months」,並使其等於你的數組,你可以調用這個方法「setArray」併發送你想要的數組。 –

+0

很好的回答你的問題!但是,當您爲列設置不同的條寬時,是否知道如何適應x標籤? –

6

實現上面如果你是一個子類圖的建議清晰的方法是實現在子類本身

class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {} 

這樣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在它和我試過這個way-

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

from th是我學到的鏈接 https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk

29

我認爲這是用字符串設置x軸標籤而不創建任何類的更完美的解決方案,如下所示。在雨燕3.0

解決方案x軸標籤: -

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

這對我來說非常適合感謝分享。像魅力一樣工作 –

相關問題