【问题标题】:How to implement Zoom-in and Zoom-Out with Core-Plot line chart on iPhone?如何在 iPhone 上使用 Core-Plot 折线图实现放大和缩小?
【发布时间】:2010-02-15 07:43:10
【问题描述】:

是否可以在 iPhone 上使用 Core-Plot Chart 组件实现放大和缩小?如果是这样,请建议我怎么做?

提前致谢。

【问题讨论】:

    标签: iphone charts core-plot


    【解决方案1】:

    是的,我这样做的方式是像这样调整 PlotSpace(可能不是最好的解决方案,但我能想到的最好的解决方案):

    -(void)zoomOut 
    {
        CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
    
        graphScaleX+=5;
        graphScaleY+=5;
    
        plotSpace.xRange = [CPPlotRange plotRangeWithLocation:plotSpace.xRange.location length:CPDecimalFromFloat(graphScaleX)];
        plotSpace.yRange = [CPPlotRange plotRangeWithLocation:plotSpace.yRange.location length:CPDecimalFromFloat(graphScaleY)];
    }
    
    -(void)zoomIn
    {
        CPXYPlotSpace *plotSpace = (CPXYPlotSpace *)graph.defaultPlotSpace;
    
        graphScaleX-=5;
        graphScaleY-=5;
    
        plotSpace.xRange = [CPPlotRange plotRangeWithLocation:plotSpace.xRange.location length:CPDecimalFromFloat(graphScaleX)];
        plotSpace.yRange = [CPPlotRange plotRangeWithLocation:plotSpace.yRange.location length:CPDecimalFromFloat(graphScaleY)];
    }
    

    【讨论】:

    • 你在哪里调用这个方法?
    • 用这个方法我看到缩放不居中,有办法缩放绘图中心吗?
    【解决方案2】:

    您可以将 plotSpace 委托设置为符合 CPTPlotSpaceDelegate 协议的类实例(例如 self)[plotSpace setDelegate:self];

    配置 plotSpace 使其与用户 [plotSpace setAllowsUserInteraction:YES]; 交互

    然后在那个类中实现这个方法-(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint。如果您希望 corePlot 自动调整图形大小,则返回 YES。或否,并执行与上一个答案类似的操作。

    注意:如果您希望当前的控制器类(self)成为委托,请确保您的界面看起来像 @interface CurrentController : UISomeController<...,CPTPlotSpaceDelegate>{}。所以现在它符合 CPTPlotSpaceDelegate 协议。

    【讨论】:

      【解决方案3】:

      使用默认用户交互对我来说还不够,因为:

      1. 它同时缩放 X 和 Y 轴,我只想缩放 X轴
      2. Pan 不允许您越过零,它会跳和 基本上不能正常工作..

      我的解决办法是自己做

      我为平移、缩放添加了 2 个 UIGestureRecognizer

          UIPanGestureRecognizer* pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panChart:)];
          [pan setMinimumNumberOfTouches:1];
          [pan setMaximumNumberOfTouches:1];
          [self.view addGestureRecognizer:pan];
      
          UIPinchGestureRecognizer* scale = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(scaleChart:)];
          [self.view addGestureRecognizer:scale];
      

      然后我实现了代码来做我需要的事情

      全景图

      - (void)panChart:(UIPinchGestureRecognizer *)gestureRecognizer {
          CPTGraph *theGraph = [graphs objectAtIndex:0];
          CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)theGraph.defaultPlotSpace;
      
          CGPoint point = [gestureRecognizer  locationInView:self.view];
      
          if([(UIPanGestureRecognizer*)gestureRecognizer state] == UIGestureRecognizerStateBegan) {
      
              firstX = point.x;
              firstY = point.y;
              originX = chartBounds.origin.x;
              originY = chartBounds.origin.y;
              //NSLog(@"first (%f,%f)", firstX, firstY);
          }
          CGRect frame = theGraph.frame;
      
          float xMove =  ((firstX-point.x)/(frame.size.width/chartBounds.size.width));
          float yMove = ((firstY-point.y)/(frame.size.height/chartBounds.size.height));
          if(firstX-point.x == 0){
              xMove = 0;
          }
          if(firstY-point.y == 0){
              yMove = 0;
          }
          //NSLog(@"frame: (%f, %f)",frame.size.width, frame.size.height);
          //NSLog(@"touch (%f,%f)",firstX-point.x,firstY-point.y);
          //NSLog(@"move (%f,%f)",xMove,yMove);
      
          chartBounds.origin.x = originX+xMove;
          chartBounds.origin.y = originY-yMove;
      
          plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.x) length:CPTDecimalFromFloat(chartBounds.size.width)];
          plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.y) length:CPTDecimalFromFloat(chartBounds.size.height)];
      }
      

      比例图表

      - (void)scaleChart:(UIPinchGestureRecognizer *)gestureRecognizer {
      
      if (kMaxDataPoints < kDataPointsHistory) {
      
          if ([gestureRecognizer scale] < 1) {
              if(kMaxDataPoints/10 < 1){
                  kMaxDataPoints += 1;
              }else{
                 kMaxDataPoints += kMaxDataPoints/10; 
              }
          }
      }
      
      if (kMaxDataPoints > 5) {
          if ([gestureRecognizer scale] > 1){
              if(kMaxDataPoints/10 < 1){
                  kMaxDataPoints -= 1;
              }else{
                  kMaxDataPoints -= kMaxDataPoints/10; 
              }
          }
      }
      
      if(kMaxDataPoints <= 5){
          kMaxDataPoints = 5;
      }
      if(kMaxDataPoints > kDataPointsHistory){
          kMaxDataPoints = kDataPointsHistory;
      }
      
      chartBounds.size.width = kMaxDataPoints;
      CPTGraph *theGraph = [graphs objectAtIndex:0];
      CPTXYPlotSpace *plotSpace = (CPTXYPlotSpace *)theGraph.defaultPlotSpace;
      
      plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.x) length:CPTDecimalFromFloat(chartBounds.size.width)];
      
      //Need to calculate if its horizontal or vertical pinch gesture (not doing that yet :) )
      //plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(chartBounds.origin.y) length:CPTDecimalFromFloat(chartBounds.size.height)];
      }
      

      【讨论】:

      • 代码中有些地方漏掉了,能否提供完整的代码?
      【解决方案4】:

      要仅在 x 轴上缩放,只需将新的 y 比例强制为代表中的旧比例即可:

      -(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-20
        • 1970-01-01
        • 2022-02-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多