基于Echarts+百度地图+Three.js的数据可视化系统

Posted 修复BUG中

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于Echarts+百度地图+Three.js的数据可视化系统相关的知识,希望对你有一定的参考价值。

上周重构项目数据统计部分写了几篇echarts相关的文章,重构的后台前端框架改用Vue,关于Vue中引用Echarts及可能遇到的问题的文章如下所示:


其中提到大学的时候echarts教程较少,想要做一些理想效果比较麻烦,正好记得大三的时候写了一个,基于Echarts+Three.js+百度地图的数据可视化系统,当时这个系统参加了计算机设计大赛,是拿了安徽省一等奖,全国二等奖,里面有写了几个关于Echarts的样式,当时的技术还比较菜,系统里面的代码仅供参考。

系统介绍视频【比赛演示视频】

基于Echarts+百度地图+Three.js的数据可视化系统

下面就介绍下系统用到的Echarts+百度地图+Three.js:

一、Echarts开发介绍

关于echarts图表部分以下面这个图表进行介绍

这个图表使用的是带有涟漪特效动画的散点(气泡)图,利用动画特效可以将某些想要突出的数据进行视觉突出,在图表配置文件series中将type值设置成effectScatter就可以了。

上面效果的话,首先是把图表自带的一些样式给隐藏,主要在xAxis和yAxis更改一些属性,然后在series设置气泡的样式。关于鼠标在图表内移动展示的提示部分,主要是修改默认的提示框组件样式,将formatter方法返回的内容自定义成自己开发的组件样式,提示框组件部分如下所示:


// 该部分只是布局代码,样式写在上面的样式内
tooltip: {
    trigger: 'axis',
    axisPointer: {
        type: 'cross'
    },
        formatter: function (params) { // 当鼠标在图表的区域,设置提示栏的CSS样式
        return '<div class="echarts"><table><tr><td colspan=2""><img src="../libs/img/p.gif"></td></tr><tr><td>消防员姓名</td><td>' + params[0].name + '</td></tr><tr><td>所在楼层</td><td>' + params[0].value + '</td></tr><tr><td>当前温度</td><td>30</td></tr><tr><td>当前气压</td><td>20</td></tr><tr><td>状态</td><td>移动</td></tr></table> <img src="../libs/img/bj-1.png" alt="" class="bj-1"><img src="../libs/img/bj-2.png" alt="" class="bj-2"> <img src="../libs/img/bj-3.png" alt="" class="bj-3"><img src="../libs/img/bj-4.png" alt="" class="bj-4"></div>';
    }
}

// 其中params参数里面包含了当前位置X轴、Y轴的数据

该图表代码如下所示【系统源码下载:h5-simple-visualization】:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" name="viewport"/>
    <title></title>

    <!--  引入echarts  -->
    <script src="../libs/js/echarts.js"></script>

    <style type="text/css">
        html, body {
            overflow: hidden;
            height: 100%;
            background: linear-gradient(#104BAA, #000000);
            margin: 0;
            padding: 0;
        }
        p, ul, li {
            margin: 0;
            padding: 0;
            list-style-type: none;
        }
        .index {
            margin-top: 135px;
        }
        .index .tit {
            width: 100%;
            height: 50px;
            font-size: 25px;
            text-align: center;
            font-family: Arial, 华文新魏;
            font-weight: bold;
            line-height: 50px;
            border-radius: 20px;
            color: #00FFCC;
            border-bottom: 1px solid #0099ff;
            box-shadow: 0 0 15px 1px #20558b;
        }
        .index .box {
            width: 96%;
            height: 1200px;
            margin-left: 2%;
            margin-top: 120px;
            border: 1px solid #0099ff;
            box-shadow: 0 0 15px 1px #20558b;
            border-radius: 25px;
        }
        .index .echart {
            width: 96%;
            height: 575px;
            margin-top: 20px;
            margin-left: 2%;
            padding-top: 20px;
            background-color: rgba(0, 24, 106, 0.5);
            border: 1px solid #20558b;
            box-shadow: 0 0 15px 1px #20558b;
            position: relative;
        }
        .index #main {
            width: 100%;
            height: 600px;
        }
        .echarts {
            width: 200px;
            height: 250px;
            color: #00FFCC;
            font-size: 20px;
            font-family: Arial, 华文新魏;
            background-color: rgba(0, 24, 106, 0.5);
            border: 1px solid #20558b;
            box-shadow: 0 0 15px 1px #20558b;
            position: relative;
        }
        .moddle {
            width: 96%;
            height: 500px;
            margin-top: 10px;
            margin-left: 2%;
            background-color: rgba(0, 24, 106, 0.5);
            border: 1px solid #20558b;
            box-shadow: 0 0 15px 1px #20558b;
            position: relative;
        }
        .moddle .ifra {
            width: 96%;
            height: 470px;
            margin-left: 2%;
            margin-top: 12px;
        }
        table {
            width: 100%;
            height: 250px;
            text-align: center;
            padding-top: 10px;
        }
        table img {
            width: 100%;
            height: 80px;
        }
        .bj-1 {
            position: absolute;
            left: -1px;
            top: -1px;
        }
        .bj-2 {
            position: absolute;
            right: -1px;
            top: -1px;
        }
        .bj-3 {
            position: absolute;
            right: -1px;
            bottom: -1px;
        }
        .bj-4 {
            position: absolute;
            left: -1px;
            bottom: -1px;
        }
    </style>
</head>
<body>
<div class="index">
    <div class="box">
        <div class="tit">
            消防员信息实时监控
        </div>
        <div class="moddle">
            <iframe class="ifra" src="../libs/model/showModel.html">
            </iframe>
            <img alt="" class="bj-1" src="../libs/img/bj-1.png">
            <img alt="" class="bj-2" src="../libs/img/bj-2.png">
            <img alt="" class="bj-3" src="../libs/img/bj-3.png">
            <img alt="" class="bj-4" src="../libs/img/bj-4.png">
        </div>
        <div class="echart">
            <div id="main">
            </div>
            <img alt="" class="bj-1" src="../libs/img/bj-1.png">
            <img alt="" class="bj-2" src="../libs/img/bj-2.png">
            <img alt="" class="bj-3" src="../libs/img/bj-3.png">
            <img alt="" class="bj-4" src="../libs/img/bj-4.png">
        </div>
    </div>
</div>
</body>
</html>

<script>
    
    // 获取图表的ID值,并设置图表的主题风格
    let myChart = echarts.init(document.getElementById('main'), 'walden');

    let option = {
        title: {
            text: '所在楼层/层',
            left: '5%',
            textStyle: {
                color: '#00FFCC',
                fontFamily: '华文新魏',
                fontWeight: 'bold',
                fontSize: '25',
                align: 'center'
            }
        },
        tooltip: {
            trigger: 'axis',
            axisPointer: {
                type: 'cross'
            },
                formatter: function (params) { // 当鼠标在图表的区域,设置提示栏的CSS样式
                return '<div class="echarts"><table><tr><td colspan=2""><img src="../libs/img/p.gif"></td></tr><tr><td>消防员姓名</td><td>' + params[0].name + '</td></tr><tr><td>所在楼层</td><td>' + params[0].value + '</td></tr><tr><td>当前温度</td><td>30</td></tr><tr><td>当前气压</td><td>20</td></tr><tr><td>状态</td><td>移动</td></tr></table> <img src="../libs/img/bj-1.png" alt="" class="bj-1"><img src="../libs/img/bj-2.png" alt="" class="bj-2"> <img src="../libs/img/bj-3.png" alt="" class="bj-3"><img src="../libs/img/bj-4.png" alt="" class="bj-4"></div>';
            }
        },
        toolbox: {
            show: true,
            right: '100',
            itemGap: 20,
            itemSize: '20',
            feature: {
                dataZoom: {
                    yAxisIndex: 'none'
                },
                dataView: {
                    readOnly: false
                },
                magicType: {
                    type: ['pictorialBar', 'bar']
                },
                restore: {},
                saveAsImage: {}
            },
            iconStyle: {
                borderColor: '#00FFCC'
            }
        },
        xAxis: {
            data: ['消1号', '消2号', '消3号', '消4号', '消5号'],
            axisTick: {
                show: true
            },
            axisLine: {
                show: false
            },
            axisLabel: {
                textStyle: {
                    color: '#00FFCC',
                    fontFamily: '华文新魏',
                    fontWeight: 'bold',
                    fontSize: '20',
                }
            }
        },
        yAxis: {
            splitLine: {
                show: false
            },
            axisTick: {
                show: true
            },
            axisLine: {
                show: false
            },
            axisLabel: {
                show: true,
                textStyle: {
                    color: '#00FFCC',
                    fontFamily: '华文新魏',
                    fontWeight: 'bold',
                    fontSize: '20',
                }
            }

        },
        color: ['#ffffff'],
        series: [{
            name: '海拔高度',
            type: 'effectScatter',
            rippleEffect: {
                brushType: 'stroke'
            },
            symbolSize: 25,
            hoverAnimation: true,
            barCategoryGap: '-130%',
            symbol: 'circle',
            itemStyle: {
                normal: {
                    color: '#FF00FF'
                },
                emphasis: {
                    color: '#FF00FF'
                }
            },
            data: [5, 0, 1, 5, 3],
            z: 10
        }],
    };

    myChart.setOption(option);

    // 设置点击跳转方法,并传送图表X属性的值
    myChart.on('click', function (params) {
        if (params.name == '') {
            window.open('new_data.html?a=' + encodeURIComponent(params.name) + '');
        }
    });
</script>

二、百度地图开发介绍

系统使用百度地图主要是展示在地图上添加一些覆盖物,然后点击覆盖物到其详情页介绍,下面介绍接入流程:

因为这里用的是百度地图,首先的话要去百度地图开发者中心注册成为开发者,然后再控制台应用管理新建一个应用,应用类型选择浏览器端,白名单填写*即可,然后就能拿到应用的key,根据key的话就能调用百度地图。

因为我这个是两年前的系统,用到的地图代码和现在的不同,首先new的地图实例都改变了,具体的可以看下最新的文档。

主要就介绍下面几个方法:

  1. createMap内Point里面是想要进入地图展示的位置,如下的经纬度和setCurrentCity方法设置的是滁州,进入系统地图就会缩进到滁州那里。
  2. addMapOverlay方法就是设置地图上面的覆盖物,也就是想要在地图上面展示的自己的内容如上面的提示框组件,这里就是循环覆盖物数组,根据经纬度逐次展示覆盖物。
  3. styleMap方法就是改变地图的样式,这里的话官方提供了工具个性化地图编辑器,我用的是官方的【眼眸】样式,在官网生成JSON文件,然后在styleJson设置下就行

百度地图代码如下所示【项目源码下载:h5-simple-visualization】:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
    <title></title>

    <!--  引入百度地图,这里的key填写自己开发者创建应用的key -->
    <script src="http://api.map.baidu.com/api?v=2.0&ak=" type="text/javascript"></script>

    <!--  加载鼠标绘制工具  -->
    <script src="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.js" type="text/javascript"></script>
    <link href="http://api.map.baidu.com/library/DrawingManager/1.4/src/DrawingManager_min.css" rel="stylesheet"/>

    <!--  加载检索信息窗口  -->
    <script src="http://api.map.baidu.com/library/SearchInfoWindow/1.4/src/SearchInfoWindow_min.js" type="text/javascript"></script>
    <link href="http://api.map.baidu.com/library/SearchInfoWindow/1.4/src/SearchInfoWindow_min.css" rel="stylesheet"/>

</head>
<body>
<div class="v_box">
    <div class="v_map" id="map" style="width: 100%;height: 500px;">
    </div>
</div>
</body>
<script type="text/javascript">

    // 初始化地图
    let map;
    initMap();

    // 创建和初始化地图函数:
    function initMap() {
        createMap();      //创建地图
        setMapEvent();    //设置地图事件
        addMapControl();  //向地图添加控件
        addMapOverlay();  //向地图添加覆盖物
        styleMap();     //地图个性化模板
    }

    function createMap() {
        map = new BMap.Map("map");
        map.centerAndZoom(new BMap.Point(118.339637, 32.305602), 15);
        map.addControl(new BMap.MapTypeControl({
            mapTypes: [
                BMAP_NORMAL_MAP,
                BMAP_HYBRID_MAP
            ]
        }));

        // 设置地图显示的城市 此项是必须设置的
        map.setCurrentCity("滁州");
        map.enableScrollWheelZoom(true);

        //添加城市列表
        map.enableInertialDragging();
        map.enableContinuousZoom();

        let size = new BMap.Size(10, 10);
        map.addControl(new BMap.CityListControl({
            anchor: BMAP_ANCHOR_TOP_LEFT,
            offset: size,
        }));
    }

    // 添加地图类型和缩略图
    function add_control() {
        map.addControl(mapType1);      // 2D图,卫星图
        map.addControl(mapType2);      // 左上角,默认地图控件
        map.addControl(overView);      // 添加默认缩略地图控件
        map.addControl(overViewOpen);  // 右下角,打开
    }

    function setMapEvent() {
        map.enableScrollWheelZoom();

以上是关于基于Echarts+百度地图+Three.js的数据可视化系统的主要内容,如果未能解决你的问题,请参考以下文章

cesium 和 Three.js有啥区别,以及二者与WebGL 的关系

如何将echarts和百度地图结合

echarts结合百度地图怎么能实现动态刷新,而不需要刷新整个页面

echarts+百度地图API

使用three.js开发3d地图初探

Three.js活地图