echarts画飞机大盘动态航行路线图

这把我C 2021-04-02 15:34:57 9214

飞机航行路线图

前言

我们日常因出差、旅游、接机等需要到机场的时候,会在候机大厅或飞机上看到某航班( 例如 MZ12384 )的航线图。其中会包含该航班的出发点、目的地及航班现在所处的位置。

飞机会通过预先安装的物联网设备进行数据收集并同步上传至服务器后经解析由前端进行可视化展示。

类似如下图:

下文我们将会一步一步的讲解如何构建该数据可视化展示。

需求分析

构建这种多组件集成的功能时我们需要对需求进行拆分、整理。这样才能有一个清晰的逻辑来完成接下来的工作。

那么,首先我们将该功能分成以下几个模块:

  1. 构建背景地图
  2. 设置各个坐标点
  3. 构建坐标点内连线并渲染

技术选型

由于Apache ECharts 的高度集成API和一些已经很完善的组件, 相比于其他可视化库( D3.js
等)更加易于上手和开发。所以我们这次将使用Echarts来进行开发。

如果你对该库不是很熟悉,可以阅读 官方文档
的快速指南,它将快速带你了解 Apache ECharts 的魅力。

环境配置

安装ECharts

​ 如果你不熟悉如何安装Apache ECharts,可以点击下方的官方链接了解:

https://echarts.apache.org/en/tutorial.html#Get%20Started%20with%20ECharts%20in%205%20minutes

说干就干

构建背景地图

首先,我们需要构建一副背景地图。

我们将使用Apache Echarts 提供的 "bmap"( 百度地图API
)模块来构建我们的背景地图。


var option = {
    bmap: {
        center: [119.2166696096, 26.0446365813],
        zoom: 16,
        roam: false,
        mapStyle: {
            styleJson: [{
                featureType: "water",
                elementType: "all",
                stylers: {color: "#021019"}
            },
                {
                    featureType: "arterial",
                    elementType: "geometry.stroke",
                    stylers: {color: "#0b3d51"}
                },
                {
                    featureType: "local",
                    elementType: "geometry",
                    stylers: {color: "#000000"}
                },
                {
                    featureType: "land",
                    elementType: "all",
                    stylers: {color: "#08304b"}
                }
                //  ......  由于代码太长不再粘贴,可以通过下文讲解的[自定义样式系统] 来生成
            ]
        }
    },
    series: []
};
地图效果图

为了突出飞行轨道和标点,我们采用了深蓝色的背景。并隐藏了一些文字和建筑。

API讲解:
  • center:百度地图中心的经纬度,例如天安门的坐标【 116.403963,39.915118 】,则地图将会以该点为中心进行展示。

    如果嫌取坐标麻烦的话则可以使用百度地图提供的 坐标拾取系统 来获取坐标。

  • zoom:既然有了中心,那么必然要有比例大小,这个值就是地图的缩放等级,数字越大则比例尺越小。

  • roam:是否可以拖拽移动或放大缩小

  • mapStyle:百度的自定义样式,类似CSS语法,可以设置地图上展示的元素样式,例如point(兴趣点)、road(道路)、water(河流)、land(陆地)、building(建筑物)等。

如果感觉样式定义填写过于繁杂,可以参考百度地图官方出版的 自定义样式系统

设置坐标点

地图设置完了以后,我们将要设置起点与目标点,这样才能明确飞机飞行的航向。

首先我们先在地图上使用 ECharts 提供的 " effectScatter " 组件来设置第一个点 【 119.2070396626, 26.0471838188 】

var series = [
    {
        name: "1",
        type: "effectScatter",
        coordinateSystem: "bmap",
        zlevel: 2,
        rippleEffect: {
            brushType: "stroke"
        },
        label: {
            normal: {
                show: true,
                position: "right",
                formatter: "{b}"
            }
        },
        symbolSize: function (val) {
            return val[2] / 4;
        },
        showEffectOn: "render",
        itemStyle: {
            normal: {
                color: "#ffa022"
            }
        },
        data: [{
            name: "1",
            value: [119.2070396626, 26.0471838188, 100]
        }]
    }]
API讲解
  • effectScatter:带有涟漪特效动画的散点(气泡)图。利用动画特效可以将某些想要突出的数据进行视觉突出。

  • name: 用于更新数据和配置项时所指定的名称

  • coordinateSystem: 该系列使用的坐标系。文中所使用的为百度地图组件,则我们需要设置此参数为 "bmap"

    可选的其他参数为:

    • cartesian2d : 二维的直角坐标系( 也称笛卡尔坐标系 )通过 xAxisIndex, yAxisIndex指定相应的坐标轴组件。
    • polar : 极坐标系,通过 polarIndex 指定相应的极坐标组件。
    • geo : 地理坐标系,通过 geoIndex 指定相应的地理坐标系组件。
  • zlevel: 用于 Canvas 分层。

    不同zlevel值的图形会放置在不同的 Canvas 中, zlevel 大的 Canvas 会放在 zlevel 小的 Canvas 的上面。

  • rippleEffect: 对涟漪的效果配置。( 见下图 )。

    • color : 颜色。
    • period : 动画的周期,秒数。
    • scale : 动画波纹的最大缩放比例。
    • brushType : 波纹的绘制方式,可选 'stroke' 和 'fill'。

  • label: 配置标签内容。

    • 可以通过改变 position 的值来改变文字的展示位置。( top / left / right / bottom / inside / insideLeft / insideRight 等 )。
    • 改变 formatter 的值来控制其展示的是数据的值还是名称。
      • {a}:系列名。
      • {b}:数据名。
      • {c}:数据值。
  • showEffectOn: 配置何时显示其涟漪特效。

    • 'render' 绘制完成后显示特效。
    • 'emphasis' 高亮(hover)的时候显示特效。
  • data: 数据内容数组。其中name 为显示名称,value 为维度。

    系列中的数据内容数组。数组项通常为具体的数据项。

    在直角坐标系中,第一个和第二个值为 [ xAxis,yAxis ] 而在极坐标系中他们则代表 [ radiusAxis , angleAxis ]

    另外还有其他的值,基于不同组件将该值映射到大小、颜色等不同的属性上。

    例如在本组件中,数组 [119.2070396626, 26.0471838188, 100] 则代表 [ xAxis,yAxis,大小 ]

创建各个点位的坐标

接下来我们参照上面的讲解,将其余的各点也一起标注出来。这次我们将创建12个点位,来模拟3组数据。

为了方便复用,我们将会把一些参数抽离出来。

var geoCoordMap = {
    "1": [119.2070396626, 26.0471838188],
    "2": [119.2147498638, 26.0481609598],
    "3": [119.209339, 26.038355],
    "4": [119.2163806469, 26.0442086921],
    "5": [119.2132263691, 26.0498767809],
    "6": [119.219382299, 26.0524969442],
    "7": [119.2194920093, 26.0496647145],
    "8": [119.2194276363, 26.0475440293],
    "9": [119.225689, 26.044945],
    "10": [119.215699, 26.045237],
    "11": [119.2191260061, 26.0366349971],
    "12": [119.212969, 26.039069]
}
//  三组数据不同颜色
var color = ["#a6c84c", "#ffa022", "#46bee9"];
// 每组的点大小参数
var oneData = [ [
    { name: "1" },
    { name: "2",
      value: 20 }
  ],
  [ { name: "1" },
    { name: "3",
      value: 20
    } ],
  [ { name: "1" },
    { name: "4",
      value: 20
    }
  ]
]
// 参数与oneData类似,避免代码冗余。省略部分代码。
var twoData = [....]  
var threeData = [....]

参数准备好后我们把之前的方法改进一下,通过循环来创建其他点位:

var series = [];
[["1", oneData], ["5", twoData], ["9", threeData]].forEach(function (
    item,
    i
) {
    series.push({
            name: item[0],
            type: "effectScatter",
            coordinateSystem: "bmap",
            zlevel: 2,
            rippleEffect: {brushType: "stroke"},
            label: {
                normal: {
                    show: true,
                    position: "right",
                    formatter: "{b}"
                }
            },
            symbolSize: function (val) {
                return val[2] / 4;
            },
            showEffectOn: "render",
            itemStyle: {
                normal: {color: color[i]}
            },
            data: [{
                name: item[0],
                value: geoCoordMap[item[0]].concat([100])
            }
            ]
        },
        {
            name: item[0] + " Top10",
            type: "effectScatter",
            coordinateSystem: "bmap",
            zlevel: 2,
            rippleEffect: {brushType: "stroke"},
            label: {
                normal: {
                    show: true,
                    position: "right",
                    formatter: "{b}"
                }
            },
            symbolSize: function (val) {
                return val[2] / 4;
            },
            showEffectOn: "render",
            itemStyle: {
                normal: {color: color[i]}
            },
            data: item[1].map(function (dataItem) {
                return {
                    name: dataItem[1].name,
                    value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value])
                };
            })
        }
    );
});
多点渲染效果图

构建坐标点内连线

现在有了各个坐标点,接下来我们将使用 Apache ECharts 提供的 "lines" 组件来进行渲染各点之间的连线

  // 功能性函数,通过循环来构建所需要的参数
    var convertData = function(data) {
      var res = [];
      for (var i = 0; i < data.length; i++) {
        var dataItem = data[i];
        var fromCoord = geoCoordMap[dataItem[1].name];
        var toCoord = geoCoordMap[dataItem[0].name];
        if (fromCoord && toCoord) {
          res.push({
            coords: [fromCoord, toCoord]
          });
        }
      }
      return res;
    };
  // 将该代码填写值上文的循环内
    {
        name: item[0] + " Top10",
        type: "lines",
        coordinateSystem: "bmap",
        zlevel: 2,
        effect: {
            show: true,
            period: 6,
            trailLength: 0,
            symbolSize: 15
        },
        lineStyle: {
            normal: {
                color: color[i],
                width: 1,
                opacity: 0.4,
                curveness: 0.2
            }
        },
        data: convertData(item[1])
    },
效果图

API 讲解

大部分的api之前已经讲过,这里就不再赘述。

  • effect:是否展示上图所示的迁徙特效。
    • show 是否展示
    • period 整个过程所需时间
    • trailLength 移动点位的尾迹的长度
  • data:线数据集。

    其中主要的配置为 coords,它包含两个到多个( 在polyline 模式下 )二维坐标的数组。其中的第一个数组为起点,第二个数组为终点。

到现在为止基本功能已经实现,接下来我们将进行最后一步,对该组件进行美化完善。

最后一步,美化完善

修改小飞机模型

虽然大部分功能已经完成,但是现在组件内的指示点仍为圆形,接下来我们将通过设置 effect.symbol 参数来设置其外观,来完成最后一步。

//小飞机模型
 var planePath =
        "path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z";

//....
effect: {
  show: true,
          period: 6,
          trailLength: 0,
          symbol: planePath, // 设置该值
          symbolSize: 15
}
// ... 
小飞机图样

大功告成

经过对一个项目的讲解,相信大家对 "bmap"、"lines"、"effectScatter" 组件的使用与API的扩展都有了深刻的了解。

大家还不快动动手,一起来尝试体验一下ECharts的魅力吧!

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 96 8 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
这把我C
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区