yangg 8 months ago
parent
commit
360a984adb
43 changed files with 230 additions and 205 deletions
  1. 0 0
      dist/index.html
  2. 0 0
      dist/static/css/chunk-7dfdc0a0.50fc024e.css
  3. 0 0
      dist/static/css/chunk-d68c6fdc.81d362dc.css
  4. 0 0
      dist/static/js/app.c2222d0f.js
  5. 0 0
      dist/static/js/chunk-0ec56e2a.0c37ce4d.js
  6. 0 0
      dist/static/js/chunk-10bfc27e.21d5a037.js
  7. 0 0
      dist/static/js/chunk-11ff1a32.2b7e8c3c.js
  8. 0 0
      dist/static/js/chunk-138f7583.3d73846c.js
  9. 0 0
      dist/static/js/chunk-20bc854d.0ee0271d.js
  10. 0 0
      dist/static/js/chunk-23008ed8.1420b87a.js
  11. 0 0
      dist/static/js/chunk-29d491e2.8f0b1dbf.js
  12. 0 0
      dist/static/js/chunk-2d0d3705.008b654f.js
  13. 0 0
      dist/static/js/chunk-35464144.1446671d.js
  14. 0 0
      dist/static/js/chunk-386d37cb.39b19bfa.js
  15. 0 0
      dist/static/js/chunk-43013872.03383a49.js
  16. 0 0
      dist/static/js/chunk-44eee83d.05cdf17c.js
  17. 0 0
      dist/static/js/chunk-4ac7f82e.7af0717f.js
  18. 0 0
      dist/static/js/chunk-52f685c2.eef74343.js
  19. 0 0
      dist/static/js/chunk-5a3bdf57.4040cbd1.js
  20. 0 0
      dist/static/js/chunk-5a750430.e2a79c0f.js
  21. 0 0
      dist/static/js/chunk-647b97bd.5b1f425d.js
  22. 0 0
      dist/static/js/chunk-683feb49.eb637873.js
  23. 0 0
      dist/static/js/chunk-6a80e4ca.d70d93a6.js
  24. 0 0
      dist/static/js/chunk-6ddf6871.e749e081.js
  25. 0 0
      dist/static/js/chunk-708604c0.51d53779.js
  26. 0 0
      dist/static/js/chunk-712c0160.df8fd582.js
  27. 0 0
      dist/static/js/chunk-74560560.90b9853f.js
  28. 0 0
      dist/static/js/chunk-7a88741c.5112e2dc.js
  29. 0 0
      dist/static/js/chunk-7dbc1954.9d03f435.js
  30. 0 0
      dist/static/js/chunk-7dfdc0a0.6d6b8df9.js
  31. 0 0
      dist/static/js/chunk-9235c1ae.0a068157.js
  32. 0 0
      dist/static/js/chunk-994a158a.bbddd770.js
  33. 0 0
      dist/static/js/chunk-a577192a.5a147da2.js
  34. 0 0
      dist/static/js/chunk-d09dbc1a.74630db8.js
  35. 0 0
      dist/static/js/chunk-d4c547ca.2f6790ee.js
  36. 0 0
      dist/static/js/chunk-d68c6fdc.99c0cbc5.js
  37. 0 0
      dist/static/js/chunk-d91fed4e.a350b568.js
  38. 0 0
      dist/static/js/chunk-ec55d346.05ad96bd.js
  39. 0 0
      dist/static/js/chunk-libs.d2d03206.js
  40. 1 0
      package.json
  41. 222 195
      src/views/dashboard/admin/components/LineChart.vue
  42. 1 1
      src/views/dashboard/admin/index.vue
  43. 6 9
      vue.config.js

File diff suppressed because it is too large
+ 0 - 0
dist/index.html


+ 0 - 0
dist/static/css/chunk-647b97bd.50fc024e.css → dist/static/css/chunk-7dfdc0a0.50fc024e.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/css/chunk-d68c6fdc.81d362dc.css


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/app.c2222d0f.js


+ 0 - 0
dist/static/js/chunk-0ec56e2a.c368a9b5.js → dist/static/js/chunk-0ec56e2a.0c37ce4d.js


+ 0 - 0
dist/static/js/chunk-10bfc27e.8fef1b6d.js → dist/static/js/chunk-10bfc27e.21d5a037.js


+ 0 - 0
dist/static/js/chunk-11ff1a32.20ad57e2.js → dist/static/js/chunk-11ff1a32.2b7e8c3c.js


+ 0 - 0
dist/static/js/chunk-138f7583.91058c09.js → dist/static/js/chunk-138f7583.3d73846c.js


+ 0 - 0
dist/static/js/chunk-20bc854d.aeb8f6eb.js → dist/static/js/chunk-20bc854d.0ee0271d.js


+ 0 - 0
dist/static/js/chunk-23008ed8.9c1daac9.js → dist/static/js/chunk-23008ed8.1420b87a.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-29d491e2.8f0b1dbf.js


+ 0 - 0
dist/static/js/chunk-2d0d3705.c016b399.js → dist/static/js/chunk-2d0d3705.008b654f.js


+ 0 - 0
dist/static/js/chunk-35464144.753a989d.js → dist/static/js/chunk-35464144.1446671d.js


+ 0 - 0
dist/static/js/chunk-386d37cb.df026891.js → dist/static/js/chunk-386d37cb.39b19bfa.js


+ 0 - 0
dist/static/js/chunk-43013872.afcd79b0.js → dist/static/js/chunk-43013872.03383a49.js


+ 0 - 0
dist/static/js/chunk-44eee83d.f250a92a.js → dist/static/js/chunk-44eee83d.05cdf17c.js


+ 0 - 0
dist/static/js/chunk-4ac7f82e.91f00c3e.js → dist/static/js/chunk-4ac7f82e.7af0717f.js


+ 0 - 0
dist/static/js/chunk-52f685c2.36b43701.js → dist/static/js/chunk-52f685c2.eef74343.js


+ 0 - 0
dist/static/js/chunk-5a3bdf57.170b8380.js → dist/static/js/chunk-5a3bdf57.4040cbd1.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-5a750430.e2a79c0f.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-647b97bd.5b1f425d.js


+ 0 - 0
dist/static/js/chunk-683feb49.9ea29ed7.js → dist/static/js/chunk-683feb49.eb637873.js


+ 0 - 0
dist/static/js/chunk-6a80e4ca.3e37fa95.js → dist/static/js/chunk-6a80e4ca.d70d93a6.js


+ 0 - 0
dist/static/js/chunk-6ddf6871.aa7f3174.js → dist/static/js/chunk-6ddf6871.e749e081.js


+ 0 - 0
dist/static/js/chunk-708604c0.2ed6816a.js → dist/static/js/chunk-708604c0.51d53779.js


+ 0 - 0
dist/static/js/chunk-712c0160.d6721a50.js → dist/static/js/chunk-712c0160.df8fd582.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-74560560.90b9853f.js


+ 0 - 0
dist/static/js/chunk-7a88741c.f83d6069.js → dist/static/js/chunk-7a88741c.5112e2dc.js


+ 0 - 0
dist/static/js/chunk-7dbc1954.78960d49.js → dist/static/js/chunk-7dbc1954.9d03f435.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-7dfdc0a0.6d6b8df9.js


+ 0 - 0
dist/static/js/chunk-9235c1ae.d253b77c.js → dist/static/js/chunk-9235c1ae.0a068157.js


+ 0 - 0
dist/static/js/chunk-994a158a.c32db0c5.js → dist/static/js/chunk-994a158a.bbddd770.js


+ 0 - 0
dist/static/js/chunk-a577192a.31e844e2.js → dist/static/js/chunk-a577192a.5a147da2.js


+ 0 - 0
dist/static/js/chunk-d09dbc1a.93bb1cb4.js → dist/static/js/chunk-d09dbc1a.74630db8.js


+ 0 - 0
dist/static/js/chunk-d4c547ca.ef4bd719.js → dist/static/js/chunk-d4c547ca.2f6790ee.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-d68c6fdc.99c0cbc5.js


File diff suppressed because it is too large
+ 0 - 0
dist/static/js/chunk-d91fed4e.a350b568.js


+ 0 - 0
dist/static/js/chunk-ec55d346.e3336082.js → dist/static/js/chunk-ec55d346.05ad96bd.js


+ 0 - 0
dist/static/js/chunk-libs.403cd4c6.js → dist/static/js/chunk-libs.d2d03206.js


+ 1 - 0
package.json

@@ -85,6 +85,7 @@
     "chokidar": "2.1.5",
     "connect": "3.6.6",
     "css-loader": "^5.2.6",
+    "encoding": "^0.1.13",
     "eslint": "^6.7.2",
     "eslint-plugin-import": "^2.25.2",
     "eslint-plugin-node": "^11.1.0",

+ 222 - 195
src/views/dashboard/admin/components/LineChart.vue

@@ -136,7 +136,7 @@ export default {
  -->
 
  <template>
-  <div ref="chartDiv" style="width: 100%; height: 100%"></div>
+  <div ref="chartDiv" style="width: 100%; height: 350px"></div>
 </template>
 
 <script>
@@ -147,18 +147,35 @@ import am5themes_Animated from "@amcharts/amcharts5/themes/Animated";
 
 export default {
   name: "AmAreaChart",
+  props: {
+    className: {
+      type: String,
+      default: 'chart'
+    },
+    width: {
+      type: String,
+      default: '100%'
+    },
+    height: {
+      type: String,
+      default: '350px'
+    },
+    autoResize: {
+      type: Boolean,
+      default: true
+    }
+  },
   data() {
     return {
       chart: null,
       root: null,
-      series: null,
+      series1: null,
+      series2: null,
       xAxis: null,
-      data: [],
+      data1: [],
+      data2: [],
       timer: null,
-      lastValue: 15,
-      visits: 10,
-      isDestroyed: false,
-      isAnimating: false,
+      isDestroyed: false
     };
   },
   mounted() {
@@ -171,7 +188,6 @@ export default {
   methods: {
     initChart() {
       try {
-        // 保存 root 引用
         const root = (this.root = am5.Root.new(this.$refs.chartDiv));
         root.setThemes([am5themes_Animated.new(root)]);
 
@@ -189,9 +205,11 @@ export default {
         // 创建Y轴
         let yAxis = this.chart.yAxes.push(
           am5xy.ValueAxis.new(root, {
-            renderer: am5xy.AxisRendererY.new(root, {}),
+            renderer: am5xy.AxisRendererY.new(root, {
+              labelFormat: "{value}%"
+            }),
             min: 0,
-            max: 100,
+            max: 100
           })
         );
 
@@ -199,248 +217,257 @@ export default {
         this.xAxis = this.chart.xAxes.push(
           am5xy.DateAxis.new(root, {
             baseInterval: { timeUnit: "second", count: 1 },
-            renderer: am5xy.AxisRendererX.new(root, {}),
+            renderer: am5xy.AxisRendererX.new(root, {
+              minGridDistance: 100, // 增加标签之间的最小距离
+              cellStartLocation: 0.2,
+              cellEndLocation: 0.8,
+              dateFormats: {
+                second: "mm:ss",
+                minute: "mm:ss"
+              },
+              periodChangeDateFormats: {
+                second: "mm:ss",
+                minute: "mm:ss"
+              },
+              // 减少标签数量
+              maxDeviation: 0.5,
+              // 只显示首尾和少量中间的标签
+              minLabelGap: 50
+            }),
+            // 控制要显示的标签数量
+            gridIntervals: [
+              { timeUnit: "second", count: 5 } // 每5秒显示一个标签
+            ],
+            // 确保时间轴平滑滚动
+            interpolationDuration: 500,
+            interpolationEasing: am5.ease.cubic
           })
         );
 
-        // 修改主数据系列的配置
-        this.series = this.chart.series.push(
+        // 创建第一条线(expected)
+        this.series1 = this.chart.series.push(
           am5xy.SmoothedXLineSeries.new(root, {
-            name: "Series",
+            name: "GPU",
             xAxis: this.xAxis,
             yAxis: yAxis,
             valueYField: "value",
             valueXField: "date",
-            connect: true,
-            tension: 0.8, // 对应原代码中的 tensionX
-            stroke: am5.color("#FF425C"), // 使用相同的颜色
-            strokeWidth: 10,
+            tension: 0.8,
+            stroke: am5.color("#FF005A"),
+            strokeWidth: 3,
             tooltip: am5.Tooltip.new(root, {
-              labelText: "{valueY}",
-            }),
+              labelText: "{name}: {valueY}%"
+            })
           })
         );
 
-        // 设置渐变填充
-        this.series.fills.template.setAll({
-          visible: true,
-          fillOpacity: 1,
-          fill: am5.LinearGradient.new(root, {
-            stops: [
-              {
-                offset: 0,
-                color: am5.color("#FF425C"),
-                opacity: 0.2,
-              },
-              {
-                offset: 1,
-                color: am5.color("#FF425C"),
-                opacity: 0.9,
-              },
-            ],
-            rotation: 90,
-          }),
-        });
-
-        // 添加前端的圆形标记
-        this.bulletSeries = this.chart.series.push(
-          am5xy.LineSeries.new(root, {
-            name: "Bullet",
+        // 创建第二条线(actual)
+        this.series2 = this.chart.series.push(
+          am5xy.SmoothedXLineSeries.new(root, {
+            name: "CPU",
             xAxis: this.xAxis,
             yAxis: yAxis,
             valueYField: "value",
             valueXField: "date",
+            tension: 0.8,
+            stroke: am5.color("#3888fa"),
+            strokeWidth: 3,
+            fill: am5.color("#f3f8ff"),
+            tooltip: am5.Tooltip.new(root, {
+              labelText: "{name}: {valueY}%"
+            })
           })
         );
 
-        this.bulletSeries.bullets.push((root) => {
-          return am5.Bullet.new(root, {
-            sprite: am5.Circle.new(root, {
-              radius: 5,
-              fill: am5.color("#FF425C"),
-              fillOpacity: 1,
-            }),
-          });
-        });
-        // 确保填充区域在线条下方显示
-        this.series.fills.template.setAll({
-          visible: true,
-          fillOpacity: 0.5,
-        });
-
-        /* // 修改bullet系列,添加平滑属性
-        this.bulletSeries = this.chart.series.push(
-          am5xy.LineSeries.new(root, {
-            name: "Series",
-            xAxis: this.xAxis,
-            yAxis: yAxis,
-            valueYField: "value",
-            valueXField: "date",
-            connect: true,
-            tension: 0.5,
+        // 添加图例
+        const legend = this.chart.children.push(
+          am5.Legend.new(root, {
+            centerX: am5.percent(50),
+            x: am5.percent(50),
+            layout: root.horizontalLayout
           })
         );
+        legend.data.setAll(this.chart.series.values);
 
-        // 修复: 使用箭头函数保持this上下文,并使用外部的root引用
-        this.bulletSeries.bullets.push(() => {
-          return am5.Bullet.new(root, {
-            sprite: am5.Circle.new(root, {
-              radius: 5,
-              fill: am5.color(0xff0000),
-            }),
+        // 启用动画
+        this.series1.appear(1000);
+        this.series2.appear(1000);
+        this.chart.appear(1000, 100);
+
+        // 为 series1 添加圆点
+        this.series1.bullets.push((root) => {
+          const container = am5.Container.new(root, {});
+
+          // 创建光晕效果(外圈)
+          const halo = am5.Circle.new(root, {
+            radius: 12,
+            fill: am5.color("#FF005A"),
+            fillOpacity: 0.3,
+            stroke: am5.color("#FF005A"),
+            strokeOpacity: 0.3,
+            strokeWidth: 2
           });
-        });
- */
-        // 初始化数据
-        this.series.data.setAll(this.data);
-        this.bulletSeries.data.setAll([]);
 
-        // 启用图表动画
-        this.series.appear(1000);
-        this.chart.appear(1000, 100);
-      } catch (error) {
-        console.error("初始化图表时出错:", error);
-      }
-    },
-    // 新增资源清理方法
-    async cleanupResources() {
-      this.isDestroyed = true;
-      this.isAnimating = false;
+          // 创建主圆点(内圈)
+          const circle = am5.Circle.new(root, {
+            radius: 6,
+            fill: am5.color("#FF005A"),
+            fillOpacity: 0.8,
+            stroke: am5.color("#fff"),
+            strokeWidth: 2
+          });
 
-      // 清理定时器
-      if (this.timer) {
-        clearInterval(this.timer);
-        this.timer = null;
-      }
+          // 将两个圆形添加到容器
+          container.children.push(halo);
+          container.children.push(circle);
+
+          // 创建光晕的呼吸动画
+          halo.animate({
+            key: "radius",
+            from: 8,
+            to: 16,
+            duration: 1000,
+            loops: Infinity,
+            easing: am5.ease.cubic,
+            direction: "alternate"
+          });
 
-      // 等待所有动画完成
-      await new Promise((resolve) => setTimeout(resolve, 100));
+          halo.animate({
+            key: "fillOpacity",
+            from: 0.3,
+            to: 0.1,
+            duration: 1000,
+            loops: Infinity,
+            easing: am5.ease.cubic,
+            direction: "alternate"
+          });
 
-      try {
-        // 按特定顺序清理图表资源
-        if (this.bullet) {
-          this.bullet.dispose();
-          this.bullet = null;
-        }
+          return am5.Bullet.new(root, {
+            sprite: container
+          });
+        });
 
-        if (this.bulletSeries && !this.bulletSeries.isDisposed()) {
-          this.bulletSeries.dispose();
-          this.bulletSeries = null;
-        }
+        // 为 series2 添加圆点
+        this.series2.bullets.push((root) => {
+          const container = am5.Container.new(root, {});
+
+          // 创建光晕效果(外圈)
+          const halo = am5.Circle.new(root, {
+            radius: 12,
+            fill: am5.color("#3888fa"),
+            fillOpacity: 0.3,
+            stroke: am5.color("#3888fa"),
+            strokeOpacity: 0.3,
+            strokeWidth: 2
+          });
 
-        if (this.series && !this.series.isDisposed()) {
-          this.series.dispose();
-          this.series = null;
-        }
+          // 创建主圆点(内圈)
+          const circle = am5.Circle.new(root, {
+            radius: 6,
+            fill: am5.color("#3888fa"),
+            fillOpacity: 0.8,
+            stroke: am5.color("#fff"),
+            strokeWidth: 2
+          });
 
-        if (this.xAxis && !this.xAxis.isDisposed()) {
-          this.xAxis.dispose();
-          this.xAxis = null;
-        }
+          // 将两个圆形添加到容器
+          container.children.push(halo);
+          container.children.push(circle);
+
+          // 创建光晕的呼吸动画
+          halo.animate({
+            key: "radius",
+            from: 8,
+            to: 16,
+            duration: 1000,
+            loops: Infinity,
+            easing: am5.ease.cubic,
+            direction: "alternate"
+          });
 
-        if (this.chart && !this.chart.isDisposed()) {
-          this.chart.dispose();
-          this.chart = null;
-        }
+          halo.animate({
+            key: "fillOpacity",
+            from: 0.3,
+            to: 0.1,
+            duration: 1000,
+            loops: Infinity,
+            easing: am5.ease.cubic,
+            direction: "alternate"
+          });
 
-        if (this.root && !this.root.isDisposed()) {
-          this.root.dispose();
-          this.root = null;
-        }
-      } catch (e) {
-        console.error("清理图表资源时出错:", e);
+          return am5.Bullet.new(root, {
+            sprite: container
+          });
+        });
+
+      } catch (error) {
+        console.error("初始化图表时出错:", error);
       }
     },
 
-    // 修改数据更新方法
     async startLiveData() {
       if (this.timer) {
         clearInterval(this.timer);
       }
 
-      let lastTimestamp = Date.now();
-
       this.timer = setInterval(async () => {
-        // 多重状态检查
-        if (
-          this.isDestroyed ||
-          this.isAnimating ||
-          !this.root ||
-          this.root.isDisposed() ||
-          !this.series ||
-          this.series.isDisposed()
-        ) {
-          clearInterval(this.timer);
-          return;
-        }
-
         try {
           const response = await gpu_info();
-          const gpuData = response.data.data[0];
           const currentTime = Date.now();
 
-          if (currentTime - lastTimestamp < 900) {
-            return;
-          }
+          // 模拟两组数据
+          const expectedValue = Math.random() * 30 + 50;
+          const actualValue = response.data.data[0].usage;
 
-          // 安全地更新数据
-          if (!this.isDestroyed && this.series && !this.series.isDisposed()) {
-            const newValue = gpuData.temperature;
-
-            // 数据平滑处理
-            this.lastValue =
-              Math.abs(newValue - this.lastValue) > 10
-                ? this.lastValue + (newValue > this.lastValue ? 2 : -2)
-                : newValue;
-
-            this.data.push({
-              date: currentTime,
-              value: this.lastValue,
-            });
+          // 更新数据
+          this.data1.push({
+            date: currentTime,
+            value: expectedValue
+          });
+          this.data2.push({
+            date: currentTime,
+            value: actualValue
+          });
 
-            if (this.data.length > 100) {
-              this.data.shift();
-            }
+          // 保持固定数量的数据点
+          if (this.data1.length > 15) {
+            this.data1.shift();
+            this.data2.shift();
+          }
 
-            this.series.data.setAll(this.data);
-            this.updateBullet();
+          // 更新图表
+          this.series1.data.setAll(this.data1);
+          this.series2.data.setAll(this.data2);
 
-            // 安全地更新x轴
-            if (this.xAxis && !this.xAxis.isDisposed()) {
-              this.xAxis.zoomToDates(
-                new Date(this.data[0].date),
-                new Date(this.data[this.data.length - 1].date)
-              );
-            }
+          // 更新X轴范围
+          if (this.data1.length > 1) {
+            this.xAxis.zoomToDates(
+              new Date(this.data1[0].date),
+              new Date(this.data1[this.data1.length - 1].date)
+            );
           }
 
-          lastTimestamp = currentTime;
         } catch (error) {
-          console.error("Failed to fetch GPU info:", error);
+          console.error("Failed to fetch data:", error);
         }
       }, 2000);
     },
 
-    // 修改bullet更新方法
-    updateBullet() {
-      if (
-        this.isDestroyed ||
-        !this.root ||
-        this.root.isDisposed() ||
-        !this.bulletSeries ||
-        this.bulletSeries.isDisposed() ||
-        !this.data.length
-      ) {
-        return;
+    async cleanupResources() {
+      this.isDestroyed = true;
+      if (this.timer) {
+        clearInterval(this.timer);
+        this.timer = null;
       }
 
-      try {
-        const lastDataPoint = this.data[this.data.length - 1];
-        this.bulletSeries.data.setAll([lastDataPoint]);
-      } catch (e) {
-        console.error("更新bullet时出错:", e);
+      if (this.root) {
+        this.root.dispose();
       }
-    },
-  },
+    }
+  }
 };
-</script>
+</script>
+
+
+
+

+ 1 - 1
src/views/dashboard/admin/index.vue

@@ -15,7 +15,7 @@
       <el-col style="margin-bottom: 20px;" :span="24">
         <el-card class="box-card">
           <div slot="header" class="clearfixs">
-            <span>GPU温度</span>
+            <span>GPU使用率</span>
           </div>
           <LineChart :data="chartData" style="height: 350px"></LineChart>
         </el-card>

+ 6 - 9
vue.config.js

@@ -1,7 +1,7 @@
 'use strict'
 const path = require('path')
 const defaultSettings = require('./src/settings.js')
-
+const webpack = require('webpack')
 function resolve(dir) {
   return path.join(__dirname, dir)
 }
@@ -39,14 +39,11 @@ module.exports = {
     before: require('./mock/mock-server.js')
   },
   configureWebpack: {
-    // provide the app's title in webpack's name field, so that
-    // it can be accessed in index.html to inject the correct title.
-    name: name,
-    resolve: {
-      alias: {
-        '@': resolve('src')
-      }
-    }
+    plugins: [
+      new webpack.NormalModuleReplacementPlugin(/node:/, (resource) => {
+        resource.request = resource.request.replace(/^node:/, "");
+      }),
+    ]
   },
   chainWebpack(config) {
     // it can improve the speed of the first screen, it is recommended to turn on preload

Some files were not shown because too many files changed in this diff