ios - 更新数据源时,坐标轴、标签和标题被隐藏或重叠/遮挡

标签 ios swift core-plot

我在 Objective-C 应用程序中成功使用了 Core Plot。我正在用 Swift 编写一个新应用程序,但遇到了一些麻烦。在我为图表设置 dataSource 之前,坐标轴显示正确且符合预期。请参见以下屏幕截图:

Screenshot With Correct Axes

问题是当我设置 dataSource 时,数据正确呈现,但轴消失了。请参见以下屏幕截图:

Screenshot With Axes Gone

我希望轴、标签和标题在呈现数据时保持可见。可能的原因有很多,我已尝试排除所有我能想到的原因。这是我尝试过的:

  • 问题不在于坐标轴标题位置或图形填充,因为它们一开始显示正确。
  • 我读到一篇文章说 graph.plotAreaFrame.masksToBorder = false 应该有效。那没有做到。
  • 我尝试将图形和绘图区域填充设置为 nil 以尝试在标题被填充遮挡时显示它们。显示了图表背后的 View ,但没有显示标题。
  • 我尝试了 graph.topDownLayerOrder 的各种值,试图确保标题是最上面的项目,尤其是。在绘图区的顶部。请注意,文档说默认值是顶部的轴标题,所以我没想到这会修复它。
  • 我与调试器确认轴标签没有设置为隐藏。

在此先感谢您的帮助,感谢 Eric 与我们分享这个可爱的图书馆!

以下是我的源代码:

class TemperatureGraph: CPTGraphHostingView, CPTPlotSpaceDelegate {

    // Just needed to retain dataSource
    var dataSource: CPTPlotDataSource?

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    func setupGraphWithSession(session: Session?) {
        self.configureGraph()
        self.configurePlot()
        self.configureAxes()
        if (session != nil)
        {
            self.configureDataSource(session!)
        }
    }

    func configureGraph() {
        let graph: CPTGraph = CPTXYGraph(frame: self.bounds)
        graph.applyTheme(CPTTheme(named: kCPTSlateTheme))

        graph.title = "Temperature History (°F)"

        graph.paddingTop    = 0.0;
        graph.paddingBottom = 0.0;
        graph.paddingLeft   = 0.0;
        graph.paddingRight  = 0.0;

        //        graph.titleDisplacement = CGPoint(x: 0, y: 20)
        graph.plotAreaFrame.paddingTop    = 30.0;
        graph.plotAreaFrame.paddingBottom = 50.0;
        graph.plotAreaFrame.paddingLeft   = 50.0;
        graph.plotAreaFrame.paddingRight  = 10.0;

        // This doesn't help
        // graph.fill = nil;
        // graph.plotAreaFrame.fill = nil;

        // This doesn't help
        // graph.plotAreaFrame.masksToBorder = false

        // This doesn't help either
        //graph.topDownLayerOrder = [NSNumber(unsignedInt: CPTGraphLayerTypeAxisTitles.value)]

        // Some themes have a rounded border around the plot area. It looks bad since we removed the insets, so remove the border too.
        graph.plotAreaFrame.borderLineStyle = nil;
        graph.plotAreaFrame.cornerRadius = 0;
        self.hostedGraph = graph
    }

    func configurePlot() {
        let graph = self.hostedGraph
        var plot = CPTScatterPlot()
        // Make the data source line use curved interpolation
        // plot.interpolation = CPTScatterPlotInterpolationCurved;

        var lineStyle: CPTMutableLineStyle = plot.dataLineStyle.mutableCopy() as CPTMutableLineStyle
        lineStyle.lineWidth = 1.0;
        lineStyle.lineColor = CPTColor.redColor()
        plot.dataLineStyle = lineStyle;
        // For some reason, areaBaseValue isn't visible in swift. It's in the header and in Objective-C, don't know why it's not seen here.
        //plot.areaFill = CPTFill(color: lineStyle.lineColor.colorWithAlphaComponent(0.2))
        //plot.areaBaseValue = NSDecimalNumber.zero()

        graph.addPlot(plot)
    }

    func configureAxes() {
        let graph = self.hostedGraph
        let plot = graph.plotAtIndex(0)

        // The timestamps are large, which would make an inordinant number of axis label text by default, so to even render the graph in under a minute, simplify the axes.
        var axisSet: CPTAxisSet = graph.axisSet
        var axisTitleStyle = CPTMutableTextStyle()
        axisTitleStyle.color = CPTColor.blackColor()
        axisTitleStyle.fontName = "Helvetica-Bold"
        axisTitleStyle.fontSize = 12

        var xAxis = axisSet.axisForCoordinate(CPTCoordinateX, atIndex: 0)
        xAxis.labelingPolicy = CPTAxisLabelingPolicyNone
        xAxis.title = "Time"
        xAxis.titleOffset = 15
        xAxis.titleTextStyle = axisTitleStyle


        var yAxis = axisSet.axisForCoordinate(CPTCoordinateY, atIndex: 0)
//        yAxis.labelingPolicy = CPTAxisLabelingPolicyNone
        yAxis.title = "Temperature (°F)"
        yAxis.titleOffset = 25
        yAxis.titleTextStyle = axisTitleStyle
    }

    func configureDataSource(sesh: Session) {
        self.dataSource = TemperatureDatasource(session: sesh)

        let plot = self.hostedGraph.plotAtIndex(0)
        plot.dataSource = self.dataSource
        plot.plotSpace.scaleToFitPlots([plot])
        plot.plotSpace.allowsUserInteraction = true
        plot.plotSpace.delegate = self
    }

    func plotSpace(space: CPTPlotSpace!, shouldScaleBy interactionScale: CGFloat, aboutPoint interactionPoint: CGPoint) -> Bool {
        return true
    }

    func plotSpace(space: CPTPlotSpace!, willChangePlotRangeTo newRange: CPTPlotRange!, forCoordinate coordinate: CPTCoordinate) -> CPTPlotRange! {
        // Adjust axis to keep them in view at the left and bottom;
        // adjust scale-labels to match the scroll.
        var allowedRange = newRange
        if (coordinate.value == CPTCoordinateY.value) {
            let space = self.hostedGraph.defaultPlotSpace as CPTXYPlotSpace
            allowedRange = space.yRange
        }
        return allowedRange;
    }
}

最佳答案

默认情况下,坐标轴始终相交于 (0, 0)。我怀疑您的绘图数据没有涵盖这一点,因此 scaleToFitPlots 将 (0, 0) 推到可见绘图区域之外并隐藏了坐标轴。您有多种选择:

  1. 使用 axisConstraints 将坐标轴锁定到特定位置(例如,y 轴绘图区域的左边缘)。

  2. 调用scaleToFitPlots后,更新相应绘图范围内各轴的orthogonalPosition

  3. 调用 scaleToFitPlots 后,扩展绘图范围,使其包括零 (0)(如果需要)。

关于ios - 更新数据源时,坐标轴、标签和标题被隐藏或重叠/遮挡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27631759/

相关文章:

ios - 当相关的 NSManagedObject 更新时更新 UITableView

ios - 将 Apple Watch 添加到具有部署目标 IOS 7 的 iOS 应用程序

ios - 我如何保证对我的服务器的请求是由我的 iOS 应用程序在真实设备上生成的?

ios - "Generic parameter ' ResultType ' could not be inferred"while use NSFetchRequest() with swift 3.0

iphone - 核心图 - 设置缩放级别以仅显示图形的一部分

ios - 不同目标版本的 info.plist

ios - 每周在特定日期发送本地通知?

ios - 无法将数据传递给下一个ViewController依赖于UIPickerView textField.text?

ios - 在核心图散点图中加入缺失点

ios - 核心图 : Autoscaling y-axis labels according to plot data