整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

分享一个大数据可视化大屏看板案例(echarts实现含中国地图)

着大数据时代的来临,社会对大数据人才的需求也日益旺盛,自然少不了我们前端工程师,我们前端工程师能做什么呢?这个自然就是做大数据可视化了,数据再多,没有很直观的呈现那也是白搭。现在好多政府企事业单位对大屏可视化的项目需求日益旺盛,这无疑给我们前端工程更多的机会,那我们如何入手做一款漂亮绚丽的大数据看板呢。

首先展示下我这个项目案例的效果图


这个案例是不是直观呢:

  • 以中国地图的形式展示设备网络分布
  • 各种饼状图、柱状图、折线图数据刷新的效果图
  • 以及各种数据汇总的列表效果

是不是很高科技上档次呢,在来看一段视频的动态效果:


<script src="https://lf3-cdn-tos.bytescm.com/obj/cdn-static-resource/tt_player/tt.player.js?v=20160723"></script>


这款项目是基于echarts实现的

echarts正如官网所说,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。

具有以下特点:

  • 丰富的可视化类型,提供了常规的折线图、柱状图、散点图、饼图、K线图等
  • 多种数据格式无需转换直接使用
  • 千万数据的前端展现
  • 移动端优化
  • 多渲染方案,跨平台使用!
  • 深度的交互式数据探索
  • 多维数据的支持以及丰富的视觉编码手段
  • 动态数据
  • 绚丽的特效
  • 通过 GL 实现更多更强大绚丽的三维可视化

更多介绍请查看官网 https://www.echartsjs.com/zh/index.html

这个项目你需要用到的技术

其实用到的技术很简单,掌握基础的前端就行

  • html 和 css 布局相关的知识
  • jQuery相关基础内容
  • 掌握echarts的基本内容

代码部分

Echart引用代码示例

1、引用 echarts.min.js 文件2、准备div容器

<div id="main"></div>

3、初始化 echart 实例

var myChart = echarts.init(document.getElementById('main'));

4、初始化图表数据,示例代码如下

var option = {
    xAxis: {
        type: 'category',
        data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
    },
    yAxis: {
        type: 'value'
    },
    series: [{
        data: [820, 932, 901, 934, 1290, 1330, 1320],
        type: 'line'
    }]
};

5、显示图表

myChart.setOption(option);

适配说明(rem)

本案例设计稿宽度是1920px,rem 初始基准是24px。

1、如何做适配呢?

保持设备宽度与rem基准值比例为 80 即可

2、这里用JS进行初始化基准,窗口大小改变,就会进行调整,示例代码如下:

(function () {
    // 1、页面一加载就要知道页面宽度计算
    var setFont = function () {
        // 因为要定义变量可能和别的变量相互冲突,污染,所有用自调用函数
        var html = document.documentElement;// 获取html
        // 获取宽度
        var width = html.clientWidth;

        // 判断
        if (width < 1024) width = 1024
        if (width > 1920) width = 1920
        // 设置html的基准值
        var fontSize = width / 80 + 'px';
        // 设置给html
        html.style.fontSize = fontSize;
    }
    setFont();
    // 2、页面改变的时候也需要设置
    // 尺寸改变事件
    window.onresize = function () {
        setFont();
    }
})();

注:计算式可能有小数,很多位,保留3为有效小数,不去除0

基于 flex 布局 和 原生CSS动画

这个页面局基于flex弹性盒子布局,其他的内容都是基于原生的JS写的,动画效果基于CSS3。

如何获取本案例

由于代码比较多,就不在这一一列举了,由于文章不太方便贴下载链接,那怎么获取本案例的代码呢?

  1. 首先关注“前端达人”头条号
  2. 私信回复“大数据案例” 进行索取

建立和优化网站时,站点地图是一个重要的元素。它们是帮助搜索引擎理解和索引网页的工具。HTML站点地图与XML站点地图是两种常见的站点地图格式。虽然它们都用于相同的目的,但它们之间存在一些区别。让我们深入了解HTML站点地图和XML站点地图之间的区别以及它们各自的优势。

HTML站点地图是由HTML代码构建的页面,它为用户提供了对网站结构的可视化展示。当用户浏览网站时,他们可以通过点击链接直接导航到不同的页面。HTML站点地图通常包含网站的主要页面和子页面。它可以像任何其他网页一样被访问,而且能够被搜索引擎和用户轻松理解。这种类型的站点地图更容易创建和更新,因为它们只需使用标准的HTML语法。

然而,HTML站点地图的一个限制是它对于大型网站来说可能不够灵活。当网站的页面数量增加时,持续更新和维护HTML站点地图可能变得耗时且困难。此外,HTML站点地图只能包含有限数量的信息,如果网站有很多页面,可能会导致过于庞大和冗长的HTML代码。这可能会影响到站点地图的可用性和性能。

与之相反,XML站点地图是使用XML语言编写的文件。XML站点地图以一种更结构化的方式呈现网站的组织结构和内容。它们提供的信息不仅限于页面的URL,还可以包含其他相关元数据,如最后更新时间、重要性和变更频率。这使得搜索引擎能够更好地了解网站的内容和层次结构。

XML站点地图的另一个优势是它对于大型网站来说更加适用。由于XML是一种可扩展的标记语言,可以轻松地添加更多页面和元数据,而不会导致文件变得过于复杂和冗长。此外,XML站点地图可以自动创建和更新,通过使用脚本和工具可以轻松地生成XML站点地图。

尽管XML站点地图在技术上更加复杂,但也提供了更多的灵活性和可扩展性。它们为搜索引擎提供了有关网站的更多信息,从而增加了被索引和排名的机会。

尽管HTML站点地图和XML站点地图在某些方面存在差异,但它们并不是互斥的。实际上,在建立一个好的站点地图战略时,可以同时使用这两种格式。HTML站点地图可以用作用户友好的导航工具,而XML站点地图则可以帮助搜索引擎更好地了解和索引网站。

无论您选择哪种类型的站点地图,创建和维护一个完善的站点地图对于网站的SEO至关重要。它们有助于提高网站的索引效率,使搜索引擎更容易找到和了解网站的内容。同时,站点地图还可以改善用户体验,使他们更容易浏览和发现网站的页面。

HTML站点地图和XML站点地图分别采用不同的格式和设计方式,以帮助搜索引擎和用户更好地理解和导航网站。HTML站点地图适用于小型网站和简单的网站结构,而XML站点地图适合大型网站和复杂的内容层次结构。选择合适的站点地图格式取决于您的网站需求和目标。无论您选择哪种类型,保持定期更新和维护是确保站点地图始终有效的关键。

通过正确使用站点地图,您可以增加网站的曝光度,并提供更好的用户体验。无论是HTML站点地图还是XML站点地图,都是优化您的网站并提高搜索引擎排名的重要工具。

在您的下一个网站项目中,不要忘记考虑站点地图。它可能是您获得更多有机流量和改善用户体验的关键因素之一。

取高德地图key

进入高德地图开放平台,注册高德地图账号、登陆、认证为开发者,然后进入个人控制台、创建新应用,在创建的应用上点击“添加key”按钮。


这里我们需要用到的高德地图的JavaScript API ,所以点击添加按钮后我们选择Web 服务的JS API如图


底图切换与图层显示

功能实现

利用高德地图提供的JavaScript API 加载底图,同时增加一个新的地图控件来把原有的标准底图切换到卫星影像底图,方便了用户根据自己的实际需要能够加载恰当的背景地图,当用户点击对应的卫星图层时,底图会切换为卫星影像图,再点击图标,底图会切换为原来的标准底图。同时加入图层显示插件,可以在任一底图之上显示路况路网图层。

  • 关键代码
// 定义一个变量来引入卫星底图API
 var satellite = new AMap.TileLayer.Satellite({
 map: map,
 zIndex: 2,
 zooms: [3, 18]
 })
 // 点击按钮实现切换卫星底图,再点击就关闭卫星底图。
 document.getElementById('btn5').onclick = function() {
 if (this.innerText === '卫星') {
 this.style.backgroundColor = "skyblue"
 this.innerText = '地图'
 satellite.show()
 } else if (this.innerText === '地图') {
 this.style.backgroundColor = "white"
 this.innerText = '卫星'
 satellite.hide()
 } 
  • 运行结果


设计方法

判断当用户点击按钮,按钮名称为卫星时,底图切换为卫星图层也就是卫星图层变量satellite调用show()方法显示,同时按钮名称变为地图,当按钮名称为地图时,鼠标点击,底图会切换为标准底图,这是satellite调用hide()方法隐藏。而在后续更是可以通过加载插件AMap.MapType来增加图层显示功能,无论是在标准底图和卫星底图为当前地图都可以在之上显示路况图层或者路网图层。两者也可以同时显示,高德地图已经把这个功能封装进AMap.MapType插件了,当我们需要的时候引用此插件即可。

天气查询

功能实现

点击按钮获得当地当前的天气情况以及未来四天的天气预报显示在界面右上角部分,让用户比较简单的获取想要的天气咨询。

关键代码

var city // 定义一个变量来接收当前地图中心点所在城市
 map.getCity(function (data) {
 city = data.city
 })
AMap.plugin('AMap.Weather', function() {
 var weather = new AMap.Weather()
 //根据上面获取到的当前城市名称city来搜索当前天气
 weather.getLive(city, function(err, data) {
 if (!err) {
 var str = []
 str.push('<h4 >实时天气' + '</h4><hr>')
 str.push('<p>城市/区:' + data.city + '</p>')
 str.push('<p>天气:' + data.weather + '</p>')
 str.push('<p>温度:' + data.temperature + '℃</p>')
 str.push('<p>风向:' + data.windDirection + '</p>')
 str.push('<p>风力:' + data.windPower + ' 级</p>')
 str.push('<p>空气湿度:' + data.humidity + '</p>')
 str.push('<p>发布时间:' + data.reportTime + '</p>')
 marker = new AMap.Marker({
 map: map,
 position: map.getCenter()
 })
 var infoWin = new AMap.InfoWindow({
 content: '<div id="weatherShow2" class="info" style="position:inherit;margin-bottom:0;">' + str.join('') + '</div><div class="sharp"></div>',
 isCustom: true,
 offset: new AMap.Pixel(0, -37)
 })
 infoWin.open(map, marker.getPosition())
 marker.on('mouseover', function() {
 infoWin.open(map, marker.getPosition())
 })
 }
 }) 
  • 运行结果

设计方法

判断当用户点击按钮,按钮名称为天气查询时,使用变量weather来引用API天气插件AMap.Weather然后调用其中的getLive方法,此方法需要传入一个地点参数作为查询地点才能得到目标地点结果,所以我在运行这个代码之前先定义一个city变量,为这个变量赋值,值为map.getCity方法得到的当前城市地点名称。 传入city函数调用方法会得到当前地点的天气咨询,但是都是数据类型,我们需要把这些数据图像化呈现出来,所以之后代码就是把得到的查询结果放置在相应的中文结果名称上,再以可视化显示到界面上。这样就完成了天气查询功能了。 另外,为了优化用户体验,可以添加一个普通的点标记来记录当前地图中心点并把得到的结果显示在此标记上面,这样我们再后续移动页面的时候不会对结果造成遮挡。 此外,天气查询功能还增加了查询未来4天天气预报的功能,也是通过变量weather来调用getForecast方法来获取结果并显示在界面上,原理同上。

距离测量

功能实现

点击按钮实现进入距离测量功能,鼠标左键点击起始点,确定位置留下一个记号N,再点击下一个点得到两个点之前的直线物理距离,单位为公里(km),此时距离测量功能还没结束,还可以点击下一个地点得到三个点之间的直线距离总和,以此类推,可以供用户测量多个点的总和长度和每两个点之间的长度。按右键结束当前测量。

关键代码

var ruler // 定义一个变量来接收距离测量插件
 map.plugin(["AMap.RangingTool"], function() {
 ruler = new AMap.RangingTool(map)
 })
 document.getElementById('btn3').onclick = function() {
 console.dir(this)
 if (this.innerText === '距离测量') {
 this.style.backgroundColor = "skyblue"
 this.innerText = '关闭测量'
 ruler.turnOn()
 } else if (this.innerText === '关闭测量') {
 this.style.backgroundColor = "white"
 this.innerText = '距离测量'
 ruler.turnOff()
 }
 }
复制代码
  • 运行结果

设计方法

判断当用户点击按钮,按钮名称为距离测量时,通过定义新的变量ruler来引入API距离测量插件AMap.RangingTool(map),来调用其封装的turnOn方法进入测量模式。 这里需要注意的是跟底图切换功能不同,这里引入API时需要传入当前地图对象map,因为该功能时需要对整个地图对象map进行一个操作调用方法实现的功能,进入测量模式后点击多个地方测量各个地点的距离和总和距离。通过用户点击鼠标右键来结束当前这一次的距离测量,但是需要注意的是此时还没有退出距离测量模式,这时再点击鼠标左键的话会进行新的距离测量方法。 所以为了提高用户体验,在原按钮上也应该增加点击按钮彻底退出距离测量模式的功能,此方法原理同底图切换功能,这里不再赘述。

输入提示与POI搜索

功能实现

用户在地点查询搜索框中输入地点名称时,搜索框会自动根据用户当前输入的地点自动生成关键地点提示,并以列表的形式展现在输入框下面,可以让用户不必输入完整的地点就可以之间看到可能出现匹配的目的地地点。 当用户点击出现的匹配列表中的某一个具体地点时,则代表用户需要搜索这个地点的所在位置和相关信息,界面应该跳转到用户输入的地点,并且如果通过POI搜索得到多个结果,界面应该缩小到可以同时显示多个相关地点的程度来让用户更加直观的看到搜索结果。 如果POI搜索结果出现多个匹配的地点,需要在搜索框下面呈现这些匹配的地点并以列表图像化的形式出现在界面上,当用户点击某个匹配的地点的时候,界面应该跳到用户点击地点的所在位置并根据目标所占面积放大或缩小到适当的程度。

  • 关键代码
// 定义变量来接收指定搜索框用户输入的地点,下面的变量tipinput是指页面元素输入框的id值,以此来接收用户在特点输入框输入的内容。
 var autoOptions = {
 input: "tipinput"
 }
 var auto = new AMap.Autocomplete(autoOptions)
 // ===========================================================数据展示
 var placeSearch = new AMap.PlaceSearch({
 pageSize: 5, // 单页显示结果总条数
 pageIndex: 1, // 页码
 panel: "panel", // 结果列表将在此容器中进行展示
 city: "010", // 兴趣点城市
 citylimit: true, //是否强制限制在设置的城市内搜索
 map: map, // 展现结果的当前地图对象
 autoFitView: true // 选择是否自动调整当前地图视野来使绘制的 Marker点都处于当前视口的可见范围内
 }) // 构造地点查询类
 AMap.event.addListener(auto, "select", select) //注册监听,当选中匹配地点时会触发
 function select(e) {
 placeSearch.setCity(e.poi.adcode); //设置当前城市编码查询
 placeSearch.search(e.poi.name); //关键字查询查询
 } 
  • 运行结果
  • 输入提示


  • POI搜索

设计方法

输入提示与POI搜索功能其实非常巧妙的用到了两个功能的API组合来完成。因为地点查询功能是用户使用地图的时候最常见也是最重要的功能,所以我们一般把输入框放在界面上,可以适当的通过CSS类样式做一点的美化。重点是利用输入框的ID值来记录用户的输入内容才能完成下面两个插件的功能。 为了提升用户体验,系统应该充分利用地图关键点数据库,在日常使用地图的情况下,当用户想要搜索某个地点的时候,往往会遇到目标地点名称过长或者忘记了目标地点的完整名称时,输入提示功能就有着极高的使用率和十分良好的使用体验,当用户输入目标地点前几个名称的时候,系统会根据地图关键点数据库来查询当中是否有与用户输入部分名称匹配的地点,再把这些地点以列表的形式展示给用户看,整个过程都不影响用户的正常输入。 也就是说,在不影响用户输入的情况下,给用户提供一个可供参考的地点来提高用户选择地点的准确性。同时,用户打字输入名称一般都是很快的,时间可以以秒位单位,为了提高搜索数据库的效率,可以给自动输入设定限定城市搜索,不过为了提高数据的范围性,本系统还是使用全国的范围进行搜索目的来提示用户。 为了接收到HTML界面用户在输入框输入的地点名称,我们先定义一个变量autoOptions来根据输入框的ID值来接收用户在此输入框输入的内容。然后定义一个新变量auto引用API输入提示AMap.Autocomplete(autoOptions),传入刚才的变量,根据这个变量得到的内容查询数据库并把得到的结果呈现在输入框下方。

这时,为输入提示列表中的每一条数据都绑定一个监听事件,通过上面的代码可以看到当用户选择列表中的某条数据的时候,会触发预先封装好的select 方法,而select方法的功能就是POI搜索功能。 定义一个变量placeSearch引用POI搜索API AMap.PlaceSearch。在引用的同时可以给这个POI搜索API功能设置相应的属性,比如本系统设置pageSize为5意思是查询到的数据会以每页5条数据展示出来,citylimit为true则表示在当前城市进行POI搜索,panel的值表示呈现结果的容器应该放到界面的哪一个元素内,这个容器需要在HTML页面中预先设置好标签ID值来呈现结果。其他属性可以看上面代码或者在API参考手册中自己查看,每一个属性都有其意义和重要性所在。 触发POI搜索功能后得到的具体地点结果会呈现到panel属性中,系统可以对这个容器做相应的CSS样式调整来让界面更加易用,此时得到结果的同时,地图界面会移动到搜索结果所在地。如果通过POI搜索得到多个地点,因为我们在引用此API时设置了其属性autoFitView的值为true,那么界面会调整视野把所有搜索到的地点呈现在当前窗口可见范围内。这个功能对于有多个出入口和停车场的大型建筑或者设施非常方便,如学校、购物广场等。当然更多的是在搜索一个城市的连锁店上比较常见,如KFC,金拱门等。

梅州公交线路查询

功能实现 点击按钮实现查询梅州市公交某一路的路线图,默认查询梅州公交5路,用户可以在下面出现的查询框中输入想要查询的公交路线图。

关键代码

var linesearch
 var busLineName
 /*公交线路查询*/
 function lineSearch() {
 busLineName = document.getElementById('BusLineName').value
 document.getElementById('input-card').style.display = "block"
 console.log(busLineName)
 if (!busLineName) return
 //定义变量先实例化公交线路查询,然后选择取回一条路线
 if (!linesearch) {
 linesearch = new AMap.LineSearch({
 pageIndex: 1,
 city: '梅州',
 pageSize: 1,
 extensions: 'all'
 })
 }
 //搜索“5”相关公交线路
 linesearch.search(busLineName, function (status, result) {
 map.clearMap()
 if (status === 'complete' && result.info === 'OK') {
 lineSearch_Callback(result)
 } else {
 alert(result)
 }
 })
 }
 function lineSearch_Callback(data) {
 var lineArr = data.lineInfo
 var lineNum = data.lineInfo.length
 if (lineNum == 0) {} else {
 for (var i = 0; i < lineNum; i++) {
 var pathArr = lineArr[i].path;
 var stops = lineArr[i].via_stops;
 var startPot = stops[0].location;
 var endPot = stops[stops.length - 1].location;
 if (i == 0) //作为示例,只绘制一条线路
 drawbusLine(startPot, endPot, pathArr);
 }
 }
 }
 /*绘制路线*/
 function drawbusLine(startPot, endPot, BusArr) {
 //绘制起点,终点
 new AMap.Marker({
 map: map,
 position: startPot, //基点位置
 icon: "https://webapi.amap.com/theme/v1.3/markers/n/start.png",
 zIndex: 10
 })
 new AMap.Marker({
 map: map,
 position: endPot, //基点位置
 icon: "https://webapi.amap.com/theme/v1.3/markers/n/end.png",
 zIndex: 10
 })
 //绘制乘车的路线
 busPolyline = new AMap.Polyline({
 map: map,
 path: BusArr,
 strokeColor: "#09f", //线颜色
 strokeOpacity: 0.8, //线透明度
 isOutline: true,
 outlineColor: '#C4C4C4',
 strokeWeight: 6 //线宽
 })
 map.setFitView()
 }
 document.getElementById('search').onclick = lineSearch
 document.getElementById('btn7').onclick = function () {
 if (this.innerText === '公交查询') {
 this.style.backgroundColor = "skyblue"
 this.innerText = '关闭查询'
 lineSearch()
 } else if (this.innerText === '关闭查询') {
 this.style.backgroundColor = "#C4C4C4"
 this.innerText = '公交查询'
 document.getElementById('input-card').style.display = "none"
 map.clearMap()
 }
 } 
复制代码
  • 运行结果

  • 设计方法

用户点击按钮,系统会预先将设定的好梅州公交5路呈现给用户,先获取路线路的所有路线,再将路线绘制成路线图,并同时加入起点和终点的标志,下面的查询框中的查询按钮也通过onclick绑定了查询功能。让用户能够自己选择查询某条路线来选择查询的路线。

右键菜单

  • 功能实现

在日常使用地图的时候,用户一般的操作就只有鼠标拖拽,左键点击,右键菜单了,可以说鼠标的右键菜单功能是很重要的一个功能,我们可以在菜单中设置一些比较实用的功能,如放大、缩小、设置起点、途径点、终点以及添加标记等等,所以这个功能的重点不是其中某一个功能,而是实现右键打开的菜单中出现我们想要的功能,同时,为这些菜单上的选项绑定我们需要的功能才是最重要的。

  • 关键代码
 // =====================================================自定义右键菜单类
 var menu = new ContextMenu(map)
 function ContextMenu(map) {
 var me = this
 // 地图中添加鼠标工具MouseTool插件
 this.mouseTool = new AMap.MouseTool(map)
 this.contextMenuPositon = null
 var content = [] // 创建一个容器来设置右键菜单的样式
 content.push("<div class='info context_menu'>")
 content.push(" <p onclick='menu.zoomMenu(0)'>缩小</p>")
 content.push(" <p class='split_line' onclick='menu.zoomMenu(1)'>放大</p>")
 content.push(" <i class='menu-icon menu-icon-from'></i><p onclick='menu.addOrigin()'>设为起点</p>")
 content.push(" <p onclick='menu.addWaypoints()'>设为途经点</p>")
 content.push(" <p onclick='menu.addDestination()'>设为终点</p>")
 content.push(" <p onclick='menu.addMarkerMenu()'>添加标记获取经纬度</p>")
 content.push("</div>")
 // 通过content自定义右键菜单内容
 this.contextMenu = new AMap.ContextMenu({
 isCustom: true,
 content: content.join('')
 })
 //地图map绑定鼠标右击事件——弹出右键菜单
 map.on('rightclick', function(e) {
 me.contextMenu.open(map, e.lnglat)
 me.contextMenuPositon = e.lnglat //右键菜单出现的位置
 })
 }
 ContextMenu.prototype.zoomMenu = function zoomMenu(tag) { // 右键菜单缩放地图
 if (tag === 0) {
 map.zoomOut()
 }
 if (tag === 1) {
 map.zoomIn()
 }
 this.contextMenu.close()
 }
复制代码
  • 运行结果

  • 设计方法

高德地图的右键菜单API不需要引入插件,直接定义一个变量引用API右键菜单AMap.ContextMenu(map)传入一个地图对象就可以了,这样我们地图有可以出现一个菜单列表,但是按照我们普通用户的实用习惯一般都是通过点击鼠标右键来生成这个菜单,所以本系统还需要定义一个变量mouseTool来引用一个API鼠标工具AMap.MouseTool(map)。 这里本系统通过DOM操作的方式来设置右键菜单的文字内容和CSS样式,所以定义一个变量content通过push方法来不断添加需要的功能名称,这里的重点是通过DOM操作可以给这些功能都增加一个点击事件oncilck的名称。然后再为这个菜单的出现位置绑定一个地图右键事件,当通过地图对象map的on事件绑定,使用其参数(e)来获取鼠标当前位置的经纬度lnglat。通过上面一系列设置能够实现用户在地图任一地点点击鼠标右键能让右键的菜单正确的出现在用户点击的地方。

因为这个功能涉及的方法很多,所以本系统采用重新封装一个新的构造函数ContextMenu(map)为后面绑定菜单各自功能的操作更加方便。 这里我们以右键缩放地图功能为例,通过ContextMenu.protorype.zoomMenu也就是给这个构造函数的原型prototype添加一个方法属性zoomMenu来封装缩放功能的方法,通过这个方法使用一个参数(tag)来判断用户点的是放大还是缩小,这里就需要上文所说的onclick事件,在设置右键菜单中的放大、缩小两个名称菜单的同时给他们绑定好了onclick事件,点击就调用zoomMenu(tag)方法,参数上本系统选择0为放大,1为缩小,最后不要忘记点击事件后要使用close方法把右键菜单关闭。

添加标记获取经纬度

  • 功能实现

在上文通过封装一个新的构造函数ContextMenu来初始化了右键菜单,那么添加标记功能也可以通过右键菜单来执行,获取目标点经纬度是用户使用地图很常用的一个功能,地图上的每一个点都可以通过经纬度来表达其所在位置,所以本系统通过要让用户在目标点右键出现菜单中选择添加标记获取经纬度功能来获取目的点的经纬度并以数据的形式直接展现在点标记上面。

  • 关键代码
//=========================封装获取当前经纬度方法
 function getLngLat() {
 var lnglatInput = document.getElementById('lnglat')
 lnglatInput.setAttribute('value', lnglat.toString())
 }
 ContextMenu.prototype.addMarkerMenu = function() { // 右键菜单添加Marker标记
 this.mouseTool.close()
 this.marker = new AMap.Marker({
 map: map,
 position: this.contextMenuPositon //基点位置
 })
 this.contextMenu.close()
 // ==================infowidnow 窗口的 innerHTML
 var infoWindowContent =
 '<div id="infoWindow" className="custom-infowindow input-card">' +
 '<label style="color:grey">当前地点</label>' +
 '<div class="input-item">' +
 '<div class="input-item-prepend">' +
 '<span class="input-item-text" >经纬度</span>' +
 '</div>' +
 '<input id="lnglat" type="text" />' +
 '</div>' +
 // 为 infowindow 添加自定义事件
 '<input id="lnglat2container" type="button" class="btn" value="获取该位置经纬度" onclick="getLngLat()"/>' +
 '</div>'
 // 创建自定义内容的 infowindow 实例
 this.infoWindow = new AMap.InfoWindow({
 position: this.contextMenuPositon,
 offset: new AMap.Pixel(0, -35),
 content: infoWindowContent
 })
 this.infoWindow.open(map)
 // 将当前经纬度展示在 infowindow 的 input 中
 } 
  • 运行结果

  • 设计方法

这个功能主要还是依靠右键菜单绑定的onclick来触发,首先获取当前经纬度这个功能可以先封装为一个方法getLngLat。然后就是通过DOM操作定义变量infoWindowContent来创建要出现在选定地点的信息窗口,id值为infoWindow,信息窗口也是高德地图JavaScript API一个比较实用的功能,可以通过设置其position属性来设置这个信息窗口出现在界面上的位置,这里信息窗体的内容content就是上面的变量infoWindowContent。 还有添加标记也是需要用到地图map的API点标记AMap.Marker,同理也是需要定义一个变量来引用此API,但是这个功能不同,因为是在构造函数ContextMenu内,所以这里需要把这个变量作为ContextMenu的一个新属性来引用这个API。 最后回来右键菜单中的“添加标记获取经纬度”选项,用户点击这个选项,会在鼠标所在经纬度添加一个点标记,并且在点标记上面出现一个信息窗口,上面有一个按钮点击获取经纬度,当用户点击这个按钮时,再触发之前封装好的getLngLat方法,然后把得到的内容显示在经纬度的窗口内。

设置起终点规划驾车导航

  • 功能实现

规划驾车导航一般情况下需要一个起点和一个终点,系统就可以通过算法的数据将规划路线从起点到终点。所以用户在起点处点击右键,在弹出的菜单中选择设为起点,此时地图会在当前鼠标位置生成一个点标记,名称为“起”,然后用户可以选择一个途径点,同样在途径点处点击鼠标右键在弹出的菜单中选择设为途径点,最后用户在想要导航到的终点处点击鼠标右键,在弹出的菜单中选择设为终点。在用户点击后,地图会自动出现一个导航信息列表,其内容包括选择走哪一条路走多米后左转或者右转等导航信息。而在地图上会出现由起点到途径点再到终点的路线。这就是规划驾车导航功能。

  • 关键代码
// 定义变量引用导航API
 var driving = new AMap.Driving({
 map: map,
 panel: "panel2"
 })
 // 为设为起点封装方法
 ContextMenu.prototype.addOrigin = function() { //右键菜单添加Marker标记
 this.mouseTool.close()
 // 创建一个 Icon
 var startIcon = new AMap.Icon({
 // 图标尺寸
 size: new AMap.Size(25, 34),
 // 图标的取图地址
 image: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
 // 图标所用图片大小
 imageSize: new AMap.Size(135, 40),
 // 图标取图偏移量
 imageOffset: new AMap.Pixel(-9, -3)
 })
 this.origin = new AMap.Marker({
 map: map,
 position: this.contextMenuPositon, //基点位置
 icon: startIcon,
 offset: new AMap.Pixel(-9, -3)
 })
 this.contextMenu.close()
 this.origin1 = this.contextMenuPositon
 }
// 为设为途径点封装方法
 ContextMenu.prototype.addWaypoints = function() { //右键菜单添加Marker标记
 this.mouseTool.close()
 var viaIcon = new AMap.Icon({
 size: new AMap.Size(25, 34),
 // 图标的取图地址
 image: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png',
 })
 this.waypoints = new AMap.Marker({
 map: map,
 position: this.contextMenuPositon, //基点位置
 icon: viaIcon,
 offset: new AMap.Pixel(-9, -3)
 })
 this.contextMenu.close()
 this.waypoints1 = this.contextMenuPositon
 }
 // 为设为终点封装方法
 ContextMenu.prototype.addDestination = function() { //右键菜单添加Marker标记
 this.mouseTool.close()
 var endIcon = new AMap.Icon({
 size: new AMap.Size(25, 34),
 image: 'https://a.amap.com/jsapi_demos/static/demo-center/icons/dir-marker.png',
 imageSize: new AMap.Size(135, 40),
 imageOffset: new AMap.Pixel(-95, -3)
 })
 this.destination = new AMap.Marker({
 map: map,
 position: this.contextMenuPositon, //基点位置
 icon: endIcon,
 offset: new AMap.Pixel(-9, -3)
 })
 this.contextMenu.close()
 this.destination1 = this.contextMenuPositon
 // 根据起终点经纬度规划驾车导航路线
 driving.search(this.origin1, this.destination1, {
 waypoints: [this.waypoints1]
 }, function(status, result) {
 // result 即是对应的驾车导航信息
 if (status === 'complete') {
 log.success('绘制驾车路线完成')
 // 因为驾车导航会自动生成相应的点标记,所以之前通过右键设置的点标记要隐藏
 menu.origin.hide()
 menu.waypoints.hide()
 menu.destination.hide()
 } else {
 log.error('获取驾车数据失败:' + result)
 }
 })
 } 
复制代码
  • 运行结果

  • 设计方法

这个功能是本系统较为复杂的功能,因为是需要用到右键菜单来设置起点、途径点和终点的,先是在右键菜单中加入设置起点、设置途径点、设置终点三个选项,分别给三个选项都设置onclick事件为addOrigin、addWaypoints、addDestination。 用户在某一点右键弹出菜单,然后点击设置起点,这个时候系统首先会通过close方法关闭菜单,然后再用户鼠标的当前位置放置一个点标记,同时,为了提高用户体验,这里用到了地图对象map的Icon属性API,也就是字体图标,为了让用户知道哪个是起点,哪个是途径点,哪个是终点,定义变量startIcon、viaIcon、endIcon分别为其三个关键点的图标,三个图标是有样式属性的起、经、终三个中文名称的字体图标。

三个设为关键的方法都是通过给构造函数ContextMenu新增方法来添加,这样做有利于起点、途径点和终点的经纬度保存到变量中,再把变量作为构造函数的新属性的值。用户添加好起点、途径点和终点时,三个关键点的经纬度都保存好了。

接下来就时通过定义一个变量driving来引用高德地图的导航功能API也就是AMap.Driving,传入地图对象map和导航信息出现的一个HTML标签已经提前准备的窗口panel2。 本系统选择在当用户选择设为终点的选项后,立即通过变量driving调用其search方法,把之前保存在构造函数的起点、途径点和终点的变量传进入,然后在回调函数中增加导航完成提醒和获取驾车数据失败提醒。