textForAxis delegate method called multiple times

6 posts, 0 answers
  1. Guillaume
    Guillaume avatar
    3 posts
    Member since:
    May 2015

    Posted 20 May 2015 Link to this post

    I'm using a TKChart inside a UIView acting as its delegate and data source.

    I want to format the graph's xAxis text labels using the textForAxis delegate method upon graph initialization. Problem is, that method is often called 4 or 5 times AFTER the initialization process (once I changed all the graph's xAxis and yAxis by custom built ones) and I'd like to know what fires it.

     My graph contains numerous dataPoints (2000 to 10 000) so repeating the naming of all xAxis values takes a long time. Any way to track or monitor from where the calls are coming or at least limit the number of ticks for which this method is called upon graph initialization?

     Thanks

  2. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 25 May 2015 Link to this post

    Hi Guillaume,

    Thank you  for contacting us.

    Yes, I confirm that the chart calls chart:textForAxis:value:atIndex: method many times during the process of initialization. Our assumption is that regardless of the data range presented in TKChart, the axis will contain only a few ticks because of the available space. However, this process can be improved and I added an issue in our feedback portal. Use this link to track its status and vote/comment on it. I updated your Telerik points for this suggestion.

    One option in this scenario is to cache axis labels. For example, creating a new instance of NSDateFormatter class for every axis value is an expensive operation. This can be improved by sharing a single instance of that class. Could you, please create a sample application demonstrating the issue and send it to us. We will analyse the situation and we will try to find a proper solution.

    Should you have other questions, do not hesitate to ask.

    Regards,
    Jack
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  3. DevCraft banner
  4. Guillaume
    Guillaume avatar
    3 posts
    Member since:
    May 2015

    Posted 25 May 2015 in reply to Jack Link to this post

    Hi Jack,

    Your suggestion about limiting variables initialization during the textForAxis:value:atIndex: proved to be effective. However, my graph does not seem to limit the initial number of ticks regarding the available space for the graph. This means all dataPoints on graph have a tick, and that each of them is named right away. 

    If the user zoom in on the graph though, the number of ticks is limited and looks OK. The behavior described above only happens when the xAxis.zoom value is 1, hence when there's no zoom at all. I do set the major tick interval to 1 when creating axes, so maybe the problem comes from there?

    I've joined code snippets and screenshots to illustrate my saying. We use a numeric xAxis to represent temporal values, because they and not continuous and we wanted to prevent wholes of data in the graph for weekends and such off business days.

    01.- (void)initChart
    02.{
    03.// Graphique
    04.self.chart = [[TKChart alloc] initWithFrame:CGRectZero];
    05.self.chart.delegate = self;
    06.self.chart.dataSource = self;
    07.[self.chart setInsets:UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0)];
    08.self.chart.translatesAutoresizingMaskIntoConstraints = NO;
    09.[self addSubview:_chart];
    10.[self bringSubviewToFront:self.chartPeriodSelector];
    11.     
    12.//Configuration axe X
    13.TKChartNumericAxis *xAxis = [[TKChartNumericAxis alloc] initWithMinimum:((DCOStockDataPoint *)[self.chartData firstObject]).dataXValue andMaximum:((DCOStockDataPoint *)[self.chartData lastObject]).dataXValue];
    14.xAxis.majorTickInterval = @1;
    15.xAxis.style.majorTickStyle.ticksHidden = NO;
    16.xAxis.style.labelStyle.fitMode = TKChartAxisLabelAlignmentBottom | TKChartAxisLabelAlignmentVerticalCenter;
    17.xAxis.allowZoom = YES;
    18.xAxis.allowPan = YES;
    19.self.chart.xAxis = xAxis;
    20. 
    21.// Configuration axe Y
    22.NSNumber *yMin = ((DCOStockDataPoint *)self.chartData[0]).low;
    23.NSNumber *yMax = ((DCOStockDataPoint *)self.chartData[0]).high;
    24. 
    25.for (DCOStockDataPoint *dataPoint in self.chartData)
    26.    if ([dataPoint.high compare:yMax] == NSOrderedDescending) {
    27.        yMax = dataPoint.high;
    28.    }
    29.         
    30.    if ([dataPoint.low compare:yMin] == NSOrderedAscending) {
    31.       yMin = dataPoint.low;
    32.    }
    33.}
    34.double pct = (0.05 * ([yMax doubleValue] - [yMin doubleValue]));
    35.double adjustedYMin = [yMin doubleValue] - pct < 0 ? 0 : [yMin doubleValue] - pct;
    36. 
    37.TKChartNumericAxis *yAxis = [[TKChartNumericAxis alloc] initWithMinimum:[NSNumber numberWithDouble:adjustedYMin] andMaximum:[NSNumber numberWithDouble:[yMax doubleValue]+pct]];
    38.yAxis.style.labelStyle.textAlignment = TKChartAxisLabelAlignmentRight | TKChartAxisLabelAlignmentBottom;
    39.yAxis.style.labelStyle.firstLabelTextAlignment = TKChartAxisLabelAlignmentRight | TKChartAxisLabelAlignmentTop;
    40.yAxis.style.lineHidden = YES;
    41.yAxis.position = TKChartAxisPositionLeft;
    42.[yAxis setMajorTickInterval:[NSNumber numberWithDouble:([yMax doubleValue] - [yMin doubleValue]) / 4]];
    43.self.chart.yAxis = yAxis;
    44.     
    45.// On initie le style de la grille
    46.self.chart.gridStyle.horizontalFill = [TKSolidFill solidFillWithColor:[UIColor colorWithRed:0.96 green:0.96 blue:0.96 alpha:1.0]];
    47.self.chart.gridStyle.horizontalAlternateFill = [TKSolidFill solidFillWithColor:[UIColor whiteColor]];
    48.     
    49.// TrackBall
    50.self.chart.allowTrackball = YES;
    51.self.chart.trackball.orientation = TKChartTrackballOrientationVertical;
    52.self.chart.trackball.tooltip.pinPosition = TKChartTrackballPinPositionNone;
    53.self.chart.trackball.line.hidden = NO;
    54.self.chart.trackball.snapMode = TKChartTrackballSnapModeAllClosestPoints;
    55.self.chart.trackball.tooltip.style.textAlignment = NSTextAlignmentLeft;
    56.}
    57. 
    58.- (NSString *)chart:(TKChart *)chart textForAxis:(TKChartAxis *)axis value:(id)value atIndex:(NSUInteger)index
    59.{
    60.    //Index du tick par rapport au nombre complet de ticks du graphique
    61.    NSInteger tickIndexInGraph = (NSInteger) roundl([value doubleValue]);
    62.    NSString *textToReturn = @"";
    63.     
    64.    // Si on a l'axe des X, que l'index est un entier et est plus petit que le nombre de donnees dans l'array
    65.    if(!axis.isVertical) {
    66.        if(tickIndexInGraph < self.chartData.count && tickIndexInGraph == [value doubleValue]) {
    67.            DCOStockDataPoint *dataPoint = self.chartData[tickIndexInGraph];
    68.            if(chart.xAxis.zoom != 1) {
    69.                textToReturn = [dataPoint dateStringForPeriod:self.chartPeriod];
    70.            } else if (tickIndexInGraph == 0 || tickIndexInGraph == self.chartData.count-1) {
    71.                textToReturn = [dataPoint dateStringForPeriod:self.chartPeriod];
    72.            }
    73.        }
    74.    }
    75.    // Si on a l'axe des Y
    76.    else {
    77.        textToReturn = [[[DCOFormatterManager manager] numberFormatterWithTwoDecimals] stringFromNumber:value];
    78.    }
    79.     
    80.    return textToReturn;
    81.}

     

  5. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 26 May 2015 Link to this post

    Hi Guillaume,

    Thank you for sending me those details.

    Yes, the performance issue is caused by the value of majorTickInterval property. You will improve the performance of TKChart by setting this property to a greater value. I suppose this this is not a problem since you are displaying only first and last values.

    Regards,
    Jack
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
  6. Guillaume
    Guillaume avatar
    3 posts
    Member since:
    May 2015

    Posted 26 May 2015 Link to this post

    But knowing that I want the user to be able to zoom in on the data and that each tick represent one dataPoint I want to label, I don't think setting the majorTickInterval to a higher value is a viable option. That being said, if it was possible to label minorTicks the same way it is for majorTicks, probably that this problem could be resolved. (I think there is already a ticket for a new feature which would allow us to label minorTicks)

    Thanks for your help

  7. Jack
    Admin
    Jack avatar
    2335 posts

    Posted 27 May 2015 Link to this post

    Hi Guillaume,

    Yes, you are correct this is logged as an issue in our feedback portal and we will consider implementing it in one of our upcoming releases. One thing that you could do now is to adjust the majorTickInterval property dynamically when zooming. This can be done by adopting TKChartDelegate protocol and implementing its chartDidZoom method. Consider the sample below:
    - (void)chartDidZoom:(TKChart *)chart
    {
        TKChartNumericAxis *axis = (TKChartNumericAxis*)_chart.xAxis;
        axis.majorTickInterval = @(chart.xAxis.zoom * [axis.majorTickInterval floatValue]/2.);
    }

    I hope this helps.

    Regards,
    Jack
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
DevCraft banner