美文网首页『ios』进阶iOS开发之常用技术点iOS新手学习
『ios』echarts放到原生中所带来的极致体验。

『ios』echarts放到原生中所带来的极致体验。

作者: butterflyer | 来源:发表于2018-10-10 16:27 被阅读26次
    image.png

    需求驱动开发。

    因项目需求,需要在app中搞大量的表格。当然相如什么charts,pncharts等原生插件也可以用,之前也用过,但是因为他们可以说没有什么文档,当时踩过不少坑,纯靠猜属性是什么意思。所以,决定选择echarts来实现。
    但是如何使用echarts才能让其达到跟原生一样的体验,不会出现白屏,不会加载缓慢?
    so,继续往下看。

    首先我们肯定知道,html css js什么的放到本地,加载的速度肯定比下载的快,毕竟一个echarts.conmmon.min.js文件都有0.5M大小。
    还有webview的选型,选择的wkwebview,虽然wkwebview肯定是有不少坑,但是,毕竟快啊。
    最后一点,对于数据的获取,如果是通用的图表,会让服务器来拼数据。如果不是通用的图表,我选择在本地model中拼option,直接拿来用。
    置于传值什么的,直接走js 交互,还是很简单的。

    第一步

    首先自定义了一个BaseWKWebView

    -(WKWebView *)webView{
        if (!_webView) {
    //        self.userInteractionEnabled= NO;
            self.userInteractionEnabled = true;
            WKWebViewConfiguration * configuration = [[WKWebViewConfiguration alloc]init];
            configuration.preferences.javaScriptEnabled = YES;//打开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;//打开网页间的 滑动返回
            _webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
    //        //监控进度
    //        [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
            [self addSubview:_webView];
        }
        return _webView;
    }
    
    

    然后就开始遇到坑了,看下面这两个方法,就是坑所在的地方,刚开始一直用第一个方法,然后总是取不到css和js的路径,最后发现是没搞根目录,也就是第二个方法。

    -(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];
    }
    
    

    第二步

    在这里先看下服务器返回的格式 数据格式

    然后根据数据格式抽了一个model出来。

    @property (nonatomic, retain) NSMutableArray * target_source;       // 按钮数据源
    @property (nonatomic, retain) NSMutableArray * timeAxis;            // 横坐标
    @property (nonatomic, retain) NSMutableArray * source;              // 数据
    

    在这里我们从baseWKwebView里抽个代理方法出来。然后在app中的wkwebview加载完毕的时候把数据通过js交互注入进去。

    #pragma mark -- BaseWkWebViewDelegate
    - (void)baseWkWebView:(BaseWKWebView *)baseWkWebView didFinishNavigation:(WKNavigation *)navigation {
        [self loadBaseWKWebview:self.chartModel];
    }
    
    // 监测数据是否取到,未取到数据隔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调用js的方法。

    /**
     *  webview调用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

    该来看看放在本地的html里都是写的什么了。

    <!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 = [];
                // 指定图表的配置项和数据
                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
                };
            
            /**
             *  设置图数据
             *  keys:[key1,key2,...]   下面这个是拼接数据格式option   具体格式可以去echars官网去看
             */
            function setKeys(keys){
                //  设置图数据
                var yAxis = [];
                var series = [];
                keys.push({name:'默认',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调用的js方法注入数据
                //  组装数据
                 data.source.map(d=>{
                     source[d.key] = d;//把数据抽成一个数组里面是key value形式。
                 })
                 timeAxis = data.timeAxis;//直接给x轴
                 setKeys([]);//这个方法是默认选中
            }
            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

    不管是从加载速度还是响应速度都跟原生相差无几。

    当遇到需要定制化的图的时候,可以在本地拼接option,同样走交互传到html中

    /**
     *  model转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;
    }
    
    

    深坑更新中。。

    为了实现这个效果


    image.png image.png

    首先是push是把数组后面添加元素,unshift是往首位添加元素。
    如果不用unshift的话就会面临,series_obj['yAxisIndex'] 对不上的情况。

    ios自习室欢迎进入,一起学习一起进步。

    IMG_7291.JPG

    相关文章

      网友评论

        本文标题:『ios』echarts放到原生中所带来的极致体验。

        本文链接:https://www.haomeiwen.com/subject/apuyaftx.html