guonan
2025-04-30 742cecf2dd52906ff00a50461839bda83a3cbc6d
修改y轴动态变化
已修改8个文件
776 ■■■■■ 文件已修改
src/assets/css/global.css 92 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monifangzhen/ResultAssess.vue 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monifangzhen/RiverLevel.vue 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/monifangzhen/echartInfo.vue 521 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/store/simAPI.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/Home.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/CitySim.vue 36 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/left/KGSimOption/PredictiveSimulation.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/css/global.css
@@ -19,6 +19,7 @@
  text-indent: 80px;
  letter-spacing: 2px;
}
.left-content {
  margin-top: 20px;
  background: url("@/assets/img/left/leftbg.png");
@@ -26,6 +27,7 @@
  width: 100%;
  height: calc(100% - 70px);
}
.el-button {
  background-color: #009688 !important;
  border-color: #009688 !important;
@@ -38,30 +40,22 @@
  border-color: #009688 !important;
  color: #fff !important;
}
.el-picker-panel__icon-btn {
  color: #fff !important;
  font-size: 18px;
}
.el-date-range-picker__header [class*="arrow-left"] {
  color: #ffffff;
}
.el-select-dropdown__item.is-hovering {
  background-color: #009688;
}
.el-select__placeholder {
  color: white;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  color: white !important;
  background-color: rgb(38, 124, 124, 0.5) !important;
}
.el-select__placeholder,
.el-form-item__label,
.el-input__inner {
  color: #fff !important;
}
.el-slider__bar {
  background-color: #009688 !important;
  border-color: #009688 !important;
@@ -70,3 +64,79 @@
.el-slider__button {
  border-color: rgb(0, 150, 136) !important;
}
.el-select-dropdown {
  background: rgba(8, 75, 66, 1) !important;
  color: white !important;
}
.el-picker-panel__body div {
  background: #084b42 !important;
}
.el-picker-panel {
  background: rgba(8, 75, 66, 1) !important;
}
.el-select-dropdown__item {
  color: white !important;
  font-size: 12px !important;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  color: #409eff !important;
}
.el-input__wrapper {
  background: rgba(8, 75, 66, 1) !important;
  border: 2px solid #437a74 !important;
  box-shadow: none !important;
}
.el-select__wrapper {
  background: rgba(8, 75, 66, 1) !important;
  border: 2px solid #437a74 !important;
  box-shadow: none !important;
}
.el-time-spinner__item:hover:not(.is-disabled):not(.is-active),
.el-date-table td.current:not(.disabled) .el-date-table-cell__text {
  background: #009688 !important;
}
.el-picker-panel__footer {
  background-color: #084b42 !important;
}
.el-date-table td.end-date .el-date-table-cell__text,
.el-date-table td.start-date .el-date-table-cell__text {
  background-color: #61f7d4 !important;
}
.el-date-table td.today .el-date-table-cell__text {
  color: #61f7d4 !important;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover,
.el-time-panel__btn.confirm,
.el-date-editor .el-range-separator,
.el-date-editor .el-range-input,
.el-time-panel__btn,
.el-time-spinner__item,
.el-date-table th,
.el-picker-panel__body,
.el-select__placeholder,
.el-form-item__label,
.el-input__inner,
.el-select__placeholder,
.el-date-range-picker__header [class*="arrow-left"] {
  color: white !important;
}
.el-date-editor.el-input,
.el-date-editor.el-input__wrapper {
  height: 100% !important;
  width: 100% !important;
}
src/components/monifangzhen/ResultAssess.vue
@@ -260,47 +260,4 @@
  color: white !important;
}
</style>
<style>
.el-select-dropdown {
  background: rgba(8, 75, 66, 1) !important;
  color: white !important;
}
.el-picker-panel__body {
  color: white !important;
}
.el-picker-panel__body div {
  background: transparent !important;
}
.el-picker-panel {
  background: rgba(8, 75, 66, 1) !important;
}
.el-select-dropdown__item {
  color: white !important;
  font-size: 12px !important;
}
.el-date-table th {
  color: white !important;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  color: #409eff !important;
}
.el-input__wrapper {
  background: rgba(8, 75, 66, 1) !important;
  border: 2px solid #437a74 !important;
  box-shadow: none !important;
}
.el-select__wrapper {
  background: rgba(8, 75, 66, 1) !important;
  border: 2px solid #437a74 !important;
  box-shadow: none !important;
}
</style>
src/components/monifangzhen/RiverLevel.vue
@@ -194,70 +194,4 @@
  color: white !important;
}
</style>
<style>
.el-select-dropdown {
  background: rgba(8, 75, 66, 1) !important;
  color: white !important;
}
.el-picker-panel__body {
  color: white !important;
}
.el-picker-panel__body div {
  background: transparent !important;
}
.el-picker-panel {
  background: rgba(8, 75, 66, 1) !important;
}
.el-select-dropdown__item {
  color: white !important;
  font-size: 12px !important;
}
.el-date-table th {
  color: white !important;
}
.el-select-dropdown__item.hover,
.el-select-dropdown__item:hover {
  color: #409eff !important;
}
.el-input__wrapper {
  background: rgba(8, 75, 66, 1) !important;
  border: 2px solid #437a74 !important;
  box-shadow: none !important;
}
.el-select__wrapper {
  background: rgba(8, 75, 66, 1) !important;
  border: 2px solid #437a74 !important;
  box-shadow: none !important;
}
.level-list {
  display: flex;
  margin-top: 10px;
  flex-wrap: wrap;
  .level-item {
    width: 150px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    background: rgba(8, 75, 66, 1);
    color: white;
    margin-right: 10px;
    margin-bottom: 10px;
    cursor: pointer;
    border-radius: 5px;
    &.active {
      background: #11b6a6;
    }
  }
}
</style>
src/components/monifangzhen/echartInfo.vue
@@ -317,279 +317,163 @@
  return timeOnly;
};
//初始化并配置第一个ECharts图表(降雨数据图表)
const setEcharts1 = () => {
  // 获取DOM元素并初始化ECharts实例
  // 1. 初始化图表
  const chartDom = document.getElementById("echarts1");
  myChart1 = echarts.init(chartDom);
  // 响应式数据定义
  let rainfallData = ref([]); // 存储从JSON加载的原始降雨数据
  let data1 = ref([]); // 存储降雨数据(mm/min)
  let data2 = ref([]); // 存储累计雨量数据(mm)
  let xAxisData = ref([]); // 存储x轴时间数据
  let updateInterval = null; // 定时器ID
  let dataIndex = ref(0); // 当前数据索引
  // 2. 数据定义(完全保持您的原始变量)
  let rainfallData = ref([]);
  let data1 = ref([]);
  let data2 = ref([]);
  let xAxisData = ref([]);
  let updateInterval = null;
  let dataIndex = ref(0);
  // 从JSON文件加载降雨数据
  // 4. 动态计算Y轴(新增的核心逻辑)
  const getDynamicYAxis = (dataArray) => {
    const currentMax = Math.max(...dataArray, 1); // 确保最小显示范围
    const step = Math.ceil(currentMax / 3);
    return {
      max: step * 3,
      interval: step,
    };
  };
  // 5. 加载数据(完全保持您的逻辑)
  const loadJsonData = async () => {
    try {
      // 发起网络请求获取数据
      const response = await fetch("/json/rainfall.json");
      const result = await response.json();
      // 验证数据格式
      if (result && result.data && Array.isArray(result.data)) {
      if (result?.data?.length) {
        rainfallData.value = result.data;
        xAxisData.value = ["00:00"] || syncTimeWithTimeline(); // 初始时间点
        // 计算数据的最大值用于y轴刻度
        const maxValue = Math.max(
          ...rainfallData.value.map((item) => item.value)
        );
        const maxTotal = Math.max(
          ...rainfallData.value.map((item) => item.total)
        );
        // 初始化时间轴和第一个数据点
        xAxisData.value = ["00:00"]; // 起始时间
        if (rainfallData.value.length > 0) {
          data1.value.push(rainfallData.value[0].value); // 添加第一个降雨数据
          data2.value.push(rainfallData.value[0].total); // 添加第一个累计雨量
          data1.value = [rainfallData.value[0].value];
          data2.value = [rainfallData.value[0].total];
          updateChart(); // 初始化图表
        }
        // 计算y轴参数并更新图表
        const yAxis1Params = calculateYAxisParams(maxValue); // 左侧y轴(降雨数据)
        const yAxis2Params = calculateYAxisParams(maxTotal); // 右侧y轴(累计雨量)
        updateChart(yAxis1Params, yAxis2Params);
      } else {
        console.error(
          "Invalid JSON format: 'data' is missing or not an array!"
        );
      }
    } catch (error) {
      console.error("Error fetching data:", error);
      console.error("数据加载失败:", error);
    }
  };
  /**
   * 计算y轴参数(生成均匀分布的刻度)
   * @param {number} max - 数据最大值
   * @returns {Object} 包含max和interval的对象
   */
  const calculateYAxisParams = (max) => {
    const step = Math.ceil(max / 3); // 将范围分成3等份(产生4个刻度点)
    return {
      max: step * 3, // 确保最大值是步长的整数倍
      interval: step, // 刻度间隔
    };
  };
  /**
   * 更新图表配置
   * @param {Object} yAxis1Params - 左侧y轴参数
   * @param {Object} yAxis2Params - 右侧y轴参数
   */
  const updateChart = (yAxis1Params, yAxis2Params) => {
  // 6. 图表配置(仅修改Y轴部分)
  const updateChart = () => {
    const option = {
      animation: false, // 禁用动画提高性能
      // 提示框配置
      tooltip: {
        trigger: "axis", // 坐标轴触发
        axisPointer: {
          // 指示器样式
          type: "cross", // 十字准星指示器
          crossStyle: { color: "#fff" }, // 白色线条
        },
      },
      // 图表布局
      grid: {
        left: "1%",
        right: "1%",
        bottom: "1%", // 边距
        containLabel: true, // 包含坐标轴标签
      },
      // 图例配置
      // >>> 保持您原有的所有配置 <<<
      animation: false,
      tooltip: { trigger: "axis" },
      grid: { left: "1%", right: "1%", bottom: "1%", containLabel: true },
      legend: {
        data: ["降雨数据", "累计雨量"], // 系列名称
        textStyle: { color: "#fff" }, // 白色文字
        right: "10px", // 靠右对齐
        data: ["降雨数据", "累计雨量"],
        textStyle: { color: "#fff" },
      },
      // x轴配置(时间轴)
      // >>> 您原来的xAxis配置(完全不变) <<<
      xAxis: [
        {
          type: "category", // 类目轴
          data: xAxisData.value, // 时间数据
          axisPointer: { type: "shadow" }, // 阴影指示器
          axisLabel: {
            color: "#fff", // 白色标签
            rotate: 0, // 不旋转
          },
          type: "category",
          data: xAxisData.value, // 您的时间数据
          axisLabel: { color: "#fff", rotate: 0 },
        },
      ],
      // y轴配置(双y轴)
      // >>> 修改的Y轴配置(动态范围) <<<
      yAxis: [
        // 左侧y轴(降雨数据)
        {
          type: "value",
          name: "单位:mm",
          min: 0, // 最小值为0
          max: yAxis1Params.max, // 动态计算的最大值
          interval: yAxis1Params.interval, // 动态计算的间隔
          axisLabel: {
            formatter: "{value}",
            color: "#fff",
            align: "right", // 标签右对齐
          },
          nameTextStyle: {
            padding: [0, 0, 0, 30], // 名称右侧内边距
            color: "#fff",
          },
          splitLine: { show: false }, // 不显示网格线
        },
        // 右侧y轴(累计雨量)
        {
          // 左侧Y轴(降雨)
          type: "value",
          name: "单位:mm",
          min: 0,
          max: yAxis2Params.max,
          interval: yAxis2Params.interval,
          axisLabel: {
            formatter: "{value}",
            color: "#fff",
            align: "left", // 标签左对齐
          },
          nameTextStyle: {
            padding: [0, 10, 0, 0], // 名称左侧内边距
            color: "#fff",
          },
          splitLine: { show: true }, // 显示网格线
          ...getDynamicYAxis(data1.value), // 动态范围
          axisLabel: { color: "#fff" },
          splitLine: { show: false },
        },
        {
          // 右侧Y轴(累计)
          type: "value",
          name: "单位:mm",
          min: 0,
          ...getDynamicYAxis(data2.value), // 动态范围
          axisLabel: { color: "#fff" },
          splitLine: { show: true },
        },
      ],
      // 数据系列配置
      // >>> 保持您原有的series配置 <<<
      series: [
        // 柱状图(降雨数据)
        {
          name: "降雨数据",
          type: "bar", // 柱状图
          tooltip: {
            valueFormatter: (value) => value + " mm/min", // 提示框单位
          },
          data: data1.value, // 绑定数据
          itemStyle: { color: "#3268fe" }, // 蓝色柱状图
          label: { show: false, color: "#fff" }, // 不显示数据标签
          type: "bar",
          data: data1.value,
          itemStyle: { color: "#3268fe" },
        },
        // 折线图(累计雨量)
        {
          name: "累计雨量",
          type: "line", // 折线图
          yAxisIndex: 1, // 使用第二个y轴
          tooltip: {
            valueFormatter: (value) => value + " mm", // 提示框单位
          },
          data: data2.value, // 绑定数据
          lineStyle: { color: "#ffb637" }, // 黄色线条
          label: { show: false, color: "#fff" }, // 不显示数据标签
          type: "line",
          yAxisIndex: 1,
          data: data2.value,
          lineStyle: { color: "#ffb637" },
        },
      ],
    };
    // 应用配置到图表
    myChart1.setOption(option);
    myChart1.setOption(option, true);
  };
  // 定时更新图表数据
  // 7. 数据更新(保持您的时间逻辑)
  const updateData = () => {
    // 检查是否还有数据需要显示
    if (dataIndex.value < rainfallData.value.length) {
      const newItem = rainfallData.value[dataIndex.value];
      // 添加新数据
      data1.value.push(newItem.value); // 添加降雨数据
      data2.value.push(newItem.total); // 添加累计雨量
      xAxisData.value.push(syncTimeWithTimeline()); // 添加时间点
      dataIndex.value++; // 递增索引
      // 更新图表(保持原有y轴范围)
      updateChart(
        {
          max: myChart1.getOption().yAxis[0].max,
          interval: myChart1.getOption().yAxis[0].interval,
        },
        {
          max: myChart1.getOption().yAxis[1].max,
          interval: myChart1.getOption().yAxis[1].interval,
        }
      );
      const item = rainfallData.value[dataIndex.value];
      data1.value.push(item.value);
      data2.value.push(item.total);
      xAxisData.value.push(syncTimeWithTimeline()); // 您的时间生成方法
      dataIndex.value++;
      updateChart(); // 动态调整Y轴
    } else {
      console.log("All data has been displayed.");
      stopUpdating(); // 数据全部显示完成后停止更新
      stopUpdating();
    }
  };
  //启动定时更新
  // 8. 控制方法(完全不变)
  const startUpdating = (interval = 1000) => {
    if (!updateInterval) {
      updateInterval = setInterval(updateData, interval);
      console.log("Started updating...");
    }
  };
  //停止定时更新
  const stopUpdating = () => {
    if (updateInterval) {
      clearInterval(updateInterval);
      updateInterval = null;
      console.log("Stopped updating...");
    }
  };
  //重置图表数据和状态
  const resetLoading = () => {
    stopUpdating(); // 停止当前更新
    // 重置状态
    stopUpdating();
    dataIndex.value = 0;
    data1.value = [];
    data2.value = [];
    xAxisData.value = ["00:00"];
    // 重新加载第一个数据点(如果有数据)
    if (rainfallData.value.length > 0) {
      data1.value.push(rainfallData.value[0].value);
      data2.value.push(rainfallData.value[0].total);
    if (rainfallData.value.length) {
      data1.value = [rainfallData.value[0].value];
      data2.value = [rainfallData.value[0].total];
    }
    // 重新绘制图表(保持原有y轴范围)
    updateChart(
      {
        max: myChart1.getOption().yAxis[0].max,
        interval: myChart1.getOption().yAxis[0].interval,
      },
      {
        max: myChart1.getOption().yAxis[1].max,
        interval: myChart1.getOption().yAxis[1].interval,
      }
    );
    console.log("Reset loading...");
    updateChart();
  };
  // 初始化:加载数据
  // 9. 初始化
  loadJsonData();
  // 返回公共接口
  return {
    myChart1, // 图表实例
    startUpdating, // 启动更新方法
    stopUpdating, // 停止更新方法
    resetLoading, // 重置方法
    myChart1,
    startUpdating,
    stopUpdating,
    resetLoading,
  };
};
@@ -597,263 +481,178 @@
  const chartDom = document.getElementById("echarts2");
  myChart2 = echarts.init(chartDom);
  let jsonData = ref([]); // 存储从 JSON 文件中加载的数据
  let data1 = ref([]); // 实时流量数据
  let data2 = ref([]); // 累计流量数据
  let xAxisData = ref([]); // 动态时间轴
  let updateInterval = null; // 定时器变量
  let dataIndex = ref(0); // 当前数据索引,用于按顺序更新
  let jsonData = ref([]);
  let data1 = ref([]);
  let data2 = ref([]);
  let xAxisData = ref([]);
  let updateInterval = null;
  let dataIndex = ref(0);
  // 加载 JSON 数据
  // 加载 JSON 数据(完全保持原有逻辑)
  const loadJsonData = async () => {
    try {
      const response = await fetch("/json/于家西沟断面下数据.json");
      const result = await response.json();
      if (result && result.data && Array.isArray(result.data)) {
        jsonData.value = result.data;
        // 计算 value 和 total 的最大值
        const maxValue = Math.max(...jsonData.value.map((item) => item.value));
        const maxTotal = Math.max(...jsonData.value.map((item) => item.total));
        // 初始化时间轴(从00:00开始)
        xAxisData.value = ["00:00"] || syncTimeWithTimeline(); // 初始时间点
        // 初始化图表(仅加载第一个数据点)
        xAxisData.value = ["00:00"] || syncTimeWithTimeline(); // 保持您的时间初始化
        if (jsonData.value.length > 0) {
          data1.value.push(jsonData.value[0].value); // 实时流量
          data2.value.push(jsonData.value[0].total); // 累计流量
          data1.value.push(jsonData.value[0].value);
          data2.value.push(jsonData.value[0].total);
        }
        // 根据最大值设置 y 轴参数并初始化图表
        const yAxis1Params = calculateYAxisParams(maxValue);
        const yAxis2Params = calculateYAxisParams(maxTotal);
        updateChart(yAxis1Params, yAxis2Params);
      } else {
        console.error(
          "Invalid JSON format: 'data' is missing or not an array!"
        );
        updateChart(); // 初始化时自动计算Y轴范围
      }
    } catch (error) {
      console.error("Error fetching data:", error);
      console.error("数据加载失败:", error);
    }
  };
  // 计算 y 轴参数(最多有 4 个点)
  const calculateYAxisParams = (max) => {
    const step = Math.ceil(max / 3); // 最多有 4 个点(包括 0),所以分成 3 份
  // 动态计算Y轴参数(新增核心功能)
  const calculateDynamicYAxis = (dataArray) => {
    const currentMax = Math.max(...dataArray, 1); // 确保最小显示范围
    const step = Math.ceil(currentMax / 3);
    return {
      max: step * 3, // 确保最大值是步长的整数倍
      interval: step,
      max: step * 3,
      interval: step
    };
  };
  // 更新图表配置
  const updateChart = (yAxis1Params, yAxis2Params) => {
  // 更新图表配置(仅修改Y轴部分)
  const updateChart = () => {
    const option = {
      animation: false, // 禁用动画
      // >>> 保持您原有的所有配置 <<<
      animation: false,
      tooltip: {
        trigger: "axis",
        axisPointer: {
          type: "cross",
          crossStyle: {
            color: "#fff",
          },
        },
        axisPointer: { type: "cross" }
      },
      grid: {
        left: "1%",
        right: "1%",
        bottom: "1%",
        containLabel: true,
        containLabel: true
      },
      legend: {
        data: ["实时流量", "累计流量"],
        textStyle: {
          color: "#fff",
        },
        right: "10px", // 将图例靠右贴边
        textStyle: { color: "#fff" },
        right: "10px"
      },
      xAxis: [
        {
          type: "category",
          data: xAxisData.value, // 使用动态时间轴
          axisPointer: {
            type: "shadow",
          },
          axisLabel: {
            color: "#fff",
            rotate: 0, // 将旋转角度设置为0,取消倾斜
          },
        },
      ],
      // >>> 您原来的xAxis配置(完全不变) <<<
      xAxis: [{
        type: "category",
        data: xAxisData.value,
        axisLabel: { color: "#fff", rotate: 0 }
      }],
      // >>> 修改的Y轴配置(动态范围) <<<
      yAxis: [
        {
        { // 左侧Y轴(实时流量)
          type: "value",
          name: "单位:m³/min",
          min: 0,
          max: yAxis1Params.max,
          interval: yAxis1Params.interval,
          axisLabel: {
          ...calculateDynamicYAxis(data1.value),
          axisLabel: {
            formatter: "{value}",
            color: "#fff",
            align: "right", // 将标签右对齐
            align: "right"
          },
          nameTextStyle: {
            padding: [0, 0, 0, 20], // 在右侧添加一些内边距
            color: "#fff",
            padding: [0, 0, 0, 20],
            color: "#fff"
          },
          splitLine: {
            show: false, // 关闭左侧 y 轴的横线
          },
          splitLine: { show: false }
        },
        {
        { // 右侧Y轴(累计流量)
          type: "value",
          name: "单位:m³",
          min: 0,
          max: yAxis2Params.max,
          interval: yAxis2Params.interval,
          axisLabel: {
          ...calculateDynamicYAxis(data2.value),
          axisLabel: {
            formatter: "{value}",
            color: "#fff",
            align: "left", // 将标签右对齐
            align: "left"
          },
          nameTextStyle: {
            padding: [0, 10, 0, 0], // 在右侧添加一些内边距
            color: "#fff",
            padding: [0, 10, 0, 0],
            color: "#fff"
          },
          splitLine: {
            show: true, // 保留右侧 y 轴的横线
          },
        },
          splitLine: { show: true }
        }
      ],
      // >>> 保持您原有的series配置 <<<
      series: [
        {
          name: "实时流量",
          type: "bar",
          tooltip: {
            valueFormatter: function (value) {
              return value + " m³/min";
            },
          },
          tooltip: { valueFormatter: value => value + " m³/min" },
          data: data1.value,
          itemStyle: {
            color: "blue", // 设置柱状图颜色为蓝色
          },
          label: {
            show: false,
            color: "#fff",
          },
          itemStyle: { color: "blue" }
        },
        {
          name: "累计流量",
          type: "line",
          yAxisIndex: 1,
          tooltip: {
            valueFormatter: function (value) {
              return value + " m³";
            },
          },
          tooltip: { valueFormatter: value => value + " m³" },
          data: data2.value,
          lineStyle: {
            color: "#ffb637", // 设置折线图线条颜色为黄色
          },
          label: {
            show: false, // 确保标签不显示
            color: "#fff",
          },
        },
      ],
          lineStyle: { color: "#ffb637" }
        }
      ]
    };
    myChart2.setOption(option);
    myChart2.setOption(option, true); // 强制刷新
  };
  // 定义按顺序更新数据的方法
  // 数据更新(保持您的时间逻辑)
  const updateData = () => {
    if (dataIndex.value < jsonData.value.length) {
      // 获取当前索引的数据项
      const newItem = jsonData.value[dataIndex.value];
      data1.value.push(newItem.value); // 添加实时流量
      data2.value.push(newItem.total); // 添加累计流量
      const nextTime = syncTimeWithTimeline();
      xAxisData.value.push(nextTime);
      // 更新当前索引
      dataIndex.value += 2;
      // 更新图表
      updateChart(
        {
          max: myChart2.getOption().yAxis[0].max,
          interval: myChart2.getOption().yAxis[0].interval,
        }, // 左侧 y 轴保持不变
        {
          max: myChart2.getOption().yAxis[1].max,
          interval: myChart2.getOption().yAxis[1].interval,
        } // 右侧 y 轴保持不变
      );
      data1.value.push(newItem.value);
      data2.value.push(newItem.total);
      xAxisData.value.push(syncTimeWithTimeline()); // 您的时间生成方法
      dataIndex.value += 2; // 保持您的索引步长
      updateChart(); // 自动调整Y轴
    } else {
      console.log("All data has been displayed.");
      stopUpdating(); // 停止定时更新
      stopUpdating();
    }
  };
  // 启动定时更新
  // 控制方法(完全不变)
  const startUpdating = (interval = 1000) => {
    if (!updateInterval) {
      updateInterval = setInterval(updateData, interval); // 每隔 interval 毫秒更新一次数据
      console.log("Started updating...");
      updateInterval = setInterval(updateData, interval);
    }
  };
  // 停止定时更新
  const stopUpdating = () => {
    if (updateInterval) {
      clearInterval(updateInterval);
      updateInterval = null;
      console.log("Stopped updating...");
    }
  };
  // 重置加载
  const resetLoading = () => {
    stopUpdating(); // 停止定时器
    dataIndex.value = 0; // 重置数据索引
    data1.value = []; // 清空实时流量数据
    data2.value = []; // 清空累计流量数据
    xAxisData.value = ["00:00"]; // 重置时间轴
    // 重新加载第一个数据点
    if (jsonData.value.length > 0) {
      data1.value.push(jsonData.value[0].value); // 实时流量
      data2.value.push(jsonData.value[0].total); // 累计流量
    stopUpdating();
    dataIndex.value = 0;
    data1.value = [];
    data2.value = [];
    xAxisData.value = ["00:00"];
    if (jsonData.value.length) {
      data1.value.push(jsonData.value[0].value);
      data2.value.push(jsonData.value[0].total);
    }
    // 重新绘制图表
    updateChart(
      {
        max: myChart2.getOption().yAxis[0].max,
        interval: myChart2.getOption().yAxis[0].interval,
      }, // 左侧 y 轴保持不变
      {
        max: myChart2.getOption().yAxis[1].max,
        interval: myChart2.getOption().yAxis[1].interval,
      } // 右侧 y 轴保持不变
    );
    console.log("Reset loading...");
    updateChart();
  };
  // 初始化加载 JSON 数据
  // 初始化
  loadJsonData();
  return {
    myChart2,
    startUpdating,
    stopUpdating,
    resetLoading,
    resetLoading
  };
};
src/store/simAPI.js
@@ -47,6 +47,7 @@
    // 保存方案逻辑
    const saveScheme = async (forms) => {
        // forms.hours = dayjs(val[0]).format("YYYY-MM-DD HH:mm:ss");
        if (isLoading.value) {
            ElMessage.warning('正在保存,请稍候...')
            return
@@ -63,7 +64,9 @@
                type: forms.type,
                status: 0,
                data: JSON.stringify({
                    startTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
                    startTime: Array.isArray(forms.hours)
                        ? dayjs(forms.hours[0]).format("YYYY-MM-DD HH:mm:ss")
                        : dayjs(forms.hours).format("YYYY-MM-DD HH:mm:ss"),
                    type: forms.type,
                    total: forms.rainfall,
                    duration: forms.duration,
@@ -98,6 +101,7 @@
            })
            // 用户确认后执行保存
            await saveScheme(forms)
            console.log(forms, 'ffffffffff')
        } catch (error) {
            if (error !== 'cancel') {
                console.error('保存出错:', error)
src/views/Home.vue
@@ -53,7 +53,7 @@
// import Device from "@/components/menu/Device.vue";
import Detail from "@/components/tools/Detail.vue";
// 不可以删除,否则全局样式会丢掉,不知道原因
import ResultAssess from "@/components/monifangzhen/ResultAssess.vue";
// import ResultAssess from "@/components/monifangzhen/ResultAssess.vue";
// import DangerAssess from "@/components/monifangzhen/DangerAssess.vue";
import { showDeviceDetail } from "@/store";
import { setupTokenRefresh } from "@/api/hpApi.js"
src/views/left/CitySim.vue
@@ -80,9 +80,28 @@
            <template #append>mm</template>
          </el-input>
        </el-form-item>
        <el-form-item label="选择时间:">
          <el-date-picker
            v-if="forms.fileList.length !== 0"
            v-model="forms.hours"
            type="datetime"
            placeholder="Select date and time"
          />
          <el-date-picker
            v-if="forms.fileList.length == 0"
            v-model="forms.hours"
            type="datetimerange"
            start-placeholder="开始时间"
            end-placeholder="结束时间"
            format="YYYY-MM-DD HH:mm:ss"
            date-format="YYYY/MM/DD ddd"
            time-format="A hh:mm:ss"
            @change="change"
          />
        </el-form-item>
        <el-form-item label="降雨时长:">
          <el-input
            disabled
            v-model="forms.duration"
            style="max-width: 600px"
            placeholder="Please input"
@@ -120,6 +139,7 @@
import { SimAPIStore } from "@/store/simAPI";
import { getRegionData } from "@/api/trApi";
import { storeToRefs } from "pinia";
import dayjs from "dayjs";
const simStore = SimAPIStore();
const { selectTab } = storeToRefs(simStore);
@@ -173,7 +193,20 @@
  fileList: [],
  type: 3,
  rainFallList: [],
  hours: "",
});
// 计算累计时长
const calculateHoursDifference = (val) => {
  if (!val || val.length !== 2) return 0;
  const [startDate, endDate] = val;
  const diffInHours = dayjs(endDate).diff(dayjs(startDate), "hour", true); // true 表示返回浮点数
  return diffInHours;
};
const change = (val) => {
  forms.duration = calculateHoursDifference(val);
};
const addSimCheme = async () => {
  await simStore.addSimCheme(forms);
@@ -188,6 +221,7 @@
  forms.intensity = "";
  forms.fileList = [];
  forms.rainFallList = [];
  forms.hours = "";
};
// 计算属性:获取上传文件的名称列表
src/views/left/KGSimOption/PredictiveSimulation.vue
@@ -81,12 +81,12 @@
          ><template #append>h</template></el-input
        >
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="openPlan">打开方案</el-button>
        <el-button type="primary" @click="openSaveDialog">保存方案</el-button>
        <el-button type="success" @click="startPlay">开始模拟</el-button>
      </el-form-item>
    </el-form>
    <div class="buttons">
      <el-button type="primary" @click="openPlan">打开方案</el-button>
      <el-button type="primary" @click="openSaveDialog">保存方案</el-button>
      <el-button type="success" @click="startPlay">开始模拟</el-button>
    </div>
  </div>
</template>
<script setup>