过度拥挤的标签在饼图和条形图中不可读
Overcrowded labels are unreadable in piechart and barcharts
对于PieCharts来说,往往有几个"slices"的数据非常少(例如<2%),导致标签相互重叠,无法读取,如下图所示.有谁知道这个的解决方案?我看到一些图表显示饼图外的标签并指向相应的部分,但我不确定 ios-charts.
是否可能有类似的东西
条形图也会出现类似的问题,其中所有值都相互重叠并且变得不可读,如下所示。我能想到的解决方案是只显示一部分条形,如果用户平移则显示其他条形。
如果有人处理过这两个问题,我将很高兴看到您是如何解决它的,或者使用其他库是否更好。我在下面发布了一些代码,但不确定它是否有帮助,因为这可能不是真正的实现错误。
条形图
//...init view...
_chartView.delegate = self;
_chartView.descriptionText = @"";
_chartView.noDataTextDescription = @"No data";
_chartView.drawHighlightArrowEnabled = true;
_chartView.drawValueAboveBarEnabled = YES;
_chartView.drawMarkers = true;
_chartView.dragEnabled = true;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawGridLinesEnabled = NO;
xAxis.spaceBetweenLabels = 2.0;
ChartYAxis *rightAxis = _chartView.rightAxis;
rightAxis.enabled = NO;
NSMutableArray *yVals = [[NSMutableArray alloc] init];
NSMutableArray *xVals = [[NSMutableArray alloc] init];
//populate xVals and yVals with data..
BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yVals label:@"Occurences"];
set1.colors = ChartColorTemplates.vordiplom;
set1.drawValuesEnabled = YES;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *bdata = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
[bdata setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
_chartView.data = bdata;
[self.view addSubview:_chartView];
饼图
//初始化饼图..
_pieChart.delegate = 自我;
_pieChart.usePercentValuesEnabled = YES;
_pieChart.descriptionText = @"";
_pieChart.drawCenterTextEnabled = YES;
NSMutableArray *yVals = [[NSMutableArray alloc] init];
NSMutableArray *xVals = [[NSMutableArray alloc] init];
//...populate xVals and yVals with data
PieChartDataSet *dataSet = [[PieChartDataSet alloc] initWithYVals:yVals label:@"Locations"];
dataSet.sliceSpace = 2.0;
dataSet.colors = ChartColorTemplates.joyful;
PieChartData *data1 = [[PieChartData alloc] initWithXVals:xVals dataSet:dataSet];
NSNumberFormatter *pFormatter = [[NSNumberFormatter alloc] init];
pFormatter.numberStyle = NSNumberFormatterPercentStyle;
pFormatter.maximumFractionDigits = 1;
pFormatter.multiplier = @1.f;
pFormatter.percentSymbol = @" %";
[data1 setValueFormatter:pFormatter];
_pieChart.data = data1;
[self.view addSubview:_pieChart];
基本上,您可以在视图(或 CALayer,无论使用什么)上计算一个中间点并绘制文本,并针对图形进行适当缩放:
NSString *dataString = [[NSString alloc]
initWithFormat:@"Some data"];
CGPoint centerPoint =
CGPointMake(self.bounds.origin.x + self.bounds.size.width / 2,
self.bounds.origin.y + self.bounds.size.height / 2);
CATextLayer *textLayer = [CATextLayer layer];
[textLayer setFont:@"Helvetica-Bold"];
//Scale the font and set proper alignment
[textLayer setFontSize:12];
[textLayer setAlignmentMode:kCAAlignmentCenter];
[textLayer setBounds:self.frame];
[textLayer setPosition:centerPoint];
[textLayer setString:dataString];
[self.layer addSublayer:textLayer];
首先,我建议在 github 页面上提交一个问题,并提供使用 ChartsDemo 重现的示例代码。我试过了,我确实看到了小的重叠,但如果条形继续变小,那么就不会绘制值。所以问题是粒度。
是否绘制文字基于:
internal func passesCheck() -> Bool
{
guard let dataProvider = dataProvider, barData = dataProvider.barData else { return false }
return CGFloat(barData.yValCount) < CGFloat(dataProvider.maxVisibleValueCount) * viewPortHandler.scaleX
}
如果值太多,则不会绘制;但是对你来说粒度好像不够
有办法解决,比如条形图,可以计算出文字宽度,与条形像素宽度比较,决定是否绘制文字。您可以在 drawValues
中覆盖或者如果您需要快速解决它。饼图类似。
喜欢:
// calculate bar pixel width
let barWidth: CGFloat = 0.5
let barSpaceHalf = dataSet.barSpace / 2.0
let left = 0 - barWidth + barSpaceHalf
let right = 0 + barWidth - barSpaceHalf
var leftPoint = CGPoint(x: left, y: 0)
var rightPoint = CGPoint(x: right, y: 0)
trans.pointValueToPixel(&leftPoint)
trans.pointValueToPixel(&rightPoint)
let barPixelWidth = rightPoint.x - leftPoint.x
let valueTextWidth = valueText.sizeWithAttributes([NSFontAttributeName: valueFont]).width
if valueTextWidth < barPixelWidth
{
// draw text
}
对于PieCharts来说,往往有几个"slices"的数据非常少(例如<2%),导致标签相互重叠,无法读取,如下图所示.有谁知道这个的解决方案?我看到一些图表显示饼图外的标签并指向相应的部分,但我不确定 ios-charts.
是否可能有类似的东西条形图也会出现类似的问题,其中所有值都相互重叠并且变得不可读,如下所示。我能想到的解决方案是只显示一部分条形,如果用户平移则显示其他条形。
如果有人处理过这两个问题,我将很高兴看到您是如何解决它的,或者使用其他库是否更好。我在下面发布了一些代码,但不确定它是否有帮助,因为这可能不是真正的实现错误。
条形图
//...init view...
_chartView.delegate = self;
_chartView.descriptionText = @"";
_chartView.noDataTextDescription = @"No data";
_chartView.drawHighlightArrowEnabled = true;
_chartView.drawValueAboveBarEnabled = YES;
_chartView.drawMarkers = true;
_chartView.dragEnabled = true;
ChartXAxis *xAxis = _chartView.xAxis;
xAxis.labelPosition = XAxisLabelPositionBottom;
xAxis.labelFont = [UIFont systemFontOfSize:10.f];
xAxis.drawGridLinesEnabled = NO;
xAxis.spaceBetweenLabels = 2.0;
ChartYAxis *rightAxis = _chartView.rightAxis;
rightAxis.enabled = NO;
NSMutableArray *yVals = [[NSMutableArray alloc] init];
NSMutableArray *xVals = [[NSMutableArray alloc] init];
//populate xVals and yVals with data..
BarChartDataSet *set1 = [[BarChartDataSet alloc] initWithYVals:yVals label:@"Occurences"];
set1.colors = ChartColorTemplates.vordiplom;
set1.drawValuesEnabled = YES;
NSMutableArray *dataSets = [[NSMutableArray alloc] init];
[dataSets addObject:set1];
BarChartData *bdata = [[BarChartData alloc] initWithXVals:xVals dataSets:dataSets];
[bdata setValueFont:[UIFont fontWithName:@"HelveticaNeue-Light" size:10.f]];
_chartView.data = bdata;
[self.view addSubview:_chartView];
饼图
//初始化饼图.. _pieChart.delegate = 自我;
_pieChart.usePercentValuesEnabled = YES;
_pieChart.descriptionText = @"";
_pieChart.drawCenterTextEnabled = YES;
NSMutableArray *yVals = [[NSMutableArray alloc] init];
NSMutableArray *xVals = [[NSMutableArray alloc] init];
//...populate xVals and yVals with data
PieChartDataSet *dataSet = [[PieChartDataSet alloc] initWithYVals:yVals label:@"Locations"];
dataSet.sliceSpace = 2.0;
dataSet.colors = ChartColorTemplates.joyful;
PieChartData *data1 = [[PieChartData alloc] initWithXVals:xVals dataSet:dataSet];
NSNumberFormatter *pFormatter = [[NSNumberFormatter alloc] init];
pFormatter.numberStyle = NSNumberFormatterPercentStyle;
pFormatter.maximumFractionDigits = 1;
pFormatter.multiplier = @1.f;
pFormatter.percentSymbol = @" %";
[data1 setValueFormatter:pFormatter];
_pieChart.data = data1;
[self.view addSubview:_pieChart];
基本上,您可以在视图(或 CALayer,无论使用什么)上计算一个中间点并绘制文本,并针对图形进行适当缩放:
NSString *dataString = [[NSString alloc]
initWithFormat:@"Some data"];
CGPoint centerPoint =
CGPointMake(self.bounds.origin.x + self.bounds.size.width / 2,
self.bounds.origin.y + self.bounds.size.height / 2);
CATextLayer *textLayer = [CATextLayer layer];
[textLayer setFont:@"Helvetica-Bold"];
//Scale the font and set proper alignment
[textLayer setFontSize:12];
[textLayer setAlignmentMode:kCAAlignmentCenter];
[textLayer setBounds:self.frame];
[textLayer setPosition:centerPoint];
[textLayer setString:dataString];
[self.layer addSublayer:textLayer];
首先,我建议在 github 页面上提交一个问题,并提供使用 ChartsDemo 重现的示例代码。我试过了,我确实看到了小的重叠,但如果条形继续变小,那么就不会绘制值。所以问题是粒度。
是否绘制文字基于:
internal func passesCheck() -> Bool
{
guard let dataProvider = dataProvider, barData = dataProvider.barData else { return false }
return CGFloat(barData.yValCount) < CGFloat(dataProvider.maxVisibleValueCount) * viewPortHandler.scaleX
}
如果值太多,则不会绘制;但是对你来说粒度好像不够
有办法解决,比如条形图,可以计算出文字宽度,与条形像素宽度比较,决定是否绘制文字。您可以在 drawValues
中覆盖或者如果您需要快速解决它。饼图类似。
喜欢:
// calculate bar pixel width
let barWidth: CGFloat = 0.5
let barSpaceHalf = dataSet.barSpace / 2.0
let left = 0 - barWidth + barSpaceHalf
let right = 0 + barWidth - barSpaceHalf
var leftPoint = CGPoint(x: left, y: 0)
var rightPoint = CGPoint(x: right, y: 0)
trans.pointValueToPixel(&leftPoint)
trans.pointValueToPixel(&rightPoint)
let barPixelWidth = rightPoint.x - leftPoint.x
let valueTextWidth = valueText.sizeWithAttributes([NSFontAttributeName: valueFont]).width
if valueTextWidth < barPixelWidth
{
// draw text
}