一.tab切换的时候,echarts显示不完整的问题

一.tab切换的时候,echarts显示不完整的问题

通过切换头部tab,控制主体内容的显示与隐藏。如下图所示,图标除了第一个tab分页,其他分页的图表没有占满一行,蜷缩在页面左边。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-frgKM3Ui-1638624897975)(D:\home\笔记\工作相关\图片\tab切换echarts显示不全.png)]

Echarts展示一张图表时,承载其的html容器一定要设置好宽度,所以想着是不是页面结构问题,Echarts图表容器的宽度设置出错。检查发现,肯定是设置了宽高的。

缘由追查

查看图表容器,发现容器元素宽度被设置为100px了;说明是Echart源码进行了某些处理。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbAmkPt1-1638624897976)(D:\home\笔记\工作相关\图片\图标样式.webp)]

echarts3源码中获取容器的宽高的代码

_getSize: function (whIdx) {
    var opts = this._opts;
    var wh = ['width', 'height'][whIdx];
    var cwh = ['clientWidth', 'clientHeight'][whIdx];
    var plt = ['paddingLeft', 'paddingTop'][whIdx];
    var prb = ['paddingRight', 'paddingBottom'][whIdx];

    if (opts[wh] != null && opts[wh] !== 'auto') {
      return parseFloat(opts[wh]);
    }

    var root = this.root; // IE8 does not support getComputedStyle, but it use VML.

    var stl = document.defaultView.getComputedStyle(root);
    return (root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh])) - (parseInt10(stl[plt]) || 0) - (parseInt10(stl[prb]) || 0) | 0;
  },

这才发现问题所在,获取图表宽度时,由于图表所在的分页display:none,所以root.clientWidth获取失败;

这样也就解释为什么我们的图表宽度都是100px了。

解决方法1:
     <el-tabs v-model="activeName" @tab-click="handleClick">
          <el-tab-pane label="新增用户" name="first" lazy>
            <new-users></new-users>
          </el-tab-pane>
          <el-tab-pane label="累计用户" name="second" lazy>
            <total-users></total-users>
          </el-tab-pane>
          <el-tab-pane label="用户占比" name="third" lazy>
            <percentage-users></percentage-users>
          </el-tab-pane>
        </el-tabs>

代码中加入elementUI标签tabs中的lazy属性就可以实现这个功能。

但是经测试发现有时候,还是会出现突然闪现左移的问题。

解决方案2:
  <el-tabs v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="新增用户" name="first">
           <new-users v-if="'first' === activeName"></new-users>
       </el-tab-pane>
       <el-tab-pane label="累计用户" name="second">
           <total-users v-if="'second' === activeName"></total-users>
       </el-tab-pane>
       <el-tab-pane label="用户占比" name="third">
           <percentage-users v-if="'third' === activeName"></percentage-users>
        </el-tab-pane>  
   </el-tabs>
 data() {
    return {
        //默认展示的页面
      activeName: "first",
    };
  },

方案二:完全没有问题,但是每一次切换的时候,echarts图就要重新进行渲染。

到这里这个问题已经完美的解决啦啦啦啦啦。。。。写一个问题。

二.echarts的引入和配置问题总结
方法一:

1.echarts在vue项目中一般是全局引用的。

npm install echarts -S

2.在main.js中引入

// 引入echarts
import echarts from 'echarts'
Vue.prototype.$echarts = echarts

3.在项目中使用时

<div id="myChart" :style="{width: '300px', height: '300px'}"></div>

export default {
  name: 'hello',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  },
  mounted(){
    this.drawLine();
  },
  methods: {
    drawLine(){
        // 基于准备好的dom,初始化echarts实例
        let myChart = this.$echarts.init(document.getElementById('myChart'))
        // 绘制图表
        myChart.setOption({
            title: { text: '在Vue中使用echarts' },
            tooltip: {},
            xAxis: {
                data: ["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]
            },
            yAxis: {},
            series: [{
                name: '销量',
                type: 'bar',
                data: [5, 20, 36, 10, 10, 20]
            }]
        });
    }
  }
}
方法二:

1.echarts在vue项目中一般是全局引用的。

npm install echarts -S

2.在main.js中引入

import myCharts from './utils/myCharts.js'
Vue.use(myCharts)

3.utils/myCharts.js中定义方法

//引入echarts
import echarts from 'echarts'
//方法挂载
const install = function (Vue) {
  Object.defineProperties(Vue.prototype, {
    $chart: {
      get() {
        return {
          // 折线图
          userLine: function (id, lineObj) {
            this.chart = echarts.init(document.getElementById(id));
            this.chart.clear();
            this.chart.xAxis = [];
            this.chart.yAxis = [];

            const userData = {
                //设置折线的颜色
              // color: ["#60d1de", "#abeca3", "#f78181", "#8ce7ca","#fee78b","#a2cdfc"],
              title: {
                // text: '折线图堆叠'
              },
              tooltip: {
                // trigger: 'axis',
                formatter:null
              },
              legend: {
                data: lineObj.legendData,
                selected: lineObj.selectedData
              },
              grid: {
                left: '3%',
                right: '4%',
                bottom: '3%',
                containLabel: true
              },
              // xAxis: {
              //   type: 'category',
              //   boundaryGap: false,
              //   data: lineObj.xData
              // },
              xAxis: {
                type: 'category',
                boundaryGap: false,
                data: lineObj.xData
            },
              yAxis: {
                type: 'value',
                minInterval: lineObj.yAxis.minInterval,
                axisLabel: {
                  formatter: null
                },
              },
              series: lineObj.seriesData
            };
              //当折线图是使用的坐标轴需要用不同的形式表现时
              //百分比的表示dataFormat进行判断是使用百分比还是正常
            userData.xAxis.data = lineObj.xData;
            userData.legend.data = lineObj.legendData;
            userData.series = lineObj.seriesData;
            var dataFormat = lineObj.dataFormats;
            if (dataFormat == 'normal') {
              userData.yAxis.axisLabel.formatter = null;
              userData.tooltip.formatter = null;
            } else if (dataFormat == 'percentage') {
              userData.yAxis.axisLabel.formatter = function (value, index) {
                return (value * 100) + '%';
              };
                //鼠标经过对应图标时,显示seriesName,marker(颜色),value(值)。
              userData.tooltip.formatter = function (params) {
              if(params.seriesName.indexOf("series") == -1) {
                return  params.seriesName + '
'
+params.marker+ params.name + ' '+ (params.value * 100).toFixed(2) + '%' } else{ return params.marker+ params.name + ' '+ (params.value * 100).toFixed(2) + '%' } }; } this.chart.setOption(userData, true); }, // 柱状图 userBar: function (id, barObj) { this.chart = echarts.init(document.getElementById(id)); this.chart.clear(); this.chart.xAxis = []; this.chart.yAxis = []; const actionUserData = { title: { text: barObj.title, textStyle: { fontSize: 16, fontStyle: "normal" }, left: 10, top: 0, }, tooltip: { trigger: 'axis', // axisPointer: { // 坐标轴指示器,坐标轴触发有效 // type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' // } formatter: function (barObj) { var res; var resList = []; //当tip需要使用不同格式表现时。 for (let i in barObj) { if (barObj[i].seriesName == "活跃用户" || barObj[i].seriesName == "非活跃用户") { resList.push('

'+ barObj[i].marker + barObj[i].seriesName +' ' +barObj[i].name+' ' + barObj[i].value+'

'
) } else if (barObj[i].seriesName == "活跃用户占比" || barObj[i].seriesName == "非活跃用户占比") { resList.push('

'+ barObj[i].marker + barObj[i].seriesName + ' ' +barObj[i].name+' '+ (barObj[i].value * 100).toFixed(2) + '%' + '

'
) } else { res = '

' + barObj[i].name + ':' + barObj[i].value + '

'
} } if (resList.length == 0) { return res } else { let sum = resList.reduce((accumulator, currentValue) => { return accumulator + currentValue }) return sum } }, }, legend: { data: barObj.legendData, selected: barObj.selectedData }, grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true }, xAxis: [{ type: 'category', data: barObj.xData, axisTick: { alignWithLabel: true } }], yAxis: [{ type: 'value' }], series: barObj.seriesData }; this.chart.setOption(actionUserData); }, // 饼图 userPie: function (id, pieObj) { this.chart = echarts.init(document.getElementById(id)); this.chart.clear(); this.chart.xAxis = []; this.chart.yAxis = []; const industryData = { color: ["#5470c6", "#9fe080", "#ffdc60", "#ff7070", "#7ed3f4", "#40b27d", "#a969c6", "#ff915a"], title: { // text: '占比图', }, tooltip: { trigger: 'item', formatter: '{b} : {d}% ({c})' }, legend: { top: 'bottom', orient: 'horizontal', }, series: [{ name: '暂无数据', type: 'pie', radius: [0, 200], center: ['50%', '50%'], data: pieObj.data }] } this.chart.setOption(industryData); }, } } } }) } export default { install }

4.按需引入的对应的图标,比如bar图

<div id="newUserLine"></div>

data(){
    return{
          lineObj: {
        legendData: [
          "新增注册用户",
          "新增试用用户",
          "新增正式用户",
          "新增使用用户",
        ],
        xData: [],
        yAxis: {
          minInterval: 1,
        },
        seriesData: [
          {
            name: "新增注册用户",
            type: "line",
            data: [],
          },
          {
            name: "新增试用用户",
            type: "line",
            data: [],
          },
          {
            name: "新增正式用户",
            type: "line",
            data: [],
          },
          {
            name: "新增使用用户",
            type: "line",
            data: [],
          },
        ],
        selectedData: {
          新增试用用户: false,
          新增正式用户: false,
          新增使用用户: false,
        },
      },
    }
},
    created(){
        this.getUserLine();
    },
  methods:{
        getUserLine(val) {
            //请求对应的数据
           getNewAccountSerial(val).then((res) => {
              this.lineObj.seriesData[0].data = res.data.newAccountSerial.data;
              this.lineObj.seriesData[1].data = res.data.newTrailAccountSerial.data;
              this.lineObj.seriesData[2].data = res.data.newFormalAccountSerial.data;
              this.lineObj.seriesData[3].data = res.data.newUseAccountSerial.data;
              this.lineObj.xData = res.data.newTrailAccountSerial.time;
               //实例化echarts对象,将dom元素挂载到页面中
             this.$chart.userLine("newUserLine", this.lineObj);
      });
    },
  }

这是最近数据统计中一些比较重要的问题记录。这次需求中,自己做的不够的地方,就是完成之后进行测试了,但是没有进行系统的测试,而且不够细心。主要就是占比需要用百分比显示的问题,没有注意过。

还有一些细节性的问题,希望下次能够注意一点,加油奥利给!!!!!
this.lineObj.seriesData[3].data = res.data.newUseAccountSerial.data;
this.lineObj.xData = res.data.newTrailAccountSerial.time;
//实例化echarts对象,将dom元素挂载到页面中
this.$chart.userLine(“newUserLine”, this.lineObj);
});
},
}


这是最近数据统计中一些比较重要的问题记录。这次需求中,自己做的不够的地方,就是完成之后进行测试了,但是没有进行系统的测试,而且不够细心。主要就是占比需要用百分比显示的问题,没有注意过。

还有一些细节性的问题,希望下次能够注意一点,加油奥利给!!!!!

你可能感兴趣的:(vue,echarts,前端,javascript,vue,vue.js)