浏览代码

添加毛高正态分布分析

liling 2 天之前
父节点
当前提交
a7385cf26b
共有 2 个文件被更改,包括 314 次插入9 次删除
  1. 2 2
      src/api/calc/calcMaogao.js
  2. 312 7
      src/views/calc/calcMaogao/index.vue

+ 2 - 2
src/api/calc/calcMaogao.js

@@ -7,10 +7,10 @@ export function GetMaoGao() {
         params: null
     })
 }
-export function GetMaoGaoDetail(v) {
+export function GetMaoGaoDetail(v,month) {
     return request({
         url: `/api/formula/detail/` + v,
         method: "get",
-        params: null
+        params: {month:month}
     })
 }

+ 312 - 7
src/views/calc/calcMaogao/index.vue

@@ -8,7 +8,7 @@
       </div>
       <div style="height: 700px;width: 100%;background-color: rgb(237 237 237 / 23%);margin-top: 10px;display: flex;">          
           <div style="height: 700px;width: 30%;margin-left: 1%;">
-            <div class="table_caption" style="height: 30px;line-height: 30px;">汇总统计</div>
+            <div class="table_caption" style="height: 30px;line-height: 30px;"><b>当前占比分布统计</b></div>
             <el-table v-loading="loading" height="750px" :data="datalist">
                   <el-table-column label="毛高" align="center" prop="height"></el-table-column>
                   <el-table-column label="设备数量" align="center" prop="num"></el-table-column>
@@ -20,9 +20,28 @@
                   </el-table-column>
                 </el-table>
           </div>
-          <div style="height: 700px;width: 68%;margin-left: 1%;">
-              <div class="table_caption" style="height: 30px;line-height: 30px;">毛高({{detailValue}})明细数据</div>
-              <el-table class="titletable" cellspacing="0" cellpadding="0" height="750px" width="800px" :data="detailDataList">
+          <div style="height: 780px;width: 68%;margin-left: 1%;">
+              <div style="height: 300px;width: 100%;">
+                <div style="height: 42px;width: 100%;padding: 5px;line-height: 30px;">
+                  <span style="position: relative;"><b>毛高({{detailValue}})正态及趋势分析</b>     月份:</span>
+                  <el-date-picker
+                    style="width: 180px;"
+                    v-model="queryMonth"
+                    value-format="YYYY-MM"
+                    date-format="YYYY-MM" 
+                    format="YYYY-MM" 
+                    :value-format="'YYYY-MM'"
+                    type="date"
+                    placeholder="请选择月"
+                  ></el-date-picker>
+                </div>
+                <div style="height: 255px;width: 100%;padding: 5px;background-color: #fff;display: flex;">
+                  <div style="height: 100%;width:50%" ref="echatrs1"></div>
+                  <div style="height: 100%;width:50%" ref="echatrs2"></div>
+                </div>
+              </div>
+              <div class="table_caption" style="height: 30px;line-height: 30px;"><b>毛高({{detailValue}})明细数据</b></div>
+              <el-table class="titletable" cellspacing="0" cellpadding="0" height="450px" width="800px" :data="detailDataList">
                 <el-table-column label="设备名" align="center" prop="device"></el-table-column>
                 <el-table-column label="机台号" align="center" prop="formula_data_2"></el-table-column>
                 <el-table-column label="毛高" align="center" prop="formula_data_15"></el-table-column>
@@ -63,6 +82,10 @@
           let detailDataList=ref([]);
           let detailValue=ref('');
           const loading=ref(true);
+          const echatrs1 = ref(null);
+          const echatrs2 = ref(null);
+          var nowMonth = new Date(new Date().getTime() - 31 * 60 * 60 * 1000).Format('yyyy-MM');
+          const queryMonth = ref(nowMonth);
           function impquery(){
               detailDataList.value=[];
               datalist.value=[];
@@ -78,7 +101,8 @@
                   if(res.code!=0){
                       return;
                   }
-                  datalist.value = res.data;
+                  datalist.value = res.data||[];
+                  if(datalist.value.length>0) getDetail(res.data[0]);
               }).catch(res=>{
                   ElMessage({
                       message:"数据获取失败!",
@@ -95,12 +119,14 @@
                       type:"info",
                       duration:0, //一直显示
               });
-              GetMaoGaoDetail(v.height).then((res)=>{
+              GetMaoGaoDetail(v.height,queryMonth.value).then((res)=>{
                   msg.close();
                   if(res.code!=0){
                       return;
                   }
-                  detailDataList.value = res.data;
+                  detailDataList.value = res.data.curr;
+                  showEcharts1(res.data.his);
+                  showEcharts2(res.data.his);
               }).catch(res=>{
                   ElMessage({
                       message:"数据获取失败!",
@@ -108,6 +134,282 @@
                   });
               });
           }
+          //正态分布图
+          function showEcharts1(seriesValuedata){            
+    
+            let listData = [];
+            let xAxis = [];
+            seriesValuedata.forEach((item, index) => {
+                listData.push(item.num)
+            });
+
+            let objGroup = listData.reduce(function(obj, name) {
+                obj[name] = obj[name] ? ++obj[name] : 1;
+                return obj;
+            }, {});
+
+            let max = Math.max(...listData);
+            let min = Math.min(...listData);
+
+            //x轴最大最小前后范围
+            let dataRangeMinOP = 2;
+            let dataRangeMaXOP = 2.1;
+            //间距 ,X轴的步距 
+            let dataRangeOP = 0.1;
+            //小数点位数.这个要和数据精确到哪一位相匹配
+            let Xpiont = 0;
+
+            //处理x轴,把数据范围内的x轴求出来,并设置值轴没有的值为空,按顺序对应
+            for (let i = min - dataRangeMinOP; i <= max + dataRangeMaXOP; i += dataRangeOP) {
+                let str = i.toFixed(Xpiont).toString();
+                xAxis.push(str);
+                if (objGroup[str] == null) {
+                    objGroup[str] = 0;
+                } 
+            }
+            //结果不对,用下面这个 解决 0.0!=0,1.0!=1的问题
+           /* for (let i = min - dataRangeMinOP; i <= max + dataRangeMaXOP; i += dataRangeOP) {
+              let str = i.toFixed(Xpiont).toString();
+              xAxis.push(str);
+              if (objGroup[Number(str)] == null) {
+                objGroup[str] = 0;
+              }
+            }*/
+
+            let barYaxis = [];
+            Object.keys(objGroup).sort(function(a, b) {
+                return parseFloat(a) - parseFloat(b)
+            }).map(key => {
+                let num = Math.floor((objGroup[key] / listData.length * 100) * 100) / 100;
+                barYaxis.push(num)
+            })
+             
+            
+            function sum(array) {
+                let s = 0;
+                array.forEach(function(val, idx, arr) {
+                    s += Number(val);
+                }, 0);
+                return s;
+            };
+
+            //正太曲线计算的基本数据和方法
+            let avg = 0;
+            let stdev = 0;
+            avg = sum(listData) / listData.length;
+
+            let sumXY = function(x, y) {
+                return Number(x) + Number(y);
+            };
+            let square = function(x) {
+                return Number(x) * Number(x);
+            };
+            let mean = listData.reduce(sumXY) / listData.length;
+            let deviations = listData.map(function(x) {
+                return x - mean;
+            });
+            
+            
+            stdev = Math.sqrt(deviations.map(square).reduce(sumXY) / (listData.length - 1));
+
+            //计算正太曲线
+            function NDjs(array) {
+                let NDarr = [];
+                for (let i = 0; i < array.length; i++) {
+                    let ND = (Math.sqrt(2 * Math.PI) * stdev) * Math.pow(Math.E, (-(Math.pow(array[i] - avg, 2) / (2 * Math.pow(stdev, 2)))));
+                    NDarr.push(ND);
+                }
+                return NDarr
+            }
+            let lineYaxis = NDjs(xAxis)
+            
+            
+            //配置项,本身项目是可以动态在页面配置修改这些属性的,贴到这里用了默认值
+            let opacityOption = 'off';
+            let opacity = 0.5;
+            if (opacityOption == 'off') {
+                opacity = 0;
+            }
+            let endPositionOption = 'all';
+            let endPositionPercentum = '';
+            let endPosition;
+            if (endPositionOption == 'all') {
+                endPosition = 100;
+            } else if (endPositionOption == 'third') {
+                endPosition = 29;
+            } else {
+                endPosition = endPositionPercentum;
+            }
+
+            let persents = 'on';
+            let format1;
+            let format2;
+            if (persents == 'on') {
+                format1 = '{value} %'
+                format2 = '{c} %'
+            }
+
+            let data = [];
+            let lineDataSet = {
+                type: 'line',
+                smooth: true,
+                yAxisIndex: 1,
+                areaStyle: {
+                    opacity: opacity
+                },
+                data: lineYaxis,
+                name: '正太分布曲线',
+                itemStyle: {
+                    normal: {
+                        label: {
+                            formatter: format2,
+                            show: false, //开启显示
+                            position: 'top', //在上方显示
+                            textStyle: { //数值样式
+                                fontSize: 16
+                            }
+                        }
+                    }
+                }
+            }
+            let barDataSet = {
+                type: 'bar',
+                smooth: true,
+                yAxisIndex: 0,
+                areaStyle: {
+                    opacity: opacity
+                },
+                data: barYaxis,
+                name: '实际分布',
+                itemStyle: {
+                    normal: {
+                        label: {
+                            formatter: format2,
+                            show: false, //开启显示
+                            position: 'top', //在上方显示
+                            textStyle: { //数值样式
+                                fontSize: 16
+                            }
+                        }
+                    }
+                }
+            }
+            data.push(lineDataSet, barDataSet);
+
+            let option = {
+                type: 'scroll',
+                title: {
+                    text: ''
+                },
+                dataZoom: [{
+                        type: 'inside',
+                        show: false,
+                        xAxisIndex: [0],
+                        start: 0,
+                        end: endPosition,
+                        borderColor: '#F5A9D0',
+                        backgroundColor: '#F5A9D0'
+                    },
+                    {
+                        show: false,
+                        type: 'slider',
+                        xAxisIndex: [0],
+                        start: 0,
+                        end: endPosition
+                    }
+                ],
+                tooltip: {
+                    trigger: "item",
+                    axisPointer: {
+                        type: "shadow"
+                    },
+                    formatter:function(params){
+                      //console.log(params)
+                      var v = (params.value*1).toFixed(2)
+                      return `${params.name} ${params.seriesName}:${v}`
+                    }
+                },
+                legend: {
+                    data: ['正太分布曲线', '实际分布']
+                },
+                xAxis: {
+                    boundaryGap: false,
+                    type: 'category',
+                    data: xAxis
+                },
+                yAxis: [{
+                    type: 'value',
+                    axisLabel: {
+                        formatter: format1
+                    }
+                }, {
+                    show: false,
+                    type: 'value',
+                    axisLabel: {
+                        formatter: '{value} %'
+                    }
+                }],
+                grid: [{
+                    left: '8%',
+                    top: '10%',
+                    width: '92%',
+                    height: '75%'
+                }],
+                series: data
+            };
+            let myChart = echarts.init(echatrs1.value)
+            myChart.setOption(option);
+          }
+          function showEcharts2(hisdata){
+            let dates=[];
+            let values=[];
+            hisdata.forEach(ele=>{
+              dates.push(ele.time.substr(5));
+              values.push(ele.num);
+            })
+            let option = {
+              tooltip:{
+                show:true,
+              },
+              title: {
+                show:false,
+                text: "机台数",
+              },
+              xAxis: {
+                type: "category",
+                data:dates,
+                axisLabel: {
+                //interval: 0,
+                rotate: -45 // 倾斜的角度
+                }
+              },
+              yAxis: {
+                name:'机台数',
+                type: "value",
+              },
+              legend: {
+                show: false,
+                bottom: "0",
+              },
+              series: [
+                {
+                  name: "机台数",
+                  data: values,
+                  type: "line",
+                  itemStyle: {
+                    color: "#a6cfa8",
+                  },
+                  label: {
+                    show: true, // 开启数据标签
+                    position: "top", // 标签显示在数据点上方,可选 'top'/'bottom'/'left'/'right' 等
+                    color: "#a6cfa8", // 标签文字颜色
+                  },
+                }
+              ],
+            };
+            let mychat = echarts.init(echatrs2.value)
+            mychat.setOption(option);
+          }
 
           function impdata(){
             if(detailValue.value==null ||detailValue.value==''){
@@ -132,6 +434,9 @@
               getDetail,
               impquery,
               loading,
+              queryMonth,
+              echatrs1,
+              echatrs2,
           }
       }
   }