2016-08-13 4 views
0

私はCore Plotを試しています。私はx:2.0、y:50.0のグラフにカスタム "ゴール"ラベルを追加しようとしています。基本的にy == 50のラベルを別のビューに表示しています。つまり、私のポイントをCore Plotから私のUIViewの範囲。すべてのiPhone画面サイズで機能するレイヤー/ビューからのポイント変換の組み合わせは見つかりませんでした。私の写真の下には、iPhone 6sが最も近い。iOS CorePlotポイント変換

iPhoneの6S +:iphone 6s+

iPhone 6S:iphone 6s

iPhone 5S:iphone 5s

マイビューのレイアウト: View layout

ここでは、私のクラスである:

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を初めて使っているので、おそらく何か不足している。すべての画面サイズでラベルが正しく表示されるためには、どのコンバージョンを達成する必要がありますか?

+0

グラフのタイトルは表示されません。なぜあなたは 'titleDisplacement'と' titlePlotAreaFrameAnchor'を更新していますか? –

+0

良いキャッチ、私は私の例のコードからそれを引き出すのを忘れて、私はいくつかの私の実験でそれを使用していた。 – Brad

答えて

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) 

これを使用して、グラフホスティングビューに対してテキストボックスの制約を更新します。

+0

私はこれを試してみましたが、私もiPhone 5s、6s、6s +で同じ座標x:325、y:256を返すようにデータポイントを表示しました。 x = 2.0以上で右に6s +:yが小さすぎるとxが大きすぎる - それを線の上に、そして遠くに押し出す。座標がすべて違うべきだと私は誤っていますか? – Brad

+0

私はステップを忘れました。レイヤのレイアウトも更新してください。 (私は私の答えを編集しました) –

+0

あなたの最後のコメントの後で、私の高さ/幅が正しくないことに気づいたので、layoutIfNeededはviewWillAppearで動作していませんでした。私はviewDidLayoutSubviewsに私の更新コードを変更し、最終的に私に正しい値を与える私のdataPointを持っていた。 layoutIfNeededがviewWillAppearで動作していない理由はまだ完全にはわかりませんか?答えてくれてありがとう。 – Brad

関連する問題