JS 异步加载
有些第三方的 JS 是异步加载的,例如:地图组件。下面以引入高德地图为例,说明引入方式
运行效果
在地图上显示车辆标注,点击标注可以查看当前位置区域的监测数据和汽车信息。点击工具栏,可以显示当前车辆统计信息,以及显示隐藏点位信息,可快速检索出对应车辆。
设计思路
使用高德地图 Js API 来实现地图渲染,使用地图标注实现车辆渲染。通过弹层来显示当前位置的空气质量和车辆统计信息。
使用方法如下
// 全局变量
let map;
let AMap;
export default class IndexPage extends Page {
initAMap = () => {
return new Promise(function (resolve, reject) {
if (window.AMap) {
resolve(window.AMap);
return;
}
window.onLoad = function () {
resolve(window.AMap);
}
let url = 'https://webapi.amap.com/maps?v=1.4.15&key=2a25c002bb67874654f9d77587a5e168&callback=onLoad';
let jsapi = document.createElement('script');
jsapi.charset = 'utf-8';
jsapi.src = url;
document.head.appendChild(jsapi);
});
}
onPageReady = (event) => {
let self = this;
this.initAMap().then(function (_AMap) {
AMap = _AMap;
map = new AMap.Map('airmonitor-map-container', {
center: [110.353214, 19.950745],
zoom: 12
});
map.setFeatures(['road', 'bg']);
self.displayCar();
map.plugin(["AMap.ToolBar"], function () {
map.addControl(new AMap.ToolBar()); // 工具条控件;范围选择控件
});
map.plugin(["AMap.MapType"], function () {
map.addControl(new AMap.MapType()); //实现默认图层与卫星图、实施交通图层之间切换的控件
});
});
}
}
页面开发过程
初始化地图
- 创建一个 div 节点,用于渲染地图,在页面的初次渲染事件中,异步加载高德地图 Js,使用 window.onload 事件待页面中所有内容都加载完成后,渲染指定 div 节点。
<antdpro:Page class="x-page" id="page" on:onReady="onPageReady" style="height:100%" uix="true" xmlns:antdpro="$UI/comp/antdpro/components" xmlns:attr="http://www.wex5.com/attr" xmlns:bind="http://www.wex5.com/wx/bind" xmlns:catch="http://www.wex5.com/wx/event/catch" xmlns:chart="$UI/comp/chart/components" xmlns:ext="http://www.wex5.com/ext" xmlns:on="http://www.wex5.com/wx/event/on" xmlns:wx="$UI/wxsys/comps">
<div id="airmonitor-map-container" style="height:100%;position:relative;">
</div>
</antdpro:Page>
initAMap = () => {
return new Promise(function (resolve, reject) {
if (window.AMap) {
resolve(window.AMap);
return;
}
window.onLoad = function () {
resolve(window.AMap);
}
let url = 'https://webapi.amap.com/maps?v=1.4.15&key=2a25c002bb67874654f9d77587a5e168&callback=onLoad';
let jsapi = document.createElement('script');
jsapi.charset = 'utf-8';
jsapi.src = url;
document.head.appendChild(jsapi);
});
}
onPageReady = (event) => {
let self = this;
this.initAMap().then(function (_AMap) {
AMap = _AMap;
map = new AMap.Map('airmonitor-map-container', {
center: [110.353214, 19.950745],
zoom: 12
});
map.setFeatures(['road', 'bg']);
self.displayCar();
map.plugin(["AMap.ToolBar"], function () {
map.addControl(new AMap.ToolBar()); // 工具条控件;范围选择控件
});
map.plugin(["AMap.MapType"], function () {
map.addControl(new AMap.MapType()); //实现默认图层与卫星图、实施交通图层之间切换的控件
});
});
}
汽车标注绘制
displayCar = () => {
// 获取小车以及最新数据
let car = this.comp("restData0");
let travelData = this.comp("restData4");
let queryData = this.comp("tableCustomData0");
let self = this;
car.each(({ row }) => {
let longitude = row.travelvehiclecollectdatadetailtemp_longitude;
let latitude = row.travelvehiclecollectdatadetailtemp_latitude;
if (longitude && latitude) {
let image = this.getCarIcon(row.travelvehiclecollectdatadetailtemp_pm25excessive, row.travelvehiclecollectdatadetailtemp_pm10excessive);
let bubbleData = this.getCarMarkerData(row);
let bubbleColor = this.getCarMarkerColor(row, bubbleData);
let angle = Math.random() * 360;
//空气pm值和汽车图片
var markerContent = '' +
'<div style="position:absolute;">' +
' <div style="background:' + bubbleColor + ';color:#FFF;opacity:0.8;margin-bottom:5px;padding:0px 5px">' + bubbleData + '</div>' +
' <img style="width:30px;height:15px;transform:rotate(' + angle + 'deg)" src="' + image + '">' +
'</div>';
var marker = new AMap.Marker({
position: new AMap.LngLat(longitude, latitude),
offset: new AMap.Pixel(0, 0),
content: markerContent,
title: row.travelVehicleId
});
// 鼠标滑上去出现车牌号
AMap.event.addListener(marker, 'mouseover', function () {
var infoWindow = new AMap.InfoWindow({
content: marker.getTitle(),
offset: new AMap.Pixel(10, 20)
});
infoWindow.open(map, marker.getPosition());
});
// 鼠标点击弹出车辆监测详情
AMap.event.addListener(marker, 'click', function () {
// 车辆数据跳转
car.to(row);
// 获取api数据
queryData.setValue("detailTravelVehicleId", row.travelVehicleId);
travelData.refreshData().then(function () {
// 显示详情
queryData.setValue("displayCarDetail", 1);
});
});
// 添加到地图中
map.add(marker);
}
});
// 统计
this.carStat();
}
// 车辆情况统计
carStat = () => {
let car = this.comp("restData0");
let onlineNum = 0;
let offlineNum = 0;
let pm25Num = 0;
let pm10Num = 0;
car.each(({ row }) => {
onlineNum++;
//offlineNum
// pm25
if (row.travelvehiclecollectdatadetailtemp_pm25excessive == 1) {
pm25Num++;
}
// pm10
if (row.travelvehiclecollectdatadetailtemp_pm10excessive == 1) {
pm10Num++;
}
});
let carStat = this.comp("tableCustomData1");
carStat.setValue("onlineNum", onlineNum);
carStat.setValue("offlineNum", offlineNum);
carStat.setValue("pm25Num", pm25Num);
carStat.setValue("pm10Num", pm10Num);
}
getCarMarkerData = (row) => {
let data = "";
let legendType = this.comp("tableCustomData0").getValue("legendType");
switch (legendType) {
case "pm25":
data = row.travelvehiclecollectdatadetailtemp_pm25;
break;
case "pm10":
data = row.travelvehiclecollectdatadetailtemp_pm10;
break;
}
return data;
}
getCarMarkerColor = (row, data) => {
// 默认深红
let color = "#7B2B40";
let legendType = this.comp("tableCustomData0").getValue("legendType");
let rows = this.comp("restData2").find(["factor"], [legendType]);
rows.forEach(row => {
if (data >= row.fromVal && data <= row.toVal) {
color = row.color;
}
});
return color;
}
getCarIcon = (pm25Excessive, pm10Excessive) => {
let imagePrefix = '$UI/pcx/js_ybjz/images/';
let image = 'car3.png';
if (pm25Excessive != null && pm10Excessive != null) {
if (pm25Excessive == 0 && pm10Excessive == 0) {
//绿色
image = 'car1.png';
}
else if (pm25Excessive == 1 || pm10Excessive == 1) {
//红色
image = 'car2.png';
}
}
return this.getUIUrl(imagePrefix + image);
}
搜索区
完成车辆及对应走航信息检索
<div id="divPcx0" style="position:absolute;top:20px;left:150px;width:400px;z-index:1000;">
<antdpro:Input allowClear="true" bind:ref="tableCustomData0.current.travelVehicleId" id="input0" placeholder="请输入车牌号..." size="large" xmlns:antd="$UI/comp/antd/components">
<attr:addonAfter id="default11" xmlns:attr="http://www.wex5.com/attr">
<antdpro:Button class="input-btn-after" displayMode="only-icon" icon="search,outlined" id="button0" on:onClick="onButton0Click" size="large" text="按钮"/>
</attr:addonAfter>
</antdpro:Input>
</div>
/**
* 搜索
*/
onButton0Click = (event) => {
// 刷新小车
let self = this;
this.comp("restData0").refreshData().then(function () {
// 清除原来marker
map.clearMap();
// 重新绘制marker
self.displayCar();
});
}
区域监测数据的面板
用于显示指定车辆信息及指定车辆所在位置对应监测数据
<div bind:class="wx.Util.classConcat({'x-dynamic-hiden':wx.Util.iif(tableCustomData0.current?.displayCarDetail==1,false,true)})" id="divPcx1" style="width:320px;position:absolute;top:70px;left:150px;background-color:#ffffff;z-index:1000;background:#2f3d85;padding:12px;box-sizing:border-box;">
<div style="background-color: white;">
<antdpro:Row id="row2" style="background-color:#CCCCCC;">
<antdpro:Col id="col16" span="21">
<antdpro:Typography.Text id="typographyText0" style="margin-left:10px" text="{"车辆及监测数据"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col17" style="text-align: right">
<antdpro:Button displayMode="only-icon" icon="close,outlined" id="button4" on:onClick="{"operation":"commonOperation.setValue","args":{"item":"tableCustomData0.current.displayCarDetail","data":"tableCustomData0","col":"displayCarDetail","value":"js:0","row":"js:tableCustomData0.current"}}" size="small" text="按钮" type="link"/>
</antdpro:Col>
</antdpro:Row>
<antdpro:Row gutter="[{},{"xs":10,"sm":10,"md":10,"lg":10,"xl":10,"xxl":10}]" id="row0" style="padding-left:5px;padding-right:5px;border-width:1px;border-color:#000" xmlns:antd="$UI/comp/antd/components">
<antdpro:Col id="col1" span="12" style="margin-left:10px">
<antdpro:Button bind:text="restData0.current.travelVehicleId" id="button1" size="small" style="width:100px" text="{restData0.current?.travelVehicleId}" type="primary"/>
</antdpro:Col>
<antdpro:Col id="col2" span="10">
<antdpro:Typography.Text id="typographyText1" text="{restData0.current?.owner}"/>
</antdpro:Col>
<antdpro:Col id="col4" span="12" style="text-align:center;">
<antdpro:Typography.Text id="typographyText3" text="{"状态"}"/>
</antdpro:Col>
<antdpro:Col id="col5" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText4" style="color:#6cd730" text="{"在线"}"/>
</antdpro:Col>
<antdpro:Col id="col6" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText5" text="{"车辆品牌"}"/>
</antdpro:Col>
<antdpro:Col id="col7" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText6" text="{restData0.current.vehicleBrand}"/>
</antdpro:Col>
<antdpro:Col id="col8" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText7" text="{"今日在线时长"}"/>
</antdpro:Col>
<antdpro:Col id="col9" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText8" text="{restData0.current.devicestatistical_onlinetime + " h"}"/>
</antdpro:Col>
<antdpro:Col id="col10" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText11" text="{"今日行驶里程"}"/>
</antdpro:Col>
<antdpro:Col id="col3" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText12" text="{restData0.current.devicestatistical_mileage + " km"}"/>
</antdpro:Col>
<antdpro:Col id="col23" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText13" text="{"今日平均车速"}"/>
</antdpro:Col>
<antdpro:Col id="col33" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText14" text="{restData0.current.devicestatistical_speedavg + " km/h"}"/>
</antdpro:Col>
<antdpro:Col id="col43" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText171" text="{"监测时间"}"/>
</antdpro:Col>
<antdpro:Col id="col53" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText181" text="{restData0.current?.travelvehiclecollectdatadetailtemp_datetime}"/>
</antdpro:Col>
<antdpro:Col id="col73" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText19" text="{"经纬度"}"/>
</antdpro:Col>
<antdpro:Col id="col63" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText20" text="{restData0.current.travelvehiclecollectdatadetailtemp_longitude + "," + restData0.current.travelvehiclecollectdatadetailtemp_latitude}"/>
</antdpro:Col>
<antdpro:Col id="col83" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText15" text="{"PM2.5"}"/>
</antdpro:Col>
<antdpro:Col id="col93" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText16" text="{restData0.current.travelvehiclecollectdatadetailtemp_pm25 + " ug/m³"}"/>
</antdpro:Col>
<antdpro:Col id="col32" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText17" text="{"PM10"}"/>
</antdpro:Col>
<antdpro:Col id="col31" span="12" style="text-align: center">
<antdpro:Typography.Text id="typographyText18" text="{restData0.current.travelvehiclecollectdatadetailtemp_pm10+ " ug/m³"}"/>
</antdpro:Col>
</antdpro:Row>
</div>
</div>
统计信息的面板
用于显示空气测量统计数据面板
<div bind:class="wx.Util.classConcat({'x-dynamic-hiden':wx.Util.iif(this.state.visible==true,false,true)})" id="divPcx6" style="position:absolute;right:10px;top:120px;width:300px;background-color:#2f3d85;z-index:100;padding:20px;box-sizing:content-box;">
<antdpro:Row align="top" id="row5" justify="middle" style="text-align: center">
<antdpro:Col flex="1" id="col25">
<antdpro:Image id="image0" preview="false" src="$UI/pcx/js_ybjz/images/car1.png" style="width:30px;height:15px"/>
<antdpro:Typography.Text id="typographyText10" style="color:#FFFFFF" text="{"在线"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col26">
<antdpro:Image id="image1" preview="false" src="$UI/pcx/js_ybjz/images/car2.png" style="width:30px;height:15px"/>
<antdpro:Typography.Text id="typographyText21" style="color:#FFFFFF" text="{"超标"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col27">
<antdpro:Image id="image2" preview="false" src="$UI/pcx/js_ybjz/images/car3.png" style="width:30px;height:15px"/>
<antdpro:Typography.Text id="typographyText22" style="color:#FFFFFF" text="{"离线"}"/>
</antdpro:Col>
</antdpro:Row>
<antdpro:Row align="middle" id="row6" style="margin-top:20px">
<antdpro:Col flex="3" id="col29">
<antdpro:Typography.Text id="typographyText23" style="color:#FFFFFF" text="{"刷新时间:"}"/>
<antdpro:Typography.Text id="typographyText24" style="color:#FFFFFF" text="{restData0.current?.travelvehiclecollectdatadetailtemp_datetime}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col28" style="text-align: center">
<antdpro:Button id="button15" on:onClick="onButton15Click" size="small" style="height:30px;border:1px solid #2f3d85;width:50px" text="自动" type="link" xmlns:bind="http://www.wex5.com/wx/bind"/>
</antdpro:Col>
</antdpro:Row>
<antdpro:Row id="row7" style="margin-top:20px;text-align: center">
<antdpro:Col flex="1" id="col313">
<antdpro:Typography.Text id="typographyText25" style="color:#FFFFFF" text="{"在线"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col34">
<antdpro:Typography.Text id="typographyText26" style="color:#FFFFFF" text="{"离线"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col35">
<antdpro:Button bind:class="wx.Util.classConcat({'c-white':wx.Util.iif(tableCustomData0.current.legendType!="pm25",true,false)})" id="button7" on:onClick="onButton7Click" size="small" text="PM2.5" type="link"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col36">
<antdpro:Button bind:class="wx.Util.classConcat({'c-white':wx.Util.iif(tableCustomData0.current.legendType!="pm10",true,false)})" id="button8" on:onClick="onButton8Click" size="small" text="PM10" type="link" xmlns:on="http://www.wex5.com/wx/event/on"/>
</antdpro:Col>
</antdpro:Row>
<antdpro:Row id="row8" style="margin-top:15px;text-align: center">
<antdpro:Col flex="1" id="col37">
<antdpro:Typography.Text id="typographyText29" style="color:#FFFFFF" text="{tableCustomData1.current.onlineNum + "辆"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col38">
<antdpro:Typography.Text id="typographyText30" style="color:#FFFFFF" text="{tableCustomData1.current.offlineNum + "辆"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col39">
<antdpro:Typography.Text id="typographyText34" style="color:#FFFFFF" text="{tableCustomData1.current.pm25Num + "辆"}"/>
</antdpro:Col>
<antdpro:Col flex="1" id="col40">
<antdpro:Typography.Text id="typographyText33" style="color:#FFFFFF" text="{tableCustomData1.current.pm10Num + "辆"}"/>
</antdpro:Col>
</antdpro:Row>
</div>
工具栏
点击显示统计信息弹层;设置中心点;设置汽车标注是否显示。
<div id="divPcx4" style="position:absolute;bottom:140px;right:20px;width:50px;z-index:1000">
<antdpro:Row id="row9" style="background-color:#2f3d85">
<antdpro:Col id="col41" span="24" style="text-align: center">
<antdpro:Button displayMode="only-icon" icon="{wx.Util.iif(this.state.visible==true,"eye-invisible,outlined","eye,outlined")}" id="button12" on:onClick="onButton12Click" style="background-color:#2f3d85;color:#FFFFFF;border:1px solid #2f3d85" text="按钮"/>
</antdpro:Col>
<antdpro:Col id="col41" span="24" style="text-align: center">
<antdpro:Button displayMode="only-icon" icon="aim,outlined" id="button13" on:onClick="onButton13Click" style="background-color:#2f3d85;color:#FFFFFF;border:1px solid #2f3d85" text="按钮"/>
</antdpro:Col>
<antdpro:Col id="col42" span="24" style="text-align: center">
<antdpro:Button block="false" id="button6" on:onClick="onButton6Click" size="small" style="height:30px;width:50px;background-color:#2f3d85;border:1px solid #2f3d85" text="点位" type="primary" xmlns:bind="http://www.wex5.com/wx/bind"/>
</antdpro:Col>
</antdpro:Row>
</div>