Coreplot iOS - 图形栏之间的自定义空间

时间:2013-12-13 16:52:18

标签: ios core-plot scatter-plot

我想知道使用 Coreplot iOS库在一段固定间隔后是否可以在栏之间设置自定义间距。
如下图所示,在每个 7条之后,会显示一个不寻常的条形空间 如果有可能,请指导一下如何实现这一目标?

Problem Visual

3 个答案:

答案 0 :(得分:0)

您需要修改X轴

的Core Plot数据源方法中的定位
- (NSNumber *) numberForPlot:(CPTPlot *)plot field:(NSUInteger)fieldEnum recordIndex:(NSUInteger)idx

并考虑您希望间距发生的位置。如果你仍然没有得到它,请发布一些代码,我会告诉你。

逻辑示例:

我想表示一个月的数据,假设有30天的数据,但是每隔5天,我想在每5天暂停一次。因此,而不是在

中返回30
- (NSUInteger)numberOfRecordsForPlot:(CPTPlot *)plot

,你返回34,在索引6,11,16,21和26你返回0表示上述方法。

如果你不想为'暂停'留出那么多的空间并且返回两倍的天数(60),减去4,你可以扩展这个(因为暂停只返回一个记录的值为0)并返回每个2记录数据源中的相应值。这可以再次扩展到您需要的乘数。我希望你明白我的意思。

答案 1 :(得分:0)

CPTBarPlot有代码来管理它。

-(BOOL)barAtRecordIndex:(NSUInteger)idx basePoint:(CGPoint *)basePoint tipPoint:(CGPoint *)tipPoint

基本上获取该栏并设置其basePointtipPoint

最后,它使用barOffsetLength根据索引来偏移每个条形。

CGFloat barOffsetLength = [self lengthInView:self.barOffset] * self.barOffsetScale;

对于垂直条,在您的情况下,它会抵消基点和尖点的x坐标。这些通常都是一样的。在这里,您可以选择添加自己的偏移量。

简单地说,这就是你需要在同一个功能中做的事情:

CGFloat barOffsetLength = [self lengthInView:self.barOffset] * self.barOffsetScale;
if ([self.dataSource hasGapBeforeIndex:idx]) {
    offsetGap += [self.dataSource gapValue];
}

// Offset
if ( horizontalBars ) {
    basePoint->y += barOffsetLength;
    tipPoint->y  += barOffsetLength;
}
else {
    //HERO

    basePoint->x += barOffsetLength + offsetGap;
    tipPoint->x += barOffsetLength + offsetGap;
}

在这里,您在CPTBarPlot中引入了一个名为offsetGap的新变量,每当您引入间隙时,该变量都会增加。 (注意,更改数据集时需要将其重置为零)。

另外,在CPTPlotDataSource介绍

- (BOOL) hasGapBeforeIndex:(NSUInteger)index;
- (CGFloat) gapValue;

并在View Controller中实现它。现在你可以在任何地方介绍差距。

PS:这显然是一个黑客攻击并扰乱了轴标签以及其他可能需要调整的事情,但无论如何都给出了概述。

我使用示例应用程序来实现此目的。

答案 2 :(得分:0)

感谢@zakishaheen回答,我设法实现了这一点,但是我打破了标签位置并滚动了内容大小。这种实现方式有些拙劣,这就是为什么我决定不继续对其进行修复的原因,而仅仅是一个示例。

我创建了自定义CustomOffsetBarPlot类,并应用了一些Objective-C运行时魔术。

- (BOOL)superImplementation:(SEL)selector idx:(NSUInteger)idx basePoint:(nonnull CGPoint *)basePoint tipPoint:(nonnull CGPoint *)tipPoint {
    Class granny = [self superclass];
    BOOL(* grannyImp)(id,SEL,NSUInteger,CGPoint*, CGPoint*) = (BOOL (*)(id,SEL,NSUInteger,CGPoint*, CGPoint*))class_getMethodImplementation(granny, selector);
    return grannyImp(self, selector, idx, basePoint, tipPoint);
}

-(BOOL)barAtRecordIndex:(NSUInteger)idx basePoint:(nonnull CGPoint *)basePoint tipPoint:(nonnull CGPoint *)tipPoint {
    SEL selector = _cmd;

    CGPoint originBasePointStart = *basePoint;
    CGPoint originTipPointStart = *tipPoint;
    [self superImplementation:selector idx:0 basePoint:&originBasePointStart tipPoint:&originTipPointStart];

    BOOL result = [self superImplementation:selector idx:idx basePoint:basePoint tipPoint:tipPoint];

    Class granny = [self class];
    SEL lengthView = NSSelectorFromString(@"lengthInView:");
    CGFloat(* grannyImp)(id,SEL,NSDecimal) = (CGFloat (*)(id,SEL,NSDecimal))class_getMethodImplementation(granny, lengthView);

    CGFloat barOffsetLengthOrigin = grannyImp(self, selector, self.barOffset.decimalValue);

    NSInteger barOffsetLength = originBasePointStart.x + idx * 18 + idx * 5; // idx * 5 - your offset
    basePoint->x = barOffsetLength;
    tipPoint->x = barOffsetLength;

    return result;
}