SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, and now iOS Charting & Android Chart Components

3
3

I will continue to this question here, but with more details. So I need to be able to drag axis annotations separately. Is there any possible way to achieve this in iOS? Basically I subclassed SCIAxisMarkerAnnotation and implemented my own -onPanGesture:At: but it does not separate instances of the class when I try to drag one of the annoation. All moves to same place. How can I detect which annotation is being dragged?

CDAxisMarkerAnnotation.h

#import <SciChart/SciChart.h>
@class CDAxisMarkerAnnotation;

@protocol CDAxisMarkerAnnotationDelegate <NSObject>

- (void)axisMarkerAnnotation:(CDAxisMarkerAnnotation *)axisMarkerAnnotation
           didPanToAxisValue:(double)axisValue;

@end

@interface CDAxisMarkerAnnotation : SCIAxisMarkerAnnotation

@property (weak, nonatomic) id<CDAxisMarkerAnnotationDelegate> delegate;

@end

CDAxisMarkerAnnotation.m

#import "CDAxisMarkerAnnotation.h"

@implementation CDAxisMarkerAnnotation

- (BOOL)onPanGesture:(UIPanGestureRecognizer *)gesture At:(UIView *)view
{
    if (![view isKindOfClass:[SCIChartSurfaceView class]]) {
        return [super onPanGesture:gesture At:view];
    }

    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:
        case UIGestureRecognizerStateChanged:
        case UIGestureRecognizerStateEnded: {
            CGPoint location = [gesture locationInView:view];
            id<SCIRenderSurface> renderSurface = [self.parentSurface renderSurface];
            CGPoint pointInChart = [renderSurface pointInChartFrame:location];
            id<SCICoordinateCalculator> yCalculator = [self.yAxis getCurrentCoordinateCalculator];
            double valueForYAxis = [yCalculator getDataValueFrom:pointInChart.y];
            [self.delegate axisMarkerAnnotation:self didPanToAxisValue:valueForYAxis];
            break;
        }
        default: {
            break;
        }
    }
    return YES;
}

@end

Thanks,
Irmak

Version
1.2.0.8
  • Kelvin Roy
    I am looking for exact same feature for a finance app. Android has this capability, can it be added to iOS as well? This is a deciding factor and we need to integrate as soon as possible
  • You must to post comments
1
0

Good day

There was bug in SCIModifierGroup. So you need latest version of SDK. You can get it at this link http://www.scichart.com/Downloads/iOS/v1.2/SciChart_iOS_v1.2.2.915_SDK.zip

You need to add some kind of hit test to your code to check what annotation to move.
After that you have to set the following option for SCIAnnotationGroup

[annotationGroup setHandleGestureFirstOnly:YES];

Taht means if annotation returns YES from gesture handler, gesture is considered handled and won’t be checked by other annotations. In that case when annotations are placed at the same position you can drag them separately.

Assuming you are using absolute coordinate mode for SCIAxisMarkerAnnotation placement:

 marker.coordMode = SCIAnnotationCoord_Absolute;

You can do the following:

@class CDAxisMarkerAnnotation;

@protocol CDAxisMarkerAnnotationDelegate <NSObject>

- (void)axisMarkerAnnotation:(CDAxisMarkerAnnotation *)axisMarkerAnnotation
           didPanToAxisValue:(double)axisValue;

@end

@interface CDAxisMarkerAnnotation : SCIAxisMarkerAnnotation

@property (weak, nonatomic) id<CDAxisMarkerAnnotationDelegate> delegate;

@end

@implementation CDAxisMarkerAnnotation {
    BOOL _gestureLocked;
}

- (BOOL)onPanGesture:(UIPanGestureRecognizer *)gesture At:(UIView *)view
{
    const BOOL GESTURE_HANDLED = YES;
    const BOOL GESTURE_NOT_HANDLED = NO;

    if (![view isKindOfClass:[SCIChartSurfaceView class]]) {
        return [super onPanGesture:gesture At:view];
    }

    CGPoint location = [gesture locationInView:view];
    id<SCIRenderSurface> renderSurface = [self.parentSurface renderSurface];
    CGPoint pointInChart = [renderSurface pointInChartFrame:location];
    id<SCICoordinateCalculator> yCalculator = [self.yAxis getCurrentCoordinateCalculator];
    double valueForYAxis = [yCalculator getDataValueFrom:pointInChart.y];

    switch (gesture.state) {
        case UIGestureRecognizerStateBegan: {
            double markerCoord = [yCalculator getCoordinateFrom:SCIGenericDouble(self.position)];
            const double hitTestDistance = 25;
            BOOL pointInHitTest = fabs(pointInChart.y - markerCoord) < hitTestDistance;
            if ( !pointInHitTest ) return GESTURE_NOT_HANDLED;
            _gestureLocked = YES;
            break;
        }
        case UIGestureRecognizerStateChanged:
            if (!_gestureLocked) return GESTURE_NOT_HANDLED;
//            [self.delegate axisMarkerAnnotation:self didPanToAxisValue:valueForYAxis];
            // I don't know what "axisMarkerAnnotation:didPanToAxisValue:" actually do, but the following code moves your axis marker and triggers redraw
            [self setPosition:SCIGeneric(valueForYAxis)];
            [renderSurface invalidateElement];
            break;
        case UIGestureRecognizerStateEnded:
            _gestureLocked = NO;
        default: {
            break;
        }
    }
    return GESTURE_HANDLED;
}

@end

Please let me know if you have troubles using that example

Best regards
Andrii
SciChart iOS Developer

  • You must to post comments
Showing 1 result
Your Answer

Please first to submit.