iOS使用Charts 混合柱狀圖開發(fā)

近期公司的產(chǎn)品有新的需求,大概效果就如下所示:


~混合柱子~

我們使用的是ios-charts這個(gè)第三方,但是在網(wǎng)上找了一大堆也沒有發(fā)現(xiàn)這種效果的柱狀圖,沒辦法只能自己操刀來實(shí)現(xiàn)了。實(shí)現(xiàn)過程中借鑒了安卓中的MPCharts類似效果的實(shí)現(xiàn)方法,話不多說,直接上代碼,代碼中注釋已經(jīng)比較清晰了,有不懂得歡迎咨詢。
我是寫了一個(gè)這種效果實(shí)現(xiàn)的工具類,在.h文件中申明方法:

/**
 兩根柱子以及折線的混合顯示

 @param combineChart 需要設(shè)置的CombineChartView
 @param xValues X軸的值數(shù)組,里面放字符串
 @param lineValues 折線值數(shù)組
 @param bar1Values 柱子1的值數(shù)組
 @param bar2Values 柱子2的值數(shù)組
 @param lineTitle 圖例中折線的描述
 @param bar1Title 圖例中柱子1的描述
 @param bar2Title 圖例中柱子2的描述
 
 warning:由于繪制有順序,所以繪制高柱子應(yīng)該在繪制低柱子之前進(jìn)行,所以bar1Values中的值要大于對(duì)應(yīng)的bar2Values中的值,繪制折線應(yīng)該在最后進(jìn)行
 */
- (void)setCombineBarChart:(CombinedChartView *)combineChart xValues:(NSArray *)xValues lineValues:(NSArray *)lineValues bar1Values:(NSArray *)bar1Values bar2Values:(NSArray *)bar2Values lineTitle:(NSString *)lineTitle bar1Title:(NSString *)bar1Title bar2Title:(NSString *)bar2Title;

在.m文件中實(shí)現(xiàn)這個(gè)方法:

- (void)setCombineBarChart:(CombinedChartView *)combineChart xValues:(NSArray *)xValues lineValues:(NSArray *)lineValues bar1Values:(NSArray *)bar1Values bar2Values:(NSArray *)bar2Values lineTitle:(NSString *)lineTitle bar1Title:(NSString *)bar1Title bar2Title:(NSString *)bar2Title
{
    combineChart.descriptionText = @"";
    combineChart.pinchZoomEnabled = YES;
    combineChart.marker = [[ChartMarkerView alloc] init];
    combineChart.drawOrder = @[@0,@0,@2];//CombinedChartDrawOrderBar,CombinedChartDrawOrderLine 繪制順序
    combineChart.doubleTapToZoomEnabled = NO;//取消雙擊放大
    combineChart.scaleYEnabled = NO;//取消Y軸縮放
    combineChart.dragEnabled = YES;//啟用拖拽圖表
    combineChart.dragDecelerationEnabled = YES;//拖拽后是否有慣性效果
    combineChart.dragDecelerationFrictionCoef = 0.9;//拖拽后慣性效果的摩擦系數(shù)(0~1),數(shù)值越小,慣性越不明顯
    combineChart.highlightPerTapEnabled = NO;//取消單擊高亮顯示
    combineChart.highlightPerDragEnabled = NO;//取消拖拽高亮
    ChartXAxis *xAxis = combineChart.xAxis;
    xAxis.labelPosition = XAxisLabelPositionBottom;
    xAxis.drawGridLinesEnabled = NO;
    xAxis.labelFont = [UIFont systemFontOfSize:15];
    xAxis.labelCount = xValues.count;
    xAxis.labelRotationAngle = -40;
    
    xAxis.valueFormatter = [[ChartIndexAxisValueFormatter alloc] initWithValues:xValues];//設(shè)置X軸顯示的值
    
    //左側(cè)Y軸設(shè)置
    ChartYAxis *leftAxis = combineChart.leftAxis;
    leftAxis.labelPosition = YAxisLabelPositionOutsideChart;
    leftAxis.axisMinimum = 0.0f;
    leftAxis.drawGridLinesEnabled = YES;
    
    float yMin = [[bar2Values valueForKeyPath:@"@min.floatValue"] floatValue]*0.9;
    float yMax = [[bar1Values valueForKeyPath:@"@max.floatValue"] floatValue]*1.1;
    leftAxis.axisMinimum = yMin;
    leftAxis.axisMaximum = yMax;

    //右側(cè)Y軸
    ChartYAxis *rightAxis = combineChart.rightAxis;
    rightAxis.labelPosition = YAxisLabelPositionOutsideChart;
    rightAxis.drawGridLinesEnabled = NO;
    rightAxis.axisMinimum = 0;
    rightAxis.axisMaximum = 100;
    //設(shè)置圖例
    ChartLegend *legend = combineChart.legend;
    legend.horizontalAlignment = ChartLegendHorizontalAlignmentLeft;
    legend.verticalAlignment = ChartLegendVerticalAlignmentBottom;
    legend.orientation = ChartLegendOrientationHorizontal;
    legend.drawInside = NO;
    legend.direction = ChartLegendDirectionLeftToRight;
    legend.form = ChartLegendFormSquare;
    legend.formSize = 12;
    //設(shè)置數(shù)據(jù)
    CombinedChartData *data = [[CombinedChartData alloc] init];
    data.lineData = [self generateLineData:lineValues lineTitle:lineTitle];
    data.barData = [self generateCombineBarData:bar1Values bar2Values:bar2Values title1:bar1Title title2:bar2Title];
    combineChart.data = data;
    
    
    //讓柱子在X軸顯示全
    xAxis.axisMinimum = data.xMin - 1.0f;
    xAxis.axisMaximum = data.xMax + 1.0f;
    combineChart.extraBottomOffset = 10;
    combineChart.extraTopOffset = 30;
    [combineChart animateWithYAxisDuration:1.0];//添加Y軸動(dòng)畫
}
//生成折線的數(shù)據(jù)
- (LineChartData *)generateLineData:(NSArray *)lineValues lineTitle:(NSString *)lineTitle
{
    NSMutableArray *entries = [NSMutableArray array];
    for (int i = 0; i < lineValues.count; i++) {
        ChartDataEntry *entry = [[ChartDataEntry alloc] initWithX:i y:[lineValues[i] floatValue]];
        [entries addObject:entry];
    }
    
    LineChartDataSet *dataSet = [[LineChartDataSet alloc] initWithValues:entries label:lineTitle];
    dataSet.colors = @[[UIColor greenColor]];
    dataSet.lineWidth = 2.5f;
    dataSet.circleColors = @[[UIColor redColor]];
    dataSet.circleHoleColor = [UIColor purpleColor];
    dataSet.axisDependency = AxisDependencyRight;
    dataSet.drawValuesEnabled = YES;//不繪制線的數(shù)據(jù)
    
    LineChartData *lineData = [[LineChartData alloc] initWithDataSet:dataSet];
    [lineData setValueFont:[UIFont systemFontOfSize:10]];
    
    return lineData;
}
//生成復(fù)雜的組合柱圖的數(shù)據(jù)(兩根重疊的柱和折線的圖)
- (BarChartData *)generateCombineBarData:(NSArray *)bar1Values bar2Values:(NSArray *)bar2Values title1:(NSString *)bar1Title title2:(NSString *)bar2Title
{
    NSMutableArray *bar1Entries = [NSMutableArray array];
    NSMutableArray *bar2Entries = [NSMutableArray array];
    for (int i=0; i<bar1Values.count; i++) {
        BarChartDataEntry *barEntry = [[BarChartDataEntry alloc] initWithX:i y:[bar1Values[i] floatValue]];
        [bar1Entries addObject:barEntry];
    }
    for (int i=0; i<bar2Values.count; i++) {
        BarChartDataEntry *barEntry = [[BarChartDataEntry alloc] initWithX:i y:[bar2Values[i] floatValue]];
        [bar2Entries addObject:barEntry];
    }
    
    BarChartDataSet *dataSet1 = [[BarChartDataSet alloc]  initWithValues:bar1Entries label:bar1Title];
    dataSet1.colors = @[[UIColor grayColor]];
    dataSet1.valueColors = @[[UIColor orangeColor]];
    dataSet1.axisDependency = AxisDependencyLeft;
    dataSet1.drawValuesEnabled = NO;
    
    BarChartDataSet *dataSet2 = [[BarChartDataSet alloc]  initWithValues:bar2Entries label:bar2Title];
    dataSet2.colors = @[[UIColor brownColor]];
    dataSet2.valueColors = @[[UIColor orangeColor]];
    dataSet2.axisDependency = AxisDependencyLeft;
    dataSet2.drawValuesEnabled = NO;
    BarChartData *data = [[BarChartData alloc] initWithDataSets:@[dataSet1,dataSet2]];
    [data setValueFont:[UIFont systemFontOfSize:10]];
    data.barWidth = 0.9f;
    return data;
}

要使用這個(gè)工具類也很簡(jiǎn)單,在需要的控制器中引入這個(gè)工具類,實(shí)現(xiàn)如下方法:

- (void)createCombineBarChartView
{
    CombinedChartView *combine = [[CombinedChartView alloc] init];
    self.combineChartView = combine;
    combine.frame = CGRectMake(0, KScreenHeight/2, KScreenWidth, KScreenHeight/2);
    combine.backgroundColor = [UIColor colorWithRed:230/255.0f green:253/255.0f blue:253/255.0f alpha:1];
    [self.view addSubview:combine];
    
    //我自己的工具類
    BarChartsHelper *helper = [[BarChartsHelper alloc] init];
    [helper setCombineBarChart:self.combineChartView xValues:self.xStrings lineValues:@[@"30",@"10",@"50",@"30",@"60"] bar1Values:@[@"80",@"40",@"60",@"30",@"70"] bar2Values:@[@"60",@"30",@"53",@"20",@"45"] lineTitle:@"line" bar1Title:@"bar1" bar2Title:@"bar2"];
}

其中有個(gè)注意點(diǎn)就是:因?yàn)橹途€的繪制是有先后順序的。所以要讓bar1Values中的值大于bar2Values中對(duì)應(yīng)的值,這樣才不會(huì)被遮擋住。
還有設(shè)置的lineTitle、bar1Title、bar2Title都是圖例中的對(duì)應(yīng)的描述。
代碼已經(jīng)放在GitHub上https://github.com/coolLeee/LGBarCharts,歡迎交流討論~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 178,733評(píng)論 25 709
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,037評(píng)論 4 61
  • 晚飯過后,涼風(fēng)習(xí)習(xí),恰逢周末。踏上單車,塞上耳機(jī),身披夕陽余暉,一路蹬到開遠(yuǎn)市滇南發(fā)電總廠——是的,就是那個(gè)7路、...
    聆聽_自然閱讀 369評(píng)論 0 0
  • 封建社會(huì)是絕對(duì)的男權(quán)社會(huì),男人一直試圖禁錮女性的思想,以三從四德要求她們,似乎很怕婦女變成獨(dú)立自主的個(gè)體,但有些東...
    常晴空閱讀 2,128評(píng)論 0 3
  • 因?yàn)楸救艘o沽湖玩幾天,所以停更大概三天左右。 希望一直支持我的朋友能夠理解。 謝謝。 ...
    大作家史努比閱讀 183評(píng)論 2 0

友情鏈接更多精彩內(nèi)容