ios - 在单个条形图中同时显示负水平和正水平

标签 ios objective-c core-plot bar-chart

Without animation for negative values enter image description here enter image description here我想在其中显示水平条形图...正条形图将从左到右设置动画,负条形图将从右到左设置动画。

我还附上了我的两种不同类型的数组...1 个用于正数,1 个用于负数

当我运行这段代码时...负条值看起来像镜面效果...对于正值,它在每个条中使用两种颜色...

请帮我解决一下.. 如果您在代码中发现任何错误...请告诉我

我也附上两张图片.. 1 张为负片,1 张为正片

是的,你可以看到值是如何显示在负栏中的……我也需要解决它……

sampleArray:
<__NSArrayM 0xbae0940>(
{
    x = 0;
    y = "97.71425628662109";
},
{
    x = 0;
    y = "-70.55500793457031";
}
)


sampleArray:
<__NSArrayM 0x12a295a0>(
{
    x = 0;
    y = "97.71425628662109";
},
{
    x = 0;
    y = "450.6826171875";
}
)

这是我的完整代码...

CPTGraphHostingView *hostingView = [[CPTGraphHostingView alloc] initWithFrame:CGRectMake(200, 100, 300, 300)];
hostingView.hostedGraph = self.barChart;
[self addSubview:hostingView];
    plotSpace = (CPTXYPlotSpace *) self.barChart.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-200.0f) length:CPTDecimalFromDouble(650.0f)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(00.0f) length:CPTDecimalFromDouble(400.0f)];



- (void) animateNow
{


CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor orangeColor] horizontalBars:YES];

// define the plot range -  between LTM and NEW, diffrence is 200
barPlot.plotRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(200)];//xAxisLength

// LTM will display at 100th point and NEW will display at 300th coz of 200 range
barPlot.barOffset = CPTDecimalFromFloat(100.00f);
barPlot.baseValue = CPTDecimalFromString(@"0");
barPlot.borderColor = [[UIColor clearColor]CGColor];
barPlot.lineStyle = nil;

// Width of the each bar
barPlot.barWidth = CPTDecimalFromFloat(30.0f);
barPlot.cornerRadius = 1.0f;
barPlot.dataSource = self;


// transform.scale.x for horizontal bar growth
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale.x"];
if([[[self.sampleArray objectAtIndex:0]valueForKey:Y_VAL]floatValue] < 0)
{
    anim.toValue = [NSNumber numberWithFloat:-1.0];
    anim.fromValue = [NSNumber numberWithFloat:0.0f];
}
else
{
    anim.toValue = [NSNumber numberWithFloat:1.0];
    anim.fromValue = [NSNumber numberWithFloat:0.0f];

}
[anim setDuration:2.0f];
anim.toValue = [NSNumber numberWithFloat:1.0];
anim.fromValue = [NSNumber numberWithFloat:0.0f];

anim.removedOnCompletion = NO;
anim.delegate = self;
anim.fillMode = kCAFillModeForwards;

barPlot.anchorPoint = CGPointMake(0.0, 0.0);
[barPlot addAnimation:anim forKey:@"grow"];
[self.barChart addPlot:barPlot toPlotSpace:plotSpace ];


}


-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    /* if([plot.identifier isEqual:@"LTM"])
      return [self.sampleArray count]; */
        // return [self.sampleArray count];
    return [self.sampleArray count];
 }


-(CPTLayer *)dataLabelForPlot:(CPTPlot *)plot recordIndex:(NSUInteger)index
{

NSDictionary *bar;
CPTTextLayer *label;

if([plot.identifier isEqual:@"LTM"])
{
    bar = [self.sampleArray objectAtIndex:0];
    label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%.02f", [[bar valueForKey:Y_VAL]floatValue]]];
}
else if([plot.identifier isEqual:@"NEW"])
{
    bar = [self.sampleArray objectAtIndex:1];
    label = [[CPTTextLayer alloc] initWithText:[NSString stringWithFormat:@"%.02f", [[bar valueForKey:Y_VAL]floatValue]]];    }
else
{
    return nil;
}

float dataLabelOffset;
if([[self.sampleArray objectAtIndex:index]valueForKey:Y_VAL]> 0)
{
    dataLabelOffset = -5.0f;

}
else
{
    dataLabelOffset = 10.0f;

}

plot.labelOffset = dataLabelOffset;
NSLog(@"Offset = %f",plot.labelOffset);
// label.textStyle = textStyle;
return label;
}

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

   NSDictionary *sample = [self.sampleArray objectAtIndex:index];

if (fieldEnum == CPTScatterPlotFieldX)
{
    return [sample valueForKey:X_VAL];
}
else
{

    return [sample valueForKey:Y_VAL];
}
}


-(CPTFill *)barFillForBarPlot:(CPTBarPlot *)barPlot recordIndex:(NSUInteger)index
{
     CPTColor *color = nil;

// Index = 0, for LTM and Index = 1 for NEW.

NSLog(@"%@",barPlot.identifier);

switch ( index )
{
    case 0:
        color = [CPTColor colorWithComponentRed:147.0/255.0 green:149.0/255.0 blue:152.0/255.0 alpha:1.0];
        break;

    case 1:
        color = [CPTColor colorWithComponentRed:255.0/255.0 green:160.0/255.0 blue:47.0/255.0 alpha:1.0];
        break;


    default:
        break;
}

CPTGradient *fillGradient = [CPTGradient gradientWithBeginningColor:color endingColor:color];

return [CPTFill fillWithGradient:fillGradient];

}

最佳答案

设置绘图时,不要使用plotRangebarOffset。如果您使用纯色填充而不是渐变(您的渐变具有相同的开始和结束颜色),您将获得更好的绘图性能。

- (void) animateNow
{
    CPTBarPlot *barPlot = [CPTBarPlot tubularBarPlotWithColor:[CPTColor orangeColor] horizontalBars:YES];
    barPlot.lineStyle = nil;
    barPlot.barWidth = CPTDecimalFromFloat(30.0f);
    barPlot.cornerRadius = 1.0f;
    barPlot.dataSource = self;

    CPTColor *color = [CPTColor colorWithComponentRed:147.0/255.0 green:149.0/255.0 blue:152.0/255.0 alpha:1.0];
    barPlot.fill = [CPTFill fillWithColor:color];

    CPTBarPlot *barPlot1 = [CPTBarPlot tubularBarPlotWithColor:[CPTColor blueColor] horizontalBars:YES];
    barPlot1.barWidth = CPTDecimalFromFloat(30.0f);
    barPlot1.lineStyle = nil;
    barPlot1.cornerRadius = 1.0f;
    barPlot1.dataSource = self;

    CPTColor *color1 = [CPTColor colorWithComponentRed:255.0/255.0 green:160.0/255.0 blue:47.0/255.0 alpha:1.0];
    barPlot1.fill = [CPTFill fillWithColor:color1];

    barPlot.identifier = @"LTM";
    [self.barChart addPlot:barPlot toPlotSpace:plotSpace ];

    barPlot1.identifier = @"NEW";
    [self.barChart addPlot:barPlot1 toPlotSpace:plotSpace ];
}

以这种方式配置绘图,绘图空间设置更简单:

plotSpace = (CPTXYPlotSpace *) self.barChart.defaultPlotSpace;
plotSpace.xRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(0.0) length:CPTDecimalFromDouble(450.0)];
plotSpace.yRange = [CPTPlotRange plotRangeWithLocation:CPTDecimalFromDouble(-0.5) length:CPTDecimalFromDouble(1.0)];

我假设您想要使用两个图构建一个水平条以获得不同的颜色。如果是这样,我将如何编写数据源方法:

// datasource
-(NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot
{
    return 1;
}

-(NSNumber *)numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)index
{
    NSDictionary *sample = nil;
    if([plot.identifier isEqual:@"LTM"])
    {
        sample = self.sampleArray[0];
    }
    else if([plot.identifier isEqual:@"NEW"])
    {
        sample = self.sampleArray[1];
    }

    switch (fieldEnum) {
    case CPTBarPlotFieldBarLocation:
        return @(index);
        break;
    case CPTBarPlotFieldBarTip:
        return sample[Y_VAL];
        break;
    }

    return nil;
}

请注意,绘图字段标识符是条形图位置和提示,而不是散点图枚举值。对于水平条形图,位置值沿 y 轴,尖端和底部位于 x 轴上。

关于ios - 在单个条形图中同时显示负水平和正水平,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21045038/

相关文章:

iphone - UITableView 自定义单元格显示奇怪的结果?

objective-c - IOS:使用标签值更改 UIImageView

ios - 如何让 UILabel 淡出而不是在 iOS 上显示三点省略号?

ios - 带有 "done"按钮的 UIDatePicker

xcode - 核心图:删除散点图中连接点的线?

ios - ITMS-90086 "Missing 64-bit support"将 Adob​​e Air 应用程序上传到 iTunes Connect 时出错

ios - 如何使 Objective-C 类符合 Swift 中定义的协议(protocol)?

ios - Core Plot iOS 从 CPTPlotSpace 点的数据中获取点

ios - CorePlot/iOS 7.1/XCode 5.1 更新到 XCode 5.1 后构建失败

ios - 废弃的内存问题