【发布时间】:2013-12-13 16:52:17
【问题描述】:
我想知道是否可以使用 Coreplot iOS 库在某个固定间隔后在条形之间设置自定义间距。
如下图所示,每 7 个条形 后会显示一个不寻常的条形空间。
如果可能的话,请您指导如何实现这一目标?
【问题讨论】:
标签: ios core-plot scatter-plot
我想知道是否可以使用 Coreplot iOS 库在某个固定间隔后在条形之间设置自定义间距。
如下图所示,每 7 个条形 后会显示一个不寻常的条形空间。
如果可能的话,请您指导如何实现这一目标?
【问题讨论】:
标签: ios core-plot scatter-plot
CPTBarPlot 有代码来管理这个。
-(BOOL)barAtRecordIndex:(NSUInteger)idx basePoint:(CGPoint *)basePoint tipPoint:(CGPoint *)tipPoint
基本上是获取bar并设置它的basePoint和tipPoint。
最后,它使用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;
并在您的视图控制器中实现它。现在您可以在任何地方引入差距。
PS:这显然是一个 hack,并且扰乱了轴标签和其他可能也需要调整的东西,但无论如何给出了一个概述。
我使用示例应用程序来实现这一点。
【讨论】:
您需要在 Core Plot 数据源方法中修改 x 轴的定位
- (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 记录您数据源中的相应值。这可以再次扩展到您需要的乘数。我希望你明白我的意思。
【讨论】:
0,这会导致空白。你有没有先尝试过我的建议?
感谢@zakishaheen 的回答,我设法做到了这一点,但我打破了标签位置和滚动内容大小?。这个实现是 hacky 这就是为什么我决定不继续修复它,它只是一个例子。
我创建了自定义 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;
}
【讨论】: