ZhangXianQiang
2024-05-24 2bddfa78e65f351d6cb81f670775e79620f684a6
feat:分数统计
1个文件已修改
279 ■■■■■ 已修改文件
src/views/answer/dataStatistics.vue 279 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/answer/dataStatistics.vue
@@ -3,7 +3,8 @@
    <el-form :model="queryParam" ref="queryForm" :inline="true" style="display: flex">
      <el-form-item label="试卷:">
        <el-select v-model="queryParam.id" filterable placeholder="试卷">
          <el-option v-for="item in examPaperList" :key="item.id" :value="item.id" :label="item.name" @change="getType(item.type)" />
          <el-option v-for="item in examPaperList" :key="item.id" :value="item.id" :label="item.name"
            @change="getType(item.paperType)" />
        </el-select>
      </el-form-item>
      <el-form-item>
@@ -12,20 +13,83 @@
    </el-form>
    <el-row :gutter="20">
      <el-col :xl="12" class="echarts-row">
        <el-card>
          <div class="card-chart-container">
            <div id="ageChart" ref="ageChart" class="chart-style" v-loading="chartLoading1" />
          </div>
        </el-card>
      </el-col>
      <el-col :xl="24" class="echarts-row">
        <el-row :gutter="20">
          <el-col :span="6">
            <el-card>
              <div class="data-item">
                <div class="data-icon" :style="{ 'background-color': iconList[0].color }">
                  <i class="el-icon-tickets"></i>
                </div>
                <div class="data-info">
                  <div class="data-label">
                    总考试次数
                  </div>
                  <div class="data-num">
                    {{ totalInfo.examTotal }}
                  </div>
                </div>
              </div>
            </el-card>
      <el-col :xl="12" class="echarts-row">
        <el-card>
          <div class="card-chart-container">
            <div id="scoreChart" ref="scoreChart" class="chart-style" v-loading="chartLoading2" />
          </div>
        </el-card>
          </el-col>
          <el-col :span="6">
            <el-card>
              <div class="data-item">
                <div class="data-icon" :style="{ 'background-color': iconList[1].color }">
                  <i class="el-icon-s-claim"></i>
                </div>
                <div class="data-info">
                  <div class="data-label">
                    参考人数
                  </div>
                  <div class="data-num">
                    {{ totalInfo.factPeopleTotal }}
                  </div>
                </div>
              </div>
            </el-card>
          </el-col>
          <el-col :span="6">
            <el-card>
              <div class="data-item">
                <div class="data-icon" :style="{ 'background-color': iconList[2].color }">
                  <i class="el-icon-edit"></i>
                </div>
                <div class="data-info">
                  <div class="data-label">
                    平均分
                  </div>
                  <div class="data-num">
                    {{ totalInfo.averageScore }}
                  </div>
                </div>
              </div>
            </el-card>
          </el-col>
          <el-col :span="6">
            <el-card>
              <div class="data-item">
                <div class="data-icon" :style="{ 'background-color': iconList[3].color }">
                  <i class="el-icon-s-data"></i>
                </div>
                <div class="data-info">
                  <div class="data-label">
                    参考人数百分比
                  </div>
                  <div class="data-num">
                    {{ totalInfo.referencePercentage }}%
                  </div>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </el-col>
    </el-row>
@@ -33,7 +97,7 @@
      <el-col :xl="24">
        <el-card>
          <div class="card-chart-container">
            <div id="peopleChart" ref="peopleChart" class="chart-style" v-loading="chartLoading3" />
            <div id="peopleChart" ref="peopleChart" class="chart-style" v-loading="chartLoading" />
          </div>
        </el-card>
      </el-col>
@@ -44,38 +108,31 @@
import { mapGetters, mapState } from 'vuex';
import dashboardApi from '@/api/dashboard';
const colorList = ['#3498DB', '#E74C3C', '#F1C40F', '#95A5A6', '#8E44AD', '#F39C12', '#D35400'];
const colorList = ['#3eba45', '#3da7f8', '#ffbe40', '#95A5A6', '#8E44AD', '#F39C12', '#D35400'];
const ageLabel = {
  'age0To19': '0-19岁',
  'age20To29': '20-29岁',
  'age30To39': '30-39岁',
  'age40To49': '40-49岁',
  'ageOver50': '大于50岁',
const dataKeyMap = {
  'factPeopleTotal': '参考人数',
  'averageScore': '平均分',
  'referencePercentage': '参考人数百分比',
};
const scoreLabel = {
  'score0To59': '小于60分',
  'score60To69': '60-69分',
  'score70To79': '70-79分',
  'score80To89': '80-89分',
  'score90To100': '90-100分'
};
const pieLabel = {
  'totalAttended': '参与考试',
  'totalAbsent': '未参与考试'
};
let ageChart = null;
let scroeChart = null;
let peopleChart = null;
let observer = null;
export default {
  data() {
    return {
      examPaperList: [],
      chartLoading1: false,
      chartLoading2: false,
      chartLoading3: false,
      totalInfo: {},
      dataList: [],
      iconList: [
        { icon: 'el-icon-tickets', color: '#7868d9' },
        { icon: 'el-icon-s-claim', color: '#3eba45' },
        { icon: 'el-icon-edit', color: '#3da7f8' },
        { icon: 'el-icon-warning', color: '#ffbe40' },
        { icon: 'el-icon-error', color: '#fe640d' },
      ],
      chartLoading: false,
      queryParam: {
        id: '',
        type: 1
@@ -87,13 +144,11 @@
    if (sessionStorage.getItem('deptAdmin') == 1) {
      this.admin = false;
    }
    ageChart = echarts.init(this.$refs.ageChart);
    scroeChart = echarts.init(this.$refs.scoreChart);
    peopleChart = echarts.init(this.$refs.peopleChart);
    dashboardApi.queryCondition().then(res => {
      this.examPaperList = res.response;
      this.queryParam.id = this.examPaperList[0].id
      this.queryParam.type = this.examPaperList[0].paperType
      this.queryParam.id = this.examPaperList[0].id;
      this.queryParam.type = this.examPaperList[0].paperType;
      this.getChartData();
      this.observe();
    });
@@ -104,32 +159,25 @@
      this.getChartData();
    },
    getChartData() {
      this.chartLoading1 = true;
      this.chartLoading2 = true;
      this.chartLoading3 = true;
      this.chartLoading = true;
      dashboardApi.data(this.queryParam).then(re => {
        const { age, score, examPeopleNum } = re.response;
        const ageOption = this.barOption('年龄段统计', age, ageLabel);
        const scoreOption = this.barOption('分数段统计', score, scoreLabel);
        const peopleOption = this.pieOption('考试人数', examPeopleNum, pieLabel);
        ageChart.setOption(ageOption, true);
        scroeChart.setOption(scoreOption, true);
        peopleChart.setOption(peopleOption, true);
        this.chartLoading1 = false;
        this.chartLoading2 = false;
        this.chartLoading3 = false;
        const { data, total } = re.response;
        this.totalInfo = total;
        this.dataList = data;
        this.barOption(this.dataList);
        this.chartLoading = false;
      });
    },
    barOption(title, data, labelList) {
      const dataKeys = data.map(item => labelList[Object.keys(item)[0]]);
      const dataValues = data.map(item => Object.values(item)[0]);
      return {
    barOption(dataList) {
      const nameList = dataList.map((item) => item.name);
      const options = {
        title: {
          text: title,
          text: '部门统计',
          x: 'left'
        },
        legend: {
          orient: 'horizontal',
        },
        color: colorList,
        tooltip: {
@@ -138,69 +186,41 @@
        grid: {
          left: 10,
          right: 10,
          bottom: 20,
          bottom: 10,
          top: 40,
          containLabel: true
        },
        xAxis: {
          type: 'category',
          data: dataKeys
          data: nameList,
          axisLabel: {
            show: true,
            rotate: 35,
          },
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            type: 'bar',
            label: {
              show: true,
              fontSize: 16
            },
            barMaxWidth: '40%',
            data: dataValues,
          }
        ]
        series: Object.keys(dataKeyMap).map(key => {
          console.log(key);
          return this.filterData(dataList, key);
        })
      };
      peopleChart.setOption(options, true);
    },
    pieOption(title, data, labelList) {
      const pieData = data.map(item => {
        return {
          name: labelList[Object.keys(item)[0]],
          value: Object.values(item)[0]
        };
      });
    filterData(data, key) {
      const mapData = data.map(item => item[key]);
      return {
        title: {
          text: title,
          x: 'left'
        name: dataKeyMap[key],
        type: 'bar',
        label: {
          show: true,
        },
        color: ['#E74C3C', '#3498DB',  '#F1C40F', '#95A5A6', '#8E44AD', '#F39C12', '#D35400'],
        tooltip: {
          trigger: 'item'
        },
        legend: {
          orient: 'horizontal',
        },
        series: [
          {
            type: 'pie',
            radius: '50%',
            data: pieData,
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
        data: mapData
      };
    },
    submitForm() {
      this.getChartData();
    },
@@ -218,12 +238,6 @@
    handleResize() {
      if (ageChart) {
        ageChart.resize();
      }
      if (scroeChart) {
        scroeChart.resize();
      }
      if (peopleChart) {
        peopleChart.resize();
      }
    }
  },
@@ -246,7 +260,7 @@
.card-chart-container {
  width: 100%;
  height: 400px;
  height: 500px;
}
@@ -254,4 +268,33 @@
  width: 100%;
  height: 100%;
}
.data-item {
  width: 100%;
  display: flex;
  align-items: center;
  border-radius: 10px;
  overflow: hidden;
  .data-icon {
    font-size: 70px;
    padding: 20px 30px;
    color: #fff;
    border-radius: 10px;
    overflow: hidden;
    margin-right: 20px;
  }
  .data-info {
    .data-label {
      font-size: 18px;
      margin-bottom: 10px;
      color: #707070;
    }
    .data-num {
      font-size: 28px;
    }
  }
}
</style>