Merge pull request '热力图dashboard\big\heatmap.vue' (#2) from pht/SamATV:main into main

Reviewed-on: #2
This commit is contained in:
Huiting Pei 2025-05-06 16:20:33 +08:00
commit b658257881
7 changed files with 824 additions and 144 deletions

View File

@ -71,23 +71,61 @@
```
src/
├── main.js # 入口文件
├── api/ # 接口请求
│ └── system/
│ └── atvApi.ts
│ └── fcrudApi.ts
│ └── fileApi.ts
├── router/ # 路由
│ └── index.js
├── store/ # 状态管理Vuex/Pinia
│ ├── index.js
│ └── modules/
├── views/ # 页面组件(路由级)
│ ├── Home.vue
│ └── list/
│ └── backEnd.ts
│ └── index.ts
│ └── frontEnd.ts
│ └── router.ts
├── stores/ # 状态管理Vuex/Pinia
│ ├── interface/
│ └── index.ts/
├── views/ # 页面组件
│ ├── atv #活动
│ ├── common #公共组件
│ ├── facade #门面
│ ├── monitor #监控中心
│ └── system #系统
├── components/ # 公共组件
│ ├── BaseTable.vue
│ └── SelectDict.vue
│ ├── auth 权限
│ │ ├── auth.vue
│ │ ├── AuthAll.vue
│ │ └── Auths.vue
│ ├── cropper #头像剪裁
│ │ └── index.vue
│ ├── editor #富文本编辑器
│ │ └── index.vue
│ ├── iconSelect #图标选择
│ │ └── index.vue
│ ├── sam #核心组件
│ ├── svgIcon #svg图标
│ └── noticeBar 通知栏
│ └── index.vue
├── assets/ # 静态资源
│ ├── images/
│ ├── style/
│ └── font/
├── utils/ # 工具函数
│ └── request.js # axios封装
├── styles/ # 全局样式
│ ├── variables.scss
│ └── reset.scss
└── layout/ # 全局布局
└── AppLayout.vue
│ └── ajax/
│ └── echarts/
│ └── sam/
│ └── *.ts
├── layout/ # 全局布局
│ └── component/
│ └── footer/ #底部
│ └── lockScreen/ #锁屏
│ └── logo/ #logo
│ └── main/
│ └── navBars/ #导航栏
│ └── navMenu/ #导航菜单
│ └── routerView/ #路由视图
```
重要的文件
G:\Projects\VueProject\SamATV\src\views\common
src/views/common/dashboard/big/index.vue dashboard仪表盘
前端路由G:\Projects\VueProject\SamATV\src\router\route.ts

View File

@ -19,7 +19,7 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
path: '/home', name: 'home',
component: () => import('/@/views/common/dashboard/atv/index.vue'),
meta: {
title: 'message.router.home',
title: '首页',
isLink: '', isHide: false, isKeepAlive: true,
isAffix: true, isIframe: false,
roles: ['admin', 'common'], icon: 'fa fa-home',
@ -33,7 +33,16 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
path: '/big', name: 'grafana',
component: () => import('/@/views/common/dashboard/big/index.vue'),
meta: {
title: 'message.router.bigscreen', isIframe: false, isLink: '/big',
title: '数据监测', isIframe: false, isLink: '/big',
isHide: false, isKeepAlive: false, isAffix: false,
roles: ['admin'], icon: 'fa fa-window-restore'
},
},
{
path: '/line', name: 'line',
component: () => import('/@/views/common/dashboard/big/LineIndex.vue'),
meta: {
title: '具体传感器', isIframe: false, isLink: '/line',
isHide: false, isKeepAlive: false, isAffix: false,
roles: ['admin'], icon: 'fa fa-window-restore'
},
@ -42,7 +51,7 @@ export const dynamicRoutes: Array<RouteRecordRaw> = [
path: '/set_config', name: 'config',
component: () => import('/@/views/common/dashboard/config_page/index.vue'),
meta: {
title: 'message.router.set_config', isIframe: false, isLink: '/set_config',
title: '配置管理', isIframe: false, isLink: '/set_config',
isHide: false, isKeepAlive: false, isAffix: false,
roles: ['admin'], icon: 'fa fa-window-restore'
},

View File

@ -0,0 +1,204 @@
<template>
<div className="home">
<!-- 这个单选框不知道为啥一直有问题-->
<!-- <div class="mb-2 ml-4">-->
<!-- <el-radio-group v-model="picRadio">-->
<!-- <el-radio value="1" size="large">温度监测图</el-radio>-->
<!-- <el-radio value="2" size="large">湿度监测图</el-radio>-->
<!-- <el-radio value="3" size="large">应力监测图</el-radio>-->
<!-- </el-radio-group>-->
<!-- </div>-->
<!-- 查询时间范围和按钮 -->
<div className="form-container">
<el-form-item label="可视化类型:" className="form-item">
<el-select
v-model="typeValue"
placeholder="Select"
size="large"
style="width: 130px"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="查询时间范围:" className="form-item">
<el-date-picker
v-model="timeValue"
type="datetimerange"
range-separator="到"
start-placeholder="开始时间"
end-placeholder="结束时间"
@change="handleDateChange"
style="width: 380px"
/>
</el-form-item>
<el-form-item label="光栅编号范围:" className="form-item">
<el-input-number
v-model="gratingIdMin"
:min="1"
:max="1399"
@change="updateSeries"
placeholder="最小值"
style="width: 150px;"
/>
<span style="margin: 0 5px;"> - </span>
<el-input-number
v-model="gratingIdMax"
:min="1"
:max="1400"
@change="updateSeries"
placeholder="最大值"
style="width: 150px;"
/>
<el-cascader
v-model="value"
:options="options"
style="width: 150px; margin-left: 10px;"
placeholder="其他选项"
@change="handleOtherChange"
/>
</el-form-item>
</div>
<div className="heatmap-container"></div>
<line-chart
:gratingIdArray="gratingIdArray"
:timeRange="timeValue"
:time-granularity="value[1]"
:picType="typeValue"
/>
<!-- 折线图-->
</div>
</template>
<script>
import axios from "axios";
import LineChart from "/@/views/common/dashboard/big/lineChart.vue"; // 线
export default {
components: { LineChart },
data() {
return {
typeValue: "temperature", //
typeOptions: [
{
value: "temperature",
label: "温度监测图",
},
{
value: "humidity",
label: "湿度监测图",
},
{
value: "stress",
label: "应力监测图",
}
],
// picType: "temperature", //
timeValue: [], //
gratingIdMin: 1, //
gratingIdMax: 12, //
gratingIdArray: [], //
value: [], //
options: [
{
value: "timeGranularity",
label: "时间粒度",
children: [
{
value: "hour",
label: "每小时",
},
{
value: "quarterHour",
label: "每15分钟",
},
{
value: "minute",
label: "每分钟",
}
],
}
]
};
},
methods: {
handleDateChange() {
console.log("选中的时间范围:", this.timeValue);
},
//
updateSeries() {
if (this.gratingIdMax - this.gratingIdMin < 0) {
this.$message.error("请输入正确的光栅编号范围!");
}
else if (this.gratingIdMax - this.gratingIdMin >=20) {
this.$message.error( "请选择20个以内的光栅");
}
else{
//
this.gratingIdArray = Array.from(
{ length: this.gratingIdMax - this.gratingIdMin + 1 },
(_, i) => this.gratingIdMin + i
)
}
},
// ,beforeMount()
setDefaultXYRange() {
// 1
const now = new Date();
const oneDayAgo = new Date();
oneDayAgo.setDate(now.getDate() - 1);
this.timeValue = [oneDayAgo, now];
// 1 12
this.gratingIdMin = 1;
this.gratingIdMax = 12;
//
this.gratingIdArray = Array.from(
{ length: this.gratingIdMax - this.gratingIdMin + 1 },
(_, i) => this.gratingIdMin + i
)
},
handleOtherChange(value) {
console.log("级联选择器的值:", value);
console.log("时间粒度:", value[1]);
}
},
mounted() {
},
beforeMount() {
this.setDefaultXYRange();
}
};
</script>
<style scoped>
.home {
width: 100%;
height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px;
}
.form-container {
display: flex;
align-items: center; /* 垂直居中对齐 */
flex-wrap: wrap; /* 当屏幕宽度不足时自动换行 */
margin-top: 10px; /* 与顶部的间距 */
margin-bottom: 10px; /* 和 iframe 的间距 */
margin-left: 10px;
width: 100%;
justify-content: flex-start;
}
.form-item {
margin-right: 10px; /* 按钮和输入框之间的间距 */
}
</style>

View File

@ -0,0 +1,210 @@
<template>
<div ref="chartContainer" style="width: 100%; height: 800px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'Heatmap',
props: {
timeRange: {
type: Array,
default: () => []
},//
gratingIdRange: {
type: Array,
default: () => []
},//
timeGranularity: {
type: String,
default: 'hour'
},//
picType: {
type: String,
default: 'temperature'
}//
},
data() {
return {
chart: null
};
},
mounted() {
this.initChart();
},
watch: {
// timeRange
timeRange: {
handler() {
this.initChart();
},
deep: true
},
// gratingIdRange
gratingIdRange: {
handler() {
this.initChart();
},
deep: true
},
// timeGranularity
timeGranularity() {
this.initChart();
},
// picType
picType() {
this.initChart();
}
},
methods: {
initChart() {
// ECharts
if (this.chart) {
this.chart.dispose();
}
console.log("picType:", this.picType);
// DOM
const chartDom = this.$refs.chartContainer;
// ECharts
this.chart = echarts.init(chartDom);
console.log('timeGranularity:', this.timeGranularity);
//
let timeData = [];
if (this.timeGranularity === 'quarterHour') {
timeData = this.generateQuarterHourData();
console.log('timeData:', timeData);
} else if (this.timeGranularity === 'minute') {
timeData = this.generateMinuteData();
console.log('timeData:', timeData);
} else {
timeData = this.generateHourData();
console.log('timeData:', timeData);
}
//
const gratingIdData = this.generateGratingIdData();
console.log('gratingIdData:', gratingIdData);
//
const option = {
tooltip: {
position: 'top'
},
animation: false,
grid: {
height: '50%',
top: '10%'
},
xAxis: {
type: 'category',
data: timeData,
splitArea: {
show: true
}
},
yAxis: {
type: 'category',
data: gratingIdData,
splitArea: {
show: true
}
},
visualMap: {
min: 0,
max: 100,
calculable: true,
orient: 'horizontal',
left: 'center',
bottom: '15%'
},
series: [
{
name: '数值',
type: 'heatmap',
data: this.getGatingData(gratingIdData.length, timeData.length),
label: {
show: false
},
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowColor: 'rgba(0, 0, 0, 0.5)'
}
}
}
]
};
// 使
this.chart.setOption(option);
},
//
generateHourData() {
const [start, end] = this.timeRange;
const startTime = new Date(start);
const endTime = new Date(end);
const timeData = [];
const currentTime = new Date(startTime);
while (currentTime < endTime) {
timeData.push(currentTime.toLocaleString());
currentTime.setHours(currentTime.getHours() + 1);
}
return timeData;
},
// 15
generateQuarterHourData() {
const [start, end] = this.timeRange;
const startTime = new Date(start);
const endTime = new Date(end);
const timeData = [];
const currentTime = new Date(startTime);
while (currentTime < endTime) {
timeData.push(currentTime.toLocaleString());
currentTime.setMinutes(currentTime.getMinutes() + 15);
}
return timeData;
},
// 1
generateMinuteData() {
const [start, end] = this.timeRange;
const startTime = new Date(start);
const endTime = new Date(end);
const timeData = [];
const currentTime = new Date(startTime);
while (currentTime < endTime) {
timeData.push(currentTime.toLocaleString());
currentTime.setMinutes(currentTime.getMinutes() + 1);
}
return timeData;
},
//
generateGratingIdData() {
const [min, max] = this.gratingIdRange;
const gratingIdData = [];
for (let i = min; i <= max; i++) {
gratingIdData.push(i.toString());
}
return gratingIdData;
},
// propsdata
getGatingData(rows, cols) {
const data = [];
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
data.push([j, i, Math.floor(Math.random() * 100)]);
}
}
return data;
}
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose();
}
}
};
</script>
<style scoped>
/* 组件样式 */
</style>

View File

@ -1,7 +1,30 @@
<template>
<div class="home">
<!-- 这个单选框不知道为啥一直有问题-->
<!-- <div class="mb-2 ml-4">-->
<!-- <el-radio-group v-model="picRadio">-->
<!-- <el-radio value="1" size="large">温度监测图</el-radio>-->
<!-- <el-radio value="2" size="large">湿度监测图</el-radio>-->
<!-- <el-radio value="3" size="large">应力监测图</el-radio>-->
<!-- </el-radio-group>-->
<!-- </div>-->
<!-- 查询时间范围和按钮 -->
<div class="form-container">
<el-form-item label="可视化类型:" class="form-item">
<el-select
v-model="typeValue"
placeholder="Select"
size="large"
style="width: 130px"
>
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="查询时间范围:" class="form-item">
<el-date-picker
v-model="timeValue"
@ -13,136 +36,129 @@
style="width: 380px"
/>
</el-form-item>
<el-form-item label="光栅编号:" class="form-item">
<el-input
v-model="gratingId"
placeholder="请输入光栅编号"
style="width: 200px;"
<el-form-item label="光栅编号范围:" class="form-item">
<el-input-number
v-model="gratingIdMin"
:min="1"
:max="1399"
@change="validateRange"
placeholder="最小值"
style="width: 150px;"
/>
<span style="margin: 0 5px;"> - </span>
<el-input-number
v-model="gratingIdMax"
:min="10"
:max="1400"
@change="validateRange"
placeholder="最大值"
style="width: 150px;"
/>
<el-cascader
v-model="value"
:options="options"
style="width: 150px; margin-left: 10px;"
placeholder="其他选项"
@change="handleOtherChange"
/>
</el-form-item>
<el-button type="primary" @click="updateIframe">查询</el-button>
</div>
<!-- iframe 容器 -->
<div class="iframe-container">
<iframe
v-if="iframeUrl1"
class="embedded-iframe large"
:src="iframeUrl1"
frameborder="0"
></iframe>
<div class="iframe-row">
<iframe
v-if="iframeUrl2"
class="embedded-iframe small"
:src="iframeUrl2"
frameborder="0"
></iframe>
<iframe
v-if="iframeUrl3"
class="embedded-iframe small"
:src="iframeUrl3"
frameborder="0"
></iframe>
<iframe
v-if="iframeUrl4"
class="embedded-iframe small"
:src="iframeUrl4"
frameborder="0"
></iframe>
</div>
</div>
<!-- 热力图的容器 -->
<Heatmap
:timeRange="timeValue"
:gratingIdRange="[gratingIdMin, gratingIdMax]"
:time-granularity="value[1]"
:picType="typeValue"
/>
<div class="heatmap-container"></div>
<!-- 折线图-->
</div>
</template>
<script>
import axios from "axios";
import Heatmap from "/@/views/common/dashboard/big/heatmap.vue"; //
import LineChart from "/@/views/common/dashboard/big/lineChart.vue"; // 线
export default {
components: { Heatmap },
data() {
return {
typeValue: "temperature", //
typeOptions: [
{
value: "temperature",
label: "温度监测图",
},
{
value: "humidity",
label: "湿度监测图",
},
{
value: "stress",
label: "应力监测图",
}
],
// picType: "temperature", //
timeValue: [], //
gratingId: "1", // 1
iframeUrl1: "", // iframe
iframeUrl2: "", // iframe
iframeUrl3: "", // iframe
iframeUrl4: "", // iframe
baseUrl1:
"http://b40-4.com:13001/d-solo/ee6lox8dz1zb4a/test-normal?orgId=1&timezone=browser&panelId=2&__feature.dashboardSceneSolo",
baseUrl2:
"http://b40-4.com:13001/d-solo/ee6lox8dz1zb4a/test-normal?orgId=1&timezone=browser&panelId=1&__feature.dashboardSceneSolo",
baseUrl3:
"http://b40-4.com:13001/d-solo/ee6lox8dz1zb4a/test-normal?orgId=1&timezone=browser&panelId=4&__feature.dashboardSceneSolo",
baseUrl4:
"http://b40-4.com:13001/d-solo/ee6lox8dz1zb4a/test-normal?orgId=1&timezone=browser&panelId=3&__feature.dashboardSceneSolo",
gratingIdMin:1 , //
gratingIdMax: 12, //
value: [], //
options: [
{
value: "timeGranularity",
label: "时间粒度",
children: [
{
value: "hour",
label: "每小时",
},
{
value: "quarterHour",
label: "每15分钟",
},
{
value: "minute",
label: "每分钟",
}
],
}
]
};
},
methods: {
handleDateChange() {
console.log("选中的时间范围:", this.timeValue);
},
async updateIframe() {
//
if (this.timeValue.length !== 2) {
this.$message.error("请选择完整的时间范围!");
return;
}
if (!this.gratingId) {
this.$message.error("请输入光栅编号!");
return;
}
const from = new Date(this.timeValue[0]).getTime(); //
const to = new Date(this.timeValue[1]).getTime(); //
try {
// API
const response = await axios.get(`/api/file/getGratingData/${this.gratingId}`);
const gratingData = response.data?.data;
if (!gratingData) {
this.$message.error(`未找到光栅编号为 ${this.gratingId} 的数据!`);
return;
}
//
const temperature_wavelenth = gratingData["温度波长基准值"] || "1550.0";
const stress_wavelenth = gratingData["应变波长基准值"] || "1550.0";
const temperature_sensitivity = gratingData["温敏系数"] || "0.01";
const temperature_sensitivity2 = gratingData["温湿系数"] || "0.01";
const stress_sensitivity = gratingData["应变系数"] || "0.01";
const stress_base = gratingData["应变基准值"] || "0.01";
const temperature_base = gratingData["温度基准值"] || "25.0";
const humidity_base = gratingData["湿度基准值"] || "25.0";
const humidity_sensitivity = gratingData["湿敏系数"] || "25.0";
// iframe
this.iframeUrl1 = `${this.baseUrl1}&from=${from}&to=${to}&var-start_wavelength=${temperature_wavelenth}&var-temperature_sensitivity=${temperature_sensitivity}&var-temperature_base=${temperature_base}`;
this.iframeUrl2 = `${this.baseUrl2}&from=${from}&to=${to}&var-start_wavelength=${temperature_wavelenth}&var-temperature_sensitivity=${temperature_sensitivity}&var-sensor=${this.gratingId-1}&var-temperature_base=${temperature_base}`;
this.iframeUrl3 = `${this.baseUrl3}&from=${from}&to=${to}&var-temperature_sensitivity=${temperature_sensitivity}&var-start_wavelength=${temperature_wavelenth}&var-sensor=${this.gratingId-1}&var-humidity_sensitivity=${humidity_sensitivity}&var-humidity_base=${humidity_base}&var-temperature_sensitivity2=${temperature_sensitivity2}`;
this.iframeUrl4 = `${this.baseUrl4}&from=${from}&to=${to}&var-stress_wavelenth=${stress_wavelenth}&var-stress_sensitivity=${stress_sensitivity}&var-sensor=${this.gratingId-1}&var-stress_base=${stress_base}`; // iframe
} catch (error) {
console.error("获取光栅数据失败:", error);
this.$message.error("获取光栅数据失败,请检查光栅编号或服务状态!");
validateRange() {
if (this.gratingIdMax - this.gratingIdMin < 9) {
this.$message.error("至少选择10个光栅");
}
},
setDefaultIframe() {
//
setDefaultXYRange() {
// 1
const now = new Date();
const oneDayAgo = new Date();
oneDayAgo.setDate(now.getDate() - 1);
this.timeValue = [oneDayAgo, now];
// 1 12
this.gratingIdMin = 1;
this.gratingIdMax = 12;
//
this.updateIframe();
},
handleOtherChange(value) {
console.log("级联选择器的值:", value);
console.log("时间粒度:", value[1]);
}
},
mounted() {
//
this.setDefaultIframe();
},
beforeMount() {
this.setDefaultXYRange();
}
};
</script>
@ -160,7 +176,9 @@ export default {
display: flex;
align-items: center; /* 垂直居中对齐 */
flex-wrap: wrap; /* 当屏幕宽度不足时自动换行 */
margin-bottom: 20px; /* 和 iframe 的间距 */
margin-top: 10px; /* 与顶部的间距 */
margin-bottom: 10px; /* 和 iframe 的间距 */
margin-left: 10px;
width: 100%;
justify-content: flex-start;
}
@ -169,28 +187,4 @@ export default {
margin-right: 10px; /* 按钮和输入框之间的间距 */
}
.iframe-container {
width: 100%;
}
.iframe-row {
display: flex;
justify-content: space-between;
gap: 10px; /* 三个 iframe 之间的间距 */
margin-top: 10px;
}
.embedded-iframe {
border: 1px solid #ccc;
}
.embedded-iframe.large {
width: 100%; /* 上方 iframe 占整行 */
height: 400px; /* 高度根据需求调整 */
}
.embedded-iframe.small {
width: 32%; /* 下方三个 iframe 各占三分之一宽度 */
height: 300px; /* 高度根据需求调整 */
}
</style>

View File

@ -0,0 +1,225 @@
<template>
<div ref="chartContainer" style="width: 100%; height: 800px;"></div>
</template>
<script>
import * as echarts from 'echarts';
import { markRaw } from 'vue'
export default {
name: 'LineChart',
props: {
timeRange: {
type: Array,
default: () => []
},//
gratingIdArray: {
type: Array,
default: () => []
},//
timeGranularity: {
type: String,
default: 'hour'
},//
picType: {
type: String,
default: 'temperature'
}//
},
data() {
return {
chart: null,
seriesData: [] // 线
};
},
mounted() {
this.initChart();
},
watch: {
// timeRange
timeRange: {
handler() {
this.initChart();
},
deep: true
},
// gratingIdArray
gratingIdArray: {
handler() {
this.initChart();
},
deep: true
},
// timeGranularity
timeGranularity() {
this.initChart();
},
// picType
picType() {
this.initChart();
}
},
methods: {
initChart() {
// ECharts
if (this.chart) {
this.chart.dispose();
}
console.log("picType:", this.picType);
// DOM
const chartDom = this.$refs.chartContainer;
// ECharts
this.chart = markRaw(echarts.init(chartDom));
console.log('timeGranularity:', this.timeGranularity);
//
let timeData = [];
if (this.timeGranularity === 'quarterHour') {
timeData = this.generateQuarterHourData();
//console.log('timeData:', timeData);
} else if (this.timeGranularity === 'minute') {
timeData = this.generateMinuteData();
//console.log('timeData:', timeData);
} else {
timeData = this.generateHourData();
//console.log('timeData:', timeData);
}
//
this.seriesData = this.getGatingData(this.gratingIdArray.length, timeData.length);
// 线
const option = {
tooltip: {
trigger: 'axis',
formatter: function (params) {
// params
let tip = `<div style="font-size: 14px;">${params[0].name}</div>`; // x
tip += params.map(item => {
return `<div style="color: ${item.color}; margin: 4px 0;">${item.seriesName}: ${item.value}</div>`;
}).join('');
return tip;
}
},
legend: {
data: this.$props.gratingIdArray.map(id => `光栅 ${id}`)
},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
toolbox: {
feature: {
saveAsImage: {}
}
},
xAxis: {
type: 'category',
boundaryGap: false,
data: timeData
},
yAxis: {
type: 'value'
},
series: this.seriesData
};
console.log('seriesData:', this.seriesData);
// 使
// console.log('option:', option)
// console.log('Legend Data:', option.legend.data);
// console.log('Series Names:', option.series.map(s => s.name));
this.chart.setOption(option);
},
//
generateHourData() {
const [start, end] = this.timeRange;
const startTime = new Date(start);
const endTime = new Date(end);
const timeData = [];
const currentTime = new Date(startTime);
while (currentTime < endTime) {
timeData.push(currentTime.toLocaleString());
currentTime.setHours(currentTime.getHours() + 1);
}
return timeData;
},
// 15
generateQuarterHourData() {
const [start, end] = this.timeRange;
const startTime = new Date(start);
const endTime = new Date(end);
const timeData = [];
const currentTime = new Date(startTime);
while (currentTime < endTime) {
timeData.push(currentTime.toLocaleString());
currentTime.setMinutes(currentTime.getMinutes() + 15);
}
return timeData;
},
// 1
generateMinuteData() {
const [start, end] = this.timeRange;
const startTime = new Date(start);
const endTime = new Date(end);
const timeData = [];
const currentTime = new Date(startTime);
while (currentTime < endTime) {
timeData.push(currentTime.toLocaleString());
currentTime.setMinutes(currentTime.getMinutes() + 1);
}
return timeData;
},
//
// propsdata
getGatingData(rows, cols) {
let data = [];
console.log('cols:', cols, 'rows:', rows);
for (let i = 0; i < rows; i++) {
let oneLine = [];
for (let j = 0; j < cols; j++) {
oneLine.push(Math.floor(Math.random() * 100));
}
data.push(oneLine);
}
console.log("data", data);
return this.processSeriesData(data);
},
// ECharts
// processSeriesData(seriesData) {
// const rows = seriesData.length;
// const cols = seriesData[0].length;
// const data = [];
// let legendData = this.gratingIdArray.map(id => ` ${id}`);
// for (let i = 0; i < rows; i++) {
// let oneLine = {};
// oneLine['name'] = legendData[i];
// oneLine['type'] = 'line';
// // oneLine['stack'] = 'Total';
// oneLine['data'] = seriesData[i];
// data.push(oneLine);
// }
//
// return data;
// }
processSeriesData(data) {
const legendData = this.gratingIdArray.map(id => `光栅 ${id}`);
return data.map((rowData, index) => ({
name: legendData[index],
type: 'line',
// stack: 'Total'
data: rowData
}));
}
},
beforeDestroy() {
if (this.chart) {
this.chart.dispose();
}
}
};
</script>
<style scoped>
/* 组件样式 */
</style>