如何在iPhone上使用Core-Plot折线图实现缩放?

12

是否有可能在iPhone上使用Core-Plot图表组件实现缩放功能?如果可以,请建议我如何实现?

提前感谢。

4个回答

9

是的,我所做的方法是通过调整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
你在哪里调用这些方法? - Pooja
使用这种方法,我发现缩放并不居中,有没有一种方法可以使绘图区域居中缩放? - francesco.venica

7

你可以将plotSpace的delegate设置为符合CPTPlotSpaceDelegate协议的某个类实例(比如self)[plotSpace setDelegate:self];

配置plotSpace以便它与用户交互 [plotSpace setAllowsUserInteraction:YES];

然后在该类中实现这个方法- (BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint。如果你想让CorePlot自动调整图形大小,则返回YES。否则,像前一个答案中所述,返回NO并执行一些操作。

注意:如果你希望当前的控制器类(self)成为一个委托,请确保你的接口看起来像这样:@interface CurrentController : UISomeController<...,CPTPlotSpaceDelegate>{}。这样它就符合CPTPlotSpaceDelegate协议了。


2
使用默认的用户交互对我来说还不够,因为:
  1. 它同时缩放X和Y轴,而我只想缩放X轴
  2. 平移不允许你越过零,会跳跃并且基本上无法正常工作。
我的解决方案是自己做。
我添加了2个手势识别器,用于平移和缩放。
    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];

然后我实现了所需功能的代码。

Pan 图表

- (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)];
}

代码中有一些缺失的部分,请您提供完整的代码,谢谢。 - Peter Lapisu

1

如果只想在x轴上缩放,请在委托中强制新的y轴比例尺与旧的比例尺相同:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接