Как реализовать Zoom-in и Zoom-Out с графиком Core-Plot на iPhone? - PullRequest
12 голосов
/ 15 февраля 2010

Возможно ли реализовать функцию увеличения и уменьшения масштаба с компонентом Core-Plot Chart на iPhone? Если так, пожалуйста, предложите мне, как это сделать?

Заранее спасибо.

Ответы [ 4 ]

9 голосов
/ 24 февраля 2010

Да, я делаю это, настраивая 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)];
}
7 голосов
/ 25 октября 2011

Вы можете установить делегат plotSpace для некоторого экземпляра класса, который соответствует протоколу CPTPlotSpaceDelegate (например, self) [plotSpace setDelegate:self];.

настроить plotSpace так, чтобы он взаимодействовал с пользователем [plotSpace setAllowsUserInteraction:YES];

А затем в этом классе реализовать этот метод -(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint. Верните YES, если хотите, чтобы corePlot автоматически изменил размер графика. Или НЕТ и сделай что-нибудь, как в предыдущем ответе.

Примечание: если вы хотите, чтобы ваш текущий класс контроллера (self) был делегатом, убедитесь, что ваш интерфейс выглядит следующим образом @interface CurrentController : UISomeController<...,CPTPlotSpaceDelegate>{}. Теперь он соответствует протоколу CPTPlotSpaceDelegate.

2 голосов
/ 19 апреля 2012

Мне было недостаточно использовать пользовательское взаимодействие по умолчанию, потому что:

  1. Он масштабирует обе оси X & Y одновременно, и я хотел только масштабировать Ось X
  2. Панорамирование не позволяет вам идти дальше нуля, и оно прыгает и в основном не работает правильно ..

Мое решение было сделать это сам

Я добавил 2 UIGestureRecognizer для Pan, Zoom

    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)];
}
1 голос
/ 28 мая 2012

Чтобы масштабировать только по оси x, просто установите новую шкалу y в качестве старой в делегате:

-(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...