1.效果
2.说明
- 这个升级版几乎就是我们公司用的这个功能了,设计到的功能就是可以根据后台数据重新进行位置排布,且实时刷新节点的数据。用ec写出这个效果不难,参考demo1
- 这个主要是设计到如何根据数据进行重新排布,实时刷数据,这些都是ec插件没有的,需要我们去苦逼手写的。
3.代码:
3.1要知道的:
- 其实在敲代码前,就应该意识到和后台要的数据是什么样的,要知道我们是用地图模块实现的,所以节点的定位就要设计到坐标,而这个坐标是后台不会给我们的,他只会给我们这些个节点的基本信息,状态,来自哪个节点,要去哪个节点。换句话说,就是这个节点的定位是需要我们算的。
- OK,既然是我们算,就要知道,我们算的这个地图的模块的边界大小和起始点。这里我用的世界地图,没有用中国地图,是有原因的。这就是说到我们的边界和起始点。世界地图的边界和起始点比较好设置和计算,都是整数,而中国地图首先得合理的把中国地图放大,找到起始点坐标和边界大小,虽然说后面的计算方法和世界地图的计算是一样的,但是找起始点就恶心的很,所以强烈建议用世界地图。
- 世界地图的起始点和边界:
- 数据也不难找 中心点坐标是[0,0],宽度是东经到西经360,高度不是北纬到南纬180,是北纬80度到南纬50度的样子,这个也没有具体是怎么样的数值,原因就是地图会向上偏移点,北纬80度到南纬50度的范围更合适点。所以可以得出:
me.conf = {
// 起始点
start: [-180, 80],
w: 360,
h: 130,
padding: 5,
// 列宽
_lie_w: 0,
}
3.2主要过程:
- 主要流程:1.确定了起始点和边界范围 2.根据数据确定每列数据的宽度;3.初始化节点数据,4.初始化航线数据,5.注入数据 6.设置实时更新
_init: function() {
// 起始点确定
me._flow_start_p();
// 确认列宽
me._flow_lie_w();
//
me._flow();
},
_flow: function() {
// **************************************模拟数据
for (var lie_key in all_data) {
all_data[lie_key].forEach(function(ele, index) {
ele.id = `${lie_key}_${index+1}`;
ele.name = `lie_${lie_key}_${index+1}`;
ele.status = (Math.random() > 0.5 ? 0 : 1);
});
}
// **********************************************
// 初始化节点
me._flow_node();
// **************************************模拟数据
for (var lie_key in all_data) {
all_data[lie_key].forEach(function(ele, index) {
// console.log();
ele.to = me._flow_lines_to_test(ele.id);
});
}
// **********************************************
// 初始化线
me._flow_lines();
// 生成数据
me._flow_init();
//
setTimeout(function() {
// **************************************模拟数据
// for (var lie_key in all_data) {
// all_data[lie_key].forEach(function(ele, index) {
// // console.log();
// ele.to = me._flow_lines_to_test(ele.id);
// });
// }
// **********************************************
// me.all_obj.ec.clear();
me.all_obj.pt_p_arr.length = 0;
me.all_obj.alarm_p_arr.length = 0;
me.all_obj.pt_lines_arr.length = 0;
me.all_obj.alarm_lines_arr.length = 0;
me._flow();
}, 5000)
},
- 认识下数据格式,要知道后台是不给我们坐标的,所以猜下大概的数据格式应该是:id是节点的坐标,statu节点的状态,to就是表示我们这个节点要去哪个节点的坐标。这些都是我作为前端想到的。到时候有其他字段再加就行了。
var all_data = {
1: [
//
{
id: 1,
status: 0,
name: 'lie-1-1',
to:'2_1',
},
//
{
id: 1,
status: 1,
name: 'lie-1-2',
to:'2_1',
},
//
{
id: 1,
status: 1,
name: 'lie-1-3',
to:'2_2',
},
],
2:...
}
- 这里是5列数据,所以走第一步,先确定列的宽度:(在配置起始坐标和边界时,我同时设置了一个padding值,就是以防我们经理说撑的太满了要往里面收下的这个low的要求。)
// 宽度确定
_flow_lie_w: function() {
// 数据处理
var index = 0;
for (var lie in all_data) {
index++;
}
// 初始化列宽
me.conf._lie_w = Math.floor(me.conf.w / index);
},
- 然后就是初始化每一列数据:核心就是要确定每一列第一个节点的经纬度,知道如歌通过遍历得到同列下面节点的经纬度,这里要注意的是:1.在最后要收集每个节点的ID和坐标的对应关系,因为我们在初始化巡航线的时候要用到这些点的坐标。2.根据不同的状态收集不同的数据,这里主要是有普通点就是没有动态效果,报警点有报警效果的区别,我也是担心经理有这个要求,没等他说我就直接这样写了,如果是报警直接节点颜色变了,没有动画效果,就没必要通过两个数组进行收集数据了,因为看ec的API颜色也是可以用个回调函数进行颜色的设置。
// 初始化节点
_flow_node: function() {
for (var lie in all_data) {
me._flow_node_init(all_data[lie], lie);
}
},
_flow_node_init: function(arr, lie) {
// console.log(arr, lie);
var lie_index = null;
switch (lie) {
case "1":
lie_index = 1;
break;
case "2":
lie_index = 2;
break;
case "3":
lie_index = 3;
break;
case "4":
lie_index = 4;
break;
case "5":
lie_index = 5;
break;
}
// 每一列的项目高
var _item_h = Math.floor(me.conf.h / arr.length);
// 每列起始经度
var lng = me.conf.start[0] + (lie_index - 0.5) * me.conf._lie_w;
// 纬度
var lat = 0;
//
arr.forEach(function(ele, index) {
lat = me.conf.start[1] - (index + 1 - 0.5) * _item_h;
// PT
if (ele.status) {
// 普通点收集
me.all_obj.pt_p_arr.push({
id: ele.id,
name: ele.name,
value: [lng, lat]
});
}
// 报警点收集
else {
me.all_obj.alarm_p_arr.push({
id: ele.id,
name: ele.name,
value: [lng, lat]
});
}
// 生成字典
me.all_obj.p_obj[ele.id] = [lng, lat];
});
},
- 初始化巡航线:就是更加节点数据里的to字段。知道我们要去哪个节点的ID,根据前面收集的ID的坐标的对应关系,拿到要去的节点的坐标。
// 初始化线
_flow_lines: function() {
for (var lie in all_data) {
all_data[lie].forEach(function(ele, index) {
if (ele.to) {
// PT
if (ele.status) {
me.all_obj.pt_lines_arr.push({
"coords": [
me.all_obj.p_obj[ele.id],
me.all_obj.p_obj[ele.to],
]
});
}
// 报警
else {
me.all_obj.alarm_lines_arr.push({
"coords": [
me.all_obj.p_obj[ele.id],
me.all_obj.p_obj[ele.to],
]
});
}
}
});
}
},
- 说下我和后台要的数据格式 ,注意这里写的我和后台要,意思就是后台给我的数据格式是我前端定的,我和他约定要什么格式,他就得按照这个格式来。不然没法配合。对吧?
- 最后就是设置定时刷了,核心就是递归加定时器,保证数据在上一次没有请求完成不会发出下次请求,唉,我们的老业务场景了。
-
源码:点star,不迷路