『ios』echarts放到原生中所帶來(lái)的極致體驗(yàn)。

image.png

需求驅(qū)動(dòng)開(kāi)發(fā)受葛。

因項(xiàng)目需求题涨,需要在app中搞大量的表格。當(dāng)然相如什么charts总滩,pncharts等原生插件也可以用携栋,之前也用過(guò),但是因?yàn)樗麄兛梢哉f(shuō)沒(méi)有什么文檔咳秉,當(dāng)時(shí)踩過(guò)不少坑,純靠猜屬性是什么意思鸯隅。所以澜建,決定選擇echarts來(lái)實(shí)現(xiàn)。
但是如何使用echarts才能讓其達(dá)到跟原生一樣的體驗(yàn)蝌以,不會(huì)出現(xiàn)白屏炕舵,不會(huì)加載緩慢?
so跟畅,繼續(xù)往下看咽筋。

首先我們肯定知道,html css js什么的放到本地徊件,加載的速度肯定比下載的快奸攻,畢竟一個(gè)echarts.conmmon.min.js文件都有0.5M大小蒜危。
還有webview的選型,選擇的wkwebview睹耐,雖然wkwebview肯定是有不少坑辐赞,但是,畢竟快啊硝训。
最后一點(diǎn)响委,對(duì)于數(shù)據(jù)的獲取,如果是通用的圖表窖梁,會(huì)讓服務(wù)器來(lái)拼數(shù)據(jù)赘风。如果不是通用的圖表,我選擇在本地model中拼option纵刘,直接拿來(lái)用邀窃。
置于傳值什么的,直接走js 交互彰导,還是很簡(jiǎn)單的蛔翅。

第一步

首先自定義了一個(gè)BaseWKWebView

-(WKWebView *)webView{
    if (!_webView) {
//        self.userInteractionEnabled= NO;
        self.userInteractionEnabled = true;
        WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
        configuration.preferences.javaScriptEnabled = YES;//打開(kāi)js交互
        _webConfiguration = configuration;
//        _jsHandler = [[XLJSHandler alloc]initWithViewController:self configuration:configuration];
        _webView = [[WKWebView alloc]initWithFrame:self.bounds configuration:configuration];
        [_webView setOpaque:NO];
        _webView.scrollView.backgroundColor = [UIColor clearColor];
        _webView.scrollView.scrollEnabled = false;
        _webView.navigationDelegate = self;
        _webView.backgroundColor = [UIColor clearColor];
//        _webView.allowsBackForwardNavigationGestures =YES;//打開(kāi)網(wǎng)頁(yè)間的 滑動(dòng)返回
        _webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
//        //監(jiān)控進(jìn)度
//        [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
        [self addSubview:_webView];
    }
    return _webView;
}

然后就開(kāi)始遇到坑了,看下面這兩個(gè)方法,就是坑所在的地方位谋,剛開(kāi)始一直用第一個(gè)方法山析,然后總是取不到css和js的路徑,最后發(fā)現(xiàn)是沒(méi)搞根目錄掏父,也就是第二個(gè)方法笋轨。

-(void)setLocalUrl:(NSString *)localUrl{
    NSURL * url = [[NSBundle mainBundle] URLForResource:localUrl withExtension:@"html"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
}

-(void)setLocalUrl:(NSString *)localUrl subdirectory:(NSString *)subdirectory {
    NSURL * url = [[NSBundle mainBundle] URLForResource:localUrl withExtension:@"html" subdirectory:subdirectory];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [self.webView loadRequest:request];
}

第二步

在這里先看下服務(wù)器返回的格式 數(shù)據(jù)格式

然后根據(jù)數(shù)據(jù)格式抽了一個(gè)model出來(lái)。

@property (nonatomic, retain) NSMutableArray * target_source;       // 按鈕數(shù)據(jù)源
@property (nonatomic, retain) NSMutableArray * timeAxis;            // 橫坐標(biāo)
@property (nonatomic, retain) NSMutableArray * source;              // 數(shù)據(jù)

在這里我們從baseWKwebView里抽個(gè)代理方法出來(lái)赊淑。然后在app中的wkwebview加載完畢的時(shí)候把數(shù)據(jù)通過(guò)js交互注入進(jìn)去爵政。

#pragma mark -- BaseWkWebViewDelegate
- (void)baseWkWebView:(BaseWKWebView *)baseWkWebView didFinishNavigation:(WKNavigation *)navigation {
    [self loadBaseWKWebview:self.chartModel];
}

// 監(jiān)測(cè)數(shù)據(jù)是否取到,未取到數(shù)據(jù)隔0.4秒獲取一次
- (void)loadBaseWKWebview:(QuotesChartModel *)data {
    if (!data) {
        [self performSelector:@selector(loadBaseWKWebview:) withObject:self.chartModel afterDelay:0.4];
        return;
    }
    NSString * jsonStr = [[data mj_keyValues] mj_JSONString];
    [self.chartView jsFuncationName:@"setData" params:@[jsonStr]];
}

下面的是webview調(diào)用js的方法陶缺。

/**
 *  webview調(diào)用JS方法
 */
-(void)jsFuncationName:(NSString *)funcation params:(NSArray *)params {
    NSString * params_str = [params componentsJoinedByString:@","];
    NSString * js = [NSString stringWithFormat:@"%@(%@)",funcation,params_str];
    [self.webView evaluateJavaScript:js completionHandler:nil];
}

第三步

image.png

該來(lái)看看放在本地的html里都是寫(xiě)的什么了钾挟。

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
                <meta http-equiv="X-UA-Compatible" content="ie=edge">
                    <link type="text/css" rel="stylesheet" href="./CSS/common.css">//引入css
                        <title>Document</title>
    </head>
    <body>
        <script type="text/javascript" src="./modules/echarts.common.min.js"></script>//引入js文件
        <div id="sc_chart" style="width: 100%;height:100%"></div>
        <script type="text/javascript">
            var source = [];
            var timeAxis = [];
            // 指定圖表的配置項(xiàng)和數(shù)據(jù)
            var option = {
                dataZoom:{
                    type:'inside'
                },
                tooltip: {
                    trigger: 'axis',
                    axisPointer: {
                        type: 'line',
                        label: {
                            backgroundColor: '#343A45'
                        }
                    }
                },
                grid:{
                    top:'0px',
                    bottom:'30px',
                    left:'0px',
                    right:'0px',
                },
                xAxis: {},
                yAxis: [],
                series: [],
                animationThreshold:false
            };
        
        /**
         *  設(shè)置圖數(shù)據(jù)
         *  keys:[key1,key2,...]   下面這個(gè)是拼接數(shù)據(jù)格式option   具體格式可以去echars官網(wǎng)去看
         */
        function setKeys(keys){
            //  設(shè)置圖數(shù)據(jù)
            var yAxis = [];
            var series = [];
            keys.push({name:'默認(rèn)',key:'default',color:'#FFFFFF'})
            keys.forEach((d,index) => {
             if (source.hasOwnProperty(d.key)) {
                 var obj = source[d.key];
                 var color = d.color ? d.color : '#fff'
                 var name = obj.data['yAxis']['name'];
                 var unit = obj.data['yAxis']['unit'];
                 
             var yAxis_obj = {
                 show:false,
             }
             var series_obj = obj.data['series']
             series_obj['symbol'] = 'circle';
             series_obj['lineStyle'] = {width:0.5};
             series_obj['yAxisIndex'] = index;
             series_obj["itemStyle"] = {
                 normal:{
                     color:d.color,
                 }
             },
             series.push(series_obj)
             yAxis.push(yAxis_obj);
             }
             });
             option.yAxis = yAxis;
             option.xAxis = {
                 axisLabel: {color:  "#fff"},
                 data:timeAxis,
                 fontSize:9,
             }
             option.series = series;
             var echartsDom = document.getElementById('sc_chart');
             echartsDom.removeAttribute("_echarts_instance_");
             var myChart = echarts.init(echartsDom);
             myChart.setOption(option);
             window.addEventListener('resize', function () {
                 myChart.resize();
             })
        }
        function setData(data){ //webview調(diào)用的js方法注入數(shù)據(jù)
            //  組裝數(shù)據(jù)
             data.source.map(d=>{
                 source[d.key] = d;//把數(shù)據(jù)抽成一個(gè)數(shù)組里面是key value形式。
             })
             timeAxis = data.timeAxis;//直接給x軸
             setKeys([]);//這個(gè)方法是默認(rèn)選中
        }
        function setOption(opt){
            option = opt;
            var echartsDom = document.getElementById('sc_chart');
            echartsDom.removeAttribute("_echarts_instance_");
            var myChart = echarts.init(echartsDom);
            myChart.setOption(option);
            window.addEventListener('resize', function () {
                myChart.resize();
            })
        }
        </script>
    </body>
</html>

下面是具體效果饱岸。


QQ20181010-161525-HD.gif

不管是從加載速度還是響應(yīng)速度都跟原生相差無(wú)幾掺出。

當(dāng)遇到需要定制化的圖的時(shí)候,可以在本地拼接option苫费,同樣走交互傳到html中

/**
 *  model轉(zhuǎn)chartOption
 */
- (NSDictionary *)chartOptionByModel{
    NSDictionary * option = [NSDictionary dictionary];
    NSMutableArray * out_arr = [NSMutableArray array];
    for (id value in self.outAxis) {
        NSInteger v = 0 - [value doubleValue];
        [out_arr addObject:[NSNumber numberWithInteger:v]];
    };
    option = @{
               @"dataZoom":@{
                       @"type":@"inside"
                       },
               @"tooltip":@{
                       @"trigger":@"axis",
                       @"axisPointer":@{
                               @"type":@"line",
                               }
                       },
               @"grid":@[@{
                             @"left":@"0px",
                             @"right":@"0px",
                             @"bottom":@"30px",
                             @"top":@"0px",
                        }],
               @"xAxis":@{@"axisLabel": @{@"color":@"#fff"},
                          @"data":self.timeAxis,
                          @"axisLine":@{@"show":[NSNumber numberWithBool:false]},
                          @"axisTick":@{@"show":[NSNumber numberWithBool:false]},
                          @"fontSize":@"9"},
               @"yAxis":@[@{
                              @"show":[NSNumber numberWithBool:false],
                              @"inverse": @0,
                            },
                          @{
                              @"show":[NSNumber numberWithBool:false],
                          }],
               @"series":@[@{
                               @"type":@"bar",
                               @"name": @"In",
                               @"stack": @"one",
                               @"barMaxWidth": @"60px",
                               @"data":self.inAxis,
                               @"itemStyle":@{
                                       @"normal": @{
                                                    @"color": @"#FA5452"
                                                    },
                                        }
                            },
                           @{
                               @"type":@"bar",
                               @"name": @"Out",
                               @"stack": @"one",
                               @"barMaxWidth": @"60px",
                               @"data":out_arr,
                               @"itemStyle":@{
                                       @"normal": @{
                                               @"color": @"#3CC28C"
                                               },
                                       }
                            }]
               };
    return option;
}

深坑更新中汤锨。。

為了實(shí)現(xiàn)這個(gè)效果


image.png
image.png

首先是push是把數(shù)組后面添加元素百框,unshift是往首位添加元素闲礼。
如果不用unshift的話(huà)就會(huì)面臨,series_obj['yAxisIndex'] 對(duì)不上的情況。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末柬泽,一起剝皮案震驚了整個(gè)濱河市慎菲,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌聂抢,老刑警劉巖钧嘶,帶你破解...
    沈念sama閱讀 211,290評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異琳疏,居然都是意外死亡有决,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)空盼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)书幕,“玉大人,你說(shuō)我怎么就攤上這事揽趾√ɑ悖” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,872評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵篱瞎,是天一觀的道長(zhǎng)苟呐。 經(jīng)常有香客問(wèn)我,道長(zhǎng)俐筋,這世上最難降的妖魔是什么牵素? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,415評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮澄者,結(jié)果婚禮上笆呆,老公的妹妹穿的比我還像新娘。我一直安慰自己粱挡,他們只是感情好赠幕,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著询筏,像睡著了一般榕堰。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上嫌套,一...
    開(kāi)封第一講書(shū)人閱讀 49,784評(píng)論 1 290
  • 那天局冰,我揣著相機(jī)與錄音,去河邊找鬼灌危。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碳胳,可吹牛的內(nèi)容都是我干的勇蝙。 我是一名探鬼主播,決...
    沈念sama閱讀 38,927評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼挨约,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼味混!你這毒婦竟也來(lái)了产雹?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,691評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤翁锡,失蹤者是張志新(化名)和其女友劉穎蔓挖,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體馆衔,經(jīng)...
    沈念sama閱讀 44,137評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘟判,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評(píng)論 2 326
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了角溃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拷获。...
    茶點(diǎn)故事閱讀 38,622評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖减细,靈堂內(nèi)的尸體忽然破棺而出匆瓜,到底是詐尸還是另有隱情,我是刑警寧澤未蝌,帶...
    沈念sama閱讀 34,289評(píng)論 4 329
  • 正文 年R本政府宣布驮吱,位于F島的核電站,受9級(jí)特大地震影響萧吠,放射性物質(zhì)發(fā)生泄漏左冬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評(píng)論 3 312
  • 文/蒙蒙 一怎憋、第九天 我趴在偏房一處隱蔽的房頂上張望又碌。 院中可真熱鬧,春花似錦绊袋、人聲如沸毕匀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)皂岔。三九已至,卻和暖如春展姐,著一層夾襖步出監(jiān)牢的瞬間躁垛,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工圾笨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留教馆,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,316評(píng)論 2 360
  • 正文 我出身青樓擂达,卻偏偏與公主長(zhǎng)得像土铺,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容