我试过了,
我只使用 yAxis,不需要 xAxis
这是我的整个代码
我的ChartViewController
//
// ChartViewController.swift
// MCOS
//
// Created by Burhan Cankurt on 01.09.23.
//
import UIKit
import CorePlot
class ChartViewController: UIViewController, CPTScatterPlotDataSource, CPTScatterPlotDelegate, CPTAxisDelegate {
var ArrayStockClose: [(date: String, close: Double)] = []
@IBOutlet weak var graphHostingView: CPTGraphHostingView!
override func viewDidLoad() {
super.viewDidLoad()
chartViewStockClose(with: .fiveMinute)
}
func chartViewStockClose(with timeFrame: TimeFrame) {
print("chartViewStockClose called") // Debug
let fetcher = chartFetcherStockClose()
chartLoadStockClose(with: timeFrame, fetcher: fetcher) { [weak self] result in
print("chartLoadStockClose completion called") // Debug
switch result {
case .success(let data):
self?.ArrayStockClose = data
print("Daten im ViewController: \(data) und zählung \(data.count)")
DispatchQueue.main.async {
print("initializeGraph called") // Debug
// Hier können Sie Ihren Graphen initialisieren oder aktualisieren
self?.initializeGraph()
}
case .failure(let error):
print("Error fetching data: \(error)")
}
}
}
func initializeGraph() {
// Konfigurieren Sie die Ansicht und den Graphen
configureGraphView(for: graphHostingView, plotData: ArrayStockClose, delegate: self) // Angenommen, Sie haben eine Funktion namens configureGraphView
// Konfigurieren Sie den Plot
configurePlot(for: graphHostingView, dataSource: self, delegate: self) // Angenommen, Sie haben eine Funktion namens configurePlot
}
}
// Erweiterung für CorePlot Datenquelle und Delegat
extension ChartViewController {
func numberOfRecords(for plot: CPTPlot) -> UInt {
print("numberOfRecords called, count: \(ArrayStockClose.count)")
return UInt(ArrayStockClose.count)
}
func number(for plot: CPTPlot, field: UInt, record: UInt) -> Any? {
print("number called for field: \(field), record: \(record)")
switch CPTScatterPlotField(rawValue: Int(field)) {
case .X:
return NSNumber(value: record) // Da wir die X-Achse nicht verwenden, können wir einfach den Index verwenden
case .Y:
return NSNumber(value: ArrayStockClose[Int(record)].close)
default:
return nil
}
}
}
我的图表FetcherStock关闭
//
// ChartFetcherStockClose.swift
// MCOS
//
// Created by Burhan Cankurt on 01.09.23.
//
import Foundation
import Foundation
class chartFetcherStockClose {
func fetch(url: URL, completion: @escaping (Result<[(date: String, close: Double)], Error>) -> Void) {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
completion(.failure(error))
return
}
guard let data = data else {
completion(.failure(NSError(domain: "No data", code: 0, userInfo: nil)))
return
}
do {
let decoder = JSONDecoder()
let stockData = try decoder.decode([StructStockClose].self, from: data)
// Sortiere die Datenpunkte nach dem Datum
let sortedStockData = stockData.sorted { $0.date < $1.date }
// Erstelle ein leeres Array, um die Ergebnisse zu speichern.
var resultArray: [(date: String, close: Double)] = []
// Durchlaufe jedes Element in sortedStockData.
for data in sortedStockData {
resultArray.append((date: data.date, close: data.close))
}
// Rufe den Completion Handler mit dem Ergebnis-Array auf.
completion(.success(resultArray))
} catch {
completion(.failure(error))
}
}
task.resume()
}
}// Class End
我的图表加载库存关闭
//
// ChartLoadStockClose.swift
// MCOS
//
// Created by Burhan Cankurt on 01.09.23.
//
import Foundation
enum TimeFrame {
case oneMinute
case fiveMinute
case fifteenMinute
case thirtyMinute
case oneHour
case fourHour
case oneDay
}
func chartLoadStockClose(with timeFrame: TimeFrame, fetcher: chartFetcherStockClose, completion: @escaping (Result<[(date: String, close: Double)], Error>) -> Void) {
let timeFrameParameter: String
switch timeFrame {
case .oneMinute: timeFrameParameter = "1min"
case .fiveMinute: timeFrameParameter = "5min"
case .fifteenMinute: timeFrameParameter = "15min"
case .thirtyMinute: timeFrameParameter = "30min"
case .oneHour: timeFrameParameter = "1hour"
case .fourHour: timeFrameParameter = "4hour"
case .oneDay: timeFrameParameter = "1day"
}
let url = URL(string: "https://financialmodelingprep.com/api/v3/historical-chart/\(timeFrameParameter)/AAPL?apikey=BLABLABLA")!
fetcher.fetch(url: url) { result in
switch result {
case .success(let data):
// Verwende nur die letzten 48 Datenpunkte
let filteredData = Array(data.suffix(48))
completion(.success(filteredData))
case .failure(let error):
completion(.failure(error))
}
}
}
我的图表配置GraphView
//
// ChartConfigureGraphView.swift
// MCOS
//
// Created by Burhan Cankurt on 01.09.23.
//
import CorePlot
import UIKit
func configureGraphView(for graphView: CPTGraphHostingView, plotData: [(date: String, close: Double)], delegate: CPTAxisDelegate) {
print("configureGraphView called") // Debug
graphView.allowPinchScaling = false
// Configure graph
let graph = CPTXYGraph(frame: graphView.bounds)
graph.plotAreaFrame?.masksToBorder = false
graphView.hostedGraph = graph
graph.backgroundColor = UIColor.black.cgColor
graph.paddingBottom = 40.0
graph.paddingLeft = 50.0
graph.paddingTop = 30.0
graph.paddingRight = 5.0
// Set plot space
let yMin = plotData.min(by: { $0.close < $1.close })?.close ?? 0
let yMax = plotData.max(by: { $0.close < $1.close })?.close ?? 0
print("yMin: \(yMin)") // Debug
print("yMax: \(yMax)") // Debug
let yRange = yMax - yMin
let paddingPercentage = 0.05
print("yRange: \(yRange)") // Debug
let yMinAdjusted = yMin - (yRange * paddingPercentage)
let yMaxAdjusted = yMax + (yRange * paddingPercentage)
print("yMinAdjusted: \(yMinAdjusted)") // Debug
print("yMaxAdjusted: \(yMaxAdjusted)") // Debug
guard let plotSpace = graph.defaultPlotSpace as? CPTXYPlotSpace else { return }
plotSpace.yRange = CPTPlotRange(locationDecimal: CPTDecimalFromDouble(yMinAdjusted), lengthDecimal: CPTDecimalFromDouble(yMaxAdjusted - yMinAdjusted))
// Configure axes
let axisSet = graph.axisSet as! CPTXYAxisSet
let axisTextStyle = CPTMutableTextStyle()
axisTextStyle.color = CPTColor.white()
axisTextStyle.fontName = "HelveticaNeue-Bold"
axisTextStyle.fontSize = 10.0
axisTextStyle.textAlignment = .center
if let x = axisSet.xAxis {
x.isHidden = true // Versteckt die X-Achse
}
if let y = axisSet.yAxis {
print("Configuring yAxis") // Debug
y.majorIntervalLength = NSNumber(value: Double((yMaxAdjusted - yMinAdjusted) / 10.0)) // Dynamically adjust the interval
y.minorTicksPerInterval = 5
y.labelTextStyle = axisTextStyle
y.axisConstraints = CPTConstraints(lowerOffset: 0.0)
y.delegate = delegate
}
}
我的结构
//
// Structs.swift
// MCOS
//
// Created by Burhan Cankurt on 01.09.23.
//
import Foundation
struct StructStockClose: Decodable {
let close: Double
let date: String
}
我的图表配置图
//
// ChartConfigurePlot.swift
// MCOS
//
// Created by Burhan Cankurt on 01.09.23.
//
import CorePlot
import UIKit
func configurePlot(for graphView: CPTGraphHostingView, dataSource: CPTScatterPlotDataSource, delegate: CPTScatterPlotDelegate) {
print("configurePlot called") // Debug
let plot = CPTScatterPlot()
let plotLineStile = CPTMutableLineStyle()
plotLineStile.lineJoin = .round
plotLineStile.lineCap = .round
plotLineStile.lineWidth = 2
plotLineStile.lineColor = CPTColor.white()
plot.dataLineStyle = plotLineStile
plot.curvedInterpolationOption = .catmullCustomAlpha
plot.interpolation = .curved
plot.identifier = "coreplot-graph" as NSCoding & NSCopying & NSObjectProtocol
guard let graph = graphView.hostedGraph else { return }
plot.dataSource = dataSource
plot.delegate = delegate
graph.add(plot, to: graph.defaultPlotSpace)
}
我解决了可视化问题,问题是无论您是否使用 xAxis,创建此代码后都需要时间戳
我的约会助手
//
// DateHelpers.swift
// MCOS
//
// Created by Burhan Cankurt on 02.09.23.
//
import Foundation
func convertDateToTimestamp(_ date: String) -> Double {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" // Anpassung an Ihr Datumsformat
dateFormatter.timeZone = TimeZone(abbreviation: "UTC")
guard let dateObject = dateFormatter.date(from: date) else {
print("Fehler beim Konvertieren des Datums: \(date)")
return 0.0
}
let timestamp = dateObject.timeIntervalSince1970
print("Zeitstempel für Datum \(date): \(timestamp)")
return timestamp
}
并在我的 ChartViewController 中使用它
// Erweiterung für CorePlot Datenquelle und Delegat
extension ChartViewController {
func numberOfRecords(for plot: CPTPlot) -> UInt {
print("Anzahl der Datenpunkte: \(ArrayStockClose.count)")
return UInt(ArrayStockClose.count)
}
func number(for plot: CPTPlot, field: UInt, record: UInt) -> Any? {
switch CPTScatterPlotField(rawValue: Int(field)) {
case .X:
return NSNumber(value: convertDateToTimestamp(ArrayStockClose[Int(record)].date)) // Verwenden Sie den Zeitstempel
case .Y:
return NSNumber(value: ArrayStockClose[Int(record)].close)
default:
return nil
}
}
}
可视化工作正常,但现在我面临一个非常奇怪的问题,时间范围 1 分钟和 5 分钟工作正常,但如果使用超过 5 分钟的时间范围,我会收到此错误
Zeitstempel für Datum 2023-09-01 15:00:00: 1693580400.0
Zeitstempel für Datum 2023-09-01 15:15:00: 1693581300.0
Zeitstempel für Datum 2023-09-01 15:30:00: 1693582200.0
Zeitstempel für Datum 2023-09-01 15:45:00: 1693583100.0
Zeitstempel für Datum 2023-09-01 16:00:00: 1693584000.0
Anzahl der Datenpunkte: 48
Anzahl der Datenpunkte: 48
2023-09-03 23:13:45.924826+0200 MCOS[40996:1540827] [Render] CoreAnimation: Message::send_message() returned 0x1000000e
2023-09-03 23:13:45.925018+0200 MCOS[40996:1540827] [API] Failed to commit transaction (client=0x1d461d53) [0x1000000e (ipc/send) msg too large]
我尝试了什么?
奇怪:如果你将我的数据点从 48 减少到 20,例如,我会在更高的时间范围 15 分钟上加载图表,当我将其减少到 10 时,它还会加载更高的时间范围图表 30 分钟
知道问题可能是什么吗?