(12)vue引用echarts

一、引用步骤:

1、先引入echarts库:

如果用的页面比较多,可以在main.js中全局引入echarts库;如果用的页面不多,可以单独引入。这里采用全局引入:

import Vue from 'vue'

import 'normalize.css/normalize.css'// A modern alternative to CSS resets

import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n

import '@/styles/index.scss' // global css
import App from './App'
import router from './router'
import store from './store'
import '@/icons' // icon
import '@/permission' // permission control
import VueJsonp from 'vue-jsonp'
import echarts from 'echarts'
Vue.use(VueJsonp)

Vue.use(ElementUI, { locale })

Vue.config.productionTip = false
Vue.prototype.$echarts = echarts
new Vue({
  el: '#app',
  router,
  store,
  render: h => h(App)
})

2、具体图表引用:参数参考echarts官网https://echarts.apache.org/en/index.html

这里写了几个常用的统计图:

代码:

<template>
  <div class="container">
    <el-row gutter="5">
      <!--柱状图-->
      <el-col span="6">
        <el-card class="card">
          <div style="height:200px" ref="bar"></div>
        </el-card>
      </el-col>
      <!--折线图-->
      <el-col span="8">
        <el-card>
          <div style="height:200px;margin-left:0px" ref="line"></div>
        </el-card>
      </el-col>
      <!--饼图-->
      <el-col span="10">
        <el-card>
          <div style="height:200px;margin-left:0px" ref="pie"></div>
        </el-card>
      </el-col>
    </el-row>
  </div>
</template>
<script>
export default {
  data() {
    return {
      //柱状图
      barList: {
        title: { text: "柱状图" },
        tooltip: {},
        xAxis: {
          data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
        },
        yAxis: {},
        series: [
          {
            name: "销量",
            type: "bar",
            data: [5, 20, 36, 10, 10, 20]
          }
        ]
      },
      //折线图
      lineList: {
        title: { text: "折线图" },
        xAxis: {
          type: "category",
          data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
        },
        yAxis: {
          type: "value"
        },
        series: [
          {
            data: [820, 932, 901, 934, 1290, 1330, 1320],
            type: "line"
          }
        ]
      },
      //饼图
      pieList: {
        title: {
          text: "饼图",
          subtext: "虚构数据",
          left: "center"
        },
        legend: {
          // orient: 'vertical',
          // top: 'middle',
          bottom: 10,
          data: ["西凉", "益州", "兖州", "荆州", "幽州"]
        },
        series: [
          {
            type: "pie",
            radius: "65%",
            center: ["50%", "50%"],
            selectedMode: "single",
            data: [
              {
                value: 1548,
                name: "幽州",
                label: {
                  formatter: [
                    "{title|{b}}{abg|}",
                    "  {weatherHead|天气}{valueHead|天数}{rateHead|占比}",
                    "{hr|}",
                    "  {Sunny|}{value|202}{rate|55.3%}",
                    "  {Cloudy|}{value|142}{rate|38.9%}",
                    "  {Showers|}{value|21}{rate|5.8%}"
                  ].join("\n"),
                  backgroundColor: "#eee",
                  borderColor: "#777",
                  borderWidth: 1,
                  borderRadius: 4,
                  rich: {
                    title: {
                      color: "#eee",
                      align: "center"
                    },
                    abg: {
                      backgroundColor: "#333",
                      width: "100%",
                      align: "right",
                      height: 25,
                      borderRadius: [4, 4, 0, 0]
                    },
                    Sunny: {
                      height: 30,
                      align: "left",
                      backgroundColor: {
                        //image: weatherIcons.Sunny
                      }
                    },
                    Cloudy: {
                      height: 30,
                      align: "left",
                      backgroundColor: {
                        //image: weatherIcons.Cloudy
                      }
                    },
                    Showers: {
                      height: 30,
                      align: "left",
                      backgroundColor: {
                        //image: weatherIcons.Showers
                      }
                    },
                    weatherHead: {
                      color: "#333",
                      height: 24,
                      align: "left"
                    },
                    hr: {
                      borderColor: "#777",
                      width: "100%",
                      borderWidth: 0.5,
                      height: 0
                    },
                    value: {
                      width: 20,
                      padding: [0, 20, 0, 30],
                      align: "left"
                    },
                    valueHead: {
                      color: "#333",
                      width: 20,
                      padding: [0, 20, 0, 30],
                      align: "center"
                    },
                    rate: {
                      width: 40,
                      align: "right",
                      padding: [0, 10, 0, 0]
                    },
                    rateHead: {
                      color: "#333",
                      width: 40,
                      align: "center",
                      padding: [0, 10, 0, 0]
                    }
                  }
                }
              },
              { value: 535, name: "荆州" },
              { value: 510, name: "兖州" },
              { value: 634, name: "益州" },
              { value: 735, name: "西凉" }
            ],
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: "rgba(0, 0, 0, 0.5)"
              }
            }
          }
        ]
      }
    };
  },
  mounted() {
    this.initCharts();
  },
  methods: {
    initCharts() {
      //柱状图
      let bar = this.$echarts.init(this.$refs.bar);
      bar.setOption(this.barList);
      //折线图
      let line = this.$echarts.init(this.$refs.line);
      line.setOption(this.lineList);
      //饼图
      let pie = this.$echarts.init(this.$refs.pie);
      pie.setOption(this.pieList);
    }
  }
};
</script>
<style scoped>
.container {
  height: 100%;
  width: 100%;
  margin: 0 0;
}
.card {
  margin-left: 0px;
}
</style>

二、动态加载echarts图表数据常见问题:

1、注意如果是从后台获取数据渲染,需要写高度和宽度,否则图表可能不展示

<!-- @format -->

<template>
  <div class="container">
   <el-col>
                  <div ref="pie" class="pie-div" ></div>
                </el-col>
  </div>
</template>

<script>

export default {
  name: 'schoolProductOverviewInfo',
  props: {
   
    schoolProjectsList: {
      required: true,
      type: Array
    }
  },
  data() {
    return {
      pieChart: '',
      //饼图
      pieData: {
        graphic: [
          {
            //环形图中间添加文字
            type: 'text', //通过不同top值可以设置上下显示
            left: 'center',
            top: '45%',
            style: {
              text: '',
              textAlign: 'center',
              fill: 'black', //文字的颜色
              width: 30,
              height: 30,
              fontSize: 30,
              fontFamily: 'Microsoft YaHei'
            }
          }
        ],
        series: [
          {
            name: '项目饼图',
            type: 'pie',
            radius: ['55%', '100%'],
            avoidLabelOverlap: false,
            label: {
              normal: {
                position: 'inside',
                show: true, //控制显隐
                textStyle: {
                  color: '#F2F2F2',
                  fontSize: 10
                }
              }
            },
            emphasis: {
              label: {
                show: true,
                fontSize: '20',
                fontWeight: 'bold'
              }
            },
            labelLine: {
              show: false
            },
            color: [],
            data: []
          }
        ]
      }
    };
  },
  created() {
    this.initProjectPieData();
  },
  mounted() {
    setTimeout(() => {
      this.initCharts();
    }, 500);
  },

  methods: {
 initCharts() {
      let pie = this.$echarts.init(this.$refs.pie);
      this.pieChart = pie;
      pie.setOption(this.pieData, true);
    },
    //计算数据
    initProjectPieData() {
      let pieDataList = [];
      let colorList = [];
      let color = '';
      let pieData = {};
      //0项目1,1项目2,2项目3,3项目4,4项目5
      for (var i = 0; i < 5; i++) {
        var projects = this.schoolProjectsList.filter(item => {
          return item.projectStatus === i + '';
        });
        let name = '';
        if (i === 0) {
          name = '项目1';
          color = '#C6D9F1';
        } else if (i === 1) {
          name = '项目2';
          color = '#558ED5';
        } else if (i === 2) {
          name = '项目3';
          color = '#F79646';
        } else if (i === 3) {
          name = '项目4';
          color = '#D3D3D3';
        } else if (i === 4) {
          name = '项目5';
          color = '#00bfbf';
        }
        if (projects.length > 0) {
          pieData = { value: projects.length, name: name + ' ' + projects.length };
          pieDataList.push(pieData);
          colorList.push(color);
        }
      }
      this.pieData.series[0].data = pieDataList;
      this.pieData.color = colorList;
      if (this.schoolProjectsList.length > 0) {
        this.pieData.graphic[0].style.text = this.schoolProjectsList.length;
      }
    }
  }
};
</script>

<style scoped lang="less">
.pie-div {
            height: 200px;
            width: 200px;
            margin: 0px;
          }
</style>

2、数据异步获取图表不渲染:动态加载,由于数据是从后台异步获取的,如果响应比较慢而echarts先初始化了可能会导致页面为空不渲染新数据,解决方法:

(1)方法一:在created钩子函数中获取数据,在mounted中延迟初始化echarts:如我这里延迟了500ms,差不多等数据已经响应了再初始化echarts

 mounted() {
    setTimeout(() => {
      this.initCharts();
    }, 500);
  },

(2)方法二:加入watch监听,监听option数据,注意一开始需要给option的data赋值(为[]),否则监听option不会监听data属性:

<!-- @format -->

<template>
    <div class="container">
        <el-row :gutter="20">
		  <!--类型饼图-->
          <el-col :span="4" :offset="1">
            <div ref="userTypePie" class="pie-div" ></div>
          </el-col>
		  <!--等级折线图饼图-->
          <el-col :span="8" :offset="1">
            <div ref="userLevel" class="level-div" ></div>
          </el-col>
		  <!--来源饼图-->
          <el-col :span="4" :offset="1">
            <div ref="userSourcePie" class="pie-div" ></div>
          </el-col>
        </el-row >
    </div>
</template>
<script>
export default {
  data() {
    return {
      userTypePie: '',
      userLevel: '',
      userSourcePie: '',
      userTypePieData: {
        title: {
          text: '用户类型',
          left: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{b}, {c}, {d}%'
        },
        series: [
          {
            name: '',
            type: 'pie',
            radius: '65%',
            center: ['50%', '50%'],
            selectedMode: 'single',
            label: {
              normal: {
                position: 'inside',
                show: true,
                textStyle: {
                  color: '#F2F2F2',
                  fontSize: 10
                }
              }
            },
            data: [
              {
                value: 1548,
                name: '幽州'
              },
              { value: 535, name: '荆州' },
              { value: 510, name: '兖州' },
              { value: 634, name: '益州' },
              { value: 735, name: '西凉' }
            ],
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      },
      userLevelData: {
        title: {
          text: '用户定级',
          left: 'center'
        },
        xAxis: {
          type: 'category',
          data: [ 'A', 'B', 'C', 'D']
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            data: [],
            type: 'bar',
            showBackground: true,
            backgroundStyle: {
              color: 'rgba(220, 220, 220, 0.8)'
            }
          }
        ]
      },
      userSourcePieData: {
        title: {
          text: '用户来源',
          left: 'center'
        },
        tooltip: {
          trigger: 'item',
          formatter: '{a} <br/>{b} : {c} ({d}%)'
        },
        series: [
          {
            name: '',
            type: 'pie',
            radius: '65%',
            center: ['50%', '50%'],
            selectedMode: 'single',
            label: {
              normal: {
                position: 'inside',
                show: true,
                textStyle: {
                  color: '#F2F2F2',
                  fontSize: 10
                }
              }
            },
            data: [
              {
                value: 1548,
                name: '幽州'
              },
              { value: 535, name: '荆州' },
              { value: 510, name: '兖州' },
              { value: 634, name: '益州' },
              { value: 735, name: '西凉' }
            ],
            emphasis: {
              itemStyle: {
                shadowBlur: 10,
                shadowOffsetX: 0,
                shadowColor: 'rgba(0, 0, 0, 0.5)'
              }
            }
          }
        ]
      }
    };
  },
  created() {
    this.getBaseUserInfo();
  },
  mounted() {
    this.initCharts();
  },

  methods: {
    getBaseUserInfo() {
      this.$api['user/getUserInfo']({}).then(data => {
        let userLevelMap = data.userLevelMap;
        let userLevelData = [];
        userLevelData.push(userLevelMap['A'].length);
        userLevelData.push(userLevelMap['B'].length);
        userLevelData.push(userLevelMap['C'].length);
        userLevelData.push(userLevelMap['D'].length);
        this.userLevelData.series[0].data = userLevelData;
      });
    },
   
    initCharts() {
      //类型饼图
      this.userTypePie = this.$echarts.init(this.$refs.userTypePie);
      this.userTypePie.setOption(this.userTypePieData, true);
      //定级折线图
      this.userLevel = this.$echarts.init(this.$refs.userLevel);
      this.userLevel.setOption(this.userLevelData, true);
      //来源饼图
      this.userSourcePie = this.$echarts.init(this.$refs.userSourcePie);
      this.userSourcePie.setOption(this.userSourcePieData, true);
    }
  },
  watch: {
    userLevelData: {
      handler(newVal, oldVal) {
        if (this.userLevel) {
          if (newVal) {
            this.userLevel.setOption(newVal);
          } else {
            this.userLevel.setOption(oldVal);
          }
        } else {
		  //如果写了immediate: true,下面的代码需要去掉,因为vue初始化生命周期获取不到DOM
          // this.userLevel = this.$echarts.init(this.$refs.userLevel);
          // this.userLevel.setOption(this.userLevelData, true);
        }
      },
      immediate: true,
      deep: true
    }
  }
};
</script>

<style lang="less" scoped>
.container {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  .level-div {
      height: 250px;
      width: 300px;
      margin: 0px;
    }
   .pie-div {
      height: 200px;
      width: 200px;
      margin: 0px;
    }
}
</style>

三、echarts图表宽度自适应问题:

1、上面说了,如果是从后台获取数据渲染,需要写高度和宽度,否则图表可能不展示。但是宽度写死了,浏览器窗口大小改变会使echarts图表显的很挤或者很空,解决方法:css设置高度,宽度写100%,浏览器窗口改变时,在windows.onresize中重置图表大小达到自适应。



<template>
    <div class="container">
        <el-row :gutter="20">
		  <!--类型饼图-->
          <el-col :span="4" :offset="1">
            <div ref="userTypePie" class="pie-div" ></div>
          </el-col>
		  <!--等级折线图饼图-->
          <el-col :span="8" :offset="1">
            <div ref="userLevel" class="level-div" ></div>
          </el-col>
		  <!--来源饼图-->
          <el-col :span="4" :offset="1">
            <div ref="userSourcePie" class="pie-div" ></div>
          </el-col>
        </el-row >
    </div>
</template>

<script>
  ......
  mounted() {
    //类型饼图
      this.userTypePie = this.$echarts.init(this.$refs.userTypePie);
      this.userTypePie.setOption(this.userTypePieData, true);
      //定级折线图
      this.userLevel = this.$echarts.init(this.$refs.userLevel);
      this.userLevel.setOption(this.userLevelData, true);
      //来源饼图
      this.userSourcePie = this.$echarts.init(this.$refs.userSourcePie);
      this.userSourcePie.setOption(this.userSourcePieData, true);
      //宽度自适应
       window.onresize = () => {
         this.userTypePie.resize();
         this.userLevel .resize();
         this.userSourcePie .resize();
      };

  },
</script>


<style lang="less" scoped>
.container {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  .pie-div {
        height: 250px;
        width: 100%;
        margin: 0px;
      }
      .level-div {
        height: 250px;
        width: 100%;
        margin: 0px;
      }
}
</style>

2、一个页面有多个图表,resize()方法只生效一个,解决方法:在使用window.onresize监听窗口变化时,要使用DOM二级绑定方式:addEventListener方式。将window.onresize改为window.addEventListener,如:

window.addEventListener("resize",()=>{
     brokenLine.resize();
 });

3、图表宽度设置为100%,实际渲染为100px问题,解决方法:

<div class="container" id="container" ref="container">
    <div ref="gaugeChart" class="gauge-div" id="gaugeChart"></div>
  </div>



 

mounted() {
    this.initCharts();
  },
 methods: {
    resizeGaugeWidth() {
      //宽度
      // let outWidth = document.getElementById('container').clientWidth;
      let outWidth = this.$refs.container.clientWidth;
      console.info('宽度:' + outWidth);
      this.$refs.gaugeChart.style.width = outWidth + 'px';
    },
    initCharts() {
      this.resizeGaugeWidth();
      this.gaugeChart = this.$echarts.init(this.$refs.gaugeChart);
      this.gaugeChart.setOption(this.gaugeOption, true);
      //宽度自适应
      window.addEventListener('resize', () => {
        this.resizeGaugeWidth();
        this.gaugeChart.resize();
      });
    }
  }




.container {
  .gauge-div {
    height: 150px;
    width: 100%;
    margin: 0px;
    display: inline;
  }
}

强制赋值宽度:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

w_t_y_y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值