日常记要 之 Echarts结合百度地图,动态添加不同颜色的markline(markpoint同理)

其实找了网上的资料,大部分是同个颜色的markline,或者没有所谓的定时,很是苦恼,于是自己查找API,解决了实际开发中的问题,今天有空特地拿出来简单整理下,有什么不懂,或者我没说清楚的,欢迎留言,废话不多说,直接开始吧。

根据echarts官方API,动态添加markline需要使用addMarkLine()方法,它接收两个参数:一个seriesIdx系列索引(这里应该是指对应每一条markline的索引值)和一个markData(这里请参考官方API)。

在遇到的实际需求中,要求动态添加传播的路线,并且能够添加根据不同的颜色区分开来。这里遇到的问题主要有一下几个:

  1. 既然是动态添加markline,那么就存在一对多,或者多对一的情况。这个比较好处理,就是在数据中,添加一个表示层级关系的属性,一方面可以表现所谓的层级传播关系,另一方面,在每次传播过程中,同一层不管是一条markline还是多条,都是一样的处理方法;
  2. 颜色的区分,因为实际遇到的情况是层级并不会很多,所以没有做一个专门的Color对象去给每一层随机添加颜色,而是实现定义好一个长度能够满足需求的数组存储颜色值,这样的一个好处是避免随机下颜色接近看不出层级的关系;但是还有一个问题,是涉及到百度地图的,这个留在后面说;
  3. 索引值的问题,既然需要动态添加markline,那么seriesIdx是否动态变化呢,还是每一层一个seriesIdx呢,想知道吗?请耐心往下看吧。

其实上面提到的问题,在单纯用echarts下应该是比较好解决的(虽然我并没有做过测试),但是结合百度地图的话,有个坑这里必须提一下,就是百度地图是可以推动、缩放,以及它和echarts其实是两个东西啊(当然我这里说的是,你动态添加到ecahrts里面的数据,对百度地图来说,根本就不知道啊)。

那么怎么解决呢,上代码吧。

首先关于上面的第1个问题,由于数据是查询出来的,并且业务需求是没有实现规定好一条markline是哪一层,所以值考虑首位是不相同的,也就是开始和结束不在同一个位置,当然中间线的传播是可以的,这个根据具体的业务去处理就可以了。(这里插句话,阿里的 fastjson还是挺好用的,但是在它的JSONArray有点尴尬,有数据冲突(还是相同这个有点忘记了)然后遍历时,会生成一个$ref这样的循环引用的东西出来,简直了,不过JSONObject则不会出现同样的问题)。

 require.config({ // ecahrts引用,这里不做解释了,请自行参考ecahrts的API例子
                paths: {
                    echarts: './lib/echarts'
                },
                packages: [
                    {
                        name: 'BMap',
                        location: './lib/echarts/Bmap',
                        main: 'main'
                    }
                ]
            });
            require(
                [
                    'echarts',
                    'BMap',
                    'echarts/chart/map'
                    // 使用柱map模块,按需加载
                ],
                function (echarts, BMapExtension) {
                    // 初始化地图
                    var BMapExt = new BMapExtension(that.element.find('div')[0], BMap, echarts, {
                        enableMapClick: false
                    });
                    var map = BMapExt.getMap();
                    
                    // 因为这个有实际用途了,所以这里的代码块就不贴出来了,可按照自己的需求实现,具体查看百度地图的API
                    // 这里主要处理的是,设置了百度地图的边界,初始化时显示的区域,以及地图的放大系数
                    ......
                    
                    // 在加载时,以下操作请加上,这里就回答了上面提到的第2个问题,因为echarts在动态加载markline时,其实数据时没有加载进百度地图的(当然我不知道这样说明对不对哈),但百度地图在每次缩放、拖拽时,都会重新渲染页面,导致出现的加载情况不是我们想要的,比如刚才添加的markline不见了,或者所有的markline颜色变得跟当前最后一条添加的markline一样,这些都是应该在这里先处理好,避免它发生。在全部的markline加载完之后,再初始化一下百度地图的数据,那么这个时候恢复百度地图原有的功能,不管怎么渲染,都不会再出现前面的情况。
                    map.disableScrollWheelZoom(); // 禁用滚轮缩放
                    map.disableDoubleClickZoom(); // 禁用双击放大
                    map.disableDragging(); // 禁止拖拽
                    map.disableAutoResize(); // 禁止自适应容器变化


                    // 初始化echarts
                    var fm = '{b}';
                    var count = 0;
                    var option = {
                        color: [],
                        tooltip: {
                            trigger: 'item',
                            formatter: fm
                        },
                        series: []
                    };
                    // 这里是添加鼠标hover在markline上时,显示的指定格式的内容
                    if (!$.isEmptyObject(that.options.tooltip)) {
                        if (that.options.tooltip.formatter && that.options.tooltip.formatter.indexOf('function') > -1) {
                            option.tooltip.formatter = eval('(' + that.options.tooltip.formatter + ')');
                        }
                    }
                  // 添加第一层的markline
                    that.buildMM(null, option, color, geoCoordVar, data, count);
                    // 百度地图获取echarts容器
                    var container = BMapExt.getEchartsContainer();
                    // 初始化
                    myChart = BMapExt.initECharts(container);
                    // 第一次设置option
                    BMapExt.setOption(option, true);


// setInterval的方式动态添加markline,count用来记录当前的层,用以判断是否所有层都已添加
                  var clear = null;
var count = 0;                        
                  clear = setInterval(function () {
                      count++;
                      if (count > level.length) {
                          clear = window.clearInterval(clear);
                          // 第二次设置option,这一步很重要,如果不设置,就会产生前面提到的情况(这真是一个坑,浪费了好多时间)
                         
BMapExt.setOption(option, true);
                          map.enableScrollWheelZoom(); // 允许滚轮缩放
                          map.enableDoubleClickZoom(); // 允许双击放大
                          map.enableDragging();
                      }
                      // 添加下一层的markline
                      that.buildMM(myChart, option, color, geoCoordVar, data, count);
             
              // 其它操作
              ......
                  }, that.options.speed); // speed是指定的添加速度
                });
                
                buildMM: function (myChart, option, color, geoCoordVar, data, count) {
            for (var i = 0; i < data.length; i++) {
              // 在查询结果数据中,level标表示层级关系,这里与count匹配下一层的数据
                if (data[i]['level'] == count) {
                  // 生成markline数据
                    var ml = {
                        smooth: true,
                        effect: {
                            show: false
                        },
                        data: this.getMM(data[i])['markline'],
                        itemStyle: {
                            normal: {
                                color: color[count],
                                borderWidth: 1,
                                lineStyle: {
                                    type: 'solid',
                                    shadowBlur: 20,
                                    color: color[count]
                                }
                            }
                        }
                    };
                    // 由于每一条markline是一个series,并且结合百度地图,所以这里的参数中,需要注意type=map,mepType=none
                    var item = {
                        name: data[i]['name'],
                        type: 'map',
                        mapType: 'none',
                        data: [],
                        markLine: ml,
                        geoCoord: geoCoordVar,
                        itemStyle: {
                            normal: {
                                color: color[count],
                                borderWidth: 1,
                                lineStyle: {
                                    type: 'solid',
                                    shadowBlur: 20,
                                    color: color[count]
                                }
                            }
                        }
                    };
                    // 将当前markline的item添加到series中
                    option.series.push(item);
                    // 调用addMarkLine,这里请注意看,seriesIdx我设置的都是0,如果不设置0,是会报错的,所以也就是这么简单地解决了第三个问题,因为每一个addMarkLine的markline对echarts来时都是新增的(当然这也只是我个人理解)
                        myChart.addMarkLine(
                            0,
                            ml
                        );

                }
            }

        }

以上的代码我没有全部贴出来,但是已经够用了,主要的内容都在里面了。在每个地方基本都有做注释,如有什么说的不对的,欢迎批评指正。

猜你喜欢

转载自blog.csdn.net/wsgjcxy13/article/details/80546226