【问题标题】:Overcrowded labels are unreadable in piechart and barcharts饼图和条形图中过度拥挤的标签不可读
【发布时间】:2016-01-19 16:26:18
【问题描述】:

对于饼图,通常有几个“切片”,其中包含非常小的部分数据(例如,

条形图也会出现类似问题,其中所有值相互重叠并变得不可读,如下所示。我能想到的解决方案是只显示部分条形图,如果用户平移则显示其他条形图。

如果有人处理过任何一个问题,我会很高兴看到您如何解决它,或者如果使用不同的库会更好。我在下面发布了一些代码,但不确定它是否会有所帮助,因为这可能不是真正的实现错误。

条形图

    //...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 = self;

_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];

【问题讨论】:

    标签: ios objective-c charts ios-charts


    【解决方案1】:

    首先,我建议在 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
    }
    

    【讨论】:

      【解决方案2】:

      基本上,您可以计算视图(或 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];
      

      【讨论】:

      • 这是用于条形图、饼图还是两者兼而有之?
      • 您可以通过 [self.layer addSublayer: 或 CALayer 将 CATextLayer 添加到任何 UIView,检查库实现。对于饼图,我会将它放在每个“切片”的中心,就像在这段代码中一样。对于条形图,您必须大幅减小字体大小、将文本方向更改为垂直或缩短文本
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-27
      • 1970-01-01
      相关资源
      最近更新 更多