Annotation layout quirk

23 views
Skip to first unread message

Mike Lischke

unread,
May 19, 2013, 7:22:26 AM5/19/13
to coreplot...@googlegroups.com
Hey Eric,

I have weird problem with one of my annotation layers that displays at a wrong position on startup but jumps to the correct one as soon as any change in the graphs happens. The annotation layer only contains an image. Look here:



As you can imagine the right arrow should display close to "Ausgaben", just like the left arrow. Here's the code to set this up:

    NSString *arrowName = topView.window.backingScaleFactor > 1 ? @"blue arrow@2x" : @"blue arrow";
    CPTImage *arrowImage = [CPTImage imageForPNGFile: [[NSBundle mainBundle] pathForResource: arrowName ofType: @"png"]];
    size_t imageWidth = CGImageGetWidth(arrowImage.image) / topView.window.backingScaleFactor;
    size_t imageHeight = CGImageGetHeight(arrowImage.image) / topView.window.backingScaleFactor;
    arrowImage.scale = topView.window.backingScaleFactor;

    if (earningsArrowAnnotation != nil) {
        [earningsMiniPlot removeAnnotation: earningsArrowAnnotation];
    }

    CPTXYAxis *axis = pieChartGraph.axisSet.axes[0]; // First x axis.
    earningsArrowAnnotation = [[CPTLayerAnnotation alloc] initWithAnchorLayer: axis.axisTitle.contentLayer];
    earningsArrowAnnotation.rectAnchor = CPTRectAnchorTopLeft;
    earningsArrowAnnotation.displacement = CGPointMake(-15, -50);

    CPTBorderedLayer *layer = [[CPTBorderedLayer alloc] initWithFrame: CGRectMake(0, 0, imageWidth, imageHeight)];
    layer.fill = [CPTFill fillWithImage: arrowImage];

    earningsArrowAnnotation.contentLayer = layer;
    [earningsMiniPlot addAnnotation: earningsArrowAnnotation];

    

    if (spendingsArrowAnnotation != nil) {
        [spendingsMiniPlot removeAnnotation: spendingsArrowAnnotation];
    }

    axis = pieChartGraph.axisSet.axes[2]; // Second x axis.
    spendingsArrowAnnotation = [[CPTLayerAnnotation alloc] initWithAnchorLayer: axis.axisTitle.contentLayer];
    spendingsArrowAnnotation.rectAnchor = CPTRectAnchorTopLeft;
    spendingsArrowAnnotation.displacement = CGPointMake(-15, -50);

    layer = [[CPTBorderedLayer alloc] initWithFrame: CGRectMake(0, 0, imageWidth, imageHeight)];
    layer.fill = [CPTFill fillWithImage: arrowImage];

    spendingsArrowAnnotation.contentLayer = layer;
    [spendingsMiniPlot addAnnotation: spendingsArrowAnnotation];

The mini plots are the bar charts. As you can see the setup for both annotation layers is exactly the same. So what could I do to have this displaying correctly right from the start? Is it ok to share the arrow image between two CPTLayers?

A side note: I saw in the coreplot code where you handle retina displays that you use the mainScreen to determine if you need to scale or not. That's probably not working well if you have several screens (e.g. a MBP Pro Retina with 2 external monitors, as I have). You should rather use the backing scale factor of the  main window instead, as this changes depending on where the app runs on.

The code above btw. runs in - (void)backingStoreChanged: (NSNotification *)notification. I checked that the plot setup happens before the backingStoreChange notification comes in.

Thank you,


Eric

unread,
May 19, 2013, 7:11:46 PM5/19/13
to coreplot...@googlegroups.com, mike.l...@googlemail.com
What version of Core Plot are you using? In the latest version of the Mac hosting view, it implements the -viewDidChangeBackingProperties method to monitor changes in the window scale. It gets the scale from its parent window, not the main screen. It automatically changes the contentsScale of the graph and all Core Plot layers as the window moves between screens with different scales.

Using the same image for both annotations won't matter. The fill property copies the CPTFill you set, including the image.

I'm not sure why one annotation is working while the other one does not. Why do you need to wait for a notification to set the annotations? Why not do it when you set up the rest of the graph? The reference to the axisTitle property creates the title layer if it doesn't already exist. You might be running into a timing issue with the layout by attaching an annotation to this layer at a bad point in the layout process.

Eric
Reply all
Reply to author
Forward
0 new messages