|
@@ -0,0 +1,543 @@
|
|
|
+<template>
|
|
|
+ <div class="sy-content">
|
|
|
+ <el-row>
|
|
|
+ <el-col>
|
|
|
+ <!-- 搜索信息 -->
|
|
|
+ <el-form ref="chartForm" :model="chartForm" :rules="chartFormRules" size="small" :inline="true">
|
|
|
+ <el-row>
|
|
|
+ <el-col :span="4" :xs="8" :sm="6" :md="4" :lg="3" :xl="4">
|
|
|
+ <el-form-item prop="trendType">
|
|
|
+ <el-radio-group v-model="chartForm.trendType">
|
|
|
+ <el-radio :label="0">实时趋势</el-radio>
|
|
|
+ <el-radio :label="1">历史趋势</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col v-if="chartForm.trendType == 0" :span="4">
|
|
|
+ <el-form-item label="更新频率" prop="frequencyValue">
|
|
|
+ <el-input v-model="chartForm.frequencyValue"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col v-if="chartForm.trendType == 0" :span="1" :xl="2">
|
|
|
+ <el-form-item prop="frequencyType">
|
|
|
+ <el-select v-model="chartForm.frequencyType">
|
|
|
+ <el-option v-for="timeType in timeTypeList" :key="timeType.value"
|
|
|
+ :label="timeType.label" :value="timeType.value">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col v-if="chartForm.trendType == 0" :span="4">
|
|
|
+ <el-form-item label="时间长度" prop="timeValue">
|
|
|
+ <el-input v-model="chartForm.timeValue"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col v-if="chartForm.trendType == 0" :span="2">
|
|
|
+ <el-form-item prop="timeType">
|
|
|
+ <el-select v-model="chartForm.timeType">
|
|
|
+ <el-option v-for="timeType in timeTypeList" :key="timeType.value"
|
|
|
+ :label="timeType.label" :value="timeType.value">
|
|
|
+ </el-option>
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col v-if="chartForm.trendType == 1" :span="6">
|
|
|
+ <el-form-item label="开始时间" prop="startTime">
|
|
|
+ <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="chartForm.startTime"
|
|
|
+ type="datetime" placeholder="选择日期">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ <el-col v-if="chartForm.trendType == 1" :span="6">
|
|
|
+ <el-form-item label="结束时间" prop="endTime">
|
|
|
+ <el-date-picker value-format="yyyy-MM-dd HH:mm:ss" v-model="chartForm.endTime"
|
|
|
+ type="datetime" placeholder="选择日期">
|
|
|
+ </el-date-picker>
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+ <el-row>
|
|
|
+ <el-form-item label="数据项" prop="itemListTitile">
|
|
|
+ <el-input :title="chartForm.itemListTitile" v-model="chartForm.itemListTitile" disabled
|
|
|
+ placeholder="请选择数据项" maxlength="10">
|
|
|
+ <el-button type="primary" slot="append" icon="el-icon-search"
|
|
|
+ @click="chooseItemEvent">选择</el-button>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="小数位" prop="decimalPlaces">
|
|
|
+ <el-input v-model="chartForm.decimalPlaces"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="量程" prop="range">
|
|
|
+ <el-input v-model="chartForm.range"></el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" plain icon="el-icon-search" size="mini"
|
|
|
+ @click="queryData">查询</el-button>
|
|
|
+ <el-button type="primary" plain icon="el-icon-folder-opened" size="mini"
|
|
|
+ @click="exportData">导出</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-row>
|
|
|
+ </el-form>
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <!-- 添加数据项 -->
|
|
|
+ <ChooseItem ref="chooseItem" @receiveCheckedData="receiveCheckedData"></ChooseItem>
|
|
|
+ <!-- 统计图 -->
|
|
|
+ <div class="lineChartContant" v-on:mouseover="mouseOver()" v-on:mouseout="mouseOut()">
|
|
|
+ <div ref="chart" class="lineChart" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { showLoading } from '@/utils/cqcy'
|
|
|
+import { parseTime } from "@/utils/index";
|
|
|
+import ChooseItem from './chooseItem.vue'
|
|
|
+import { getItemListValue } from '@/api/source/itemGroup'
|
|
|
+import qs from 'qs'
|
|
|
+import echarts from 'echarts'
|
|
|
+
|
|
|
+export default {
|
|
|
+ created() {
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ ChooseItem
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ timer: null,
|
|
|
+ //如果state为true,则是动态统计图。反之
|
|
|
+ state: null,
|
|
|
+ count: 0,
|
|
|
+ itemGroupList: [],
|
|
|
+ trendTypeList: [
|
|
|
+ { label: '实时趋势', value: 0 },
|
|
|
+ { label: '历史趋势', value: 1 }
|
|
|
+ ],
|
|
|
+ timeTypeList: [
|
|
|
+ { label: '秒', value: 0 },
|
|
|
+ { label: '分', value: 1 },
|
|
|
+ { label: '时', value: 2 },
|
|
|
+ { label: '天', value: 3 }
|
|
|
+ ],
|
|
|
+ itemList: [],
|
|
|
+ chartForm: {
|
|
|
+ itemListTitile: '',
|
|
|
+ idList: [],
|
|
|
+ //趋势类型
|
|
|
+ trendType: 0,
|
|
|
+ //频率值
|
|
|
+ frequencyValue: 1,
|
|
|
+ //频率类型
|
|
|
+ frequencyType: 0,
|
|
|
+ //时间值
|
|
|
+ timeValue: 60,
|
|
|
+ //时间类型
|
|
|
+ timeType: 0,
|
|
|
+ startTime: null,
|
|
|
+ endTime: null,
|
|
|
+ //小数位数
|
|
|
+ decimalPlaces: 2,
|
|
|
+ //量程
|
|
|
+ range: null,
|
|
|
+ },
|
|
|
+ chooseStartTime: null,
|
|
|
+ chooseEndTime: null,
|
|
|
+ chartFormRules: {
|
|
|
+
|
|
|
+ frequencyValue: [
|
|
|
+ { required: true, message: '更新频率值不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ frequencyType: [
|
|
|
+ { required: true, message: '更新频率类型不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ timeValue: [
|
|
|
+ { required: true, message: '时间值不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ timeType: [
|
|
|
+ { required: true, message: '时间类型不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ startTime: [
|
|
|
+ { required: true, message: '开始时间不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ endTime: [
|
|
|
+ { required: true, message: '结束时间不能为空', trigger: 'blur' }
|
|
|
+ ],
|
|
|
+ decimalPlaces: [
|
|
|
+
|
|
|
+ ],
|
|
|
+ range: [
|
|
|
+
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ //charts
|
|
|
+ chart: null,
|
|
|
+ //背景颜色
|
|
|
+ backgroundColor: '#394056',
|
|
|
+ //统计图标题
|
|
|
+ title: {
|
|
|
+ top: 20,
|
|
|
+ text: '数据查询',
|
|
|
+ textStyle: {
|
|
|
+ fontWeight: 'normal',
|
|
|
+ fontSize: 16,
|
|
|
+ color: '#F1F1F3'
|
|
|
+ },
|
|
|
+ left: '1%'
|
|
|
+ },
|
|
|
+ //工具提示
|
|
|
+ tooltip: {
|
|
|
+ show: true,
|
|
|
+ trigger: 'axis',
|
|
|
+ backgroundColor: 'rgba(255, 255, 255, 0.8)',
|
|
|
+ axisPointer: {
|
|
|
+ type: 'cross',
|
|
|
+ label: {
|
|
|
+ backgroundColor: '#777'
|
|
|
+ },
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //列标题
|
|
|
+ legend: {
|
|
|
+ top: 20,
|
|
|
+ icon: 'rect',
|
|
|
+ itemWidth: 14,
|
|
|
+ itemHeight: 5,
|
|
|
+ itemGap: 13,
|
|
|
+ data: [],
|
|
|
+ right: '4%',
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 12,
|
|
|
+ color: '#FFFFFF'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //布局
|
|
|
+ grid: {
|
|
|
+ top: 100,
|
|
|
+ left: '2%',
|
|
|
+ right: '2%',
|
|
|
+ bottom: '2%',
|
|
|
+ containLabel: true
|
|
|
+ },
|
|
|
+ //缩放组件
|
|
|
+ dataZoom: [{
|
|
|
+ type: 'inside', // 放大和缩小
|
|
|
+ orient: 'vertical',
|
|
|
+ }, {
|
|
|
+ type: 'inside',
|
|
|
+ }],
|
|
|
+ //x轴
|
|
|
+ xAxis: {
|
|
|
+ type: 'category',
|
|
|
+ boundaryGap: false,
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#FFFFFF'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: []
|
|
|
+ },
|
|
|
+ //y轴
|
|
|
+ yAxis: [{
|
|
|
+ type: 'value',
|
|
|
+ //是否显示坐标轴刻度。
|
|
|
+ axisTick: {
|
|
|
+ show: true
|
|
|
+ },
|
|
|
+ axisLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#FFFFFF'
|
|
|
+ }
|
|
|
+ },
|
|
|
+ axisLabel: {
|
|
|
+ margin: 10,
|
|
|
+ textStyle: {
|
|
|
+ fontSize: 14
|
|
|
+ }
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ lineStyle: {
|
|
|
+ color: '#57617B'
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }],
|
|
|
+ //数据列
|
|
|
+ series: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /** 接受传过来的数据 */
|
|
|
+ receiveCheckedData(data) {
|
|
|
+ this.itemList = data
|
|
|
+ let arr = []
|
|
|
+ let b = ''
|
|
|
+ for (let i in data) {
|
|
|
+ const a = data[i]
|
|
|
+ arr.push(a.id)
|
|
|
+ if (i == data.length - 1) {
|
|
|
+ b += a.itemGroupId + "." + a.itemReadName
|
|
|
+ } else {
|
|
|
+ b += a.itemGroupId + "." + a.itemReadName + ","
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.chartForm.idList = arr
|
|
|
+ this.chartForm.itemListTitile = b
|
|
|
+ },
|
|
|
+ /** 选择数据项事件 */
|
|
|
+ chooseItemEvent() {
|
|
|
+ this.$refs.chooseItem.selectedItemList = this.itemList
|
|
|
+ this.$refs.chooseItem.visible = true
|
|
|
+ },
|
|
|
+ /** 查询数据 */
|
|
|
+ queryData() {
|
|
|
+ //每次查询的时候,将统计图初清空,定时器清空
|
|
|
+ this.stopTimer()
|
|
|
+ this.destroyChart()
|
|
|
+ if (this.chartForm.idList.length == 0) {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择数据项',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //如果为实时趋势
|
|
|
+ if (this.chartForm.trendType == 0) {
|
|
|
+ if (!this.chartForm.frequencyValue) {
|
|
|
+ this.$message({
|
|
|
+ message: '频率不能为空',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!this.chartForm.timeValue) {
|
|
|
+ this.$message({
|
|
|
+ message: '时间长度不能为空',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ let currentTime = new Date().getTime()
|
|
|
+ this.count = this.timeCalculation(this.chartForm.timeValue, this.chartForm.timeType)
|
|
|
+ this.chooseStartTime = parseTime(new Date(currentTime - this.count))
|
|
|
+ this.chooseEndTime = parseTime(currentTime)
|
|
|
+ //添加监听事件
|
|
|
+ this.state = true
|
|
|
+ //初始化统计图
|
|
|
+ this.initChart()
|
|
|
+ //如果为历史趋势
|
|
|
+ } else if (this.chartForm.trendType == 1) {
|
|
|
+ if (!this.chartForm.startTime) {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择开始时间',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (!this.chartForm.endTime) {
|
|
|
+ this.$message({
|
|
|
+ message: '请选择结束时间',
|
|
|
+ type: 'warning'
|
|
|
+ })
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.chooseStartTime = this.chartForm.startTime
|
|
|
+ this.chooseEndTime = this.chartForm.endTime
|
|
|
+ //展示死统计图,且不添加监听事件
|
|
|
+ this.state = false
|
|
|
+ this.initChart()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /** 通过数据项id,开始结束时间获取相应的数据 */
|
|
|
+ getItemListValue(callback) {
|
|
|
+ if (this.chooseStartTime == this.chooseEndTime) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ let param = {
|
|
|
+ itemGroupId: this.chartForm.itemGroupId,
|
|
|
+ idList: this.chartForm.idList,
|
|
|
+ startTime: this.chooseStartTime,
|
|
|
+ endTime: this.chooseEndTime
|
|
|
+ }
|
|
|
+ let params = qs.stringify(param, { arrayFormat: 'repeat' })
|
|
|
+ getItemListValue(params).then(res => {
|
|
|
+ callback(res);
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 初始化统计图,如果state为true,则是动态,否则是静态 */
|
|
|
+ initChart() {
|
|
|
+ const loading = showLoading(this, "加载中,请稍候···")
|
|
|
+ this.getItemListValue((res) => {
|
|
|
+ let data = res.data
|
|
|
+ this.chart = echarts.init(this.$refs.chart)
|
|
|
+ let legendData = []
|
|
|
+ let seriesData = []
|
|
|
+ for (let a of data) {
|
|
|
+ legendData.push(a.describe ? a.describe : a.itemReadName)
|
|
|
+ let b = {
|
|
|
+ name: a.unit ? ((a.describe ? a.describe : a.itemReadName) + '(' + a.unit + ')') :
|
|
|
+ (a.describe ? a.describe : a.itemReadName),
|
|
|
+ type: 'line',
|
|
|
+ smooth: true,
|
|
|
+ symbol: 'circle',
|
|
|
+ symbolSize: 5,
|
|
|
+ showSymbol: false,
|
|
|
+ itemStyle: {
|
|
|
+ color: this.getColor()
|
|
|
+ },
|
|
|
+ lineStyle: {
|
|
|
+ normal: {
|
|
|
+ width: 1
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data: a.dataValueList
|
|
|
+ }
|
|
|
+ seriesData.push(b)
|
|
|
+ }
|
|
|
+ let decimalPlaces = parseInt(this.chartForm.decimalPlaces)
|
|
|
+ this.tooltip.formatter = function (params, ticket, callback) {
|
|
|
+ let b = '<div style="display:inline;">'
|
|
|
+ for (let a of params) {
|
|
|
+ b += '<div><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:' + a.color + ';"></span><span style="color:' + a.color + '">'
|
|
|
+ + a.name + ' ' + a.seriesName + ': ' + a.data.substring(0, a.data.indexOf(".") + 1 + decimalPlaces) + '</span></div>'
|
|
|
+ }
|
|
|
+ b += '</div>'
|
|
|
+ return b
|
|
|
+ }
|
|
|
+ this.legend.data = legendData
|
|
|
+ this.xAxis.data = data[0].dataTimeList
|
|
|
+ this.yAxis[0].max = null
|
|
|
+ if (this.chartForm.range) {
|
|
|
+ this.yAxis[0].max = parseInt(this.chartForm.range)
|
|
|
+ }
|
|
|
+ this.series = seriesData
|
|
|
+ this.chart.setOption({
|
|
|
+ backgroundColor: this.backgroundColor,
|
|
|
+ title: this.title,
|
|
|
+ tooltip: this.tooltip,
|
|
|
+ legend: this.legend,
|
|
|
+ grid: this.grid,
|
|
|
+ dataZoom: this.dataZoom,
|
|
|
+ xAxis: this.xAxis,
|
|
|
+ yAxis: this.yAxis,
|
|
|
+ series: this.series
|
|
|
+ })
|
|
|
+ if (this.state) {
|
|
|
+ //启动定时器,轮训更新统计图
|
|
|
+ this.startTimer()
|
|
|
+ }
|
|
|
+ loading.close()
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 生成颜色方法 */
|
|
|
+ getColor() {
|
|
|
+ const r = this.colorRandom(128, 255)
|
|
|
+ const g = this.colorRandom(0, 63)
|
|
|
+ const b = this.colorRandom(128, 255)
|
|
|
+ return "rgb(" + r + ", " + g + ", " + b + ")"
|
|
|
+ },
|
|
|
+ /** 颜色数字随机方法 */
|
|
|
+ colorRandom(minValue, maxValue) {
|
|
|
+ return Math.floor((Math.random() * (maxValue - minValue)) + minValue)
|
|
|
+ },
|
|
|
+ /** 鼠标移入事件 */
|
|
|
+ mouseOver() {
|
|
|
+ if (this.state) {
|
|
|
+ this.stopTimer()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /** 鼠标移出事件 */
|
|
|
+ mouseOut() {
|
|
|
+ if (this.state) {
|
|
|
+ this.startTimer()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /** 清除统计图 */
|
|
|
+ destroyChart() {
|
|
|
+ if (!this.chart) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.chart.dispose()
|
|
|
+ this.chart = null
|
|
|
+ },
|
|
|
+ /** 清除定时器 */
|
|
|
+ stopTimer() {
|
|
|
+ clearInterval(this.timer)
|
|
|
+ this.timer = null
|
|
|
+ },
|
|
|
+ /** 设置定时器,继续轮训数据 */
|
|
|
+ startTimer() {
|
|
|
+ this.timer = setInterval(() => {
|
|
|
+ this.chooseStartTime = this.chooseEndTime
|
|
|
+ this.chooseEndTime = parseTime(new Date())
|
|
|
+ this.updateChartData()
|
|
|
+ }, this.timeCalculation(this.chartForm.frequencyValue, this.chartForm.frequencyType))
|
|
|
+ },
|
|
|
+ /** 选择时间类型之后得到时间搓 */
|
|
|
+ timeCalculation(value, type) {
|
|
|
+ if (type == 0) {
|
|
|
+ return value * 1000
|
|
|
+ } else if (type == 1) {
|
|
|
+ return value * 60 * 1000
|
|
|
+ } else if (type == 2) {
|
|
|
+ return value * 60 * 60 * 1000
|
|
|
+ } else if (type == 3) {
|
|
|
+ return value * 60 * 60 * 24 * 1000
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /** 更新统计图数据 */
|
|
|
+ updateChartData() {
|
|
|
+ this.getItemListValue((res) => {
|
|
|
+ let data = res.data
|
|
|
+ if (data && data[0].dataTimeList) {
|
|
|
+ let arrX = this.xAxis.data
|
|
|
+ arrX = arrX.concat(data[0].dataTimeList)
|
|
|
+ //删除掉多余时间
|
|
|
+ let count = new Date(arrX[arrX.length - 1]).getTime() - this.count
|
|
|
+ let num = 0
|
|
|
+ for (let i in arrX) {
|
|
|
+ if (new Date(arrX[i]).getTime() >= count) {
|
|
|
+ num = i
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.xAxis.data = arrX.splice(num)
|
|
|
+ //删除多余数据
|
|
|
+ for (let i in data) {
|
|
|
+ let a = data[i]
|
|
|
+ let arr = this.series[i].data
|
|
|
+ arr = arr.concat(a.dataValueList)
|
|
|
+ this.series[i].data = arr.splice(num)
|
|
|
+ }
|
|
|
+ //更新统计图
|
|
|
+ if (this.chart) {
|
|
|
+ this.chart.setOption({ xAxis: this.xAxis, series: this.series })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ /** 导出统计图数据 */
|
|
|
+ exportData() {
|
|
|
+ console.log("---导出统计图-----")
|
|
|
+ }
|
|
|
+ },
|
|
|
+ destroyed: function () {
|
|
|
+ // 每次离开当前界面时,清除定时器
|
|
|
+ clearInterval(this.timer)
|
|
|
+ this.timer = null
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style rel="stylesheet/scss" lang="scss" scoped>
|
|
|
+.lineChartContant {
|
|
|
+ width: 180vh;
|
|
|
+ height: 75vh;
|
|
|
+
|
|
|
+ .lineChart {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|