iOS:两个条形图一起

时间:2018-06-14 09:04:57

标签: ios objective-c charts ios-charts

我正在使用图表库(Charts

我正在开发的应用程序允许我实时显示餐厅的客人数量并比较不同日期之间的数据。 例如,看看这张照片 enter image description here

虚线表示与日期比较的数据。我想创建这样的BarChart但是库只允许我显示4个分组的条形图。我想显示上面带有小偏移的彩色条纹。请帮帮我

enter image description here

我的代码是:

for (int i = 0; i < days.count; i++) {
        BarChartDataEntry *guysEntry = [[BarChartDataEntry alloc] initWithX:i y:[guys[i] integerValue]];
        [guysChartDataArray addObject:guysEntry];

        BarChartDataEntry *girlsEntry = [[BarChartDataEntry alloc] initWithX:i y:[girls[i] integerValue]];
        [girlsChartDataArray addObject:girlsEntry];

        BarChartDataEntry *guysCompareToEntry = [[BarChartDataEntry alloc] initWithX:i y:[guysCompareTo[i] integerValue]];
        [guysCompareToChartDataArray addObject:guysCompareToEntry];

        BarChartDataEntry *girlsCompareToEntry = [[BarChartDataEntry alloc] initWithX:i y:[girlsCompareTo[i] integerValue]];
        [girlsCompareToChartDataArray addObject:girlsCompareToEntry];
    }
    BarChartDataSet *guysChartDataSet = [[BarChartDataSet alloc] initWithValues:guysChartDataArray label:@"Guys"];
    guysChartDataSet.colors = @[[UIColor maleColor]];
    guysChartDataSet.valueTextColor = [UIColor clearColor];

    BarChartDataSet *girlsChartDataSet = [[BarChartDataSet alloc] initWithValues:girlsChartDataArray label:@"Girls"];
    girlsChartDataSet.colors = @[[UIColor femaleColor]];
    girlsChartDataSet.valueTextColor = [UIColor clearColor];

    LineChartXAxisFormatter *barGraphXFormatter = [[LineChartXAxisFormatter alloc] init];
    barGraphXFormatter.xLabels = [days mutableCopy];
    self.barChartView.xAxis.valueFormatter = barGraphXFormatter;
    self.barChartView.xAxis.centerAxisLabelsEnabled = YES;

    self.combinedChartView.xAxis.valueFormatter = barGraphXFormatter;
    self.combinedChartView.xAxis.centerAxisLabelsEnabled = YES;

    float groupSpace = 0.06f;
    float barSpace = 0.02f;
    float barWidth = 0.45f;

    BarChartDataSet *guysCompareToChartDataSet = [[BarChartDataSet alloc] initWithValues:guysCompareToChartDataArray label:@"Guys (Compare)"];
    guysCompareToChartDataSet.colors = @[[UIColor clearColor]];
    guysCompareToChartDataSet.barBorderWidth = 1.f;
    guysCompareToChartDataSet.barBorderColor = [UIColor grayColor];
    guysCompareToChartDataSet.isDashedBorder = YES;

    guysCompareToChartDataSet.axisDependency = AxisDependencyLeft;
    guysCompareToChartDataSet.valueTextColor = [UIColor clearColor];

    BarChartDataSet *girlsCompareToChartDataSet = [[BarChartDataSet alloc] initWithValues:girlsCompareToChartDataArray label:@"Girls (Compare)"];
    girlsCompareToChartDataSet.colors = @[[UIColor clearColor]];
    girlsCompareToChartDataSet.barBorderWidth = 1.f;
    girlsCompareToChartDataSet.barBorderColor = [UIColor grayColor];
    girlsCompareToChartDataSet.isDashedBorder = YES;
    girlsCompareToChartDataSet.axisDependency = AxisDependencyLeft;
    girlsCompareToChartDataSet.valueTextColor = [UIColor clearColor];

    NSArray *dataSets = @[guysChartDataSet, girlsChartDataSet, guysCompareToChartDataSet, girlsCompareToChartDataSet];

    BarChartData *barChartData = [[BarChartData alloc] initWithDataSets:dataSets];
    barChartData.barWidth = barWidth;

    CGFloat initialValue = 0;
    CGFloat groupCount = days.count;

    self.barChartView.xAxis.axisMinimum = initialValue;

    self.barChartView.xAxis.axisMaximum = initialValue + [barChartData groupWidthWithGroupSpace:groupSpace barSpace: barSpace] * groupCount;

    [barChartData groupBarsFromX:0 groupSpace:groupSpace barSpace:barSpace];
    self.barChartView.data = barChartData;

我想做类似的事情: enter image description here

2 个答案:

答案 0 :(得分:1)

使用Charts,它看起来可以

  1. 将数据堆叠到同一个栏中。
  2. 组合条形以使它们重叠。
  3. 看起来你可以

    1. 为堆叠条中的每个数据条目指定单独的边框颜色。 (如果提供边框颜色,它将应用于整个条形图。)
    2. 关于文档的说明

      请记住,Charts是在MPAndroidChart之后建模的,并且非常密切地遵循其API。

      因此,如果您需要帮助,请参阅他们的documentation。 Java语法对我来说有点陌生,但在Xcode的自动完成功能的帮助下,我能够找到我需要的一切。

      <强>代码:

      请注意三个具体部分:

      1. 如何创建堆叠数据条目。
      2. 无法在堆叠条中为每个项目设置单独的边框。
      3. 如何通过提供负条间距来重叠条形。
      4. 我绝不是这个图书馆的专家,但只是阅读文档,我就能把它放在一起。

        // MARK: Data Entries
        
        for (int i = 0; i < days.count; i++) {
            NSNumber *guyValue = guys[i];
            NSNumber *girlValue = girls[i];
        
        
            // NOTE 1: To get "stacked" bars, use the initializer `initWithX:yValues:`
            BarChartDataEntry *guyGirlDataEntry = [[BarChartDataEntry alloc] initWithX:i
                                                                               yValues:@[guyValue, girlValue]];
        
        
            NSNumber *guyCompareToValue = guysCompareTo[i];
            NSNumber *girlCompareToValue = girlsCompareTo[i];
        
            BarChartDataEntry *guyGirlCompareToEntry = [[BarChartDataEntry alloc] initWithX:i
                                                                                    yValues:@[guyCompareToValue, girlCompareToValue]];
        
            [guyGirlChartDataArray addObject:guyGirlDataEntry];
            [guyGirlCompareToChartDataArray addObject:guyGirlCompareToEntry];
        }
        
        
        
        // MARK: Data Sets
        
        BarChartDataSet *guysGirlsChartDataSet = [[BarChartDataSet alloc] initWithValues:guyGirlChartDataArray label:nil];
        BarChartDataSet *guysGirlsCompareToChartDataSet = [[BarChartDataSet alloc] initWithValues:guyGirlCompareToChartDataArray label:nil];
        
        BarChartData *data = [[BarChartData alloc] initWithDataSets:@[guysGirlsCompareToChartDataSet, guysGirlsChartDataSet]];
        
        
        
        // MARK: Styling
        
        guysGirlsChartDataSet.stackLabels = @[@"Guys", @"Girls"];
        guysGirlsChartDataSet.colors = @[[UIColor maleColor],
                                         [UIColor femaleColor]];
        
        // NOTE 2: Unfortunately, you can only set one border color to the bar.
        // It seems, you won't be able to use separate dashed borders in the same bar, like you want.
        // For demonstration purposes, I've simply made the comparison colors 50% transparent.
        guysGirlsCompareToChartDataSet.stackLabels = @[@"Guys (Compare)", @"Girls (Compare)"];
        guysGirlsCompareToChartDataSet.colors = @[[[UIColor maleColor] colorWithAlphaComponent:0.5],
                                                  [[UIColor femaleColor] colorWithAlphaComponent:0.5]];
        
        // Sets the x axis label interval, so it doesn't show labels like "0.9"
        barChartView.xAxis.granularity = 1;
        
        // Centers the x axis label over the bar group, rather than on the grid line.
        barChartView.xAxis.centerAxisLabelsEnabled = YES;
        
        
        
        // MARK: Displaying Chart Data
        
        barChartView.data = data;
        
        // Grouping
        
        // I still can't seem to set this properly.
        // Even though I tell it to fit the bars exactly and don't show below 0 on the x axis,
        // the chart still shows below zero and the right-most bar gets cut off.
        
        // If this isn't a bug, then perhaps you can find the answer to this elsewhere.
        barChartView.fitBars = YES;
        [barChartView setVisibleXRangeMinimum:0];
        
        // Calculate bar grouping parameters.
        NSInteger barCountPerGroup = data.dataSetCount;
        double barWidth = 0.4;
        
        // NOTE 3: Negative bar spacing will make the bars overlap.
        double barSpace = -0.3;
        
        // According to documentation, total group width (bars and spacing) must add up to 1
        double groupSpace = 1 - (barWidth + barSpace) * barCountPerGroup;
        
        // Set the grouping parameters.
        data.barWidth = barWidth;
        [barChartView groupBarsFromX:0 groupSpace:groupSpace barSpace:barSpace];
        
        // Refresh the chart (if necessary)
        [barChartView notifyDataSetChanged];
        

        输出:

        样式不是很好,但是条形图按照您的需要进行分组和重叠。

        我相信你可以在其他地方寻找样式的帮助。

        chart with overlapping bars, resulting from sample code

答案 1 :(得分:1)

现在你已经改变了你的问题,这需要一个不同的解决方案。

正如我在之前的评论中所提到的,您需要手动计算每个栏的位置。然后, 使用分组功能,因为您已经按照自己的意愿对其进行了分组。

// Determine bar sizing and spacing parameters.
int barsPerGroup = 2;
double targetGroupWidth = 1;
double barSpacing = 0.2;
double groupSpacing = 0.3;
double barWidth = (targetGroupWidth - groupSpacing - barSpacing * barsPerGroup) / barsPerGroup;
double compareBarOffset = barWidth / 3;

for (int i = 0; i < entryCount; i++) {

    // Determine X position for each bar
    // NOTE: This is the most important step!
    double groupStartPosition = targetGroupWidth * i;

    double group1X = groupStartPosition + barWidth / 2;
    double group1CompareX = group1X + compareBarOffset;

    double group2X = group1X + barWidth + barSpacing;
    double group2CompareX = group2X + compareBarOffset;


    // Create data entries positioned at values calculated by previous step
    NSNumber *group1Value = group1[i];
    NSNumber *group1CompareValue = group1Compare[i];

    NSNumber *group2Value = group2[i];
    NSNumber *group2CompareValue = group2Compare[i];


    BarChartDataEntry *group1DataEntry = [[BarChartDataEntry alloc] initWithX:group1X
                                                                            y:[group1Value doubleValue]];
    BarChartDataEntry *group1CompareDataEntry = [[BarChartDataEntry alloc] initWithX:group1CompareX
                                                                                   y:[group1CompareValue doubleValue]];

    BarChartDataEntry *group2DataEntry = [[BarChartDataEntry alloc] initWithX:group2X
                                                                            y:[group2Value doubleValue]];
    BarChartDataEntry *group2CompareEntry = [[BarChartDataEntry alloc] initWithX:group2CompareX
                                                                               y:[group2CompareValue doubleValue]];


    // ...
}

// Create Data Sets, set styles, etc.
// ...

// Do NOT use this method because bars are already grouped.
//[barChartView groupBarsFromX:0 groupSpace:groupSpacing barSpace:barSpacing];

<强>结果:

注意:我找不到该属性isDashedBorder,因此我不知道您正在使用的库的版本。相反,我只是设置了带有灰色边框的透明条纹。

lag