很專業的 chart,值得推荐,使用 Vue 架構更好了,與 Node Red 結合真是太美了
原因是很模組化雖然物聯網做圖表很容易,但美麗圖表畢竟較吸引人
-----index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes">
<title>eCharts/VueJS Example - Node-RED UI Builder</title>
<meta name="description" content="Node-RED UI Builder - eCharts/VueJS Example">
<link rel="icon" href="./images/node-blue.ico">
<link type="text/css" rel="stylesheet" href="../uibuilder/vendor/bootstrap/dist/css/bootstrap.min.css" />
<link type="text/css" rel="stylesheet" href="../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.css" />
<link rel="stylesheet" href="./index.css" media="all">
</head>
<body>
<div id="app">
<b-container fluid id="app_container" class="p-3">
<h4 class="ml-4 mt-4">
人臉辨識統計
</h4>
<b-row class="ml-4 mt-5">
<b-card header="條形圖" border-variant="primary" header-bg-variant="primary"
header-text-variant="white" align="center">
<v-chart :options="ecOptionsBar" />
</b-card>
</b-row>
</b-container>
</div>
<script src="../uibuilder/vendor/socket.io/socket.io.js"></script>
<script src="../uibuilder/vendor/vue/dist/vue.min.js"></script>
<script src="../uibuilder/vendor/bootstrap-vue/dist/bootstrap-vue.js"></script>
<!-- Loading from CDN, use uibuilder to install packages and change to vendor links -->
<script src="https://cdn.jsdelivr.net/npm/echarts@4.1.0/dist/echarts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue-echarts@4.0.2"></script>
<script src="./uibuilderfe.min.js"></script> <!-- //prod version -->
<script src="./index.js"></script>
</body>
</html>
----index.js
/* jshint browser: true, esversion: 5 */
/* globals document,Vue,window,uibuilder,VueECharts */
// @ts-nocheck
/*
Copyright (c) 2019 Julian Knight (Totally Information)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
'use strict'
/** @see https://github.com/TotallyInformation/node-red-contrib-uibuilder/wiki/Front-End-Library---available-properties-and-methods */
/** Reference the component (removes need for a build step with import) */
Vue.component('v-chart', VueECharts)
// var date = [];
// var data = [];
// eslint-disable-next-line no-unused-vars
var app1 = new Vue({
el: '#app',
data: {
// Data for bar chart
ecOptionsBar: {
backgroundColor: '#000',
grid: {
bottom: 100
},
tooltip: {
trigger: 'axis',
position: function (pt) {
return [pt[0], '10%'];
}
},
title: {
left: 'center',
text: '人臉辨識',
},
/*toolbox: {
feature: {
dataZoom: {
yAxisIndex: 'none'
},
restore: {},
saveAsImage: {}
}
},*/
xAxis: {
type: 'category',
//type: 'time',
boundaryGap: false,
data: [],
axisLabel: {
textStyle: {
color: '#fff'
}
}
},
yAxis: {
type: 'value',
boundaryGap: [0, '100%'],
splitLine: {
lineStyle: {
color: '#404040'
}
},
axisLabel: {
textStyle: {
color: '#fff'
}
}
},
dataZoom: [{
//type: 'inside',
show: true,
backgroundColor: '#fff',
fillerColor: "rgba(255, 255, 255, 0.3)",
dataBackground: {
areaStyle: {
color: "#654062"
}
},
start: 0,
end: 100
}, {
start: 0,
end: 10,
handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
handleSize: '80%',
handleStyle: {
color: '#fff',
shadowBlur: 3,
shadowColor: 'rgba(0, 0, 0, 0.6)',
shadowOffsetX: 2,
shadowOffsetY: 2
}
}],
series: [
{
name: '人數',
type: 'line',
smooth: true,
symbol: 'none',
sampling: 'average',
itemStyle: {
color: 'rgb(255, 70, 131)'
},
areaStyle: {
color: new VueECharts.graphic.LinearGradient(0, 0, 0, 1, [{
offset: 0,
color: 'rgb(255, 158, 68)'
}, {
offset: 1,
color: 'rgb(255, 70, 131)'
}])
},
data: []
}
]
},
}, // --- End of data --- //
computed: {
}, // --- End of computed --- //
methods: {
}, // --- End of methods --- //
// Available hooks: init,mounted,updated,destroyed
mounted: function () {
/** **REQUIRED** Start uibuilder comms with Node-RED @since v2.0.0-dev3
* Pass the namespace and ioPath variables if hosting page is not in the instance root folder
* e.g. If you get continual `uibuilderfe:ioSetup: SOCKET CONNECT ERROR` error messages.
* e.g. uibuilder.start('/nr/uib', '/nr/uibuilder/vendor/socket.io') // change to use your paths/names
*/
uibuilder.start()
var vueApp = this
// Process new messages from Node-RED
uibuilder.onChange('msg', function (newVal) {
console.log("Msg received from Node-Red", newVal);
if (newVal.topic) {
vueApp.ecOptionsBar.series[0].data = newVal.payload.yAxisData
vueApp.ecOptionsBar.xAxis.data = newVal.payload.xAxisData
// let splitTopic = newVal.topic.split('/')
// if (splitTopic.length === 2) {
// if (splitTopic[0].toLowerCase() === 'test1') {
// for (var i=0; i<newVal.payload.length; i++ )
// {
// data.push(newVal.payload[i])
// }
// }
// else
// {
// for (var j=0; j<newVal.payload.length; j++ )
// {
// var str = new Array(newVal.payload[j])
// str = str.toString()
// str = str.slice(0, -5)
// str = str.replace('T', '\n')
// date.push(str)
// }
// }
// }
}
//data.push(newVal.payload)
//date.push(newVal.payload[0])
// console.log(data)
// console.log(date)
})
} // --- End of mounted hook --- //
}) // --- End of app1 --- //
// EOF