Wie Zoom-in und Zoom-Out mit Core-Plot Liniendiagramm auf dem iPhone zu implementieren?

StackOverflow https://stackoverflow.com/questions/2264535

  •  20-09-2019
  •  | 
  •  

Frage

Ist es möglich, Zoom-In und Zoom-Out mit Core-Plot Chart-Komponente auf dem iPhone zu implementieren? Wenn dem so ist mir bitte vorschlagen, wie es zu tun?

Vielen Dank im Voraus.

War es hilfreich?

Lösung

Ja, so wie ich es tue, ist durch die PlotSpace wie so eingestellt (wahrscheinlich nicht die beste Lösung, aber die beste, die ich tun kann,):

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

Andere Tipps

Sie können plotSpace Delegierten zu einem gewissen Klasseninstanz festgelegt, dass Konform CPTPlotSpaceDelegate-Protokoll (zum Beispiel Selbst-) [plotSpace setDelegate:self];.

configure die plotSpace so die Interaktion mit Benutzern [plotSpace setAllowsUserInteraction:YES];

Und dann in dieser Klasse dieser Methode -(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint implementieren. Zurück JA, wenn Sie wollen, dass die corePlot Ihr Diagramm automatisch zu ändern. Oder NO und etwas tun, wie in früheren Antwort.

Hinweis: Wenn Sie Ihre aktuelle Controller-Klasse (Selbst-) wollen ein Delegierter sein, stellen Sie sicher, dass Ihre Schnittstelle wie folgt aussieht @interface CurrentController : UISomeController<...,CPTPlotSpaceDelegate>{}. So jetzt ist es entspricht CPTPlotSpaceDelegate Protokoll.

Mit der Standard-Benutzer-Interaktion war für mich nicht genug, denn:

  1. Er skaliert sowohl X & Y-Achse gleichzeitig und ich nur maßstabs wollte X-Achse
  2. Pan erlaubt Ihnen nicht vorbei Null gehen und es springt und im Grunde nicht richtig funktioniert ..

war meine Lösung, es selbst zu tun

Ich habe 2 UIGestureRecognizer für 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];

ich den Code dann umgesetzt zu tun, was ich brauchte

Pan-Diagramm

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

Scale-Diagramm

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

So skalieren nur in x-Achsen-Kraft gerade die neue y-Achse die alten in den Delegierten zu sein:

-(BOOL)plotSpace:(CPTPlotSpace *)space shouldScaleBy:(CGFloat)interactionScale aboutPoint:(CGPoint)interactionPoint;
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top