答案 0 :(得分:0)
当前,没有选项可以轻松更改LineChartDataSet
标签的位置,但是建议使用以下功能:
[Feature Request] Make it easier to change the position of the labels drawn above the circles in a LineChartView #2581。
可悲的是...此功能请求已经开放很长时间了,因此不确定是否有人对实现它感兴趣。
但是...如果绝对必要,则可以在LineChartRenderer.drawValues(context:)中进行更改。
在这里,它调用ChartUtils.drawText(context:text:point:align:attributes:)
,并传递CGPoint
值确定该位置的y
。
您可以通过更改以下行来在y
位置添加一些点:
pt.y - CGFloat(valOffset) - valueFont.lineHeight
收件人:
pt.y - CGFloat(valOffset) - valueFont.lineHeight + 100
我希望这会有所帮助,但是请注意,所有更改都将在您的项目中进行,并且如果您/其他人更新了组件,则这些更改将丢失。
答案 1 :(得分:0)
我已经实现了一些解决定位标签问题的方法。我的目标是排除重叠的标签和图形线。主要思想是在值字符串中添加换行符和空格,以使其正确定位。
不幸的是,源代码在Objective-C中,但是可以轻松地被Swift所采用
LineChartValueFormatter.h 文件:
#import <Foundation/Foundation.h>
@interface LineChartValueFormatter : NSObject
- (instancetype)initWithChartData:(NSArray<NSNumber *> *)chartData;
- (NSString *)formattedValueStringAtIndex:(NSUInteger)index;
@end
LineChartValueFormatter.m 文件:
#import "LineChartValueFormatter.h"
typedef enum : NSUInteger {
ChartValueDirectionTop,
ChartValueDirectionTopLeft,
ChartValueDirectionTopRight,
ChartValueDirectionBottom,
ChartValueDirectionBottomLeft,
ChartValueDirectionBottomRight,
} ChartValueDirection;
BOOL chartValueDirectionIsBottom(ChartValueDirection direction) {
return (direction == ChartValueDirectionBottom || direction == ChartValueDirectionBottomLeft || direction == ChartValueDirectionBottomRight);
}
BOOL chartValueDirectionIsTop(ChartValueDirection direction) {
return (direction == ChartValueDirectionTop|| direction == ChartValueDirectionTopLeft || direction == ChartValueDirectionTopRight);
}
@interface LineChartValueFormatter ()
@property (nonatomic, strong) NSArray<NSNumber *> * chartData;
@property (nonatomic, strong) NSMutableArray<NSNumber *> * directions;
@end
@implementation LineChartValueFormatter
- (instancetype)initWithChartData:(NSArray<NSNumber *> *)chartData {
self = [super init];
if (self) {
self.chartData = chartData;
self.directions = [NSMutableArray arrayWithCapacity:chartData.count];
[self.directions addObject:@([self firstValueDirection])];
for (NSInteger i = 1; i < self.chartData.count - 1; ++i) {
[self.directions addObject:@([self commonValueDirectionAtIndex:i])];
}
[self.directions addObject:@([self lastValueDirection])];
}
return self;
}
- (NSString *)formattedValueStringAtIndex:(NSUInteger)index {
if (!self.directions || !self.directions.count) {
return valueString;
}
ChartValueDirection direction = [self.directions[index] integerValue];
NSString * newlineString = @"\n";
NSString * valueString = [self.chartData[index] stringValue];
NSUInteger numberOfSpaces = valueString.length;
// There is U+2007 space used (“Tabular width”, the width of digits), not usual space
NSString * spaceString = [@"" stringByPaddingToLength:numberOfSpaces
withString:@" "
startingAtIndex:0];
switch (direction) {
case ChartValueDirectionTopLeft:
return [NSString stringWithFormat:@"%@%@", valueString, spaceString];
case ChartValueDirectionTopRight:
return [NSString stringWithFormat:@"%@%@", spaceString, valueString];
case ChartValueDirectionBottom:
return [NSString stringWithFormat:@"%@%@", newlineString, valueString];
case ChartValueDirectionBottomLeft:
return [NSString stringWithFormat:@"%@%@%@", newlineString, valueString, spaceString];
case ChartValueDirectionBottomRight:
return [NSString stringWithFormat:@"%@%@%@", newlineString, spaceString, valueString];
default:
return valueString;
}
}
- (ChartValueDirection)firstValueDirection {
double rate = [self.chartData[0] doubleValue];
double nextRate = [self.chartData[1] doubleValue];
if (nextRate > rate) {
return ChartValueDirectionBottomRight;
}
return ChartValueDirectionTopRight;
}
- (ChartValueDirection)lastValueDirection {
NSUInteger count = self.chartData.count;
double rate = [self.chartData[count - 1] doubleValue];
double previousRate = [self.chartData[count - 2] doubleValue];
if (previousRate > rate) {
return ChartValueDirectionBottomLeft;
}
return ChartValueDirectionTopLeft;
}
- (ChartValueDirection)commonValueDirectionAtIndex:(NSUInteger)index {
double rate = [self.chartData[index] doubleValue];
double previousRate = [self.chartData[index - 1] doubleValue];
double nextRate = [self.chartData[index + 1] doubleValue];
if (previousRate > rate && rate > nextRate) {
return ChartValueDirectionBottomLeft;
}
if (previousRate >= rate && rate <= nextRate) {
return ChartValueDirectionBottom;
}
if (previousRate < rate && rate < nextRate) {
return ChartValueDirectionTopLeft;
}
if (previousRate <= rate && rate >= nextRate) {
return ChartValueDirectionTop;
}
return ChartValueDirectionTop;
}
@end
用法示例:
// Here is your code for configuring charts ...
// chartData is your array of y values of type NSArray<NSNumber *> * defined and filled somewhere above
// lineChartDataSet is your dataset for graph drawing defined and initialized somewhere above
LineChartValueFormatter * formatter = [[LineChartValueFormatter alloc] initWithChartData:chartData];
lineChartDataSet.valueFormatter = [ChartDefaultValueFormatter withBlock:^NSString * _Nonnull(double value, ChartDataEntry * _Nonnull entry, NSInteger dataSetIndex, ChartViewPortHandler * _Nullable viewPortHandler) {
return [formatter formattedValueStringAtIndex:entry.x];
}];
这并不是一个很好的解决方案,但是它可以解决问题而无需更改Charts
源代码,这对我来说至关重要。希望对别人有帮助