更新dataSource时,图表会隐藏或重叠/标记轴,标签和标题

时间:2014-12-24 05:03:32

标签: ios swift core-plot

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

Screenshot With Correct Axes

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

Screenshot With Axes Gone

我希望在渲染数据时,轴,标签和标题保持可见。有很多可能的原因,我试图排除我能想到的所有原因。以下是我尝试过的内容:

  • 问题不在于轴标题位置或图形填充,因为它们最初显示正确。
  • 我读了一篇帖子说graph.plotAreaFrame.masksToBorder = false应该有效。那没有做到。
  • 我尝试将图表和绘图区域填充设置为nil,以尝试显示标题,如果它们被填充遮挡。图表背后的视图已被公布,但不是标题。
  • 我尝试了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;
    }
}

1 个答案:

答案 0 :(得分:1)

默认情况下,轴始终在(0,0)处交叉。我怀疑你的情节数据没有覆盖那一点,因此scaleToFitPlots将(0,0)推到可见的绘图区域之外并隐藏轴。您有几种选择:

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

  2. 致电scaleToFitPlots后,更新相应地块范围内每个轴的orthogonalPosition

  3. 调用scaleToFitPlots后,展开绘图范围,以便在需要时包含零(0)。