3 changed files with 665 additions and 24 deletions
@ -0,0 +1,618 @@ |
|||
<!DOCTYPE html> |
|||
<html lang="zh-CN" style="height: 100%"> |
|||
<head> |
|||
<meta charset="utf-8"> |
|||
<script type="text/javascript" src="/script/jquery.min.js"></script> |
|||
<script type="text/javascript" src="/script/vue.js"></script> |
|||
<script src="/script/axios.min.js"></script> |
|||
</head> |
|||
<body style="height: 100%; margin: 0"> |
|||
|
|||
<div> |
|||
<button onclick="hideDiv()"> |
|||
隐藏 |
|||
</button> |
|||
<div id="app"> |
|||
<div v-for="device in device_list"> |
|||
<div>@{{device.name}}</div> |
|||
<div v-if="device.online == 1"> |
|||
在线 |
|||
</div> |
|||
<div v-else> |
|||
离线 |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div id="container1" style="height: 60%;"></div> |
|||
<div id="container2" style="height: 40%;"></div> |
|||
<div id="container3" style="height: 100%;"></div> |
|||
|
|||
<script type="text/javascript" src="/script/jquery.min.js"></script> |
|||
<script type="text/javascript" src="https://fastly.jsdelivr.net/npm/echarts@5.3.3/dist/echarts.min.js"></script> |
|||
|
|||
|
|||
<script type="text/javascript"> |
|||
var device_list = []; |
|||
|
|||
const app = { |
|||
data() { |
|||
return { |
|||
device_list: [], |
|||
aaaa:0, |
|||
} |
|||
}, |
|||
mounted() { |
|||
var _this = this; |
|||
axios |
|||
.get('/loraDeviceList') |
|||
.then(function (response) { |
|||
device_list = response.data |
|||
_this.device_list = device_list; |
|||
}) |
|||
.catch(function (error) { // 请求失败处理 |
|||
console.log(error); |
|||
}); |
|||
|
|||
// 每隔5分钟定时刷新 |
|||
this.timer = setInterval(() => { |
|||
this.getFxItemlist(); |
|||
}, 1000 * 3) |
|||
}, |
|||
beforeDestroy() { |
|||
clearInterval(this.timer); |
|||
}, |
|||
methods: { |
|||
getFxItemlist() { |
|||
this.device_list = device_list |
|||
this.$forceUpdate(); |
|||
} |
|||
} |
|||
} |
|||
|
|||
Vue.createApp(app).mount('#app') |
|||
|
|||
|
|||
var mac = '616162626363'; |
|||
var clear = 0; |
|||
//默认显示各项对比 |
|||
var show_type = 1; |
|||
//1血氧 |
|||
var compare_type = 1; |
|||
|
|||
var dom1 = document.getElementById('container1'); |
|||
var dom2 = document.getElementById('container2'); |
|||
var dom3 = document.getElementById('container3'); |
|||
|
|||
var data_blood = []; |
|||
var data_temperature = []; |
|||
var data_heart = []; |
|||
var data_humidity = []; |
|||
var data_total = []; |
|||
|
|||
buildChart1(dom1); |
|||
buildChart2(dom2); |
|||
buildChart3(dom3); |
|||
$("#container3").hide(); |
|||
|
|||
function hideDiv() { |
|||
$("#container1").toggle(); |
|||
$("#container2").toggle(); |
|||
$("#container3").toggle(); |
|||
|
|||
clear = 1 |
|||
show_type = (show_type == 1) ? 2 : 1; |
|||
} |
|||
|
|||
/** |
|||
* 各项对比 |
|||
* @param dom |
|||
*/ |
|||
function buildChart1(dom) { |
|||
var myChart = echarts.init(dom, 'dark', { |
|||
renderer: 'canvas', |
|||
useDirtyRect: false |
|||
}); |
|||
|
|||
var option = { |
|||
color: ['#2ec7c9', '#5ab1ef', '#f5994e', '#c05050', '#c14089', '#9a7fd1'], |
|||
grid: { |
|||
left: '25%' |
|||
}, |
|||
tooltip: { |
|||
trigger: 'axis' |
|||
}, |
|||
legend: { |
|||
data: [ |
|||
{ |
|||
name: '血氧', |
|||
textStyle: { |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
{ |
|||
name: '温度', |
|||
textStyle: { |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
{ |
|||
name: '心率', |
|||
textStyle: { |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
{ |
|||
name: '湿度', |
|||
textStyle: { |
|||
color: 'auto' |
|||
} |
|||
}, |
|||
{ |
|||
name: '总体', |
|||
textStyle: { |
|||
color: 'auto' |
|||
} |
|||
} |
|||
], |
|||
textStyle: { |
|||
fontSize: 20 |
|||
} |
|||
}, |
|||
xAxis: { |
|||
type: 'time', |
|||
name: '时间(/s)', |
|||
axisLabel: { |
|||
fontSize: 16, |
|||
formatter: function (value) { |
|||
return echarts.format.formatTime('mm:ss', new Date(value)); |
|||
} |
|||
}, |
|||
nameTextStyle: { |
|||
fontSize: 16 |
|||
} |
|||
}, |
|||
yAxis: [ |
|||
{ |
|||
name: '血氧', |
|||
min: 0, |
|||
max: 100, |
|||
position: 'left', |
|||
nameTextStyle: { |
|||
align: 'right', |
|||
color: '#2ec7c9', |
|||
fontSize: 16 |
|||
}, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { |
|||
color: '#2ec7c9' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
formatter: '{value}%', |
|||
color: '#2ec7c9', |
|||
fontSize: 16 |
|||
}, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '温度', |
|||
min: 30, |
|||
max: 45, |
|||
position: 'left', |
|||
offset: 50, |
|||
nameTextStyle: { |
|||
align: 'right', |
|||
color: '#5ab1ef', |
|||
fontSize: 16 |
|||
}, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { |
|||
color: '#5ab1ef' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
formatter: '{value}°C', |
|||
color: '#5ab1ef', |
|||
fontSize: 16 |
|||
}, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '心率', |
|||
min: 0, |
|||
max: 150, |
|||
position: 'left', |
|||
offset: 100, |
|||
nameTextStyle: { |
|||
align: 'right', |
|||
color: '#f5994e', |
|||
fontSize: 16 |
|||
}, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { |
|||
color: '#f5994e' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
formatter: '{value}次', |
|||
color: '#f5994e', |
|||
fontSize: 16 |
|||
}, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '湿度', |
|||
min: 0, |
|||
max: 100, |
|||
position: 'left', |
|||
offset: 150, |
|||
nameTextStyle: { |
|||
align: 'right', |
|||
color: '#c05050', |
|||
fontSize: 16 |
|||
}, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { |
|||
color: '#c05050' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
formatter: '{value}%', |
|||
color: '#c05050', |
|||
fontSize: 16 |
|||
}, |
|||
}, |
|||
{ |
|||
type: 'value', |
|||
name: '总体', |
|||
min: 0, |
|||
max: 100, |
|||
position: 'left', |
|||
offset: 200, |
|||
nameTextStyle: { |
|||
align: 'right', |
|||
color: '#c14089', |
|||
fontSize: 16 |
|||
}, |
|||
axisLine: { |
|||
show: true, |
|||
lineStyle: { |
|||
color: '#c14089' |
|||
} |
|||
}, |
|||
axisLabel: { |
|||
formatter: '{value}%', |
|||
color: '#c14089', |
|||
fontSize: 16 |
|||
}, |
|||
} |
|||
], |
|||
series: [ |
|||
{ |
|||
name: '血氧', |
|||
type: 'scatter', |
|||
symbolSize: 10, |
|||
yAxisIndex: 0, |
|||
tooltip: { |
|||
valueFormatter: (value) => value.toFixed(2) + ' %' |
|||
} |
|||
}, |
|||
{ |
|||
name: '温度', |
|||
type: 'scatter', |
|||
symbolSize: 10, |
|||
yAxisIndex: 1, |
|||
tooltip: { |
|||
valueFormatter: (value) => value.toFixed(2) + ' ℃' |
|||
} |
|||
}, |
|||
{ |
|||
name: '心率', |
|||
type: 'scatter', |
|||
symbolSize: 10, |
|||
yAxisIndex: 2, |
|||
tooltip: { |
|||
valueFormatter: (value) => value.toFixed(2) + ' 次' |
|||
} |
|||
}, |
|||
{ |
|||
name: '湿度', |
|||
type: 'scatter', |
|||
symbolSize: 10, |
|||
yAxisIndex: 3, |
|||
tooltip: { |
|||
valueFormatter: (value) => value.toFixed(2) + ' %' |
|||
} |
|||
}, |
|||
{ |
|||
name: '总体', |
|||
type: 'line', |
|||
smooth: true, |
|||
tooltip: { |
|||
valueFormatter: (value) => value.toFixed(2) + ' %' |
|||
} |
|||
} |
|||
], |
|||
|
|||
}; |
|||
|
|||
|
|||
if (option && typeof option === 'object') { |
|||
myChart.setOption(option); |
|||
} |
|||
|
|||
window.addEventListener('resize', myChart.resize); |
|||
|
|||
|
|||
setInterval(function () { |
|||
if (show_type != 1) { |
|||
if (clear == 1) { |
|||
data_blood = [] |
|||
data_temperature = []; |
|||
data_heart = []; |
|||
data_humidity = []; |
|||
data_total = []; |
|||
clear = 0; |
|||
} |
|||
|
|||
return; |
|||
} |
|||
|
|||
$.get('/loraData2?mac=' + mac).done(function (_rawData) { |
|||
let limit = 5 |
|||
if (data_blood.length >= limit) { |
|||
data_blood.shift(); |
|||
} |
|||
if (data_temperature.length >= limit) { |
|||
data_temperature.shift(); |
|||
} |
|||
if (data_heart.length >= limit) { |
|||
data_heart.shift(); |
|||
} |
|||
if (data_humidity.length >= limit) { |
|||
data_humidity.shift(); |
|||
} |
|||
if (data_total.length >= 10 * limit) { |
|||
data_total.splice(0, 10); |
|||
} |
|||
_rawData.blood.forEach(value => data_blood.push(value)); |
|||
_rawData.temperature.forEach(value => data_temperature.push(value)); |
|||
_rawData.heart.forEach(value => data_heart.push(value)); |
|||
_rawData.humidity.forEach(value => data_humidity.push(value)); |
|||
_rawData.total_data.forEach(value => data_total.push(value)); |
|||
|
|||
myChart.setOption({ |
|||
series: [ |
|||
{ |
|||
name: '血氧', |
|||
data: data_blood |
|||
}, { |
|||
name: '温度', |
|||
data: data_temperature |
|||
}, { |
|||
name: '心率', |
|||
data: data_heart |
|||
}, { |
|||
name: '湿度', |
|||
data: data_humidity |
|||
}, |
|||
{ |
|||
name: '总体', |
|||
data: data_total |
|||
} |
|||
] |
|||
}); |
|||
}); |
|||
|
|||
}, 2000); |
|||
} |
|||
|
|||
/** |
|||
* 雷达图 |
|||
* @param dom |
|||
*/ |
|||
function buildChart2(dom) { |
|||
var myChart = echarts.init(dom, 'dark', { |
|||
renderer: 'canvas', |
|||
useDirtyRect: false |
|||
}); |
|||
|
|||
var option = { |
|||
color: ['#2ec7c9', '#5ab1ef', '#f5994e', '#c05050', '#c14089', '#9a7fd1'], |
|||
|
|||
radar: { |
|||
// shape: 'circle', |
|||
indicator: [ |
|||
{name: '血氧', max: 100}, |
|||
{name: '温度', max: 45}, |
|||
{name: '心率', max: 150}, |
|||
{name: '湿度', max: 100}, |
|||
], |
|||
axisName: { |
|||
fontSize: 18, |
|||
color: '#2ec7c9', |
|||
}, |
|||
}, |
|||
series: [ |
|||
{ |
|||
type: 'radar', |
|||
} |
|||
] |
|||
}; |
|||
|
|||
if (option && typeof option === 'object') { |
|||
myChart.setOption(option); |
|||
} |
|||
|
|||
window.addEventListener('resize', myChart.resize); |
|||
|
|||
setInterval(buildData, 1000 * 5); |
|||
|
|||
function buildData() { |
|||
if (show_type != 1 || data_blood.length == 0) { |
|||
return; |
|||
} |
|||
|
|||
let blood = data_blood.slice(-1)[0][1]; |
|||
let temperature = data_temperature.slice(-1)[0][1]; |
|||
let heart = data_temperature.slice(-1)[0][1]; |
|||
let humidity = data_humidity.slice(-1)[0][1]; |
|||
|
|||
myChart.setOption({ |
|||
series: [ |
|||
{ |
|||
data: [ |
|||
{ |
|||
value: [blood, temperature, heart, humidity], |
|||
areaStyle: { |
|||
color: 'rgba(255, 228, 52, 0.6)' |
|||
}, |
|||
label: { |
|||
show: true, |
|||
textStyle: { |
|||
color: '#2ec7c9', |
|||
fontSize: 16, |
|||
}, |
|||
formatter: function (params) { |
|||
return params.value; |
|||
} |
|||
} |
|||
} |
|||
|
|||
] |
|||
} |
|||
] |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function buildChart3(dom) { |
|||
var myChart = echarts.init(dom, 'dark', { |
|||
renderer: 'canvas', |
|||
useDirtyRect: false |
|||
}); |
|||
|
|||
var option = { |
|||
tooltip: { |
|||
trigger: 'axis' |
|||
}, |
|||
legend: { |
|||
data: ['设备1', '设备2', '设备3',], |
|||
textStyle: { |
|||
fontSize: 20 |
|||
} |
|||
}, |
|||
xAxis: { |
|||
type: 'time', |
|||
name: '时间(/s)', |
|||
axisLabel: { |
|||
fontSize: 16, |
|||
formatter: function (value) { |
|||
return echarts.format.formatTime('mm:ss', new Date(value)); |
|||
} |
|||
}, |
|||
nameTextStyle: { |
|||
fontSize: 16 |
|||
} |
|||
}, |
|||
yAxis: [ |
|||
{ |
|||
type: 'value', |
|||
min: 0, |
|||
max: 100, |
|||
nameTextStyle: { |
|||
align: 'right', |
|||
fontSize: 16 |
|||
}, |
|||
axisLine: { |
|||
show: true, |
|||
}, |
|||
axisLabel: { |
|||
formatter: '{value}%', |
|||
fontSize: 16 |
|||
}, |
|||
} |
|||
], |
|||
|
|||
}; |
|||
|
|||
|
|||
if (option && typeof option === 'object') { |
|||
myChart.setOption(option); |
|||
} |
|||
|
|||
window.addEventListener('resize', myChart.resize); |
|||
|
|||
let special_compare_data = []; |
|||
setInterval(function () { |
|||
// if (show_type != 2) { |
|||
// if (clear == 1) { |
|||
// special_compare_data = []; |
|||
// clear = 0; |
|||
// } |
|||
// |
|||
// return; |
|||
// } |
|||
|
|||
|
|||
let chart_data = []; |
|||
let expire = 0; |
|||
$.get('/getSpecialCompare?compare_type=' + compare_type).done(function (rawData) { |
|||
//追加数据 |
|||
device_list.forEach(function (item, key) { |
|||
let name = item.name; |
|||
let device_data = rawData[name]; |
|||
if (device_data) { |
|||
device_list[key].online = 1 |
|||
if (special_compare_data[name]) { |
|||
device_data.forEach(value => special_compare_data[name].push(value)); |
|||
} else { |
|||
device_data.forEach(function (value) { |
|||
special_compare_data[name] = [value] |
|||
}); |
|||
} |
|||
|
|||
if (special_compare_data[name].length > 5) { |
|||
if (special_compare_data[name][0][0] > expire) { |
|||
expire = special_compare_data[name][0][0]; |
|||
} |
|||
|
|||
} |
|||
} else { |
|||
device_list[key].online = 0 |
|||
} |
|||
}) |
|||
|
|||
//删除过期时间,构建图表数据 |
|||
for (key in special_compare_data) { |
|||
if (special_compare_data[key] |
|||
&& special_compare_data[key].length > 0 |
|||
&& special_compare_data[key][0][0] <= expire) { |
|||
special_compare_data[key].shift() |
|||
} |
|||
|
|||
chart_data.push({ |
|||
name: key, |
|||
data: special_compare_data[key], |
|||
type: 'line', |
|||
smooth: true, |
|||
}) |
|||
} |
|||
|
|||
myChart.setOption({ |
|||
series: chart_data |
|||
}); |
|||
}); |
|||
|
|||
}, 1000 * 2); |
|||
} |
|||
|
|||
|
|||
</script> |
|||
</body> |
|||
</html> |
Loading…
Reference in new issue