|
@@ -0,0 +1,214 @@
|
|
|
+<script setup lang="ts">
|
|
|
+import { onMounted, ref } from 'vue';
|
|
|
+import VChart from 'vue-echarts';
|
|
|
+import { LineChart, PieChart } from 'echarts/charts';
|
|
|
+import {
|
|
|
+ DatasetComponent,
|
|
|
+ GridComponent,
|
|
|
+ LegendComponent,
|
|
|
+ MarkLineComponent,
|
|
|
+ TitleComponent,
|
|
|
+ TooltipComponent,
|
|
|
+ TransformComponent,
|
|
|
+} from 'echarts/components';
|
|
|
+import { use } from 'echarts/core';
|
|
|
+import { CanvasRenderer } from 'echarts/renderers';
|
|
|
+
|
|
|
+import SvgIcon from './SvgIcon.vue';
|
|
|
+
|
|
|
+import type { MonitoringPointData } from '@/types';
|
|
|
+
|
|
|
+use([
|
|
|
+ CanvasRenderer,
|
|
|
+ TitleComponent,
|
|
|
+ DatasetComponent,
|
|
|
+ TransformComponent,
|
|
|
+ TooltipComponent,
|
|
|
+ LegendComponent,
|
|
|
+ GridComponent,
|
|
|
+ LineChart,
|
|
|
+ PieChart,
|
|
|
+ MarkLineComponent,
|
|
|
+]);
|
|
|
+
|
|
|
+const list: number[] = [];
|
|
|
+
|
|
|
+interface Props {
|
|
|
+ data: MonitoringPointData;
|
|
|
+}
|
|
|
+
|
|
|
+const emit = defineEmits(['editorClick']);
|
|
|
+
|
|
|
+const props = defineProps<Props>();
|
|
|
+
|
|
|
+const getCurvedData = () => {
|
|
|
+ if (props.data.tempData) {
|
|
|
+ props.data.tempData.forEach((item) => {
|
|
|
+ list.push(item.value);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+};
|
|
|
+
|
|
|
+const maxValue = 20;
|
|
|
+
|
|
|
+const option = ref({
|
|
|
+ backgroundColor: 'rgba(50, 186, 192, 0.15)',
|
|
|
+ grid: {
|
|
|
+ left: '5%',
|
|
|
+ right: '5%',
|
|
|
+ top: '5%',
|
|
|
+ bottom: '5%',
|
|
|
+ containLabel: true,
|
|
|
+ backgroundColor: 'rgba(50,186,192,0.15)',
|
|
|
+ borderRadius: 8,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ show: false, // 隐藏 X 轴
|
|
|
+ type: 'category',
|
|
|
+ data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'],
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: 'value',
|
|
|
+ // max: maxValue, // 设置 Y 轴最大值
|
|
|
+ axisLine: { show: false }, // 隐藏轴线
|
|
|
+ axisTick: { show: false }, // 隐藏刻度
|
|
|
+ position: 'left',
|
|
|
+ axisLabel: {
|
|
|
+ show: true,
|
|
|
+ color: '#666',
|
|
|
+ formatter(value: number) {
|
|
|
+ // 只显示最大值标签
|
|
|
+ return value === maxValue ? value : '';
|
|
|
+ },
|
|
|
+ },
|
|
|
+ splitLine: {
|
|
|
+ show: false, // 关闭默认分割线
|
|
|
+ },
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: 'line',
|
|
|
+ data: getCurvedData(),
|
|
|
+ symbol: 'none', // 不显示数据点
|
|
|
+ color: '#32BAC0',
|
|
|
+ lineStyle: {
|
|
|
+ width: 2,
|
|
|
+ },
|
|
|
+ markLine: {
|
|
|
+ // 添加最大值虚线
|
|
|
+ silent: true,
|
|
|
+ symbol: 'none',
|
|
|
+ label: { show: false },
|
|
|
+ lineStyle: {
|
|
|
+ type: 'dashed',
|
|
|
+ color: '#333',
|
|
|
+ width: 1,
|
|
|
+ },
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ yAxis: maxValue, // 在最大值位置画线
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+});
|
|
|
+
|
|
|
+onMounted(() => {});
|
|
|
+const editorMonitoring = (id: number) => {
|
|
|
+ emit('editorClick', id);
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="line-chart-content">
|
|
|
+ <AFlex justify="space-between" align="center">
|
|
|
+ <div class="line-chart-header-text">{{ data.name }}</div>
|
|
|
+ <SvgIcon class="line-chart-header-icon" @click="editorMonitoring(data.id)" name="adjustment" />
|
|
|
+ </AFlex>
|
|
|
+ <div style="width: 172px; height: 94px; margin-top: 12px">
|
|
|
+ <VChart class="chart" :option="option" />
|
|
|
+ </div>
|
|
|
+ <AFlex justify="space-between" align="center" class="line-chart-footer">
|
|
|
+ <AFlex align="center">
|
|
|
+ <AFlex justify="center" align="center" class="line-chart-footer-div">
|
|
|
+ <SvgIcon class="line-chart-icon" name="temperature"
|
|
|
+ /></AFlex>
|
|
|
+ <div>
|
|
|
+ <span class="line-chart-footer-text">{{ data.temperature }}</span>
|
|
|
+ <span class="line-chart-footer-unit">℃</span>
|
|
|
+ </div>
|
|
|
+ </AFlex>
|
|
|
+ <AFlex align="center">
|
|
|
+ <AFlex justify="center" align="center" class="line-chart-footer-div"
|
|
|
+ ><SvgIcon class="line-chart-icon" name="humidity"
|
|
|
+ /></AFlex>
|
|
|
+ <div>
|
|
|
+ <span class="line-chart-footer-text">{{ data.humidity }}</span>
|
|
|
+ <span class="line-chart-footer-unit">%</span>
|
|
|
+ </div>
|
|
|
+ </AFlex>
|
|
|
+ </AFlex>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.line-chart-icon {
|
|
|
+ font-size: 16px;
|
|
|
+ color: var(--antd-color-primary-hover);
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-footer-unit {
|
|
|
+ font-size: 12px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 20px;
|
|
|
+ color: rgb(0 0 0 / 85%);
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-footer-text {
|
|
|
+ font-size: 16px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 500;
|
|
|
+ line-height: 28px;
|
|
|
+ color: rgb(0 0 0 / 85%);
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-footer-div {
|
|
|
+ width: 30px;
|
|
|
+ height: 30px;
|
|
|
+ background: #f2fcf9;
|
|
|
+ border-radius: 8px;
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-footer {
|
|
|
+ margin-top: 12px;
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-header-icon {
|
|
|
+ cursor: pointer;
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-header-text {
|
|
|
+ font-size: 16px;
|
|
|
+ font-style: normal;
|
|
|
+ font-weight: 400;
|
|
|
+ line-height: 24px;
|
|
|
+ color: rgb(0 0 0 / 85%);
|
|
|
+ text-align: left;
|
|
|
+}
|
|
|
+
|
|
|
+.line-chart-content {
|
|
|
+ width: 204px;
|
|
|
+ height: 204px;
|
|
|
+ padding: 16px;
|
|
|
+ margin: 2px 4px 14px;
|
|
|
+ background: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ box-shadow: 0 2px 6px 0 rgb(0 0 0 / 10%);
|
|
|
+}
|
|
|
+</style>
|