前言

前一篇文章里面,描述了页面布局的逻辑和层次。接下来就是图例的显示以及一些JavaScript对于页面的动态处理。

主体

在面板里面配置图例和其他数据内容,这些数据样式可能是向上滚动的div,实时加载数据的图例等等。

逻辑文件

文件名 描述
canvas.js 绘制图例
config.js 基本配置以及图例option
mintool.js 小工具以及组件

全局参数配置

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var config = {
rem: document.documentElement.clientWidth/24,
color: '#fff',
title: {
padding: 2,
top: 0,
left: 'center'
},
series: {
axisLine: {
show: false
},
axisTick: {
show: false
},
splitLine: {
show: false
},
axisLabel: {
show: false
},
pointer: {
show: false
}
},
data: {}
};

config.rem 实现图例的自适应

config.color 默认的颜色

config.title 图例标题配置

config.serise 图例不需要显示一些默认配置

echart初始化和获取元素

canvas.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 初始化
var department = echarts.init(document.getElementById("department"));
var quality = echarts.init(document.getElementById("quality"));
var qualityFooter = document.getElementById("quality-footer");
var stock = echarts.init(document.getElementById("stock"));
var workspaceMon = document.getElementById("workspace-mon");
var produce = echarts.init(document.getElementById("produce"));
// var workspaceEnv = document.getElementById("workspace-env");
// var env = echarts.init(workspaceEnv);
var condition = document.getElementById("condition")
var workspaceEnv = echarts.init(condition);
var machine = document.getElementById('machines');
var workspaceMac = echarts.init(machine);
var material = document.getElementById("material");
var storeMaterial = echarts.init(material);

有一点你需要知道,echart初始器获取元素是通过元素的id。我们需要监听窗口大小是否改变从而使dom进行相应的改变。

canvas.js

1
2
3
4
5
6
7
8
window.addEventListener("resize", ()=>{
// 监听窗口大小
config.rem = document.documentElement.clientWidth / 24;
update();
});
function update(){
// 用于更新图例配置项
}

厂房人员监控

config.js

利用四个饼图展示四个部门用于监控当前人数,如需监控更多的部门可以使用数据更新或timeline参数分页设置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// 厂房人员监控
var numMax = 300;//最大人数
var numMin = 0;//最少人数
var departmentA = 120;//A部门人数
var departmentB = 80;//B部门人数
var departmentC = 60;//C部门人数
var departmentD = 210;//外来人数

function WPMOptions(config) {//参数函数
var seriesProgress = {//进度条设置
show: true,
width: config.rem / 8
};
var seriesAxisLine = {//坐标线设置
show: true,
lineStyle: {
width: config.rem / 8
}
};
var opRadius = '70%';
var opCenter = [
["14%", "75%"],
["38%", "75%"],
["62%", "75%"],
["86%", "75%"],
];
return {
title: {
text: '厂房人员监控',
textStyle: {
color: config.color,
fontSize: config.rem / 6 * 1.5
},
top: config.title.top,
left: config.title.left,
padding: config.title.padding
},
series: [
// 部门A
{
type: 'gauge',
center: opCenter[0],
radius: opRadius,
startAngle: 210,
endAngle: -30,
min: numMin,
max: numMax,
progress: seriesProgress,
axisLine: seriesAxisLine,
axisTick: config.series.axisTick,
splitLine: config.series.splitLine,
axisLabel: config.series.axisLabel,
pointer: config.series.pointer,
itemStyle: {
color: '#b20a2c'
},
detail: {
color: config.color,
fontWeight: 'normal',
fontFamily: 'sans-serif',
fontSize: config.rem / 6,
lineHeight: config.rem / 6 * 1.2,
offsetCenter: [0, 0],
formatter: '{value}\n部门A'
},
data: [{
value: departmentA
}]
},
...//后三个与部门a代码几乎一致
]
}
};

这里有一点就是WPMOptions()函数用于返回图例配置参数,这样做可以使参数自动更新省去了单独设置参数

数据更新就是直接将源数据通过series.data更新。

  1. 获取参数

    1
    var options = department.getOption()
  2. 修改参数

    1
    options.series[0].data[0].value = 60

图表分页步骤:

  1. 设置timeline

    1
    2
    3
    4
    timeline: {
    // 两页
    data: ['a', 'b']
    }
  2. 设置一页的图例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    series: [{
    type: 'gauge'
    },{
    type: 'gauge'
    },{
    type: 'gauge'
    },{
    type: 'gauge'
    }]
  3. 设置参数值

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    options: [
    {
    series: [
    { data: [120] },
    { data: [60] },
    { data: [80] },
    { data: [100] }
    ]
    },{
    series: [
    {
    data: [210],
    detail: {
    formatter: '{value}\n部门E'
    }
    },
    {
    data: [20],
    detail: {
    formatter: '{value}\n部门f'
    }
    }
    ]
    }
    ]

注意

  • 仪表盘的位置通过center来进行改变。
  • option的参数里面设置宽高和字体大小不太支持字符串形式,例如标题的字体大小、仪表盘的进度条宽度、仪表盘的轴线宽度等等。
  • echart.resize()只是改变画布大小,里面的参数不会改变。
  • setOption可以用于更新数据和参数。

产品质检数据

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 产品质检数据
var PQDOdata = [
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
[10, 10, 9, 7, 8, 7, 7, 9, 7, 9]
];

function PQDOption(config) {
return {
title: {
text: '产品质检数据',
//后面代码和上面的title一致
},
tooltip: {
trigger: 'axis',
confine: true,
formatter: '{a}:{c}',
padding: config.rem / 8,
textStyle: {
fontSize: config.rem / 5
}
},
legend: {
data: ['评分'],
show: false
},
xAxis: {
data: PQDOdata[0],
type: 'category',
boundaryGap: false,
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
yAxis: {
min: 7,
type: 'value',
interval: 0.5,
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
grid: {
left: '10%',
top: '75%',
bottom: '75%',
right: '2%'
},
series: [{
name: '评分',
type: 'line',
showSymbol: false,
data: PQDOdata[1],
smooth: true,
areaStyle: {
color: '#0044F0'
},
lineStyle: {
color: '#0044F0',
width: config.rem / 32,
}
}]
}
};

注意

  • 通过grid来对图例显示区域定位
  • 消除折线上面的标记showSymbol: false
  • 使折线平滑过渡smooth: true

向上滚动的表格

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
function creteTable(element) {
var data = {
th: ['产品类型', '产品纯度', '产品净度', '检测率', '发货率', '检测时间'],
tr: [
['产品一', 80, 100, 70, 80, '21/5/29'],
['产品二', 80, 100, 70, 80, '21/5/29'],
['产品三', 80, 100, 70, 80, '21/5/29'],
['产品四', 80, 100, 70, 80, '21/5/29'],
['产品五', 80, 100, 70, 80, '21/5/29'],
['产品六', 80, 100, 70, 80, '21/5/29']
],
data: '',
}
// 1. 创建表格
var table = document.createElement('div');
var thead = document.createElement('div');
var tbody = document.createElement('div');
var tr = document.createElement('div');
var th = document.createElement('div');
var td = document.createElement('div');

for (var i = 0; i < 6; i++) {
var th = '<div class="th">' + data.th[i] + '</div>'
data.data += th;
}

tr.setAttribute('class', 'tr');
tr.innerHTML = data.data;

thead.appendChild(tr);

data.data = '';
trList = ''
for (var i = 0; i < 6; i++) {
for (var j = 0; j < 6; j++) {
var td = '<div class="td">' + data.tr[i][j] + '</div>'
data.data += td
}
var tr = '<div class="tr" data-row="' + (i + 1) + '">' + data.data + '</div>'
trList += tr;
data.data = '';
}

table.setAttribute('class', 'table');

thead.setAttribute('class', 'thead');
table.appendChild(thead);

tbody.setAttribute('class', 'tbody');
tbody.setAttribute('id', 'scrollBox');
tbody.innerHTML = trList;
table.appendChild(tbody);

element.appendChild(table);
}

index.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
.table {
margin: 0;
}

.thead {
margin: 0;
}

.tbody {
overflow: hidden;
height: 1.25rem;
}

.tr {
text-align: center;
display: flex;
}

.th, .td {
flex: 1;
}

.th {
font-size: .125rem;
padding: 2px;
border: 2px solid #000;
background-color: RGB(0,51,180);
}

.td {
font-size: .125rem;
padding: .125rem;
}

上面的代码时关于表格的样式配置。

注意

  • appendChild()这个函数不能添加相同变量名创建的元素,会自动覆盖掉
  • 使用scrollTop的条件:
    • 父级的高度小于子级滚动元素的高度
    • 需要处理溢出情况,可以使用hidden\visible\scroll

问题

  • 表格rem不起作用(还未解决)

库房库存量监控

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
function WIMOption(config) {
WIMdata = [
{ value: 1048, name: '物料一' },
{ value: 735, name: '物料二' },
{ value: 580, name: '物料三' },
{ value: 484, name: '物料四' },
{ value: 300, name: '物料五' }
]
return {
title: {
text: '库房库存量监控',
//和上面代码一致
},
tooltip: {
trigger: 'item',
//除了没有设置formatter基本和上面配置一致
},
legend: {
data: ['物料一', '物料二', '物料三', '物料四', '物料五'],
padding: config.rem/32,//图例内边距
itemGap: config.rem / 8,//图例每项之间的间隔
itemWidth: config.rem / 4,//图例标记的图形宽度
itemHeight: config.rem / 4,//图例标记的图形高度
top: '12%',
textStyle: {
color: 'auto',
fontSize: config.rem / 6
}
},
series: [{
type: 'pie',
radius: ['30%', '55%'],//内外圈
avoidLabelOverlap: false,//标签不重叠
center: ['50%', '65%'],
itemStyle: {
borderRadius: config.rem / 20,
borderWidth: 0
},
label: {
show: true,
formatter: '{a|{c}}\n{hr|}\n{a|{b}}',
rich: {
a: {
color: 'auto',
lineHeight: config.rem / 4,
align: 'center',
fontSize: config.rem / 6
},
hr: {
borderColor: 'auto',
width: '100%',
borderWidth: 1,
height: 0
},
}
},
emphasis: {//高亮设置
label: {
show: true,
fontSize: config.rem / 6,
}
},
labelLine: {//标签引导线
show: true,
color: 'auto',
lineStyle: {
width: config.rem / 30,
},
length: config.rem / 8,//引导线第一段
length2: config.rem / 2,//引导线第二段
},
data: WIMdata,
}]
}
}

注意

  • rich可以自定义富文本样式与formatter{styleName|text content}互相配合

厂房视频监控画面

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function WMOption(element) {
var WMdata = [
'./img/gif1.gif',
'./img/gif2.gif',
'./img/gif3.gif',
'./img/gif4.gif'
]
var WMdiv = document.createElement("div");
var imgList = ''
for (var i = 0; i < 4; i++) {
var img = '<img src="' + WMdata[i] + '"/>';
imgList += img;
}
WMdiv.innerHTML = imgList;
element.appendChild(WMdiv);
}

生产实时监控

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// 生产实时监控
function PRTOption(config) {
var PRTdata = [
['date', '生产订单', '物料投入'],
['5月1日', 43.3, 85.8],
['5月2日', 83.1, 73.4],
['5月3日', 65.2, 82.5],
['5月4日', 53.9, 39.1],
['5月5日', 43.3, 85.8],
['5月6日', 83.1, 73.4],
['5月7日', 65.2, 82.5],
['5月8日', 53.9, 39.1]
]
return {
title: {
text: '库房库存量监控',
//和上面代码一致
},
tooltip: {
trigger: 'item',
//除了没有设置formatter基本和上面配置一致
},
legend: {
show: true,
itemGap: config.rem / 8,
itemWidth: config.rem / 4,
itemHeight: config.rem / 4,
textStyle: {
color: 'auto',
fontSize: config.rem / 6
}
},
dataset: {//数据集
source: PRTdata
},
xAxis: {
type: 'category',
boundaryGap: true,
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
yAxis: {
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
grid: {
left: '10%',
top: '80%',
bottom: '70%',
right: 0
},
series: [
{
type: 'bar',
},
{
type: 'bar',
},
]
};
}

厂房环境监控

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
// 厂房环境监控
function WCEOption(config) {
return {
title: {
text: '厂房环境监控',
textStyle: {
color: config.color,
fontSize: config.rem / 6 * 1.5
},
left: config.title.left,
subtext: '环境各项指标',
subtextStyle: {
fontSize: config.rem/6
}
},
}
}
// 环境指数
var WEdata = [
[{
before: '废气',
value: '12',
after: 't/a'
}, {
before: '废水',
value: '12',
after: 'm³/a',
}, {
before: '湿度',
value: '12',
after: '%RH'
}], [{
before: '噪音',
value: '12',
after: 'dB(A)'
}, {
before: '粉尘',
value: '12',
after: 'mg/NM³'
}, {
before: '温度',
value: '12',
after: '℃'
}]
]
function createEnv(element) {
var div = document.createElement('div');
div.setAttribute('id', 'envBox');
element.appendChild(div);
for (var i = 0; i < 2; i++) {
var col = document.createElement('div');
col.setAttribute('class', 'colEnv-' + i);
$('#envBox').append(col);
for (var j = 0; j < 3; j++) {
var data = WEdata[i][j]
var box = document.createElement('div');
box.setAttribute('class', 'envBox-' + i + '-' + j);
box.innerHTML = data.value;
$('.colEnv-' + i).append(box);
}
}
}

index.css

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#env-select {
position: absolute;
top: 5%;
right: 5%;
height: .25rem;
font-size: .2rem;
color:rgba(255, 255, 255, 0.6);
background-color: transparent;
border: none;
outline: none;
}

#env-select option {
color:rgba(255, 255, 255, 0.6);
background-color: #000;
font-size: .2rem;
}

#envBox {
width: 100%;
position: absolute;
top: 30%;
}

#envBox div {
display: flex;
flex-direction: row;
}

.colEnv-0 div, .colEnv-1 div {
flex: 1;
margin: .125rem .03125rem;
padding: .1875rem;
font-size: .25rem;
font-family: DS-DIGI;
color: rgb(0, 250, 130);
background: url(../img/block.png) no-repeat top center;
background-size: 100% 100%;
}

.envBox-0-0:before {
content: '废气'
}
.envBox-0-0:after {
content: 't/a'
}

.envBox-0-1:before {
content: '废水'
}
.envBox-0-1:after {
content: 'm³';
}

.envBox-0-2:before {
content: '湿度'
}
.envBox-0-2:after {
content: '%RH'
}

.envBox-1-0:before {
content: '噪音'
}
.envBox-1-0:after {
content: 'dB(A)'
}

.envBox-1-1:before {
content: '粉尘'
}
.envBox-1-1:after {
content: 'mg/m³'
}

.envBox-1-2:before {
content: '温度'
}
.envBox-1-2:after {
content: '℃'
}

.envBox-0-0:before, .envBox-0-1:before, .envBox-0-2:before, .envBox-1-0:before, .envBox-1-1:before, .envBox-1-2:before {
padding-right: .03125rem;
margin-right: auto;
color: rgba(255, 255, 255);
font-size: .1875rem;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}

.envBox-0-0:after, .envBox-0-1:after, .envBox-0-2:after, .envBox-1-0:after, .envBox-1-1:after, .envBox-1-2:after {
padding-left: .03125rem;
margin-left: auto;
color: rgb(0, 130, 250);
font-size: .0625rem;
font-family: Verdana, Geneva, Tahoma, sans-serif;
}

注意

  • 通过元素的before&after设置content的名字和单位
  • before&after可以单独设置样式

问题

  • rem不起作用

厂房设备监控

config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
var WMQdata = [
[1, 2, 3, 4, 5, 6, 7, 8, 9],
[10, 30, 20, 50, 30, 40, 43, 20, 60]
]
function WMQOptions(config) {
return {
title: {
text: '厂房设备监控',
//和上面代码一致
},
tooltip: {
trigger: 'axis',
confine: true,
formatter: '{a}:{c}',
padding: config.rem / 8,
textStyle: {
fontSize: config.rem / 5
}
},
legend: {
data: ['评分'],
show: false
},
xAxis: {
data: WMQdata[0],
type: 'category',
boundaryGap: false,
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
yAxis: {
interval: 10,
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
grid: {
left: '10%',
top: '80%',
bottom: '70%',
right: '5%'
},
series: [{
name: '评分',
type: 'line',
showSymbol: false,
data: WMQdata[1],
smooth: true,
areaStyle: {
color: '#0044F0'
},
lineStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [{
offset: 1, color: '#c6ffdd' // 0% 处的颜色
}, {
offset: 0.5, color: '#fbd786'
}, {
offset: 0, color: '#f7797d' // 100% 处的颜色
}],
global: false // 缺省为 false
}
},
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 1,
y2: 0,
colorStops: [{
offset: 0, color: '#c6ffdd' // 0% 处的颜色
}, {
offset: 0.5, color: '#fbd786'
}, {
offset: 1, color: '#f7797d' // 100% 处的颜色
}],
global: false
}
},
width: config.rem / 32,
}]
}
}

物料存储数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
var SMdata = [
['物料五', '物料四', '物料三', '物料二', '物料一'],
[{
value: 500,
itemStyle: {
color: '#1565c0'
}
}, {
value: 580,
itemStyle: {
color: '#fbd786'
}
}, {
value: 625,
itemStyle: {
color: '#00b09b'
}
}, {
value: 700,
itemStyle: {
color: '#6dd5fa'
}
}, {
value: 800,
itemStyle: {
color: '#8e2de2'
}
}]
]
function SMOptions(config) {
return {
title: {
text: '物料存储数据',
textStyle: {
color: config.color,
fontSize: config.rem / 6 * 1.5
},
left: config.title.left,
},
tooltip: {
trigger: 'axis',
confine: true,
padding: config.rem / 8,
textStyle: {
fontSize: config.rem / 5
},
enterable: true
},
xAxis: {
type: 'value',
boundaryGap: false,
axisLabel: {
show: false,
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
yAxis: {
type: 'category',
data: SMdata[0],
axisLabel: {
fontSize: config.rem / 6
},
splitLine: config.series.splitLine,
axisLine: config.series.axisLine,
axisTick: config.series.axisTick
},
grid: {
left: '15%',
top: '100%',
bottom: '80%',
right: '20%'
},
series: [{
type: 'bar',
data: SMdata[1],
label: {
normal: {
formatter: function (data) {
return data.value;
},
show: true,
fontSize: config.rem / 6,
position: 'right',
distance: config.rem / 6,
color: '#fff',
backgroundColor: '#1D3039',
padding: config.rem / 8,
borderRadius: config.rem / 4,
}
},
barCategoryGap: '45%'
}]
}
}

注意

  • 只需要切换xaxisyaxis的类型,就可以更换图形方向

效果图

【效果图网址】

下面可以看出字体出现错误布局,rem不起作用尚未解决。你可以使用电脑点击上面的链接查看正确的布局。