随着物联网的快速发展,人们对物联网设备的数据监控可视化的需求越来越强烈,为了解决企业设备数据监控可视化痛点,深圳当康科技经过不断的努力,研发了一套基于物联网的可视化图形编辑器,用户编辑器可以通过该编辑器实现自定义上传图片,和自己所需的组件图标,通过拖拽,移动等方式编辑对应的可视化图形界面,动态绑定设备数据,实现系统组态数据显示。
部分项目源码
/* eslint-disable*/
import {$Dragble} from './Dragble.js';
import store from '@/vuex/index.js';
export const Rotate = (domId) => {
const $ = (str) => {
return document.querySelector(str);
};
const setRotate = (dom, rotate) => {
store.commit('zeditor/setDataItemById', {
id: dom.id,
styleName: 'rotate',
value: rotate,
});
};
let roateBox = $(domId);
// 旋转按钮代码
// 获取方形中心坐标点即坐标轴原点
// 鼠标移动事件
const moveEvent = (e) => {
// if (e.target.className !== 'point') {
// return;
// }
const dom = e.target.parentNode;
let centerPointX =
dom.getBoundingClientRect().left + dom.getBoundingClientRect().width / 2;
let centerPointY =
dom.getBoundingClientRect().top + dom.getBoundingClientRect().height / 2;
let X = e.clientX;
let Y = e.clientY;
e.stopPropagation();
let oY = Math.abs(Y - centerPointY);
let oX = Math.abs(X - centerPointX);
// 避免水平和垂直位置的就相当于和坐标轴相交的时候设置除数为0或者不知道为360度还是180度
oY === 0 && (oY = 0.01);
oX === 0 && (oX = 0.01);
let degEnd = (Math.atan(oX / oY) / (2 * Math.PI)) * 360;
// 第一象限
if (X > centerPointX && Y < centerPointY) {
// console.log('第一象限');
setRotate(roateBox, degEnd);
}
// 第二象限
if (X > centerPointX && Y > centerPointY) {
// console.log('第二象限');
setRotate(roateBox, 180 - degEnd);
}
// 第三象限
if (X < centerPointX && Y > centerPointY) {
// console.log('第三象限');
setRotate(roateBox, degEnd + 180);
}
// 第四象限
if (X < centerPointX && Y < centerPointY) {
// console.log('第四象限');
setRotate(roateBox, 360 - degEnd);
}
};
function pointEvent (e) {
e.stopPropagation();
document.addEventListener('mousemove', moveEvent, false);
}
roateBox.querySelector('.point').addEventListener(
'mousedown',
pointEvent,
false
);
function docEvent() {
document.removeEventListener('mousemove', moveEvent);
}
document.addEventListener(
'mouseup',
docEvent,
false
);
// 释放文档按下事件
document.onmouseup = function() {
document.onmousemove = null;
};
document.oncontextmenu = function() {
document.onmousemove = null;
};
// 右下角拉伸点
let startX, startY, owidth, oheight, oleft, otop;
const MAXWIDTH = 10; // 限制最大宽度
const MAXHEIGHT = 10; // 限制最大高度
function rbPointEvent (e) {
let that = this;
startX = e.clientX;
startY = e.clientY;
oleft = parseFloat(this.parentNode.style.left);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveX = e.clientX;
let moveY = e.clientY;
let mWidth = moveX - startX;
let mHeight = moveY - startY;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'left',
value: oleft,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'width',
value: (owidth + mWidth > MAXWIDTH ? owidth + mWidth : MAXWIDTH),
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'height',
value: (oheight + mHeight > MAXHEIGHT ? oheight + mHeight : MAXHEIGHT),
});
};
}
roateBox.querySelector('.rb-point').addEventListener(
'mousedown',
rbPointEvent,
false
);
// 左下角拉伸点
function lbPointEvent (e) {
let that = this;
const mleft = that.parentNode.parentNode.getBoundingClientRect().left;
const mtop = that.parentNode.parentNode.getBoundingClientRect().top;
startX = e.clientX - mleft;
startY = e.clientY - mtop;
oleft = parseFloat(this.parentNode.style.left);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveX = e.clientX - mleft;
let moveY = e.clientY - mtop;
let mWidth = startX - moveX;
let mHeight = moveY - startY;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'left',
value: moveX,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'width',
value: (owidth + mWidth > MAXWIDTH ? owidth + mWidth : MAXWIDTH),
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'height',
value: (oheight + mHeight > MAXHEIGHT ? oheight + mHeight : MAXHEIGHT),
});
};
}
roateBox.querySelector('.lb-point').addEventListener(
'mousedown',
lbPointEvent,
false
);
// 左上角拉伸点
function ltPointEvent (e) {
let that = this;
const mleft = that.parentNode.parentNode.getBoundingClientRect().left;
const mtop = that.parentNode.parentNode.getBoundingClientRect().top;
startX = e.clientX - mleft;
startY = e.clientY - mtop;
oleft = parseFloat(this.parentNode.style.left);
otop = parseFloat(this.parentNode.style.top);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveX = e.clientX - mleft;
let moveY = e.clientY - mtop;
let mWidth = startX - moveX;
let mHeight = startY - moveY;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'left',
value: moveX,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'top',
value: moveY,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'width',
value: owidth + mWidth > MAXWIDTH ? owidth + mWidth : MAXWIDTH,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'height',
value: oheight + mHeight > MAXHEIGHT ? oheight + mHeight : MAXHEIGHT,
});
};
}
roateBox.querySelector('.lt-point').addEventListener(
'mousedown',
ltPointEvent,
false
);
// 右上角拉伸点
function rtPointEvent(e) {
let that = this;
startX = e.clientX;
startY = e.clientY - that.parentNode.parentNode.getBoundingClientRect().top;
oleft = parseFloat(this.parentNode.style.left);
otop = parseFloat(this.parentNode.style.top);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveX = e.clientX;
let moveY = e.clientY - that.parentNode.parentNode.getBoundingClientRect().top;
let mWidth = moveX - startX;
let mHeight = startY - moveY;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'left',
value: oleft,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'top',
value: moveY,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'width',
value: owidth + mWidth > MAXWIDTH ? owidth + mWidth : MAXWIDTH,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'height',
value: oheight + mHeight > MAXHEIGHT ? oheight + mHeight : MAXHEIGHT,
});
};
}
roateBox.querySelector('.rt-point').addEventListener(
'mousedown',
rtPointEvent,
false
);
// 中上拉伸点
function ctPointEvent(e) {
let that = this;
const mtop = that.parentNode.parentNode.getBoundingClientRect().top;
startX = e.clientX;
startY = e.clientY - mtop;
oleft = parseFloat(this.parentNode.style.left);
otop = parseFloat(this.parentNode.style.top);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveY = e.clientY - mtop;
let mHeight = startY - moveY;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'top',
value: moveY,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'height',
value: oheight + mHeight > MAXHEIGHT ? oheight + mHeight : MAXHEIGHT,
});
};
}
roateBox.querySelector('.ct-point').addEventListener(
'mousedown',
ctPointEvent,
false
);
// 中下拉伸点
function cbPointEvent(e) {
let that = this;
startX = e.clientX;
startY = e.clientY;
oleft = parseFloat(this.parentNode.style.left);
otop = parseFloat(this.parentNode.style.top);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveY = e.clientY;
let mHeight = moveY - startY;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'height',
value: oheight + mHeight > MAXHEIGHT ? oheight + mHeight : MAXHEIGHT,
});
};
}
roateBox.querySelector('.cb-point').addEventListener(
'mousedown',
cbPointEvent,
false
);
// 左中拉伸点
function clPointEvent(e) {
let that = this;
const mleft = that.parentNode.parentNode.getBoundingClientRect().left;
const mtop = that.parentNode.parentNode.getBoundingClientRect().top;
startX = e.clientX - mleft;
startY = e.clientY - mtop;
oleft = parseFloat(this.parentNode.style.left);
otop = parseFloat(this.parentNode.style.top);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveX = e.clientX - mleft;
let mWidth = startX - moveX;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'left',
value: moveX,
});
store.commit('zeditor/setDataItemById', {
id,
styleName: 'width',
value: owidth + mWidth > MAXWIDTH ? owidth + mWidth : MAXWIDTH,
});
};
}
roateBox.querySelector('.cl-point').addEventListener(
'mousedown',
clPointEvent,
false
);
// 右中拉伸点
function crPointEvent(e) {
let that = this;
startX = e.clientX;
startY = e.clientY;
oleft = parseFloat(this.parentNode.style.left);
otop = parseFloat(this.parentNode.style.top);
owidth = this.parentNode.getBoundingClientRect().width;
oheight = this.parentNode.getBoundingClientRect().height;
e.stopPropagation();
document.onmousemove = function(e) {
let moveX = e.clientX;
let mWidth = moveX - startX;
const id = that.parentNode.id;
store.commit('zeditor/setDataItemById', {
id,
styleName: 'width',
value: owidth + mWidth > MAXWIDTH ? owidth + mWidth : MAXWIDTH,
});
};
}
roateBox.querySelector('.cr-point').addEventListener(
'mousedown',
crPointEvent,
false
);
// 6个点按下后移除鼠标按起事件
const pointDom = roateBox.querySelectorAll('div[class*="-point"]');
for (let i = 0; i < pointDom.length; i++) {
pointDom[i].addEventListener('mouseup', () => {
document.onmousemove = null;
}, false);
}
// 清空事件方法,统一释放内存
function clearBindEvent () {
document.removeEventListener('mousemove', moveEvent);
document.removeEventListener('mousemove', pointEvent);
document.removeEventListener('mousemove', docEvent);
// 八个点的事件释放
roateBox.querySelector('.rb-point').removeEventListener('mousedown', rbPointEvent);
roateBox.querySelector('.lb-point').removeEventListener('mousedown', lbPointEvent);
roateBox.querySelector('.lt-point').removeEventListener('mousedown', ltPointEvent);
roateBox.querySelector('.rt-point').removeEventListener('mousedown', rtPointEvent);
roateBox.querySelector('.ct-point').removeEventListener('mousedown', ctPointEvent);
roateBox.querySelector('.cb-point').removeEventListener('mousedown', cbPointEvent);
roateBox.querySelector('.cl-point').removeEventListener('mousedown', clPointEvent);
roateBox.querySelector('.cr-point').removeEventListener('mousedown', crPointEvent);
// console.log('---------移除事件绑定-------');
};
return clearBindEvent;
};
/* eslint-disable*/
import store from '@/vuex/index.js';
export const $Dragble = {
centerPointX: '',
centerPointY: '',
dom: '',
id: '',
isMove: false, // 是否可以移动开关标识
left: '',
top: '',
mouseStartX: '',
mouseStartY: '',
positionType: '',
mousemove: function(maxleft, maxtop) {
if (!$Dragble.isMove) {
return;
}
const top = (window.event.pageY - $Dragble.mouseStartY);
const left = (window.event.pageX - $Dragble.mouseStartX);
store.commit('zeditor/setDataItemById', {
id: $Dragble.id,
styleName: 'top',
value: $Dragble.top + top,
});
store.commit('zeditor/setDataItemById', {
id: $Dragble.id,
styleName: 'left',
value: $Dragble.left + left,
});
// 这两行必须要有,为了移动的时候重置中心点的坐标
this.centerPointX =
$Dragble.dom.getBoundingClientRect().left +
$Dragble.dom.getBoundingClientRect().width / 2;
this.centerPointY =
$Dragble.dom.getBoundingClientRect().top +
$Dragble.dom.getBoundingClientRect().height / 2;
},
mouseup: function() {
document.removeEventListener('mousemove', this.mousemove);
},
// 初始化数据
intData: function(id, dom, type, maxLeft, maxTop) {
this.dom = dom;
this.id = id;
this.isMove = true;
this.positionType = type;
this.dom.style.position = type;
this.mouseStartX = window.event.pageX;
this.mouseStartY = window.event.pageY;
this.left = Number.parseFloat(this.dom.style.left);
this.top = Number.parseFloat(this.dom.style.top);
this.dom.style.left ? this.dom.style.left : (this.dom.style.left = 0);
this.dom.style.top ? this.dom.style.top : (this.dom.style.top = 0);
this.centerPointX = dom.getBoundingClientRect().left + dom.getBoundingClientRect().width / 2;
this.centerPointY = dom.getBoundingClientRect().top + dom.getBoundingClientRect().height / 2;
// 按下右键的时候不能移动组件
const that = this;
const vdom = document.querySelector('.editor-panel');
if (vdom) {
vdom.oncontextmenu = function() {
that.isMove = false;
};
}
},
mousedown: function(id, dom, type, maxLeft, maxTop) {
this.intData(id, dom, type, maxLeft, maxTop);
document.addEventListener('mousemove', this.mousemove, false);
document.removeEventListener('mouseup', this.mousemove);
},
};
1、编辑器可视化主界面
2、支持置顶、置底、删除、复制、粘贴、数据绑定等功能
3、拥有丰富图标组件库,支持自定义上传素材
4、支持多种类型字体输出绑定
5、动态水流方向和动态GIF图标
6、针对不同的设备类型不同的数据绑定
部分项目案例:
水厂可视化
-
供水系统图可视化
-
供暖锅炉房可视化
-
实验室风机可视化
-
煤矿可视化项目
-
物联网智能网关
-
PLC可编程控制器