After tapping legend, Label color doesn't change


#1

Hello.

Sorry for this noob quesiton. I followed the blog where explained how to “Do” something after a legend is tapped.

I encountered 1 problem.

After setting the tapped legend label color and calling the method [pieChartredrawChart]; then the app crahses becuase there is a NSArray out of bounds exception.

the only delegate method that is called before the crash is the 

- (void)sChart:(ShinobiChart *)chart alterLabel:(UILabel *)label forDatapoint:(SChartRadialDataPoint *)datapoint atSliceIndex:(int)index inRadialSeries:(SChartRadialSeries *)series

then the app crahses and the last stack call is 

[SChartGLView updatePieSliceWithDisplacement:andAngle:andLindeWith:andTexture];

Now if I change the [pieChartredrawChart]; for  [self.pieChartredrawChartAndGL:YES]; then the app doesn’t crash, the slice get selected but the label color doesn’t change.

Any ideas what am I doing wrong?

Thanks in advance for the support.


#2

Hi Gustav, 

could you please tell me the name of the tutorial or give me the link.

Thanks, 

Juan.


#3

Juan. Hi.

this is it


#4

Hi Gustav, 

I downloaded the whole project to check the problem you’re having and I can’t find the piece of code you’re referencing on your post.

Did you try running the final project and comparing its code to yours?

Maybe there was an update at some point and the web post didn’t reflect it.

Check that out and let me know how it goes.

Regards, 

Juan.


#5

Hello.

Not surprissinly the demo app works correctly, Im sure since begining the problem is on my side, thats why I asked what i might be doing worng, as you may know from the crashed method i mentioned what its being iterated, my guess is the nunmber of slices/labels,. When I run the my app with another data source that contains more slices, then the exception is there but the bounds are bigger by 1. Example I have a pie chart with 4 slices, the exception would be 

NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 8 beyond bounds [0 .. 7]'

now i wonder why are there double the actual slices/lables (if this is the case).  Maybe there is some cached information from the prev datasource?  shouldn’t that array be of size 3 (4 slices)?. 

I just did a try out and found out that if I don’t set the slice selected using this method  [series setSlice:index asSelected:YES]; and then call the redraChart method, the label indeed change colors, and the app doesn’t crash.

:frowning:


#6

Hi Gustav,

Can you tell me what you’ve changed from the demo? The chart adds the labels and the symbols to the view, which may be why you’re seeing double. If you can show me your demo (perhaps email it to our support team), we’ll be able to track this down for you :slight_smile:

Best regards,

Rob


#7

Hello.

From the demo I have modified the theme, colors bg colors and borders. Then on the tap gesture recognizer callback I do the same as in the demo except that I don’t deselect another that is selected but keep selectin/deselecting, if tapping again I deselect if selected.

It will be little complicated to send you demo as this is a bank project, so the data that its used to generate the chart its fetched form backends. But I can explain in detail what I do and the results.

  1. In my controller I initialize the pie chart like this:

    @implementation CSOBEnhancedChartViewController (Chart_Releated)

    -(void)initializeChart

    {

     if(self.level == 0){
    
         self.chartDataManager = [[HistoryChartDataManageralloc] init];
    
         self.chartDataManager.delegate = self;
    
         self.chartDataManager.currentAccount =  self.selectedAccount;
    
         [self.chartDataManagerreloadData];
    
     }
    
     else{
    
                 
    
     }
    
     
    
     self.pieChart = [[ShinobiChartalloc] initWithFrame:self.graphContainer.boundswithTheme:[selfthemeforChart]];
    
     if(IS_IPAD)
    
         self.pieChart.autoresizingMask = ~UIViewAutoresizingNone;
    
     
    
    //self.pieChart.backgroundColor = [UIColor clearColor];
    
     self.pieChart.licenseKey = LICENCE_KEY;
    
     self.pieChart.datasource = self;
    
     self.pieChart.delegate = self;
    
     self.pieChart.legend.hidden = NO;
    
     self.pieChart.legend.position = SChartLegendPositionBottomMiddle;
    
     [self.graphContainerinsertSubview:self.pieChartatIndex:0];
    
     
    
     UITapGestureRecognizer *tap = [[UITapGestureRecognizeralloc] initWithTarget:selfaction:@selector(legendClick:)];
    
     [self.pieChart.legendaddGestureRecognizer:tap];
    

    }

    -(SChartTheme *)themeforChart

    {

     SChartTheme * theme = [SChartDarkThemenew];
    
     
    
     theme.chartStyle.backgroundColor = [UIColorclearColor];
    
     theme.chartStyle.backgroundColorGradient = [UIColorclearColor];
    
     theme.chartStyle.borderColor = [UIColorclearColor];
    
     //Customization....
    
     theme.legendStyle.font = [UIFont fontWithName:@"HelveticaNeue" size:IS_IPAD ? 16.f : 14.0f];
    
     if(IS_IPAD){
    
         theme.legendStyle.fontColor =colorForValueTableCell();
    
     }    
    
     return theme;
    

    }

    @end

Now HistoryChartDataManger its a proxy that is in charge of asking the dat form server and caching the results.  The fetching happens on a per month basis.

The controller gets presented and of course at this momenth there is no data so there is no chart drawn, but in consolo I get message   Dataseries 0 is empty

From: ShinobiChart at 0xad8cc70  ,wich its perfectly fine for me as there is no data when the view apperas.

2.Then the delegate method from HistoryChartManager returns with the reponse, and my controller organize the Objects (in this cases Transactions) by categories and stores them in a @property (strong, nonatomic) NSDictionary * dataForChart; which is what I access on the data source methods form the chart delegate.

  1. The datasouce methods gets called.

    -(NSInteger)numberOfSeriesInSChart:(ShinobiChart *)chart

    {

     return 1;
    

    }

    -(SChartSeries * )sChart:(ShinobiChart *)chart seriesAtIndex:(int)index

    {

     BOOL iPad = UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad;
    
     SChartPieSeries *p = [SChartPieSeriesnew];
    
     p.selectedStyle.protrusion = iPad ? 40.f : 10.f;
    
     p.style.showCrust = NO;
    
     p.selectedStyle.crustThickness = [NSNumbernumberWithDouble:2.5];
    
     p.selectedStyle.showCrust = YES;
    
     p.style.showLabels = YES;
    
     p.selectedStyle.showLabels = YES;
    
     
    
     //colors
    
     p.style.flavourColors = [selfchartColorsAtLevel:self.level];
    
     p.selectedStyle.flavourColors = [p.styleflavourColors];
    
     p.selectedStyle.crustColors = [selfcrustColors];
    
     
    
     
    
     p.selectedPosition = [NSNumber numberWithFloat:-M_PI/2.f];
    
     return p;
    

    }

    -(NSInteger)sChart:(ShinobiChart *)chart numberOfDataPointsForSeriesAtIndex:(int)seriesIndex

    {

     //Should return 0 or n, depending if the data already loaded
    
     NSInteger r = [[self.dataForChart allKeys] count];
    
     return r;
    

    }

    • (id)sChart:(ShinobiChart *)chart dataPointAtIndex:(int)dataIndex forSeriesAtIndex:(int)seriesIndex

    {

     SChartRadialDataPoint *dp = [SChartRadialDataPointnew];
    
     NSString *key = [self keyForDataObjectWithIndex:dataIndex];
    
     dp.name = key;
    
     id val = [self.dataForChart valueForKey:key];
    
     if(!self.isInNumberTransactions)
    
         dp.value = [val doubleValue] < 0 ? [NSNumber numberWithDouble:-1 * [val doubleValue]] : val;
    
     else
    
         dp.value = [NSNumber numberWithInt:[val count]];
    
     return dp;
    

    }

    #pragma mark - chart delegate

    • (void)sChart:(ShinobiChart *)chart alterLabel:(UILabel *)label forDatapoint:(SChartRadialDataPoint *)datapoint atSliceIndex:(int)index inRadialSeries:(SChartRadialSeries *)series {

      //For our pie chart - stop displaying labels for narrow slices

      if (chart == self.pieChart) {

        label.adjustsFontSizeToFitWidth = YES;
      
        
      
        if (datapoint.value.floatValue < 2.f) {
      
            label.text = @"";
      
            
      
        }  else if (datapoint.value.floatValue < 15.f) {
      
            label.adjustsFontSizeToFitWidth = YES;
      
            CGRect f = label.frame;
      
            f.size.width = 35.f;
      
            f.origin.x += 38;
      
            f.origin.y -= 20.0f;
      
            label.frame = f;
      
        }
      

      }

    }

    -(UILabel *)sChart:(ShinobiChart *)chart labelForSliceAtIndex:(int)sliceIndex inRadialSeries:(SChartRadialSeries *)series

    {

     NSString *key = [self keyForDataObjectWithIndex:sliceIndex];
    
     id val = [self.dataForChart valueForKey:key];
    
     UILabel * label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 20)];
    
     label.textColor = [UIColor whiteColor];
    
     label.backgroundColor = [UIColorclearColor];
    
     label.font = [UIFontfontWithName:@"HelveticaNeue-Light"size:12.0f];
    
     label.text = self.isInNumberTransactions == NO ? formatMoneyToCurrency([val doubleValue], self.selectedAccount.curency) : [NSString stringWithFormat:@"%i",[val count]];
    
     return label;
    

    }

 The chart gets loaded and presented properly, with the right colors and so on. I can tap on the slices and the chart slice gets selected and nicely animated. So far so good.

in the method after getting the correct label (which is doing it properly) i do: 

            SChartPieSeries * series = (SChartPieSeries*)[[self.pieChartallChartSeries] objectAtIndex:0];

            UILabel *clickedLabel = [self.pieChart.legend.labels objectAtIndex:index];

            UIColor * color;

            if ([self.selectedSlices containsObject:key]) {

                [self.selectedSlices removeObject:key];

               // [series setSlice:index asSelected:NO];

                color = colorForValueTableCell();

            }

            else{

                [self.selectedSlices addObject:key];

             //   [series setSlice:index asSelected:YES];

                color = [UIColor redColor];

            }            

            [selfsetUpTableDetailWithSelectedSlices];

            [self.pieChart redrawChartAndGL:YES];

            clickedLabel.textColor = color;

        //    [self.pieChart reloadData];

        //    [self.pieChart redrawChart];

I have here all these comments as I was trying what happens if I don’t select the slice as selected but just change the color and then call redrawChart, and the label color changes, of course the slice doesn’t get selected.

I have also change the [self.pieChart redrawChartAndGL:YES]; to use redraChart after chaning the datasource and calling the reloadData. But still the same result, there is a out of bounds exception.

Sorry for the long post.  And thanks for the support, great product, so far we are buying license, just need to get this solved :wink:

Regards

G.


#8

Hi all,

I would also be interested in a solution for this problem. If I set a new slice as selected in my donut chart and call redrawChart the app crashes as mentioned above (index out of bounds), in a pie chart it works.

If I just call redrawChartAndGL the chart is redrawn and my selection is done, but the legend is not updated.

My tap code is exactly as in the demo and my datasource is not called anywhere.

Is there already a solution to this problem?

Best regards,
Matthias


#9

Hi Guys,

I’ve managed to reproduce the issue and have logged it with our chart team - it should be fixed for the next release :slight_smile:

Regarding the redraw calls, these merely set a flag for the chart to redraw on the next drawRect cycle, so if you wanted to change the color of a label you’d have to remember the index and color, then set this after the chart has redrawn, for example, in sChartRenderFinished.

Hope this helps!

Rob


#10

Sorry OT, how will I know aboiut the update?

Thx. 

G.


#11

Hi Gustav,

I’m afraid we’ve haven’t been able to replicate that issue at our end.  Our latest version of ShinobiCharts (version 2.2.1) is now available to download, would you like to download that and see if the issue you’ve been seeing is fixed?

If that doesn’t resolve your issue, please let me know and we’ll do some more investigation into what is going on.

Many thanks,

Dan