【问题标题】:iOS CorePlot point conversioniOS CorePlot 点转换
【发布时间】:2016-08-13 20:42:01
【问题描述】:

我正在试验 Core Plot。我正在尝试在 x: 2.0, y: 50.0 的图形上添加一个自定义“目标”标签 - 基本上是 y == 50 上的标签,它在一个单独的视图中,这意味着我需要将我的点从 Core Plot 转换为我的 UIView 界限。我还没有找到适用于所有 iPhone 屏幕尺寸的图层/视图的点转换组合。在我下面的图片中,iPhone 6s 是最接近的。

iPhone 6s+:

iPhone 6s:

iPhone 5s:

我的视图布局:

这是我的课:

class BarChartViewController: UIViewController, CPTBarPlotDataSource
{
    private var barGraph : CPTXYGraph? = nil
    @IBOutlet weak var textBox: UILabel!
    @IBOutlet weak var graphHostingView: CPTGraphHostingView!
    @IBOutlet weak var textBoxView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.navigationController?.setNavigationBarHidden(false, animated: false)

        self.title = "My results"

        let newGraph = CPTXYGraph(frame: CGRectZero)
        let theme = CPTTheme(named: kCPTPlainWhiteTheme)

        newGraph.applyTheme(theme)

        let hostingView = graphHostingView
        hostingView.hostedGraph = newGraph
        if let frameLayer = newGraph.plotAreaFrame
        {
            // Border
            frameLayer.borderLineStyle = nil
            frameLayer.cornerRadius = 0.0
            frameLayer.masksToBorder = false

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

            frameLayer.paddingLeft = 70.0
            frameLayer.paddingTop = 20.0
            frameLayer.paddingRight = 20.0
            frameLayer.paddingBottom = 80.0
        }

        // Plot space
        let plotSpace = newGraph.defaultPlotSpace as? CPTXYPlotSpace
        plotSpace?.yRange = CPTPlotRange(location: 0.0, length: 100.0)
        plotSpace?.xRange = CPTPlotRange(location: 0.0, length: 4.0)

        let axisSet = newGraph.axisSet as? CPTXYAxisSet

        if let x = axisSet?.xAxis {
            x.axisLineStyle = nil
            x.majorTickLineStyle = nil
            x.minorTickLineStyle = nil
            x.majorIntervalLength = 5.0
            x.orthogonalPosition = 0.0
            x.title = "X Axis"
            x.titleLocation = 7.5
            x.titleOffset = 55.0

            // Custom labels
            x.labelRotation = CGFloat(M_PI_4)
            x.labelingPolicy = .None

            let customTickLocations = [0.5, 1.5, 2.5]
            let xAxisLabels = ["Label A", "Label B", "Label C"]

            var labelLocation = 0
            var customLabels = Set<CPTAxisLabel>()
            for tickLocation in customTickLocations
            {
                let newLabel = CPTAxisLabel(text: xAxisLabels[labelLocation], textStyle: x.labelTextStyle)
                labelLocation += 1
                newLabel.tickLocation = tickLocation
                newLabel.offset = x.labelOffset + x.majorTickLength
                newLabel.rotation = 0 //CGFloat(M_PI_4)
                customLabels.insert(newLabel)
            }

            x.axisLabels = customLabels
        }

        if let y = axisSet?.yAxis
        {
            y.axisLineStyle = nil
            y.majorGridLineStyle = CPTMutableLineStyle()
            var style = y.majorTickLineStyle?.mutableCopy() as? CPTMutableLineStyle
            //style!.lineColor = CPTColor(CGColor: UIColor.blackColor())   //UIColor.blackColor())
            style!.lineWidth = 10.0
            y.minorGridLineStyle = CPTMutableLineStyle()
            style = y.minorTickLineStyle?.mutableCopy() as? CPTMutableLineStyle
            //style.lineColor = UIColor.redColor()
            style!.lineWidth = 10.0
            style!.lineCap = .Round
            y.majorTickLength = 10.0
            y.majorIntervalLength = 50.0
            y.orthogonalPosition = 0.0
            y.title = "Y Axis"
            y.titleOffset = 45.0
            y.titleLocation = 150.0

            y.labelRotation = 0
            y.labelingPolicy = .None


            let customTickLocations = [50, 100]
            let yAxisLabels = ["50", "100"]

            var labelLocation = 0
            var customLabels = Set<CPTAxisLabel>()
            for tickLocation in customTickLocations
            {
                let newLabel = CPTAxisLabel(text: yAxisLabels[labelLocation], textStyle: y.labelTextStyle)
                labelLocation += 1
                newLabel.tickLocation = tickLocation
                newLabel.offset = y.labelOffset + y.majorTickLength
                newLabel.rotation = 0 //CGFloat(M_PI_4)
                customLabels.insert(newLabel)
            }

            y.axisLabels = customLabels
            var nums = Set<NSNumber>()
            nums.insert(NSNumber(double: 50.0))
            y.majorTickLocations = nums
        }

        // First bar plot
        let barPlot1 = CPTBarPlot.tubularBarPlotWithColor(CPTColor.yellowColor(), horizontalBars: false)
        barPlot1.baseValue = 0.0
        barPlot1.dataSource = self
        //barPlot1.barOffset = 0.5
        barPlot1.identifier = "Bar Plot 1"
        let textStyle = CPTMutableTextStyle()
        textStyle.color = CPTColor.redColor()
        textStyle.fontSize = 10.0
        barPlot1.labelTextStyle = textStyle
        newGraph.addPlot(barPlot1, toPlotSpace: plotSpace)

        self.barGraph = newGraph
    }

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

        self.view.layoutIfNeeded()

        let point: [Double] = [2.0, 50.0]
        let plotPoint = UnsafeMutablePointer<Double>(point)
        var dataPoint = self.barGraph?.defaultPlotSpace?.plotAreaViewPointForDoublePrecisionPlotPoint(plotPoint, numberOfCoordinates: 2)
        //dataPoint = graphHostingView.layer.convertPoint(dataPoint!, fromLayer: self.barGraph!.plotAreaFrame!.plotArea)
        dataPoint = graphHostingView.layer.convertPoint(dataPoint!, toLayer: graphHostingView.layer.superlayer)
        //dataPoint = barGraph?.convertPoint(dataPoint!, fromLayer: graphHostingView.layer)
        dataPoint = self.textBoxView.convertPoint(dataPoint!, fromView: graphHostingView)

        print(dataPoint!)
        for item in (self.textBoxView?.constraints)!
        {
            if let id = item.identifier
            {
                if id == "goalX"
                {
                    print(item.constant)
                    item.constant = CGFloat((dataPoint?.x)!) - item.constant
                }
                else if id == "goalY"
                {
                    print(item.constant)
                    item.constant = CGFloat((dataPoint?.y)!) - item.constant
                }
            }
        }
        barGraph?.titleDisplacement = CGPoint(x: dataPoint!.x * -1, y: dataPoint!.y * -1)
        barGraph?.titlePlotAreaFrameAnchor = .TopLeft
        self.textBoxView?.layoutIfNeeded()
   }
}

基于我看到的有关 CorePlot 的其他一些问题,我知道我需要将它从 CorePlot 层转换为我的新视图。我在 viewWillAppear() 中留下了一些实验,看看我尝试了什么。 SO 上的所有解决方案似乎都不起作用,而且我是 iOS 新手,所以可能遗漏了一些东西。关于我需要进行哪些转换才能让我的标签在所有屏幕尺寸上正确显示的任何想法?

【问题讨论】:

  • 我看不到图表标题的任何用途。为什么要更新titleDisplacementtitlePlotAreaFrameAnchor
  • 很好,我忘了把它从我的示例代码中提取出来,我在一些实验中一直在使用它。

标签: ios iphone core-plot graphing


【解决方案1】:

您在积分转换方面走在了正确的轨道上。我会这样做:

// Update layer layout if needed
self.view.layoutIfNeeded()
graphHostingView.layer.layoutIfNeeded()

// Point in data coordinates
let point: [Double] = [2.0, 50.0]

// Data point in plot area layer coordinates
var dataPoint = self.barGraph?.defaultPlotSpace?.plotAreaViewPointForPlotPoint(point)

// Convert data point to graph hosting view coordinates
dataPoint = graphHostingView.layer.convertPoint(dataPoint!, fromLayer: self.barGraph!.plotAreaFrame!.plotArea)

使用它来更新文本框上相对于图形托管视图的约束。

【讨论】:

  • 我刚试过这个,我还打印了数据点,在 iPhone 5s、6s、6s+ 上都返回相同的坐标 x:325,y:256。在 5s - 目标不在屏幕上,6s:y是正确的,但 x 不是直接超过 x = 2.0 到最右边,在 6s+ 上:y 太小而 x 太大 - 将它推到线上方并向右最远。我认为坐标都应该不同是不正确的吗?
  • 我忘记了一个步骤——确保你也更新了图层的布局。 (我编辑了我的答案。)
  • 在您上次发表评论后,我注意到我的视图高度/宽度都不正确,这导致我发现 layoutIfNeeded 在 vi​​ewWillAppear 中不起作用。我将更新代码更改为 viewDidLayoutSubviews,最后让我的 dataPoint 给了我正确的值。仍然不完全确定为什么 layoutIfNeeded 在 vi​​ewWillAppear 中不起作用?感谢您让我回答。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多