使用 Core Plot 和 Swift 的多个散点图

Multiple scatterplots using Core Plot and Swift

我正在尝试找到一种方法将两个不同的散点图添加到一个图形中,但到目前为止我还做不到。我在 Objective-C 中找到了一些示例,但在 Swift 中没有找到任何示例,只是 CorePlot 2.1 版本中的散点图示例,但它以两种不同的线条颜色绘制相同的数据。

这是我目前所拥有的(只绘制了一个散点图):

import UIKit
import CorePlot

class ViewController : UIViewController, CPTScatterPlotDataSource {
    private var scatterGraph : CPTXYGraph? = nil

typealias plotDataType = [CPTScatterPlotField : Double]
private var dataForPlot = [plotDataType]()
@IBOutlet var graphView: UIView!

// MARK: Initialization

override func viewDidAppear(animated : Bool)
{
    super.viewDidAppear(animated)

    // Create graph from theme
    let newGraph = CPTXYGraph(frame: CGRectZero)
    newGraph.applyTheme(CPTTheme(named: kCPTDarkGradientTheme))

    let hostingView = graphView as! CPTGraphHostingView
    hostingView.hostedGraph = newGraph

    // Paddings
    newGraph.paddingLeft   = 10.0
    newGraph.paddingRight  = 10.0
    newGraph.paddingTop    = 10.0
    newGraph.paddingBottom = 10.0

    // Plot space
    let plotSpace = newGraph.defaultPlotSpace as! CPTXYPlotSpace
    //plotSpace.allowsUserInteraction = true
    plotSpace.yRange = CPTPlotRange(location:0, length:10)
    plotSpace.xRange = CPTPlotRange(location:0, length:10)

    // Axes
    let axisSet = newGraph.axisSet as! CPTXYAxisSet

    if let x = axisSet.xAxis {
        x.majorIntervalLength   = 2
        x.orthogonalPosition    = 2.0
        x.minorTicksPerInterval = 2

    }

    if let y = axisSet.xAxis {
        y.majorIntervalLength   = 2
        y.minorTicksPerInterval = 5
        y.orthogonalPosition    = 2.0

        y.delegate = self
    }

    // Create a blue plot area
    let boundLinePlot = CPTScatterPlot(frame: CGRectZero)
    let blueLineStyle = CPTMutableLineStyle()
    blueLineStyle.miterLimit    = 1.0
    blueLineStyle.lineWidth     = 3.0
    blueLineStyle.lineColor     = CPTColor.blueColor()
    boundLinePlot.dataLineStyle = blueLineStyle

    boundLinePlot.identifier    = "Blue Plot"
    boundLinePlot.dataSource    = self
    newGraph.addPlot(boundLinePlot)

    // Add plot symbols
    let symbolLineStyle = CPTMutableLineStyle()
    symbolLineStyle.lineColor = CPTColor.blackColor()
    let plotSymbol = CPTPlotSymbol.ellipsePlotSymbol()
    plotSymbol.fill          = CPTFill(color: CPTColor.blueColor())
    plotSymbol.lineStyle     = symbolLineStyle
    plotSymbol.size          = CGSize(width: 10.0, height: 10.0)

    // Put an area gradient under the plot above
    let areaColor    = CPTColor(componentRed: 0.3, green: 1.0, blue: 0.3, alpha: 0.8)
    let areaGradient = CPTGradient(beginningColor: areaColor, endingColor: CPTColor.clearColor())
    areaGradient.angle = -90.0
    let areaGradientFill = CPTFill(gradient: areaGradient)

    // Add some initial data
    var contentArray = [plotDataType]()

    let plotData1: plotDataType = [.X: 0, .Y: 5]
    let plotData2: plotDataType = [.X: 5, .Y: 0]
    contentArray.append(plotData1)
    contentArray.append(plotData2)
    self.dataForPlot = contentArray

    self.scatterGraph = newGraph


}

// MARK: - Plot Data Source Methods

func numberOfRecordsForPlot(plot: CPTPlot) -> UInt
{
    return UInt(self.dataForPlot.count)
}

func numberForPlot(plot: CPTPlot, field: UInt, recordIndex: UInt) -> AnyObject?
{
    let plotField = CPTScatterPlotField(rawValue: Int(field))

    if let num = self.dataForPlot[Int(recordIndex)][plotField!] {

            return num as NSNumber

    }
    else {
        return nil
    }
}

// MARK: - Axis Delegate Methods

func axis(axis: CPTAxis, shouldUpdateAxisLabelsAtLocations locations: NSSet!) -> Bool
{
    if let formatter = axis.labelFormatter {
        let labelOffset = axis.labelOffset

        var newLabels = Set<CPTAxisLabel>()

        for tickLocation in locations {
            if let labelTextStyle = axis.labelTextStyle?.mutableCopy() as? CPTMutableTextStyle {

                if tickLocation.doubleValue >= 0.0 {
                    labelTextStyle.color = CPTColor.greenColor()
                }
                else {
                    labelTextStyle.color = CPTColor.redColor()
                }

                let labelString   = formatter.stringForObjectValue(tickLocation)
                let newLabelLayer = CPTTextLayer(text: labelString, style: labelTextStyle)

                let newLabel = CPTAxisLabel(contentLayer: newLabelLayer)
                newLabel.tickLocation = tickLocation as! NSNumber
                newLabel.offset       = labelOffset

                newLabels.insert(newLabel)
            }

            axis.axisLabels = newLabels
        }
    }

    return false
}
}

这给了我一行,但我想添加一条包含不同数据的额外行。

有什么建议吗?

首先,创建两个 CPTScatterPlot(例如 boundLinePlot1boundLinePlot2)并用不同的颜色和不同的 identifier 配置它们,然后添加它们

boundLinePlot1.identifier = "Blue Plot"
boundLinePlot2.identifier = "Green Plot"

newGraph.addPlot(boundLinePlot1) 
newGraph.addPlot(boundLinePlot2)

现在在绘图数据源方法 (numberOfRecordsForPlot & numberForPlot) 中根据 plot.identifier

计算 return 值
if plot.identifier == "Blue Plot" {
    return dataForPlot1[Int(recordIndex)][plotField!]
} else {
    return dataForPlot2[Int(recordIndex)][plotField!]
}