Forráskód Böngészése

准确率增加盒须图,预测发电量站端和云端分开执行

fanxiaoyu 5 hónapja
szülő
commit
eb7d03de6e

+ 8 - 0
cpp-admin/src/main/java/com/cpp/web/controller/accuracy/AccuracyPassRateController.java

@@ -5,6 +5,7 @@ import com.cpp.system.service.ISysConfigService;
 import com.cpp.web.domain.accuracy.AccuracyPassRate;
 import com.cpp.web.domain.enums.DataSourcesEnum;
 import com.cpp.web.domain.enums.ForecastTypeEnum;
+import com.cpp.web.domain.station.PowerStationStatusData;
 import com.cpp.web.dto.TableColumn;
 import com.cpp.web.service.accuracy.AccuracyPassRateService;
 import lombok.RequiredArgsConstructor;
@@ -37,6 +38,13 @@ public class AccuracyPassRateController {
         String[] lineNum = standLine.split(",");
         Map<String,Object> map = new HashMap<>();
         List<AccuracyPassRate> accuracyPassRateList = accuracyPassRateService.findByTimeBetweenAndForecastTypeAndDataSourcesAndAgoAndForecastModelAndStationCode(new Date(startTime), new Date(endTime), forecastType, dataSources, ago, forecastModel, stationCode);
+        // 自定义比较器(降序)
+        Collections.sort(accuracyPassRateList, new Comparator<AccuracyPassRate>() {
+            @Override
+            public int compare(AccuracyPassRate b1, AccuracyPassRate b2) {
+                return b1.getTime().compareTo(b2.getTime());
+            }
+        });
         map.put("tableData",accuracyPassRateList);
         map.put("dq",lineNum[0]);
         map.put("cdq",lineNum[1]);

+ 30 - 0
cpp-admin/src/main/java/com/cpp/web/controller/accuracy/ShortTermSinglePointDeviationController.java

@@ -0,0 +1,30 @@
+package com.cpp.web.controller.accuracy;
+
+import com.cpp.common.core.domain.R;
+import com.cpp.web.service.accuracy.ShortTermSinglePointDeviationService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.Map;
+
+/**
+ *  短期单点偏差相关
+ */
+@RestController
+@RequiredArgsConstructor
+@Slf4j
+@RequestMapping("shortTermSinglePointDeviation")
+public class ShortTermSinglePointDeviationController {
+
+    private final ShortTermSinglePointDeviationService shortTermSinglePointDeviationService;
+
+    @GetMapping("/getBoxNeed")
+    public R getBoxNeed(Long startTime,Long endTime,int ago,String stationCode){
+        Map<String,Object> map = shortTermSinglePointDeviationService.findByTimeBetweenAndHowLongAgoAndStationCode(new Date(startTime),new Date(endTime),ago,stationCode);
+        return R.ok(map);
+    }
+}

+ 2 - 1
cpp-admin/src/main/java/com/cpp/web/service/accuracy/ShortTermSinglePointDeviationService.java

@@ -5,6 +5,7 @@ import com.cpp.web.domain.accuracy.ShortTermSinglePointDeviation;
 
 import java.util.Date;
 import java.util.List;
+import java.util.Map;
 
 /**
  * idp_forecast_power_short_term
@@ -14,5 +15,5 @@ import java.util.List;
  */
 public interface ShortTermSinglePointDeviationService extends IService<ShortTermSinglePointDeviation> {
 
-    List<ShortTermSinglePointDeviation> findByTimeBetweenAndHowLongAgoAndStationCode(Date startTime,Date endTime,int ago,String stationCode);
+    Map<String,Object> findByTimeBetweenAndHowLongAgoAndStationCode(Date startTime, Date endTime, int ago, String stationCode);
 }

+ 28 - 1
cpp-admin/src/main/java/com/cpp/web/service/accuracy/impl/AccuracyPassRateServiceImpl.java

@@ -8,12 +8,14 @@ import com.cpp.web.domain.enums.DataSourcesEnum;
 import com.cpp.web.domain.enums.ForecastTypeEnum;
 import com.cpp.web.mapper.accuracy.AccuracyPassRateMapper;
 import com.cpp.web.service.accuracy.AccuracyPassRateService;
+import com.cpp.web.utils.DateTimeUtil;
 import com.cpp.web.utils.StartAndEndMonthUtil;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
+import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.*;
 import java.util.function.Function;
@@ -30,6 +32,8 @@ public class AccuracyPassRateServiceImpl extends ServiceImpl<AccuracyPassRateMap
 
     @Autowired
     private ISysDictDataService dictDataService;
+
+    private final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
     @Override
     public List<AccuracyPassRate> findByTimeBetweenAndForecastTypeAndDataSourcesAndAgoAndForecastModelAndStationCode(Date startTime, Date endTime, ForecastTypeEnum forecastType, DataSourcesEnum dataSources, Integer ago, String forecastModel, String stationCode) {
             QueryWrapper<AccuracyPassRate> wrapper = new QueryWrapper<>();
@@ -51,7 +55,30 @@ public class AccuracyPassRateServiceImpl extends ServiceImpl<AccuracyPassRateMap
         if (ago != null && !ago.equals("")) {
             wrapper.eq("forecast_how_long_ago", ago);
         }
-        return baseMapper.selectList(wrapper);
+        List<AccuracyPassRate> list = list(wrapper);
+        // 根据要求进行调整,过滤脏数据,如果所查天数为空,则显示"",而不是直接就是不展示了
+        // 过滤掉单点平均偏差大于100的
+        List<AccuracyPassRate> filterList = list.stream().filter(f -> null != f.getDeviationSum() && Double.valueOf(f.getDeviationSum().replace("%","")) <=100).collect(Collectors.toList());
+        List<String> timeList = DateTimeUtil.getDatesInRange(startTime,endTime);
+        try {
+            for (String s : timeList) {
+                if (s.equals(dateFormat.format(new Date()))){
+                    continue;
+                }
+                List<AccuracyPassRate> collectList = filterList.stream().filter(f -> dateFormat.format(f.getTime()).equals(s)).collect(Collectors.toList());
+                if (collectList.size() == 0 ){
+                    AccuracyPassRate accuracyPassRate = new AccuracyPassRate();
+                    accuracyPassRate.setTime(dateFormat.parse(s));
+                    accuracyPassRate.setDeviationSum("");
+                    accuracyPassRate.setAccuracy("");
+                    filterList.add(accuracyPassRate);
+                }
+            }
+        } catch (ParseException e) {
+            throw new RuntimeException(e);
+        }
+
+        return filterList;
     }
 
     @Override

+ 36 - 12
cpp-admin/src/main/java/com/cpp/web/service/accuracy/impl/ShortTermSinglePointDeviationServiceImpl.java

@@ -26,32 +26,56 @@ public class ShortTermSinglePointDeviationServiceImpl extends ServiceImpl<ShortT
     private final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
 
     @Override
-    public List<ShortTermSinglePointDeviation> findByTimeBetweenAndHowLongAgoAndStationCode(Date startTime, Date endTime, int ago, String stationCode) {
+    public Map<String, Object> findByTimeBetweenAndHowLongAgoAndStationCode(Date startTime, Date endTime, int ago, String stationCode) {
         QueryWrapper<ShortTermSinglePointDeviation> wrapper = new QueryWrapper<>();
-        if (null != stationCode && !"".equals(stationCode)){
-            wrapper.eq("station_code",stationCode);
+        if (null != stationCode && !"".equals(stationCode)) {
+            wrapper.eq("station_code", stationCode);
         }
-        if (null != startTime && !"".equals(startTime) && null != endTime && !"".equals(endTime)){
-            wrapper.between("time",startTime,endTime);
+        if (null != startTime && !"".equals(startTime) && null != endTime && !"".equals(endTime)) {
+            wrapper.between("time", startTime, endTime);
         }
-        wrapper.eq("forecast_how_long_ago",ago);
+        wrapper.eq("forecast_how_long_ago", ago);
 
         List<ShortTermSinglePointDeviation> list = list(wrapper);
 
         Map<String, List<Double>> groupedByDate = list.stream()
                 .collect(Collectors.groupingBy(
                         std -> sdf.format(std.getTime()),
-                        Collectors.mapping( std -> std.getDeviation().doubleValue(), Collectors.toList())
+                        Collectors.mapping(std -> std.getDeviation().doubleValue(), Collectors.toList())
                 ));
 
 
-//        double[][] arr = new int[3][3];
-
-        return null;
-    }
-
+        List dataList = new ArrayList<>();
+        List timeList = new ArrayList<>();
+        List abnormalList = new ArrayList<>();
+        for (Map.Entry<String, List<Double>> listMap : groupedByDate.entrySet()) {
+
+            timeList.add(listMap.getKey());
+            // 转数组
+            double[] array = listMap.getValue().stream().mapToDouble(Double::doubleValue).toArray();
+            // 所需盒须值
+            double[] result = plot(array);
+            dataList.add(result);
+            double max = result[result.length - 1];double min = result[0];
+
+            List<Double> doubleList = listMap.getValue().stream().filter(f -> f < min && f > max).collect(Collectors.toList());
+            if (doubleList.size() > 0) {
+                for (Double v : doubleList) {
+                    List ceShiList = new ArrayList<>();
+                    ceShiList.add(listMap.getKey());
+                    ceShiList.add(v);
+                    abnormalList.add(ceShiList);
+                }
+            }
 
+        }
+        Map<String, Object> map = new HashMap<>();
+        map.put("result", dataList);
+        map.put("time", timeList);
+        map.put("abnormal", abnormalList);
 
+        return map;
+    }
 
 
     public static double[] plot(double[] data) {

+ 3 - 1
cpp-admin/src/main/java/com/cpp/web/service/powerGeneation/DayPowerGenerationService.java

@@ -17,7 +17,9 @@ public interface DayPowerGenerationService extends IService<DayPowerGeneration>
 
     DayPowerGeneration findByStationCodeAndGenDate(String stationCode, Date genDate);
 
-    void generatePower(String stationCode);
+    void generateYdPower(String stationCode);
+
+    void generateZdPower(String stationCode);
 
     List<DayPowerGeneration> findByStationCodeAndGenDateAndPredictionDataSource(String StationCode,String genDate,String predictionDataSource);
 }

+ 40 - 11
cpp-admin/src/main/java/com/cpp/web/service/powerGeneation/impl/DayPowerGenerationServiceImpl.java

@@ -9,11 +9,13 @@ import com.cpp.web.domain.accuracy.AccuracyPassRate;
 import com.cpp.web.domain.cloud.ForecastPowerShortTermCloud;
 import com.cpp.web.domain.enums.DataSourcesEnum;
 import com.cpp.web.domain.powerGeneration.DayPowerGeneration;
+import com.cpp.web.domain.station.ForecastPowerShortTermRegulation;
 import com.cpp.web.domain.station.ForecastPowerShortTermStation;
 import com.cpp.web.mapper.powerGeneration.DayPowerGenerationMapper;
 import com.cpp.web.service.accuracy.AccuracyPassRateService;
 import com.cpp.web.service.cloud.ForecastPowerShortTermCloudService;
 import com.cpp.web.service.powerGeneation.DayPowerGenerationService;
+import com.cpp.web.service.station.ForecastPowerShortTermRegulationService;
 import com.cpp.web.service.station.ForecastPowerShortTermStationService;
 import com.cpp.web.utils.DateTimeUtil;
 import lombok.Data;
@@ -47,6 +49,7 @@ public class DayPowerGenerationServiceImpl extends ServiceImpl<DayPowerGeneratio
 
     private final AccuracyPassRateService accuracyPassRateService;
 
+    private final ForecastPowerShortTermRegulationService forecastPowerShortTermRegulationService;
     private final String dateFormat = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
 
     @Override
@@ -67,10 +70,10 @@ public class DayPowerGenerationServiceImpl extends ServiceImpl<DayPowerGeneratio
      * @param stationCode
      */
     @Override
-    public void generatePower(String stationCode) {
+    public void generateYdPower(String stationCode) {
 
         Date accuracyStartTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() - 30 * 24 * 60 * 60 * 1000L);
-        Date accuracyEndTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis()  - 24 * 60 * 60 * 1000L);
+        Date accuracyEndTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() - 24 * 60 * 60 * 1000L);
 
 
         String forecastModel = "";
@@ -99,23 +102,46 @@ public class DayPowerGenerationServiceImpl extends ServiceImpl<DayPowerGeneratio
 
         Date endTime = DateTimeUtil.getDayLastTime(startTime.getTime() + 10 * 24 * 60 * 60 * 1000L - 1);
 
-        List<DayPowerGeneration> dayPowerGenerationList = findByGenDate(dateFormat, stationCode);
+        List<DayPowerGeneration> dayPowerGenerationList = findByGenDate(dateFormat, stationCode, "云端下发");
 
         if (dayPowerGenerationList.size() > 0) {
             return;
         }
         // 云端预测
-        List<ForecastPowerShortTermCloud> forecastPowerShortTermCloudList = forecastPowerShortTermCloudService.findByForecastTimeBetweenAndStationCode(startTime, endTime, stationCode,"".equals(forecastModel)?"JY":forecastModel);
-        // 站端预测
-        List<ForecastPowerShortTermStation> forecastPowerShortTermStationList = forecastPowerShortTermStationService.findByForecastTimeBetweenAndStationCode(startTime, endTime, stationCode);
+        List<ForecastPowerShortTermCloud> forecastPowerShortTermCloudList = forecastPowerShortTermCloudService.findByForecastTimeBetweenAndStationCode(startTime, endTime, stationCode, "".equals(forecastModel) ? "JY" : forecastModel);
+        if (forecastPowerShortTermCloudList.size() > 0){
+            List<DayPowerGeneration> ydList = calculator(forecastPowerShortTermCloudList, "yd", startTime, stationCode);
+            this.saveBatch(ydList);
+        }
+       ;
+    }
+
+    /**
+     * 站端上传发电量计算
+     *
+     * @param stationCode
+     */
+    @Override
+    public void generateZdPower(String stationCode) {
+
+        Date genDate = DateTimeUtil.getDayStartTime(new Date().getTime() + 24 * 1000 * 60 * 60);
+
+        Date startTime = DateTimeUtil.getDayStartTime(System.currentTimeMillis() + 24 * 60 * 60 * 1000L);
 
-        List<DayPowerGeneration> ydList = calculator(forecastPowerShortTermCloudList, "yd", startTime, stationCode);
-        List<DayPowerGeneration> zdList = calculator(forecastPowerShortTermStationList, "zd", startTime, stationCode);
+        Date endTime = DateTimeUtil.getDayLastTime(startTime.getTime() + 10 * 24 * 60 * 60 * 1000L - 1);
 
-        this.saveBatch(ydList);
-        this.saveBatch(zdList);
+        List<DayPowerGeneration> dayPowerGenerationList = findByGenDate(dateFormat, stationCode, "站端上传");
+        if (dayPowerGenerationList.size() > 0) {
+            return;
+        }
+        List<ForecastPowerShortTermRegulation> forecastPowerShortTermRegulationList = forecastPowerShortTermRegulationService.findByForecastTimeBetweenAndGenDateAndHowLongAgo(genDate, startTime, endTime, stationCode);
+        if (forecastPowerShortTermRegulationList.size() > 0) {
+            List<DayPowerGeneration> zdList = calculator(forecastPowerShortTermRegulationList, "zd", startTime, stationCode);
+            this.saveBatch(zdList);
+        }
     }
 
+
     @Override
     public List<DayPowerGeneration> findByStationCodeAndGenDateAndPredictionDataSource(String stationCode, String genDate, String predictionDataSource) {
         QueryWrapper<DayPowerGeneration> wrapper = new QueryWrapper<>();
@@ -225,7 +251,7 @@ public class DayPowerGenerationServiceImpl extends ServiceImpl<DayPowerGeneratio
         return datas;
     }
 
-    public List<DayPowerGeneration> findByGenDate(String genDate, String stationCode) {
+    public List<DayPowerGeneration> findByGenDate(String genDate, String stationCode, String predictionDataSource) {
         QueryWrapper<DayPowerGeneration> wrapper = new QueryWrapper<>();
         if (null != genDate && !"".equals(genDate)) {
             wrapper.eq("gen_date", genDate);
@@ -233,6 +259,9 @@ public class DayPowerGenerationServiceImpl extends ServiceImpl<DayPowerGeneratio
         if (null != stationCode && !"".equals(stationCode)) {
             wrapper.eq("station_code", stationCode);
         }
+        if (null != predictionDataSource && !"".equals(predictionDataSource)) {
+            wrapper.eq("prediction_data_source", predictionDataSource);
+        }
         return list(wrapper);
     }
 

+ 2 - 0
cpp-admin/src/main/java/com/cpp/web/service/station/ForecastPowerShortTermRegulationService.java

@@ -36,4 +36,6 @@ public interface ForecastPowerShortTermRegulationService extends IService<Foreca
     List<ForecastPowerShortTermRegulation> findByForecastTimeBetweenAndForecastHowLongAgoAndStationCode(Long startTime, Long endTime, Integer howLongAgo, String stationCode);
 
     List<ForecastPowerShortTermRegulation> findByForecastTimeBetweenAndHowLongAgo(Date startTime, Date endTime, Integer howLongAgo);
+
+    List<ForecastPowerShortTermRegulation> findByForecastTimeBetweenAndGenDateAndHowLongAgo(Date genDate,Date startTime,Date endTime,String stationCode);
 }

+ 14 - 0
cpp-admin/src/main/java/com/cpp/web/service/station/impl/ForecastPowerShortTermRegulationServiceImpl.java

@@ -44,6 +44,20 @@ public class ForecastPowerShortTermRegulationServiceImpl extends ServiceImpl<For
     }
 
     @Override
+    public List<ForecastPowerShortTermRegulation> findByForecastTimeBetweenAndGenDateAndHowLongAgo(Date genDate, Date startTime, Date endTime,String stationCode) {
+
+        QueryWrapper<ForecastPowerShortTermRegulation> wrapper = new QueryWrapper<>();
+        if (null != genDate && !"".equals(genDate) && startTime != null && !"".equals(startTime) && endTime != null && !"".equals(endTime)){
+            wrapper.eq("gen_date",genDate);
+            wrapper.between("time",startTime,endTime);
+        }
+        if (null != stationCode && !"".equals(stationCode)){
+            wrapper.eq("station_code",stationCode);
+        }
+        return list(wrapper);
+    }
+
+    @Override
     public ForecastPowerShortTermRegulation findByForecastTimeAndForecastHowLongAgoAndStationCode(Long time, int howLongAgo, String stationCode) {
         QueryWrapper<ForecastPowerShortTermRegulation> wrapper = new QueryWrapper<>();
 

+ 125 - 128
cpp-ui/src/views/statistics/stationAccuracy/index.vue

@@ -26,7 +26,8 @@
           </el-select>
         </el-form-item>
         <el-form-item label="预测类型">
-          <el-select v-model="forecastType" placeholder="请选择" popper-class="cpp-popper" @change="forecastType=='dq'?ago=1:ago=8">
+          <el-select v-model="forecastType" placeholder="请选择" popper-class="cpp-popper"
+                     @change="forecastType=='dq'?ago=1:ago=8">
             <el-option
               v-for="item in forecastTypeList"
               :key="item.value"
@@ -68,7 +69,7 @@
             resizable
             highlight-current-row
             show-overflow
-            height="700"
+            height="672"
             :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)"
             :cell-class-name="cellClassName"
           >
@@ -82,11 +83,12 @@
             ></vxe-table-column>
           </vxe-table>
           <vxe-pager
+            class="custom-pager"
             perfect
             :current-page.sync="currentPage"
             :page-size.sync="pageSize"
             :total="total"
-            :page-sizes=[10,50,100]
+            :page-sizes=[13,50,100]
             :layouts="['PrevJump', 'PrevPage','JumpNumber', 'NextPage', 'NextJump', 'Sizes', 'FullJump', 'Total']"
             @page-change="handlePageChange"
           >
@@ -95,10 +97,10 @@
         </el-col>
         <el-col :span="16" style="margin-top: -47px">
           <el-row>
-            <div style="float:left;width: 100%;height: 410px" id="zqlCharts"></div>
+            <div style="float:left;width: 100%;height: 425px" id="zqlCharts"></div>
           </el-row>
           <el-row>
-            <div style="float:left;width: 100%;height: 410px" id="pcCharts"></div>
+            <div style="float:left;width: 100%;height: 425px" id="pcCharts"></div>
 
           </el-row>
 
@@ -111,9 +113,8 @@
 
 <script>
 import * as echarts from "echarts";
-
 export default {
-  name: 'inverterinfo',
+  name: 'accuracy',
   data() {
     return {
       fromHead: [
@@ -136,12 +137,13 @@ export default {
       dateTime: [new Date(new Date().toLocaleDateString()).getTime() - 15 * 60 * 60 * 24 * 1000, new Date(new Date().toLocaleDateString()).getTime() - 60 * 60 * 24 * 1000],
       total: 0,
       sortOrder: 'asc',
-      pageSize: 10,
+      pageSize: 13,
       currentPage: 1,
       stationList: [],
       stationCode: [],
       searchForm: {},
       tableData: [],
+      sortData: [],
       nameList: [],
       loading: false,
       modId: '',//备用id
@@ -163,9 +165,14 @@ export default {
       stationCodeInfo: "",
       pickerOptions: {
         disabledDate: (time) => {
-          return time.getTime() > new Date(new Date().toLocaleDateString()).getTime() -1
+          return time.getTime() > new Date(new Date().toLocaleDateString()).getTime() - 1
         }
       },
+      chartData: {
+        boxplotData:[],
+        scatterData:[],
+        xData:[]
+      }
     }
   },
   created() {
@@ -177,10 +184,7 @@ export default {
     if (this.zqlChart) {
       this.zqlChart.dispose()
       this.zqlChart = null
-
     }
-
-
     if (this.pcChart) {
       this.pcChart.dispose()
       this.pcChart = null
@@ -200,17 +204,6 @@ export default {
       }
 
     },
-    tabClick(tab) {
-      if (this.activeName == 'second') {
-        this.$nextTick(function () {
-          this.wsChart.resize();
-        })
-      }
-    },
-    nameFormat({cellValue, row, column}) {
-      const item = this.nameList.find(item => item.value === cellValue)
-      return item ? item.label : ''
-    },
     stationCodeFormat({cellValue, row, column}) {
       const item = this.stationList.find(item => item.value === cellValue)
       return item ? item.label : ''
@@ -245,29 +238,55 @@ export default {
         this.agoInfo = this.points().filter(s => s.value == this.ago)[0].label
         this.forecastTypeInfo = this.forecastTypeList.filter(s => s.value == this.forecastType)[0].label
         this.stationCodeInfo = this.stationList.filter(s => s.value == this.stationCode)[0].label
-        this.tableData = response.data.tableData
+        this.sortData = [...response.data.tableData];
+        this.tableData = [...response.data.tableData];
+        // 表格中数据降序排列
+        this.tableData.sort((a, b) => {
+          const dateA = new Date(a.time);
+          const dateB = new Date(b.time);
+          return dateB - dateA;
+        });
         this.total = response.data.tableData.length
-
         let times = []
-        let pcDatas = []
         let zqlDatas = []
-        this.tableData.forEach(t => {
+        this.sortData.forEach(t => {
           times.push(t.time)
-          zqlDatas.push(t.accuracy.replace("%", ""))
-          pcDatas.push(t.deviationSum == null ? "" : t.deviationSum.replace("%", ""))
+          if (t.accuracy != ""){
+            zqlDatas.push(t.accuracy.replace("%", ""))
+          }else {
+            zqlDatas.push(t.accuracy)
+          }
         })
-        if (this.forecastType === 'dq'){
-          this.zqlDraw(times, pcDatas,response.data.dq)
-        }else {
-          this.zqlDraw(times, pcDatas,response.data.cdq)
+        if (this.forecastType === 'dq') {
+          this.zqlDraw(times, zqlDatas, response.data.dq)
+        } else {
+          this.zqlDraw(times, zqlDatas, response.data.cdq)
         }
-        // this.zqlDraw(times, zqlDatas,this.forecastType)
-        this.pcDraw(times, pcDatas)
+        this.initChart()
         this.loading = false
       }).catch(() => {
         this.loading = false
       })
     },
+    initChart() {
+      this.loading = true
+      let startTime = Math.round(this.dateTime[0])
+      let endTime = Math.round(this.dateTime[1])
+      let queryParams = {
+        "stationCode": this.stationCode,
+        "startTime": startTime,
+        "endTime": endTime,
+        "ago": this.ago
+      }
+      this.$axios.get('/shortTermSinglePointDeviation/getBoxNeed', {params: queryParams}).then(response => {
+        this.chartData.boxplotData = response.data.result
+        this.chartData.scatterData = response.data.abnormal
+        this.chartData.xData = response.data.time
+        this.pcChart = echarts.init(document.getElementById('pcCharts'), 'dark')
+        this.setOptions(this.chartData)
+        this.loading = false
+      })
+    },
     getStationCode() {
       this.$axios({url: '/electricfield/all', method: 'get'}).then(response => {
         this.stationList = response.data
@@ -277,7 +296,7 @@ export default {
         }
       })
     },
-    zqlDraw(times, datas,standLine) {
+    zqlDraw(times, datas, standLine) {
       this.zqlChart = echarts.init(document.getElementById('zqlCharts'), "dark", {renderer: 'svg'})
       let option = {
         backgroundColor: 'transparent',
@@ -287,7 +306,6 @@ export default {
           textStyle: {
             fontWeight: 'normal',
             fontSize: 16,
-            // //color: this.lineColor
           },
           left: '1%'
         },
@@ -364,9 +382,8 @@ export default {
         }],
 
       }
-      // if (forecastType === 'cdq'){
-      if(standLine != "" || standLine != undefined) {
-        option.series=[
+      if (standLine != "" || standLine != undefined) {
+        option.series = [
           {
             name: '准确率(%)',
             type: 'line',
@@ -390,7 +407,7 @@ export default {
               data: [{
                 label: {
                   position: 'start',
-                  formatter: "合格("+Number(standLine)+")"
+                  formatter: "合格(" + Number(standLine) + ")"
                 },
                 yAxis: Number(standLine)
               }]
@@ -405,8 +422,8 @@ export default {
             data: datas
           }
         ]
-      }else {
-        option.series= [
+      } else {
+        option.series = [
           {
             name: '准确率(%)',
             type: 'line',
@@ -445,117 +462,94 @@ export default {
         _this.zqlChart.resize();
       });
     },
-    pcDraw(times, datas) {
-      this.pcChart = echarts.init(document.getElementById('pcCharts'), "dark", {renderer: 'svg'})
-
+    setOptions({xData, boxplotData,scatterData} = {}) {
+      const _this = this
       let option = {
-        backgroundColor: 'transparent',
-        title: {
-          top: 20,
-          text: '单点平均偏差(cap*%)',
-          textStyle: {
-            fontWeight: 'normal',
-            fontSize: 16,
-            //color: this.lineColor
-          },
-          left: '1%'
-        },
-        tooltip: {
-          trigger: 'axis',
-          axisPointer: {
-            lineStyle: {
-              color: '#57617B'
-            }
+        title: [
+          {
+            top: 15,
+            text: '单点平均偏差(cap*%)',
+            textStyle: {
+              fontWeight: 'normal',
+              fontSize: 16,
+              //color: this.lineColor
+            },
+            left: '1%'
           }
-        },
-        legend: {
-          top: 20,
-          width: '70%',
-          icon: 'rect',
-          itemWidth: 14,
-          itemHeight: 5,
-          itemGap: 13,
-          data: ["单点平均偏差(cap*%)"],
-          right: '4%',
-          textStyle: {
-            fontSize: 12,
-            //color: this.lineColor
-          },
-          selected: {}
-        },
-        dataZoom: [ {
-          type: 'inside'
-        }],
+        ],
         grid: {
-          top: 100,
+          top: 50,
           left: '4%',
           right: '4%',
           bottom: '10%',
           containLabel: true
         },
-        xAxis: [{
-          type: 'category',
-          boundaryGap: false,
-          axisLine: {
-            lineStyle: {
-              //color: this.lineColor
+        animation: false,
+        tooltip: {
+          trigger: 'axis',
+          formatter: function (params){
+            let str = params[0].axisValue +'<br/>'
+            for(let param of params){
+              if(param.componentSubType === 'scatter'){
+                str = str + '<div class="flex justify-between"><div>'+param.marker+param.value[0]+'异常点</div><div class="ml-0">'+param.value[1]+'</div></div>'
+              }
+              if(param.componentSubType === 'boxplot'){
+                str = str + '<div class="flex justify-between"><div>'+param.marker+'min</div><div >'+param.value[1]+'</div></div>'+
+                  '<div class="flex justify-between"><div>'+param.marker+'Q1</div><div>'+param.value[2]+'</div></div>'+
+                  '<div class="flex justify-between"><div>'+param.marker+'median</div><div>'+param.value[3]+'</div></div>'+
+                  '<div class="flex justify-between"><div>'+param.marker+'Q3</div><div>'+param.value[4]+'</div></div>'+
+                  '<div class="flex justify-between"><div>'+param.marker+'max</div><div>'+param.value[5]+'</div></div>'
+              }
             }
-          },
-          data: times
-        }],
-        yAxis: [{
+            return str
+          }
+        },
+        xAxis: {
+          type: 'category',
+          axisTick: {show: true},
+          data: xData
+        },
+        yAxis: {
           type: 'value',
-          name: 'cap*h',
-          axisTick: {
-            show: false
-          },
-          axisLine: {
-            lineStyle: {
-              //color: this.lineColor
-            }
-          },
-
           axisLabel: {
-            margin: 10,
+            padding: [3, 0, 0, 0],
+            formatter: '{value}',
             textStyle: {
               fontSize: 14,
-              //color: this.lineColor
             },
-            formatter: '{value}',
+          },
+          axisTick: {
+            show: false,
           },
           splitLine: {
             lineStyle: {
-              color: '#57617B'
-            }
-          }
-        }],
+              type: 'dashed',
+            },
+          },
+        },
         series: [
           {
-            name: '单点平均偏差(cap*%)',
-            type: 'line',
-            smooth: false,
-            symbol: 'circle',
-            symbolSize: 5,
-            showSymbol: true,
-            lineStyle: {
-              normal: {
-                width: 2
-              }
+            name: '',
+            type: 'boxplot',
+            itemStyle: {
+              color: 'rgba(126,199,250,0.86)',
+              // 边线颜色
+              borderColor: '#89BFE5',
+              // 边线宽度
+              borderWidth: 2
             },
+            data: boxplotData
+          },
+          {
+            type: 'scatter',
             itemStyle: {
-              normal: {
-                color: 'rgb(140,50,219)',
-                borderColor: 'rgba(140,50,219,0.2)',
-                borderWidth: 12
-              }
+              color: 'orange',
             },
-            data: datas
+            data: scatterData
           }
         ]
       }
-
       this.pcChart.setOption(option, true)
-      var _this = this
       window.addEventListener("resize", function () {
         _this.pcChart.resize();
       });
@@ -588,5 +582,8 @@ export default {
   background-color: #FF0000;
   color: #ffffff;
 }
+.custom-pager {
+  height: 70px; /* 设置你需要的高度 */
+}
 </style>
 <!--&gt;>>.vxe-table .vxe-body&#45;&#45;row .vxe-body&#45;&#45;column.class-style .vxe-cell .vxe-cell&#45;&#45;label{-->