新しいリリースでは、以前のコードは次のようなグラフを作成するのに苦労しました。
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軸の値を変更する方法を見つけることができませんでした、誰かが私を助けてくれることを願っています、ありがとう!!
私は解決策を見つけましたが、新しいクラスを作成することなく、別の方法でこの問題をより良い方法で解決できるかもしれませんが、これは私が見つけたものです:
まず、フォーマッタクラスとなる新しいクラスを作成し、IAxisValueFormaterインターフェイスを追加します。次に、stringForValueメソッドを使用して新しい値をカスタマイズします。2つのパラメーターが必要です。1つは実際の値ですインデックス)と2番目は値がある軸です。
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()関数の先頭で、フォーマッタクラス用と軸クラス用の2つの変数を作成する必要があります。
let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()
次に、for inループの最後に進み、インデックスと軸をフォーマッター変数に渡します。
formato.stringForValue(Double(i), axis: xaxis)
ループした後、軸変数に形式を追加します。
xaxis.valueFormatter = formato
最後のステップは、新しいxaxisformattedをbarChartViewに追加することです。
barChartView.xAxis.valueFormatter = xaxis.valueFormatter
そして、それはsetChart()関数の他のすべての行であり、それらをそのままの場所に保持します。
こんにちは最近、私は同じ問題に遭遇し、このように解決しました-
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)]
}
}
このリンクからこの解決策を考え出しました https://medium.com/@skoli/using-realm-and-charts-with-Swift-3-in-ios-10-40c42e3838c0#.minfe6kuk
多くの人が言ったように、クラスを作成したり、タイプIAxisValueFormatterで拡張したりできますが、次のメソッドを簡単に使用できます。
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
}
グラフをサブクラス化する場合に上記の提案を実装するよりクリーンな方法は、サブクラス自体に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;
最も簡単なソリューション:
barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
barChartView.xAxis.granularity = 1