0
votes

I am trying to draw two plots (scatter and bar plot) in two different plotspaces(in a graph) since I have different y scales. Both plots share same x-axis as well as datasource.

Up till now, I am able to both plots successfully. But in bar plot, bars cannot be plotted to correct height. i.e. all are plotting to max height available. I know something very silly is missing, but I am unable to figure it out. I have already tried alot of answers, but they couldn't solve my problem.

Code:

-(void) setMajorIntervalForXAxis
{
    if(totIntervalShown <= 3600 * 2)
         ((CPTXYAxisSet *)graph.axisSet).xAxis.majorIntervalLength = CPTDecimalFromFloat(1800);
    else if(totIntervalShown <= 3600 * 4)
        ((CPTXYAxisSet *)graph.axisSet).xAxis.majorIntervalLength = CPTDecimalFromFloat(3600);
    else
        ((CPTXYAxisSet *)graph.axisSet).xAxis.majorIntervalLength = CPTDecimalFromFloat(7200);

}

-(void)renderInLayer:(CPTGraphHostingView *)layerHostingView withTheme:(CPTTheme *)theme animated:(BOOL)animated
{
    // Setup scatter plot space
    plotSpace = (CPTXYPlotSpace *)graph.defaultPlotSpace;
    plotSpace.allowsUserInteraction = NO;

    barPlotSpace = [[CPTXYPlotSpace alloc]init];
    barPlotSpace.allowsUserInteraction = NO;

    if(plotData.count > 0)
    {
        NSDate *finaldate = [formatter dateFromString:[[plotData objectAtIndex:plotData.count - 1] objectAtIndex:0]];
        totIntervalShown = [finaldate timeIntervalSinceDate:refDate];
    }
    else
    {
        totIntervalShown = 0;
    }
    plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0.0) length:CPTDecimalFromFloat(/*3600 * 7.5f*/totIntervalShown)];
    plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(MinPrice - margin) length:CPTDecimalFromFloat(MaxPrice - MinPrice + margin)];
    barPlotSpace.xRange = plotSpace.xRange;
    barPlotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromFloat(0) length:CPTDecimalFromFloat(maxVolume + (maxVolume / 5))];
    [graph addPlotSpace:barPlotSpace];

    // Axes
    CPTXYAxisSet *axisSet = (CPTXYAxisSet *)graph.axisSet;
    CPTXYAxis *x          = axisSet.xAxis;
  //  x.majorIntervalLength         = CPTDecimalFromFloat(7200);
    [self setMajorIntervalForXAxis];

    x.orthogonalCoordinateDecimal = CPTDecimalFromInt(margin + MinPrice);
    x.majorGridLineStyle          = majorGridLineStyle;
    x.minorGridLineStyle = minorGridLineStyle;
    x.axisLineStyle = nil;
    x.labelingPolicy = CPTAxisLabelingPolicyFixedInterval;
    x.axisConstraints = [CPTConstraints constraintWithLowerOffset:0];

    CPTTimeFormatter *timeFormatter = [[CPTTimeFormatter alloc] initWithDateFormatter:axisFormatter];
    timeFormatter.referenceDate = refDate;
    x.labelFormatter = timeFormatter;

    CPTXYAxis *y = axisSet.yAxis;
    y.labelingPolicy              = CPTAxisLabelingPolicyAutomatic;
    y.orthogonalCoordinateDecimal = CPTDecimalFromFloat(7200);
    y.majorGridLineStyle          = majorGridLineStyle;
    y.minorGridLineStyle = minorGridLineStyle;
    y.axisLineStyle = nil;
   // y.preferredNumberOfMajorTicks = 6;
    y.axisConstraints = [CPTConstraints constraintWithLowerOffset:5];

    CPTXYAxis *rightY = [[CPTXYAxis alloc]init];
    rightY.labelingPolicy = CPTAxisLabelingPolicyAutomatic;
    rightY.orthogonalCoordinateDecimal = CPTDecimalFromFloat(totIntervalShown);
    rightY.majorGridLineStyle = majorGridLineStyle;
    rightY.axisConstraints = [CPTConstraints constraintWithUpperOffset:20];
    rightY.coordinate = CPTCoordinateY;
    rightY.axisLineStyle = nil;
    rightY.majorIntervalLength = CPTDecimalFromLongLong(maxVolume / 5);
    rightY.plotSpace  = barPlotSpace;

    graph.axisSet.axes = [NSArray arrayWithObjects:x, y, rightY, nil];

    NSNumberFormatter *numFormatter = [[NSNumberFormatter alloc] init];
    [numFormatter setNumberStyle: NSNumberFormatterDecimalStyle];
    rightY.labelFormatter = numFormatter;

    // Create a plot that uses the data source method
    linePlot = [[CPTScatterPlot alloc] init];
    linePlot.identifier = @"Line Plot";

    CPTMutableLineStyle *lineStyle = [linePlot.dataLineStyle mutableCopy];
    lineStyle.lineWidth              = 1.0;
    lineStyle.lineColor              = [CPTColor colorWithComponentRed:236/255.0 green:124/255.0 blue:41/255.0 alpha:1.0];
    linePlot.dataLineStyle = lineStyle;
    linePlot.dataSource    = self;
    [graph addPlot:linePlot];

    // Create a bar line style
    CPTMutableLineStyle *barLineStyle = [[CPTMutableLineStyle alloc] init];
    barLineStyle.lineWidth = 1.0;
    barLineStyle.lineColor = [CPTColor colorWithComponentRed:1.0 green:0 blue:0 alpha:0.4];

    barPlot = [[CPTBarPlot alloc] init];
    barPlot.identifier = @"Bar Plot";
    barPlot.plotSpace = barPlotSpace;
    barPlot.barBasesVary = NO;
    barPlot.barsAreHorizontal = NO;
    barPlot.barWidth = CPTDecimalFromCGFloat(0.5);
    barPlot.dataSource    = self;
    barPlot.lineStyle = barLineStyle;
    barPlot.fill = [CPTFill fillWithColor:[CPTColor redColor]];
    [graph addPlot:barPlot];
    //graph.axisSet.axes = [NSArray arrayWithObjects:x, y, rightY, nil];

    CPTMutableTextStyle *textstyle = [CPTMutableTextStyle textStyle];
    textstyle.fontName = @"Helvetica";
    textstyle.fontSize = 10.0;
    textstyle.color = [CPTColor whiteColor];
    x.labelTextStyle = textstyle;
    y.labelTextStyle = textstyle;
    rightY.labelTextStyle = textstyle;

}

Datasource:

-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    return plotData.count;
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    NSNumber *num;

    if([(NSString *)plot.identifier isEqualToString:@"Line Plot"])
    {
        if(fieldEnum == CPTScatterPlotFieldY)
        {
            num = [NSNumber numberWithFloat:[[[plotData objectAtIndex:index] objectAtIndex:1] floatValue]];
        }
        else
        {
            NSString *dateStrExtracted = [[plotData objectAtIndex:index] objectAtIndex:0];
            NSDate *dateExt = [formatter dateFromString:dateStrExtracted];
            float interval = [dateExt timeIntervalSinceDate:refDate];
            num = [NSNumber numberWithFloat:interval];
        }
    }
    else
    {
        if(fieldEnum == CPTBarPlotFieldBarLocation)
        {
            //num = [NSNumber numberWithFloat:[[[plotData objectAtIndex:index] objectAtIndex:1] floatValue]];
            NSString *dateStrExtracted = [[plotData objectAtIndex:index] objectAtIndex:0];
            NSDate *dateExt = [formatter dateFromString:dateStrExtracted];
            float interval = [dateExt timeIntervalSinceDate:refDate];
            num = [NSNumber numberWithFloat:interval];
        }
        else if(fieldEnum == CPTBarPlotFieldBarTip)
        {
            num = [NSNumber numberWithLongLong:[[[plotData objectAtIndex:index] objectAtIndex:2] longLongValue]];

        }
    }

    return num;
}

Values returned for bar plot tip are like 500, 1000,400,5000 etc but all are drawn with same height. I think bar plot is considering range intended for scatterplot. Or there could be something else? Please guide me where can I be wrong? Thanks.

enter image description here

1

1 Answers

1
votes

Second plot (Bar plot) was using default plotspace's yRange. I changed:

[graph addPlot:barPlot];

to:

[graph addPlot:barPlot toPlotSpace:barPlotSpace];

This solved my problem. And now correct yRange is being used.