echarts柱状图经验

涉及知识点

1.动态单位,以及单位的及时变化
2.窗口变化,重新渲染echarts
3.tooltips自定义
4.Y轴刻度过长的处理

相关代码

<template>
  <div class="usageAll">
    <router-view/>
    <div class="usageOne">
      <div class="head_title">
        <title-nav
          :title="title"
          class="title">
        </title-nav>

        <search
          :filter-obj="filterObj"
          pagefrom="usageStatistics"
          @refreshData="refreshAll"></search>

        <el-select
          v-model="serviceType"
          class="select_list"
          style="display:none"
          @change="refreshAll"
        >
          <el-option
            v-for="item in svcTypeList"
            :key="item.id"
            :label="item.value"
            :value="item.id"
          >
          </el-option>
        </el-select>
      </div>
    </div>
    <div class="usageTwo">
      <div class="twoHead">
        <div class="headOne">
          <div class="oneLeft">
            <svg
              class="img_one">
              <use xlink:href="#iconfenzu30"></use>
            </svg>
            <div class="data_value">
              <label class="labValue">{{ userRecordList.wordCount }}</label>
              <label class="labTitle">总输入字数</label>
            </div>
          </div>
          <div class="oneRight">
            <div class="borderRight"></div>
          </div>
        </div>
        <div class="headTwo">
          <div class="twoLeft">
            <svg
              class="img_two">
              <use xlink:href="#iconfenzu31"></use>
            </svg>
            <div class="data_value">
              <label class="labValue">{{ userRecordList.recordTime }}</label>
              <label class="labTitle">总录音时长</label>
            </div>
          </div>
          <div class="twoRight">
            <div class="borderRight"></div>
          </div>
        </div>
        <div class="headThree">
          <div class="threeLeft">
            <svg
              class="img_three">
              <use xlink:href="#iconfenzu9"></use>
            </svg>
            <div class="data_value">
              <label class="labValue">{{ userRecordList.departmentNum }}</label>
              <label class="labTitle">使用诊室数</label>
            </div>
          </div>
        </div>
      </div>
    </div>
    <div class="usageThree">
      <el-form
        inline
        :model="formInline"
        class="demo-form-inline"
      >
        <el-form-item
          label="日期"
        >
          <el-date-picker
            v-model="formInline.dataValue"
            type="daterange"
            unlink-panels
            value-format="yyyy-MM-dd"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :picker-options="pickerOptions"
            @change="cleanupColor"
          >
          </el-date-picker>
        </el-form-item>
        <el-form-item>
          <el-button
            v-for="item in timeList"
            :key="item.id"
            :class="active === item.timeValue ? 'active' : '' "
            @click="tabChange(item.timeValue)">
            {{ item.timeValue }}
          </el-button>
        </el-form-item>
        <el-button
          class="select_but"
          @click="queryData"
        >
          查询
        </el-button>
        <el-button
          class="export_but"
          @click="exportStatistcs"
        >
          导出
        </el-button>
      </el-form>
    </div>
    <div class="usageFour">
      <el-table
        :data="showTable"
        :height="reversedHeight"
        class="el-table"
      >
        <el-table-column
          prop="serialNumber"
          label="序号"
          show-overflow-tooltip
          min-width="110"
          align="center">
        </el-table-column>
        <el-table-column
          prop="hospital"
          label="医院"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
        <el-table-column
          prop="department"
          label="科室"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
        <el-table-column
          prop="diagnosticNum"
          label="诊室"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
        <el-table-column
          prop="useTimes"
          label="时间段"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
        <el-table-column
          prop="useDate"
          label="使用天数"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
        <el-table-column
          prop="recordTime"
          label="录音时长"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
        <el-table-column
          prop="wordCount"
          label="识别字数"
          show-overflow-tooltip
          min-width="180"
          align="center">
        </el-table-column>
      </el-table>
    </div>
    <div class="usageFive">
      <div class="usage_box">
        <span class="total">共{{ total }}条</span>
        <el-pagination
          :current-page="current"
          :page-sizes="pageList"
          :page-size="size"
          layout="sizes, prev, pager, next, jumper"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="pagingData"
        >
        </el-pagination>
      </div>
    </div>
    <div class="usageSix">
      <div class="sixHead">
        <div class="headDiv">
          <el-radio-group
            v-model="timeType"
            @change="radioTimeTypeChange">
            <el-radio-button label="年"></el-radio-button>
            <el-radio-button label="月"></el-radio-button>
            <el-radio-button label="日"></el-radio-button>
          </el-radio-group>
          <!-- <el-button
            id="userNumber"
            type="text"
            class="lab"
            @click="toUserNumber"
          >
            年
          </el-button>
          <el-button
            id="usageNumber"
            type="text"
            class="lab"
            @click="toCallNumber"
          >
            月
          </el-button>
          <el-button
            id="wordNumber"
            type="text"
            class="lab"
            @click="toWordNumber"
          >
            日
          </el-button> -->
          <!-- <el-button
            id="soundRecording"
            type="text"
            class="lab"
            @click="toRecordingTime"
          >
            录音时间
          </el-button> -->
          <!-- </div> -->
        </div>
      </div>
      <div class="sixMain">
        <!-- <div :class="has_hospital ? 'echartOne' : 'echartTwo'"> -->
        <div id="echarts">
          <!-- <div id="lineChart"></div>
          <div class="bardiv">
            <div id="barChart"></div>
            <div
              v-if="has_hospital"
              id="hospital"
            >
            </div>
          </div> -->
          <!-- 四个统计图 -->
          <div id="useNumAll"></div>
          <div id="zhenshiNum"></div>
          <div id="recordTimes"></div>
          <div id="recordWords"></div>
        </div>
      </div>
    </div>


    <cpuDiskNotice page-from="tongji"></cpuDiskNotice>
  </div>
</template>
<script>
import TitleNav from '@/components/TitleNav';
import search from './comp/search';
import cpuDiskNotice from '@/components/cpuDiskNotice';
// import {getRecordList, getRecordTable, getChartData,getIpList,realtimeData} from '@/services';
import {getRecordList, getRecordTable, getChartData} from '@/services';

import  {xdata} from './mock.js'
// import { arrayGroupByKey } from '@/utils/common';

import { getHospitalList,getDepartmentList } from '@/services/index';


// import { mapState } from 'vuex'
function pad(number){
  if(number < 10){
    return '0' + number;
  }
  return number;
}
// function forMat(d){
//   let year = d.getFullYear();
//   let month = d.getMonth()+1;
//   let day = d.getDate();
//   let time =year+ '-' + pad(month) + '-' +pad(day);
//   return time;
// }

// 定义对应关系,在四个统计图会用到






export default {
  components:{
    TitleNav,
    search,
    cpuDiskNotice
  },
  data(){
    return{
      // 首先监听cpu和disk的使用情况
      // cupDiskNotice:true,
      // serverIpList:[],
      // diskInfoList:[],

      chatDetail:{
        useNumAll:{yTitle:'总调用次数',unit:'次'},
        zhenshiNum:{yTitle:'使用诊室数',unit:'个'},
        recordTimes:{yTitle:'录音时长',unit:'小时'},
        recordWords:{yTitle:'识别字数',unit:''}
      },
      filterObj:{
        hospitalName:'',
        departmentName:[],
      },


      active:'近一周',
      tableHeight: window.innerHeight - 205,
      // 时间选项列表
      timeList: [{
        id: '1',
        timeValue: '今天'
      }, {
        id: '2',
        timeValue: '昨天'
      }, {
        id: '3',
        timeValue: '近三天'
      }, {
        id: '4',
        timeValue: '近一周'
      },
      {
        id: '5',
        timeValue: '近一个月'
      }],
      // 标题
      title: '使用统计',
      pageList:[5,10,20,30],
      // 当前页数
      current: 1,
      // 总页数
      total: 0,
      // 每页数量
      size: 10,
      // 是否有多个医院
      has_hospital: false,
      // timeType 分别为年月日
      timeType: '月',
      timeTypeMap:{年:'year',月:'month',日:'date'},

      // 折线图
      lineChart:{
        xAxis:[],
        data:[]
      },
      // 柱状图
      barChart:{
        xAxis:[],
        data:[]
      },
      dataZoomType:[],
      // 柱状图
      hospitalBarChart:{
        xAxis:[],
        data:[]
      },
      // 开始时间
      startTime: '',
      // 结束时间
      endTime: '',
      // 1 今天,2昨天 3近三天 4近一个星期 5近一个月 默认时间
      dateType: 4,
      // form表单提交内容
      formInline:{
        // 日期
        dataValue: '',
      },
      tableData:[],
      // 展示统计数
      userRecordList:{},
      // 1 识别 2 合成 3语义 4 ocr
      svcTypeList: [{
        id: '1',
        value: '识别使用统计'
      },{
        id: '4',
        value: 'OCR使用统计'
      }],
      radioTime: '近一周',
      // 服务类型
      serviceType: '1',
      //带快捷方式的时间选择器函数
      // pickerOptions: {
      //   shortcuts: [{
      //     text: '最近一周',
      //     onClick(picker) {
      //       const end = new Date();
      //       const start = new Date();
      //       start.setTime(start.getTime() - 3600 * 1000 * 24 * 6);
      //       picker.$emit('pick', [start, end]);
      //     }
      //   }, {
      //     text: '最近一个月',
      //     onClick(picker) {
      //       const end = new Date();
      //       const start = new Date();
      //       start.setTime(start.getTime() - 3600 * 1000 * 24 * 29);
      //       picker.$emit('pick', [start, end]);
      //     }
      //   }, {
      //     text: '最近三个月',
      //     onClick(picker) {
      //       const end = new Date();
      //       const start = new Date();
      //       start.setTime(start.getTime() - 3600 * 1000 * 24 * 89);
      //       picker.$emit('pick', [start, end]);
      //     }
      //   }]
      // },
      pickerOptions:{},
      // 当前四个柱状图的数据
      echartData:{
        useNumAll:{
          xAxis:[],
          data:[]
        },
        zhenshiNum:{
          xAxis:[],
          data:[]
        },
        recordTimes:{
          xAxis:[],
          data:[]
        },
        recordWords:{
          xAxis:[],
          data:[]
        },
      }
    }
  },
  computed:{
    showTable: function(){
      let i = 1;
      this.tableData.forEach(item =>{
        item.serialNumber = i;
        i++;
      })
      return this.tableData
    },
    reversedHeight(){
      let rowNumber = 0 ;
      if(this.total === 0){
        rowNumber = 1;
      }else if(this.total < this.size){
        rowNumber = this.total
      }else{
        rowNumber = this.size
      }
      return 40*(rowNumber + 1)+2 >= this.tableHeight ? this.tableHeight : 40*(rowNumber + 1)+2;
    },

  },
  mounted(){
    console.log('数据大小xdata',xdata.length);
    console.log('cpu使用度',this.cpu)

    // console.log(this.departmentlList);
    // this.drawLine();
    // this.drawBar('useNumAll');
    // this.drawBar('zhenshiNum');
    // this.drawBar('recordTimes');
    // this.drawBar('recordWords');
    // getHospitalList()
    // getDepartmentList('12346be4b16e4716aa682e4a4350f488')
    // 监听浏览器变化,重新渲染echarts
    let _this=this
    window.onresize=function () {
      console.log('当前的窗口滨化了',this);
      _this.drawBar('useNumAll');
      _this.drawBar('zhenshiNum');
      _this.drawBar('recordTimes');
      _this.drawBar('recordWords');
    };
  },
  created(){
    // 初始化函数
    this.initialization();
  },
  methods:{

    judgeTime(timeValue){
      switch(timeValue){
        case '今天':
          this.formInline.dataValue = '';
          this.startTime = '';
          this.endTime = '';
          this.dateType = 1;
          console.log('今天')
          break;
        case '昨天':
          this.formInline.dataValue = '';
          this.startTime = '';
          this.endTime = '';
          this.dateType = 2;
          console.log('昨天')
          break;
        case '近三天':
          this.formInline.dataValue = '';
          this.startTime = '';
          this.endTime = '';
          this.dateType = 3;
          console.log('近三天')
          break
        case '近一周':
          this.formInline.dataValue = '';
          this.startTime = '';
          this.endTime = '';
          this.dateType = 4;
          console.log('近一周')
          break;
        case '近一个月':
          this.formInline.dataValue = '';
          this.startTime = '';
          this.endTime = '';
          this.dateType = 5;
          console.log('近一个月')
          break;
      }
    },
    tabChange(timeValue){
      this.active = timeValue
      this.judgeTime(timeValue)
      this.getTable()
      // this.drawLine();
    },
    // table表格数据
    getTable(){
      getRecordTable(this.startTime, this.endTime, this.dateType, this.current, this.size,this.serviceType,this.filterObj.hospitalName,this.filterObj.departmentName.join(',')).then(data => {
        if(data.code === 200 && data.errorFlag === 0){
          // console.log(JSON.stringify(data));
          this.tableData = data.data.records;
          this.total = data.data.total
          this.current = data.data.current;
        }else{
          // this.$message(data.message);
        }
      })
    },
    initialization(){
      // 上方获取数据列表接口
      getRecordList(this.serviceType).then(data => {
        if(data.code === 200 && data.errorFlag === 0 ){
          this.userRecordList = data.data;
        }else{
          this.$message(data.message);
        }
      }),
      this.getTable()
      this.getEchartData()
      // getChartData(this.startTime,this.endTime,this.dateType,this.type,this.serviceType).then(data =>{
      //   if(data.code === 200 && data.errorFlag === 0 ){
      //     let data_all = data.data;
      //     if(data_all.hospitalBarChart != null && data_all.hospitalBarChart != undefined){
      //       this.has_hospital = true
      //       this.hospitalBarChart.xAxis = data_all.hospitalBarChart.xAxis;
      //       this.hospitalBarChart.data = data_all.hospitalBarChart.data;
      //     }else{
      //       this.has_hospital = false
      //       this.hospitalBarChart.xAxis = [];
      //       this.hospitalBarChart.data = [];
      //     }
      //   }
      // })

    },

    // 获取统计图,并优化数据

    getEchartData(){
      let params={
        hospital:this.filterObj.hospitalName,
        deptName:this.filterObj.departmentName.join(','),
        dateType:this.timeTypeMap[this.timeType],
      }
      // 先情况数据,再push新数据
      this.echartData.useNumAll.xAxis=[]
      this.echartData.useNumAll.data=[]
      this.echartData.zhenshiNum.data=[]
      this.echartData.recordTimes.data=[]
      this.echartData.recordWords.data=[]

      // 设置加载状态

      // this.loading('useNumAll');
      // this.loading('zhenshiNum');
      // this.loading('recordTimes');
      // this.loading('recordWords');
      getChartData(params).then(res=>{
        console.log('获取的数据',res);

        // 确定时间轴的单位
        let timeIndex=res.data.findIndex(item=>{
          return item.recordSeconds>3600
        })

        // 确定识别字数单位

        let wordCountIndex=res.data.findIndex(item=>{
          return item.wordCount>10000
        })
        console.log('事件单位有大于3600的吗',timeIndex);

        if(timeIndex>-1){
          res.data.forEach(item=>{
            this.chatDetail.recordTimes.unit='小时'
            this.echartData.useNumAll.xAxis.push(item.date)
            this.echartData.useNumAll.data.push(item.callNum)
            this.echartData.zhenshiNum.data.push(item.deptNums)
            this.echartData.recordTimes.data.push((item.recordSeconds/3600).toFixed(4))
          })
        }else{
          res.data.forEach(item=>{
            this.chatDetail.recordTimes.unit='秒'
            this.echartData.useNumAll.xAxis.push(item.date)
            this.echartData.useNumAll.data.push(item.callNum)
            this.echartData.zhenshiNum.data.push(item.deptNums)
            this.echartData.recordTimes.data.push(item.recordSeconds)
            this.echartData.recordWords.data.push(item.wordCount)
          })
        }

        // 格式化字数的
        if(wordCountIndex>-1){
          res.data.forEach(item=>{
            this.chatDetail.recordWords.unit='万'
            this.echartData.recordWords.data.push((item.wordCount/10000).toFixed(4))
          })

        }else{
          res.data.forEach(item=>{
            this.chatDetail.recordWords.unit=''
            this.echartData.recordWords.data.push(item.wordCount)
          })

        }


        // 判断x轴得数据,是否多于30个,少于30个,就不显示滚动条,多于30,就显示最后30条
        if(this.echartData.useNumAll.xAxis.length<=30){
          this.dataZoomType=[]
        }else{
          let end=this.echartData.useNumAll.xAxis.length-1
          let start=this.echartData.useNumAll.xAxis.length-30
          this.dataZoomType=[{type: 'inside',startValue:start,endValue: end},{type:'slider',startValue:start,endValue: end }]
        }

        this.drawBar('useNumAll');
        this.drawBar('zhenshiNum');
        this.drawBar('recordTimes');
        this.drawBar('recordWords');

      })
    },

    loading(type){
      let dom=document.getElementById(type)
      let barBox=this.$echarts.init(dom)
      barBox.showLoading({
        text: 'loading',
        color: '#c23531',
        textColor: '#000',
        maskColor: 'rgba(255, 255, 255, 0.2)',
        zlevel: 0,
      });

    },
    drawBar(type){
      // type分四种类型,useNumAll,zhenshiNum,recordTimes,recordWords
      let dom=document.getElementById(type)
      let barBox=this.$echarts.init(dom)
      barBox.hideLoading();

      console.log('重新渲染了吗');

      let  options={
        title: {

          text: this.chatDetail[type].yTitle,
          left:20,
          textStyle: {fontSize: 15 }

        },
        grid: {left: '18%'},
        tooltip: {
          trigger : 'axis',
          formatter: (p)=>{

            console.log('p---------',p);
            console.log('type',type,this.chatDetail[type].unit);
            if(type==='recordTimes'){
              if(this.chatDetail[type].unit==='秒'){
                return `${p[0].axisValue}<br>${p[0].value}s`
              }else{
                return `${p[0].axisValue}<br>${p[0].value}h`
              }

            }else{
              return `${p[0].axisValue}<br>${p[0].value}`
            }
          }
        },
        xAxis: [
          {
            type    : 'category',
            data    : this.echartData.useNumAll.xAxis,
            axisTick: {
              alignWithLabel: true
            },
            name:this.timeType,
            nameTextStyle:{
              fontSize: 15,
              color: '#333333',
              lineHeight:30,
              // fontWeight :'bold'
            },

          }
        ],
        yAxis: [
          {
            type: 'value',
            name:this.chatDetail[type].unit,
            nameTextStyle:{
              left:20,
              fontSize: 13,
              // color: '#333333',
              // lineHeight:30,
              // fontWeight :'bold'
            },
            // axisLabel: {
            //   formatter:'{value}'+chatDetail[type].unit
            // },
          }
        ],
        dataZoom:this.dataZoomType,
        series: [
          {
            // name     : '',
            type     : 'bar',
            barWidth : '60%',
            data     : this.echartData[type].data,
            itemStyle:{
              normal:{
                color: function(){
                  return '#339999'
                }
              }
            }
          }
        ]
      }

      barBox.setOption(options, true);





      let width= document.getElementById('echarts').offsetWidth/2;
      barBox.getDom().style.width = width+ 'px';
      barBox.resize();






    },


    cleanupColor(){
      this.dateType = null;
      this.active = '';
    },
    // 改变每页行数触发事件
    handleSizeChange(val){
      this.size =val;
      // table表格数据
      this.getTable();
    },


    // 点击查询
    queryData(){
      // table表格数据
      this.current = 1;
      let isquery = false;
      if(JSON.stringify(this.formInline.dataValue) === '[]' || this.formInline.dataValue === '' || this.formInline.dataValue === null){
        this.startTime = '';
        this.endTime = '';
      }else{
        this.startTime = this.formInline.dataValue[0];
        this.endTime = this.formInline.dataValue[1];
        isquery = true;
      }
      if(this.dateType !== null){
        isquery = true;
      }
      if(isquery){
        this.getTable()
        // this.drawLine();
      }else{
        this.$message('请选择时间')
      }
    },
    // 导出
    exportStatistcs(){



      if(JSON.stringify(this.formInline.dataValue) === '[]' || this.formInline.dataValue === '' || this.formInline.dataValue === null){
        this.startTime = '';
        this.endTime = '';
      }else{
        this.startTime = this.formInline.dataValue[0];
        this.endTime = this.formInline.dataValue[1];

      }

      // console.log('formInline.dataValue',this.formInline.dataValue,this.startTime,this.endTime);
      // debugger;
      let data_type= this.dateType;
      let start_time = this.startTime;
      let end_time = this.endTime;
      let service_type = this.serviceType;
      let hospital=this.filterObj.hospitalName
      let department=this.filterObj.departmentName.join(',')
      let str = '';
      if(data_type != null && data_type != ''){
        str+='&dateType='+data_type;
      }
      if(end_time !=null && end_time !=''){
        str+='&endTime=' +end_time
      }
      if(start_time !=null && start_time !=''){
        str+='&startTime=' +start_time
      }
      str+= `&hospital=${hospital}&department=${department}`
      let token=sessionStorage.getItem('accessToken')
      let export_url =`${this.axios.defaults.baseURL}/usage-statistics/list-speech-recognition-export?serviceType=${service_type}&token=${token}${str}`;

      console.log('导出地址  ' + export_url,'this.startTime',this.startTime)
      window.open(export_url,'_blank')
    },

    // 当前页数发生改变时触发事件
    pagingData(current){
      this.current = current;
      this.getTable()
    },
    // 下拉框选项改变时触发事件 刷新页面数据
    refreshAll(){
      if(this.serviceType==4){
        // console.log(this.serviceType);
        this.$router.push('/main/usageStatisticsOcr')
      }else{

        let params={serviceType:this.serviceType,hospital:this.filterObj.hospitalName,deptName:this.filterObj.departmentName.join(',')}
        // 获取顶部统计
        getRecordList(params).then(data => {
          if(data.code === 200 && data.errorFlag === 0 ){
            this.userRecordList = data.data;
          }else{
            this.$message(data.message);
          }
        }),
        // 获取表格数据
        this.getTable();
        // this.drawLine();
        //  刷新柱状图
        this.getEchartData()
      }

    },

    // 年月日切换的时候
    radioTimeTypeChange(){
      this.getEchartData()
      // this.drawBar('useNumAll');
      // this.drawBar('zhenshiNum');
      // this.drawBar('recordTimes');
      // this.drawBar('recordWords');
      console.log('this.dataZoomType',this.dataZoomType);
    }

  },

}
</script>
<style lang="scss"  >
@import '@/assets/scss/statisticsStyle/usageStatistics.scss';
.usageAll .usageTwo{
  height: fit-content;
  min-height: auto;
}
.usageAll .usageSix .sixHead .headDiv{
  width: fit-content;
  height: auto;
}

#echarts{
  width: 100%;
  display: flex;
  flex-wrap: wrap;
  // height: fit-content;
}
#useNumAll,#zhenshiNum,#recordTimes,#recordWords{
  width: 50%;
  height:240px;
}

span.count-node {
    color: #909399;
    margin-left: 5px;
    font-size: 12px;
}


</style>

posted @ 2022-11-21 15:20  风意不止  阅读(130)  评论(0编辑  收藏  举报