Sfoglia il codice sorgente

重构频率分布计算

Michael Wang 3 anni fa
parent
commit
2c01b96c54
1 ha cambiato i file con 92 aggiunte e 100 eliminazioni
  1. 92 100
      src/features/allAnalysis/ScoreRate.vue

+ 92 - 100
src/features/allAnalysis/ScoreRate.vue

@@ -14,9 +14,9 @@
 
       <a-collapse v-model:activeKey="activeKey">
         <a-collapse-panel
-          v-for="(item, index) in data"
+          v-for="(course, index) in courses"
           :key="index"
-          :header="item.courseName + '(' + item.courseCode + ')'"
+          :header="course.courseName + '(' + course.courseCode + ')'"
         >
           <div class="tw-flex tw-justify-between tw-items-center tw-my-4">
             <h3 class="section-title">等距({{ scoreGap }}分)分组频数分布</h3>
@@ -31,64 +31,25 @@
               <th>累计频数</th>
               <th>累计频数(%)</th>
             </tr>
-            <tr
-              v-for="(item2, index) in Math.round(item.totalScore / scoreGap)"
-              :key="index"
-            >
-              <td>{{ (item2 - 1) * scoreGap }}-</td>
-              <td>
-                {{
-                  item.scoreRangeAcc[item2 * scoreGap] -
-                  item.scoreRangeAcc[(item2 - 1) * scoreGap]
-                }}
-              </td>
-              <td>
-                {{
-                  (item.scoreRangeAcc[item2 * scoreGap] -
-                    item.scoreRangeAcc[(item2 - 1) * scoreGap]) /
-                  item.scoreRangeTotal
-                }}
-              </td>
-              <td>{{ item.scoreRangeAcc[item2 * scoreGap] }}</td>
-              <td>
-                {{
-                  item.scoreRangeAcc[item2 * scoreGap] / item.scoreRangeTotal
-                }}
-              </td>
-            </tr>
-            <tr v-if="item.totalScore % scoreGap">
-              <td>
-                {{
-                  item.scoreRangeAcc[item.scoreRangeAcc.length - 1] -
-                  item.scoreRangeAcc[
-                    item.scoreRangeAcc.length - 1 - (item.totalScore % scoreGap)
-                  ]
-                }}
-              </td>
-              <td>
-                {{
-                  (item.scoreRangeAcc[item.scoreRangeAcc.length - 1] -
-                    item.scoreRangeAcc[
-                      item.scoreRangeAcc.length -
-                        1 -
-                        (item.totalScore % scoreGap)
-                    ]) /
-                  item.scoreRangeTotal
-                }}
-              </td>
-              <td>{{ item.scoreRangeAcc[item.scoreRangeAcc.length - 1] }}</td>
-              <td>100%</td>
+            <tr v-for="(seg, index) in course.segements" :key="index">
+              <td>{{ seg[0] }}-</td>
+              <td>{{ seg[1] }}</td>
+              <td>{{ Math.round(seg[2] * 100) }}%</td>
+              <td>{{ seg[3] }}</td>
+              <td>{{ Math.round(seg[4] * 100) }}%</td>
             </tr>
           </table>
 
           <div class="tw-flex tw-justify-between tw-items-center tw-my-4">
             <h3 class="section-title">科目分数线分组的频数分布</h3>
             <div class="tw-flex tw-gap-2">
-              <a-button @click="openRangeConfigModal(item)">分段设置</a-button>
+              <a-button @click="openRangeConfigModal(course)">
+                分段设置
+              </a-button>
               <a-button @click="openModal2">说明</a-button>
             </div>
           </div>
-          <div v-if="item.rangeConfig">
+          <div v-if="course.rangeConfig">
             <table class="custom-table">
               <tr>
                 <th>分数段</th>
@@ -97,52 +58,12 @@
                 <th>累计频数</th>
                 <th>累计频数(%)</th>
               </tr>
-              <tr v-for="(item2, index) in item.rangeConfig" :key="index">
-                <td>
-                  {{ scoreTitle(item.rangeConfig[index]) }}
-                </td>
-                <td>
-                  {{
-                    (item.rangeConfig[index + 1]
-                      ? item.scoreRangeAcc[
-                          item.rangeConfig[index + 1].baseScore +
-                            item.rangeConfig[index + 1].adjustScore
-                        ]
-                      : 0) -
-                      item.scoreRangeAcc[item2.baseScore + item2.adjustScore] ||
-                    0
-                  }}
-                </td>
-                <td>
-                  {{
-                    ((item.rangeConfig[index + 1]
-                      ? item.scoreRangeAcc[
-                          item.rangeConfig[index + 1].baseScore +
-                            item.rangeConfig[index + 1].adjustScore
-                        ]
-                      : 0) -
-                      item.scoreRangeAcc[item2.baseScore + item2.adjustScore] ||
-                      0) / item.scoreRangeTotal
-                  }}
-                </td>
-                <td>
-                  {{
-                    item2.baseScore + item2.adjustScore >=
-                    item.scoreRangeAcc.length
-                      ? item.scoreRangeAcc[item.scoreRangeAcc.length - 1]
-                      : item.scoreRangeAcc[item2.baseScore + item2.adjustScore]
-                  }}
-                </td>
-                <td>
-                  {{
-                    item2.baseScore + item2.adjustScore >=
-                    item.scoreRangeAcc.length
-                      ? 1
-                      : item.scoreRangeAcc[
-                          item2.baseScore + item2.adjustScore
-                        ] / item.scoreRangeTotal
-                  }}
-                </td>
+              <tr v-for="(seg, index) in course.rangeSegements" :key="index">
+                <td>{{ seg[0] }}-</td>
+                <td>{{ seg[1] }}</td>
+                <td>{{ Math.round(seg[2] * 100) }}%</td>
+                <td>{{ seg[3] }}</td>
+                <td>{{ Math.round(seg[4] * 100) }}%</td>
               </tr>
             </table>
           </div>
@@ -162,7 +83,7 @@
 
 <script setup lang="ts">
 import { useMainStore } from "@/store";
-import { onMounted } from "vue-demi";
+import { onMounted, watch } from "vue-demi";
 import { useRoute } from "vue-router";
 import {
   getSasCourseList,
@@ -181,7 +102,7 @@ let courseId = $ref(undefined as undefined | number);
 const route = useRoute();
 const projectId = +route.params.projectId;
 
-let data = $ref([]);
+let courses = $ref([]);
 async function fetchData() {
   const res = await getSasCourseList({
     projectId,
@@ -212,7 +133,7 @@ async function fetchData() {
     return v;
   });
   console.log(res.data);
-  data = res.data;
+  courses = res.data;
 }
 
 onMounted(async () => {
@@ -222,6 +143,77 @@ onMounted(async () => {
 
 let scoreGap = $ref(10);
 
+watch(
+  () => [scoreGap, courses],
+  () => {
+    for (const course of courses) {
+      course.segements = [];
+      const validSeg = Math.round(course.totalScore / scoreGap);
+      for (let score = 0; score < validSeg; score++) {
+        const row = [];
+        row[0] = score * scoreGap;
+        let nextScore = score + 1 > validSeg ? course.totalScore : score + 1;
+        // row[1] =
+        //   course.scoreRangeAcc[nextScore * scoreGap - 1] -
+        //   course.scoreRangeAcc[score * scoreGap];
+        row[1] = course.scoreRange
+          .slice(row[0], nextScore * scoreGap)
+          .reduce((p, c) => p + c, 0);
+        row[2] = row[1] / course.scoreRangeAcc[course.totalScore];
+        row[3] = course.scoreRangeAcc[nextScore * scoreGap - 1];
+        row[4] = row[3] / course.scoreRangeAcc[course.totalScore];
+        course.segements.push(row);
+      }
+      if (validSeg * scoreGap === course.totalScore) {
+        course.segements.push([
+          course.totalScore,
+          course.scoreRange[course.totalScore],
+          course.scoreRange[course.totalScore] /
+            course.scoreRangeAcc[course.totalScore],
+          course.scoreRangeAcc[course.totalScore],
+          1,
+        ]);
+      }
+
+      course.rangeSegements = [];
+      for (let i = 0; i < course.rangeConfig.length; i++) {
+        const range = course.rangeConfig[i];
+        const nextRange =
+          i === course.rangeConfig.length - 1
+            ? { baseScore: course.totalScore, adjustScore: 0 }
+            : course.rangeConfig[i + 1];
+        const row = [];
+        row[0] = scoreTitle(range);
+        row[1] =
+          course.scoreRange
+            .slice(
+              range.baseScore + range.adjustScore,
+              nextRange.baseScore + nextRange.adjustScore
+            )
+            .reduce((p, c) => p + c, 0) || 0;
+        row[2] = row[1] / course.scoreRangeTotal;
+        row[3] =
+          course.scoreRangeAcc[
+            nextRange.baseScore + nextRange.adjustScore - 1
+          ] || 0;
+        if (
+          nextRange.baseScore + nextRange.adjustScore >=
+          course.scoreRangeAcc.length
+        ) {
+          row[3] = course.scoreRangeAcc[course.scoreRangeAcc.length - 1];
+        }
+        row[4] = row[3] / course.scoreRangeTotal;
+
+        course.rangeSegements.push(row);
+      }
+      // console.log(course);
+    }
+  },
+  {
+    immediate: true,
+  }
+);
+
 // let scores = [];
 // const scoreComputed = computed(() => {
 //   const s = {};