Creating ShinobiChart screenshot


#1

Hi, I would like to use ShinobiChart to just render me images of the chart. I have a lot of graphs and data points, so all I want for that particular part is a UIImage for each graph. I already have the screenshot from chart done.

Without adding ShinobiChart as a subview, it seems like ShinobiChart will not load the data or render anything. Calling reloadData doesn’t seem to do anything if it doesn’t have superview.

I guess I can just add it off-screen, load the data, then create an image from it after it finishes rendering.

  1. Is there any better way to do this without the need to add it off screen?

  2. What’s the best way to detect that the chart has finished rendering everything? It seems like sChartRenderFinished: can be called multiple times. 

  3. Additionally, is there anyway to tell the chart to redraw in the background thread?

  4. Is this a correct way to take screenshot of the chart from background thread? Seems to be working for me. Thanks!

    EAGLContext* chartContext = [chart.canvas.glView getContext];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    EAGLContext* context = [[EAGLContext alloc] initWithAPI:chartContext.API sharegroup:chartContext.sharegroup];
    [EAGLContext setCurrentContext:context];

         // Assuming this will create a correct image from the chart
         UIImage* image = [chart chartSnapshotImage];
         
         [EAGLContext setCurrentContext:nil];
         
         dispatch_async(dispatch_get_main_queue(), ^{
             UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
             [self.view addSubview:imageView];
         });
     });

#2

Hi Herli,

  1.  The implementation you described sounds like the only way to implement snapshoting charts off the screen. As this is a feature we currently don’t support out of the box.

  2. Currently, the only way to determine whether a chart has finished rendering is to use the “sChartRenderFinished:” SChartDelegate method. This method gets called multiple times as the chart gets rendered multiple times when laying out it’s subviews.

  3. You can’t tell the chart to redraw in a background thread, however you can load your chart’s data in a background thread by setting the “loadDataInBackground” property on your chart to YES. Now, when you call ‘reloadData’ on your chart it will load all your chart’s data in a background thread. For more information on this property can be found HERE.

  4. You don’t have to deal with EAGLContexts when taking a screenshot of a ShinobiChart. This is already handled inside the snapshot code. 
    I following code is all you need to take a snapshot in a background thread:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

     // Assuming this will create a correct image from the chart
     UIImage* image = [_chart snapshot];
     
     dispatch_async(dispatch_get_main_queue(), ^{
         UIImageView* imageView = [[UIImageView alloc] initWithImage:image];
         [self.view addSubview:imageView];
     });
    

    });

Make sure you have the lastest copy of the snapshot code from our Github repository found HERE.

Kind Regards,
Andrew Polkinghorn