基于iOS-Echarts封裝的條形圖繪制組件


現(xiàn)在很多app中的數(shù)據(jù)統(tǒng)計(jì)功能都會(huì)使用到柱狀圖折線圖等來進(jìn)行數(shù)據(jù)的展示,可能有一些比較牛的大神會(huì)選擇自己繪制,至于我嘛,還是老老實(shí)實(shí)的用網(wǎng)上開源的工具吧,先把我寫的Demo給大家放在這里,可以對(duì)照著下面的講解看。

在做這個(gè)功能之前我上網(wǎng)查了一些別人的實(shí)現(xiàn)方式,一種是使用開源組件ios-charts,這個(gè)是使用swift開發(fā)的組件,可以直接在iOS項(xiàng)目中進(jìn)行集成使用,我用這個(gè)也實(shí)現(xiàn)了功能所需的效果,但是我總感覺這個(gè)東西不好封裝,有興趣的可以去試試。

另一種是使用百度的開源圖表工具ECharts,不過不太幸運(yùn)的是這個(gè)組件是使用JS來寫的,有JS功底的呢就可以直接來使用。針對(duì)這個(gè)問題有一位活雷鋒出現(xiàn)了,Pluto-Y對(duì)ECharts進(jìn)行了封裝,名字叫做iOS-Echarts,也就是我實(shí)現(xiàn)功能所使用的組件。

雖然這位活雷鋒為我們鋪好了前期的道路,但是這個(gè)組件沒有注釋,這個(gè)問題就相當(dāng)嚴(yán)重了,給大家簡單的看一下Pluto-Y的demo中柱狀圖效果。

再給大家看一下這個(gè)簡單的柱狀圖的實(shí)現(xiàn)代碼

+ (PYOption *)basicBarOption {
    return [PYOption initPYOptionWithBlock:^(PYOption *option) {
        option.titleEqual([PYTitle initPYTitleWithBlock:^(PYTitle *title) {
            title.textEqual(@"世界人口總量")
            .subtextEqual(@"數(shù)據(jù)來自網(wǎng)絡(luò)");
        }])
        .gridEqual([PYGrid initPYGridWithBlock:^(PYGrid *grid) {
            grid.xEqual(@40).x2Equal(@50);
        }])
        .tooltipEqual([PYTooltip initPYTooltipWithBlock:^(PYTooltip *tooltip) {
            tooltip.triggerEqual(PYTooltipTriggerAxis);
        }])
        .legendEqual([PYLegend initPYLegendWithBlock:^(PYLegend *legend) {
            legend.dataEqual(@[@"2011年", @"2012年"]);
        }])
        .toolboxEqual([PYToolbox initPYToolboxWithBlock:^(PYToolbox *toolbox) {
            toolbox.showEqual(YES)
            .featureEqual([PYToolboxFeature initPYToolboxFeatureWithBlock:^(PYToolboxFeature *feature) {
                feature.markEqual([PYToolboxFeatureMark initPYToolboxFeatureMarkWithBlock:^(PYToolboxFeatureMark *mark) {
                    mark.showEqual(YES);
                }])
                .dataViewEqual([PYToolboxFeatureDataView initPYToolboxFeatureDataViewWithBlock:^(PYToolboxFeatureDataView *dataView) {
                    dataView.showEqual(YES).readOnlyEqual(NO);
                }])
                .magicTypeEqual([PYToolboxFeatureMagicType initPYToolboxFeatureMagicTypeWithBlock:^(PYToolboxFeatureMagicType *magicType) {
                    magicType.showEqual(YES).typeEqual(@[PYSeriesTypeLine, PYSeriesTypeBar]);
                }])
                .restoreEqual([PYToolboxFeatureRestore initPYToolboxFeatureRestoreWithBlock:^(PYToolboxFeatureRestore *restore) {
                    restore.showEqual(YES);
                }]);
            }]);
        }])
        .calculableEqual(YES)
        .addXAxis([PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeValue)
            .boundaryGapEqual(@[@0, @0.01]);
        }])
        .addYAxis([PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeCategory)
            .addDataArr(@[@"巴西",@"印尼",@"美國",@"印度",@"中國",@"世界人口(萬)"]);
        }])
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.nameEqual(@"2011年")
            .typeEqual(PYSeriesTypeBar)
            .addDataArr(@[@18203, @23489, @29034, @104970, @131744, @630230]);
        }])
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.nameEqual(@"2012年")
            .typeEqual(PYSeriesTypeBar)
            .addDataArr(@[@19325, @23438, @31000, @121594, @134141, @681807]);
        }]);
    }];
}

我第一次看簡直毫無頭緒,再歷經(jīng)了兩天的不斷嘗試以及查詢百度的JS文檔,總算是稍稍的理解了其中的一部分實(shí)現(xiàn)方式。

言歸正傳,先給大家看一下我所實(shí)現(xiàn)的界面效果圖。

常規(guī)柱狀圖

這是一個(gè)最為常規(guī)的條形圖,也叫柱狀圖,我們先簡單的看一下它的實(shí)現(xiàn)代碼。

#import "SimpleBarChartViewController.h"
//引入開源庫的頭文件
#import <iOS_Echarts/iOS-Echarts.h>
//這是我自己封裝后寫的一個(gè)類
#import "ZRChartsHelper.h"

@interface SimpleBarChartViewController ()
//定義一個(gè)PYEchartsView,這個(gè)是圖表繪制的view
@property (nonatomic, strong)PYEchartsView *zrSimpleChartsView;

@end

接著我們?yōu)檫@個(gè)view進(jìn)行相應(yīng)的布局

//布局chartsView
- (void)chartsViewLayout{
    self.zrSimpleChartsView = [[PYEchartsView alloc] initWithFrame:CGRectMake(0, getRectNavAndStatusHight, [UIScreen mainScreen].bounds.size.width, 350)];
    self.zrSimpleChartsView.backgroundColor = [UIColor grayColor];
    [self.view addSubview:self.zrSimpleChartsView];
    
    NSArray *chart1Array = @[@"56",@"36",@"89",@"36",@"89",@"36",@"89",@"36",@"89",@"36",@"89"];
   
    NSArray *titleArray = @[@"人員1",@"人員2",@"人員3",@"人員4",@"人員5",@"人員6",@"人員7",@"人員8",@"人員9",@"人員10",@"人員11"];
    
    //為內(nèi)容進(jìn)行渲染
    ZRChartsHelper *helper = [[ZRChartsHelper alloc] init];
    [helper setZRSimpleBarChartView:self.zrSimpleChartsView barValues:chart1Array xValues:titleArray];
    
}

繪制的主要代碼我都寫到了ZRChartsHelper這個(gè)類中,我們再看一下這個(gè)最基礎(chǔ)簡單的條形圖的實(shí)現(xiàn)代碼。

- (void)setZRSimpleBarChartView:(PYEchartsView *)chartView barValues:(NSArray *)barValues xValues:(NSArray *)xvals{
//初始化一個(gè)Option,對(duì)其屬性進(jìn)行設(shè)置,來達(dá)到我們想要的效果
    PYOption *option = [PYOption initPYOptionWithBlock:^(PYOption *option) {
        
        option.tooltipEqual([PYTooltip initPYTooltipWithBlock:^(PYTooltip *tooltip) {
            tooltip.triggerEqual(PYTooltipTriggerAxis)
            .axisPointerEqual([PYAxisPointer initPYAxisPointerWithBlock:^(PYAxisPointer *axisPoint) {
                axisPoint.typeEqual(PYAxisPointerTypeShadow);
            }]);
        }])
        
        //這個(gè)屬性是對(duì)圖表下方的文字控件進(jìn)行設(shè)置
        .legendEqual([PYLegend initPYLegendWithBlock:^(PYLegend *legend) {
            //文字的內(nèi)容
            legend.dataEqual(@[@"新增事件"]);
            //文字控件的縱坐標(biāo)
            legend.yEqual(@300);
        }])
        //這個(gè)屬性是對(duì)整個(gè)圖表的位置進(jìn)行設(shè)置
        .gridEqual([PYGrid initPYGridWithBlock:^(PYGrid *grid) {
            //第一個(gè)40為X軸距離左邊的距離,第二個(gè)x2為X軸末端距離view右面邊界的距離
            grid.xEqual(@40).x2Equal(@50);
            //圖表距離頂部的距離
            grid.yEqual(@10);
            //圖表的高度設(shè)置
            grid.heightEqual(@250);
        }])
        //這個(gè)屬性是設(shè)置圖表可左右滑動(dòng),很多情況下可能X軸要展示很多數(shù)據(jù),因此會(huì)產(chǎn)生堆積,加了這個(gè)便可以左右滑動(dòng)條形圖來查看數(shù)據(jù)
        .dataZoomEqual([PYDataZoom initPYDataZoomWithBlock:^(PYDataZoom *dataZoom) {
            dataZoom.yEqual(@335);
            dataZoom.heightEqual(@10);
            //設(shè)置為顯示滾動(dòng)欄
            dataZoom.showEqual(YES)
           //下面這兩個(gè)屬性是設(shè)置界面一開始展示那一部分的內(nèi)容,這里為圖表30%~70%間的內(nèi)容
            .startEqual(@30)
            .endEqual(@70);
        }])
        
        //設(shè)置工具欄,這個(gè)我沒有讓它進(jìn)行顯示,因此show這個(gè)屬性我設(shè)置為隱藏,大家可以去看看有很多功能
        .toolboxEqual([PYToolbox initPYToolboxWithBlock:^(PYToolbox *toolbox) {
            //設(shè)置為隱藏
            toolbox.showEqual(NO)
            .orientEqual(PYOrientVertical)
            .xEqual(PYPositionRight)
            .yEqual(PYPositionCenter)
            .featureEqual([PYToolboxFeature initPYToolboxFeatureWithBlock:^(PYToolboxFeature *feature) {
                feature.markEqual([PYToolboxFeatureMark initPYToolboxFeatureMarkWithBlock:^(PYToolboxFeatureMark *mark) {
                    mark.showEqual(YES);
                }])
                .dataViewEqual([PYToolboxFeatureDataView initPYToolboxFeatureDataViewWithBlock:^(PYToolboxFeatureDataView *dataView) {
                    dataView.showEqual(YES).readOnlyEqual(NO);
                }])
                .magicTypeEqual([PYToolboxFeatureMagicType initPYToolboxFeatureMagicTypeWithBlock:^(PYToolboxFeatureMagicType *magicType) {
                    magicType.showEqual(YES).typeEqual(@[PYSeriesTypeLine, PYSeriesTypeBar, @"stack", @"tiled"]);
                }])
                .restoreEqual([PYToolboxFeatureRestore initPYToolboxFeatureRestoreWithBlock:^(PYToolboxFeatureRestore *restore) {
                    restore.showEqual(YES);
                }]);
            }]);
        }])
        .calculableEqual(NO)
        //設(shè)置X軸title,有多少個(gè)就在數(shù)組中寫入多少個(gè)
        .addXAxis([PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeCategory)
             //這里在我封裝過后本應(yīng)寫為xvals,方便大家理解我直接填寫了數(shù)組進(jìn)去
            .addDataArr(@[@"人員1",@"人員2",@"人員3",@"人員4",@"人員5",@"人員6",@"人員7",@"人員8",@"人員9",@"人員10",@"人員11"]);
        }])
        
        
        //設(shè)置Y軸title,一般默認(rèn)是數(shù)字
        .addYAxis([PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            //Y軸顯示的值類型,這里為直接顯示數(shù)據(jù)值
            axis.typeEqual(PYAxisTypeValue);
            //Y軸的位置,這里是在左邊
            axis.positionEqual(PYPositionLeft);
        }])
        
        //這里設(shè)置柱子的屬性
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            //這個(gè)值可以隨意起名稱,他不會(huì)顯示在界面中,但是這個(gè)值很重要,我會(huì)在接下來復(fù)雜的柱狀圖中說明
            series.stackEqual(@"事件類型")
            //柱子的名稱,與上方我們設(shè)置過的表格下方的控件相對(duì)應(yīng)
            .nameEqual(@"新增事件")
            //類型,bar為柱狀圖,如果設(shè)置為line則顯示為折線
            .typeEqual(PYSeriesTypeBar)
            //設(shè)置柱子的樣式
            .itemStyleEqual([PYItemStyle initPYItemStyleWithBlock:^(PYItemStyle *itemStyle) {
                itemStyle.normalEqual([PYItemStyleProp initPYItemStylePropWithBlock:^(PYItemStyleProp *normal) {
                    normal.labelEqual([PYLabel initPYLabelWithBlock:^(PYLabel *label) {
                        //是否顯示柱子的數(shù)值,以及顯示的位置
                        label.showEqual(YES).positionEqual(@"inside");
                    }]);
                }]);
            }])
            //設(shè)置柱子的數(shù)值,X軸有多少個(gè)單位,這個(gè)數(shù)組就要對(duì)應(yīng)有多少值,封裝后這里應(yīng)填寫barValues
           .dataEqual(@[@"56",@"36",@"89",@"36",@"89",@"36",@"89",@"36",@"89",@"36",@"89"]);
        }]);
        
    }];
    
    //為負(fù)責(zé)渲染的view設(shè)置渲染option
    [chartView setOption:option];
    //加載圖表渲染
    [chartView loadEcharts];
}
以上就是一個(gè)最簡單的條形圖的設(shè)置,其實(shí)還好不算復(fù)雜,但是產(chǎn)品經(jīng)理怎么會(huì)這么輕松的放過你。

接下來就給大家看一下我司產(chǎn)品經(jīng)理的需求實(shí)現(xiàn)圖。

堆積柱狀圖

怎么樣,這個(gè)的設(shè)置就有點(diǎn)復(fù)雜了,其實(shí)說復(fù)雜也沒有很復(fù)雜,掌握規(guī)律就好了,我們再來看一下這個(gè)的實(shí)現(xiàn)代碼。

//布局chartsView
- (void)chartsViewLayout{
    self.zrchartsView = [[PYEchartsView alloc] initWithFrame:CGRectMake(0, getRectNavAndStatusHight, [UIScreen mainScreen].bounds.size.width, 350)];
    self.zrchartsView.backgroundColor = [UIColor grayColor];
    [self.view addSubview:self.zrchartsView];
    //這個(gè)數(shù)組的結(jié)構(gòu)是數(shù)組中嵌套數(shù)組,大家可以使用別的數(shù)據(jù)格式來進(jìn)行封裝
    NSArray *chart1Array = @[
                             @[@"56",@"36",@"89",@"36",@"89",@"36",@"89",@"36",@"89",@"36",@"89"],
                             @[@"34",@"46",@"26",@"46",@"26",@"46",@"26",@"46",@"26",@"46",@"26"],
                             @[@"37",@"25",@"24",@"25",@"24",@"25",@"24",@"25",@"24",@"25",@"24"],
                             @[@"98",@"56",@"35",@"56",@"35",@"56",@"35",@"56",@"35",@"56",@"35"]
                             ];
    //X軸的數(shù)據(jù)
    NSArray *titleArray = @[@"人員1",@"人員2",@"人員3",@"人員4",@"人員5",@"人員6",@"人員7",@"人員8",@"人員9",@"人員10",@"人員11"];
    
    //為內(nèi)容進(jìn)行渲染
    ZRChartsHelper *helper = [[ZRChartsHelper alloc] init];
    [helper setZRStackBarChartView:self.zrchartsView barValues:chart1Array xValues:titleArray];
    
}

開始還是一樣的,我們先布局,然后使用helper來進(jìn)行界面的渲染,再來看一下stackbar的實(shí)現(xiàn)代碼。

- (void)setZRStackBarChartView:(PYZoomEchartsView *)chartView barValues:(NSArray *)barValues xValues:(NSArray *)xvals{
    PYOption *option = [PYOption initPYOptionWithBlock:^(PYOption *option) {
        
        option.tooltipEqual([PYTooltip initPYTooltipWithBlock:^(PYTooltip *tooltip) {
            tooltip.triggerEqual(PYTooltipTriggerAxis)
            .axisPointerEqual([PYAxisPointer initPYAxisPointerWithBlock:^(PYAxisPointer *axisPoint) {
                axisPoint.typeEqual(PYAxisPointerTypeShadow);
            }]);
        }])
        
      
        .legendEqual([PYLegend initPYLegendWithBlock:^(PYLegend *legend) {
            legend.dataEqual(@[@"已處理",@"待銷項(xiàng)",@"已銷項(xiàng)",@"新增事件"]);
            legend.yEqual(@300);
        }])
        .gridEqual([PYGrid initPYGridWithBlock:^(PYGrid *grid) {
            grid.xEqual(@40).x2Equal(@50);
            grid.yEqual(@10);
            grid.heightEqual(@250);
        }])
        
        .dataZoomEqual([PYDataZoom initPYDataZoomWithBlock:^(PYDataZoom *dataZoom) {
            dataZoom.yEqual(@335);
            dataZoom.heightEqual(@10);
            dataZoom.showEqual(YES)
            .startEqual(@30)
            .endEqual(@70);
        }])
        
      
        .toolboxEqual([PYToolbox initPYToolboxWithBlock:^(PYToolbox *toolbox) {
            toolbox.showEqual(NO)
            .orientEqual(PYOrientVertical)
            .xEqual(PYPositionRight)
            .yEqual(PYPositionCenter)
            .featureEqual([PYToolboxFeature initPYToolboxFeatureWithBlock:^(PYToolboxFeature *feature) {
                feature.markEqual([PYToolboxFeatureMark initPYToolboxFeatureMarkWithBlock:^(PYToolboxFeatureMark *mark) {
                    mark.showEqual(YES);
                }])
                .dataViewEqual([PYToolboxFeatureDataView initPYToolboxFeatureDataViewWithBlock:^(PYToolboxFeatureDataView *dataView) {
                    dataView.showEqual(YES).readOnlyEqual(NO);
                }])
                .magicTypeEqual([PYToolboxFeatureMagicType initPYToolboxFeatureMagicTypeWithBlock:^(PYToolboxFeatureMagicType *magicType) {
                    magicType.showEqual(YES).typeEqual(@[PYSeriesTypeLine, PYSeriesTypeBar, @"stack", @"tiled"]);
                }])
                .restoreEqual([PYToolboxFeatureRestore initPYToolboxFeatureRestoreWithBlock:^(PYToolboxFeatureRestore *restore) {
                    restore.showEqual(YES);
                }]);
            }]);
        }])
        .calculableEqual(NO)
        //設(shè)置X軸title,有多少個(gè)就在數(shù)組中寫入多少個(gè)
        .addXAxis([PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeCategory)
            .addDataArr(xvals);
        }])
        
        
        //設(shè)置Y軸title,一般默認(rèn)是數(shù)字
        .addYAxis([PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeValue);
            axis.positionEqual(PYPositionLeft);
        }])
        
        
        //這個(gè)地方設(shè)置X軸每個(gè)單位中有幾個(gè)柱狀圖,每個(gè)柱狀圖有幾層

        //******這里的設(shè)置就是重點(diǎn)******//
        //大家可以看到,下面進(jìn)行了四項(xiàng)設(shè)置,他們的nameEqual這個(gè)屬性名稱都不一樣,但是stackEqual這個(gè)屬性的內(nèi)容都一樣,這樣就會(huì)實(shí)現(xiàn)我們所要的堆積效果
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.stackEqual(@"事件類型")
            .nameEqual(@"已處理")
            .typeEqual(PYSeriesTypeBar)
            .itemStyleEqual([PYItemStyle initPYItemStyleWithBlock:^(PYItemStyle *itemStyle) {
                itemStyle.normalEqual([PYItemStyleProp initPYItemStylePropWithBlock:^(PYItemStyleProp *normal) {
                    normal.labelEqual([PYLabel initPYLabelWithBlock:^(PYLabel *label) {
                        label.showEqual(YES).positionEqual(@"inside");
                    }]);
                }]);
            }])
            .dataEqual(barValues[0]);
        }])
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.stackEqual(@"事件類型")
            .nameEqual(@"待銷項(xiàng)")
            .typeEqual(PYSeriesTypeBar)
            .itemStyleEqual([PYItemStyle initPYItemStyleWithBlock:^(PYItemStyle *itemStyle) {
                itemStyle.normalEqual([PYItemStyleProp initPYItemStylePropWithBlock:^(PYItemStyleProp *normal) {
                    normal.labelEqual([PYLabel initPYLabelWithBlock:^(PYLabel *label) {
                        label.showEqual(YES).positionEqual(@"inside");
                    }]);
                }]);
            }])
            .dataEqual(barValues[1]);
            
        }])
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.stackEqual(@"事件類型")
            .nameEqual(@"已銷項(xiàng)")
            .typeEqual(PYSeriesTypeBar)
            .itemStyleEqual([PYItemStyle initPYItemStyleWithBlock:^(PYItemStyle *itemStyle) {
                itemStyle.normalEqual([PYItemStyleProp initPYItemStylePropWithBlock:^(PYItemStyleProp *normal) {
                    normal.labelEqual([PYLabel initPYLabelWithBlock:^(PYLabel *label) {
                        label.showEqual(YES).positionEqual(@"inside");
                    }]);
                }]);
            }])
            .dataEqual(barValues[2]);
        }])
        .addSeries([PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.stackEqual(@"事件類型")
            .nameEqual(@"新增事件")
            .typeEqual(PYSeriesTypeBar)
            .dataEqual(barValues[3]);
        }]);
        
    }];
    
    [chartView setOption:option];
    [chartView loadEcharts];
}

可以看到實(shí)現(xiàn)柱狀圖的效果的關(guān)鍵就是stackEqual,nameEqual這兩個(gè)屬性,大家可以嘗試一下,設(shè)置幾個(gè)不同的stackEqual,柱狀圖就會(huì)呈現(xiàn)一個(gè)X軸對(duì)應(yīng)多個(gè)柱子的效果,具體的效果以及代碼我都寫在Demo中了,Demo會(huì)在文章最下面的地址中給大家下載。

其實(shí)以上兩個(gè)界面的實(shí)現(xiàn)ios-charts這個(gè)組件也可以輕松的做到,我覺得不太方便的地方就是,這個(gè)組件面對(duì)混合圖表的設(shè)置看起來有那么一絲絲不太友好,導(dǎo)致我回去鉆研了兩天ECharts。

混合圖表

這種條形圖加折線圖的混合顯示圖表還是花了我一點(diǎn)時(shí)間去看文檔
的,先去看了一下JS代碼中如何設(shè)置雙Y軸,再回到iOS的項(xiàng)目中試試能不能找到設(shè)置雙Y軸JS同名屬性,如何設(shè)置坐標(biāo)的顯示格式等等,所以推薦大家遇到自己不太知道的實(shí)現(xiàn)方式時(shí),去看看百度文檔中的JS代碼的設(shè)置,再去ECharts中尋找同名屬性去試試,我也是慢慢試出來的。

關(guān)鍵實(shí)現(xiàn)代碼:

//Y軸的設(shè)置變成一個(gè)數(shù)組,裝入了兩個(gè)Y軸
.addYAxisArr(@[[PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeValue);
            //位置靠左
            axis.positionEqual(PYPositionLeft);
            
        }],[PYAxis initPYAxisWithBlock:^(PYAxis *axis) {
            axis.typeEqual(PYAxisTypeValue);
            //位置靠右
            axis.positionEqual(PYPositionRight);
            //顯示格式為百分比
            axis.axisLabel.formatterEqual(@"{value} %");
        }]])
[PYCartesianSeries initPYCartesianSeriesWithBlock:^(PYCartesianSeries *series) {
            series.stackEqual(@"事件類型");
            series.nameEqual(@"銷項(xiàng)率");
            series.yAxisIndexEqual(@(1))
            //設(shè)置類型為Line(折線)
            .typeEqual(PYSeriesTypeLine)
            .dataEqual(lineValues)
            .itemStyleEqual([PYItemStyle initPYItemStyleWithBlock:^(PYItemStyle *itemStyle) {
                itemStyle.normalEqual([PYItemStyleProp initPYItemStylePropWithBlock:^(PYItemStyleProp *normal) {
                    normal.borderColorEqual([PYColor colorWithHexString:@"#fff"])
                    .borderWidthEqual(@2)
                    //設(shè)置折線上label顯示的內(nèi)容
                    .labelEqual([PYLabel initPYLabelWithBlock:^(PYLabel *label) {
                        //  折線內(nèi)容顯示位置
                        label.positionEqual(@"inside")
                        //顯示為百分比
                        .formatterEqual(@"{c}%")
                        //文字顏色
                        .textStyleEqual([PYTextStyle initPYTextStyleWithBlock:^(PYTextStyle *textStyle) {
                            textStyle.colorEqual([PYColor colorWithHexString:@"#fff"]);
                        }]);
                    }]);
                }]);
            }]);
        }]]);

以上就是幾種柱狀圖的實(shí)現(xiàn)方式,應(yīng)該夠大部分場景使用了,我的demo中還封裝了簡單的餅狀圖環(huán)狀圖,有新的圖表效果封裝我會(huì)持續(xù)更新demo,大家對(duì)照我的博客和demo理解了之后完全可以針對(duì)自己的項(xiàng)目做更好的封裝,我這個(gè)為了趕工可能有點(diǎn)粗糙,如果有幫到你就幫我點(diǎn)個(gè)贊就好啦。

Demo地址:ZRChartsHelper

最后編輯于
?著作權(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),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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