更新一下之前写的echarts简单图表公共组件的封装,该组件可以实现自适应展示效果

废话不多说,上代码:

vue-echarts通用组件

<template>
  <div class="companyList-ctn" :style="{ 'width':'100%','height': '100%' }">
    <div :id="id" :style="{'width':'100%','height': '100%'}"></div>
  </div>
</template>
<script>
let _c = { id: 1 };
import * as echarts from 'echarts';
import echartMixins from "@/utils/resizeMixins";
//引入echart
import 'echarts-gl'
export default {
  mixins: [echartMixins],
  created() {
    _c.id++;
    this.id = "charts_" + _c.id;
  },
  props: {
    echartsData: {
      type: Object,
    },
  },
  data() {
    return {
      myPieChart:'',
      width:'100%',
      height:400+'px'
    };
  },
  computed: {
    heightFun(){
      return this.echartsData.height+'px'
    }
  },
  watch: {
    echartsData:{
         handler(newval, oldVal){
           this.initChart();
         },
         deep:true //true 深度监听
     }
  },
  mounted() {
    // 初始化echarts
    this.$nextTick(()=>{
      this.initChart();
    })
    window.addEventListener('resize',this.initChart,false);
  },
  //vue组件实例销毁之前移除监听事件,避免当我们切换路由时导致vue出现警告:
  //echarts.js?1be7:2160 Uncaught Error: Initialize failed: invalid dom.
  beforeDestroy () {
    window.removeEventListener('resize', this.initChart)
  },
  methods: {
    initChart() {
      var chartDom = document.getElementById(this.id);
      if (this.myPieChart != null && this.myPieChart != "" && this.myPieChart != undefined) {
        this.myPieChart.dispose();//销毁
      }
      this.myPieChart = echarts.init(chartDom);
      this.myPieChart.resize()
      var option=this.echartsData.option
      this.myPieChart.setOption(option);
    },
  },
};
</script>
<style lang="scss" scoped>
.companyList-ctn {
  width: 260px;
  border-radius: 4px;
  // background: white;
  .companyList-oneItem {
    display: flex;
    justify-content: space-between;
    align-items: center;
  }
}
</style>

下面的一个混入文件是用来实现,窗口改变echarts自适应的js文件:

// 混入代码 resize-mixins.js
import { debounce } from '@/utils/index';
const resizeChartMethod = '$__resizeChartMethod';

export default {
  data() {
    // 在组件内部将图表init的引用映射到chart属性上
    return {
      chart: null,
    };
  },
  created() {
    window.addEventListener('resize', this[resizeChartMethod], false);
  },
  beforeDestroy() {
    window.removeEventListener('reisze', this[resizeChartMethod]);
  },
  methods: {
    // 通过lodash的防抖函数来控制resize的频率
    [resizeChartMethod]: debounce(function() {
      if (this.chart) {
        this.chart.resize();
      }
    }, 100),
  },
};

接下来是debounce.js

export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result;

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp;

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last);
    } else {
      timeout = null;
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args);
        if (!timeout) context = args = null;
      }
    }
  };

下面直接上代码:父组件调用+展示效果

<template>
  <div class="user_protocal_box">
    <!-- 折线图 -->
    <DayLinkRatioCharts :echartsData="dayLinkRatio" />
  </div>
</template>

<script>
import DayLinkRatioCharts from "@/components/charts";
export default {
components: {
    DayLinkRatioCharts 
  },
  data () {
    return {
      dayLinkRatio:{//日环比
        option:{
          tooltip: {
            trigger: "axis",
          },
          legend: {
            //标记属性
            data: ['今日','昨日'],
            orient: "horizontal", //标记排列显示
            top:20, //标记位置
            right:23, //标记位置
            icon:'rect',
            itemWidth: 16,
            itemHeight:3,
            itemGap:16,
            formatter: [//用富文本组件实现图例与文字对齐的关键是富文本的格式转换
              '{a|{name}}'
            ].join('\n'),
            textStyle: {
              color:'rgba(159,216,253,0.6)',
              fontSize:13,
              height:20,//图例字体高度
              lineHeight:22, //图例字体行高
              rich:{//用富文本组件实现图例与文字对齐
                a:{
                  verticalAlign: 'middle'//图例与文字对齐方式
                }
              }
            },
          },
          grid:{
            //绘图区调整
            left:23,
            right:23,
            bottom:20,
            containLabel: true,
          },
          xAxis: {
            type: "category",
            boundaryGap: true,
            data: ["0点","1点","2点","3点","4点","5点","6点","7点","8点","9点","10点","11点","12点","13点","14点","15点","16点","17点","18点","19点","20点","21点","22点","23点"],//x轴数据
            axisLabel: {
              //坐标轴文字显示样式
              lineHeight: 15, //字体行高
              fontSize:13,
              fontNum: 15, //每行显示字数
              rotate: 0, //文字旋转角度,0不旋转
              color:'rgba(159,216,253,0.4)',
              interval: 2//刻度间隔个数
            },
            axisLine: {//坐标轴线样式
              lineStyle: {
                color: 'rgba(159,216,253,0.4)',
                type: 'solid'
              },
            },
            axisTick:{//x轴刻度设置
              alignWithLabel: true,//刻度线与点对齐
              length:4,//刻度线的长度
              interval: 2,//刻度间隔个数
              show:true // 不显示坐标轴刻度线
            },
          },
          yAxis:{ 
            name:'',
            type: "value",
            axisLabel:{
              color:'rgba(159,216,253,0.4)'
            },
            splitLine: {
              show: true,//是否显示网格线
              lineStyle: {
                color: "rgba(159,216,253,0.15)",
                textShadow: '0px 2px 4px 0px rgba(0,0,0,0.50)',
                type: "solid"
              }    
            },
            axisLine:{show:false},//隐藏y轴
          },
          series: [
            {
              name: "今日",
              data:  [13.3, 11.34, 15.44, 13.53, 12.98, 12.36, 13.14, 14.46, 12.36, 12.45, 13.19, 10.64, 11.95, 12.2, 15.94, 15.73, 17.95, 14.94, 12.34, 17.55, 15.5, 15.82, 12.99, 15.98],
              type: "line",
              color:'#46A0FA',
              showSymbol: false,//不显示圆点,hover时显示
              smooth:true,//折线变为曲线
              // yAxisIndex:1,
              areaStyle: {//曲线阴影
                opacity: 0.8,
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  {
                    offset: 0,
                    color: "rgba(70,160,250,0.4)", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "rgba(70,160,250,0)", // 100% 处的颜色
                  }
                ])
              },
            },
            {
              name: "昨日",
              data: [13.25, 12.96, 11.82, 14.66, 14.63, 12.75, 12.93, 15.29, 18.51, 17.03, 15.18, 15.81, 18.18, 19.14, 14.2, 7.71, 10, 15, 5.5, 6.5, 7.5, 8.5, 9.5, 10.5,]
              type: "line",
              color:'#3FD4CF',
              smooth:true,//折线变为曲线
              showSymbol: false,//不显示圆点,hover时显示
              // yAxisIndex:0,
              areaStyle: {//曲线阴影
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1,[
                  {
                    offset: 0,
                    color: "rgba(63,212,207,0.4)", // 0% 处的颜色
                  },
                  {
                    offset: 1,
                    color: "rgba(63,212,207,0)", // 100% 处的颜色
                  }]),
              },
            }
          ],
        },
      },
    }
  },
  mounted () {
    
  },
  methods: {
    
  }
}
</script>

<style lang="scss" scoped>

</style>

截图:

下面是一个仪表盘的效果:请看代码:

<template>
  <div class="user_protocal_box">
    <!-- 仪表盘 -->
    <HeightElectricCharts :echartsData="heightElectric" />
  </div>
</template>

<script>
import HeightElectricCharts from "@/components/charts";
export default {
components: {
    HeightElectricCharts 
  },
  data () {
    return {
      heightElectric:{//电力高压负荷监控仪表盘
        option:{
          series: [
            {//外圈的仪表盘
              type: 'gauge',
              startAngle: 180,
              endAngle: 0,
              min: 0,
              max: 6000,
              radius:'140%',
              center:['50%','85%'],
              splitNumber: 10,
              progress: {
                show: true,
                roundCap: false,
                width:30,
                itemStyle: {
                color:'rgba(255,255,255,0.25)',
                  shadowColor: 'rgba(255,255,255,0.5)',//rgba(0,255,255,0.8)
                  shadowBlur: 10,
                  shadowOffsetX: 2,
                  shadowOffsetY: 2,
                },
              },
              pointer: {//指针
                icon: 'path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z',
                length: '28%',
                width: 3,
                offsetCenter: [0, '-72%'],
                itemStyle: {
                color:'rgba(255,255,255,1)',
                  shadowColor: 'rgba(255,255,255,0.5)',//rgba(0,255,255,0.8)
                  shadowBlur: 10,
                  shadowOffsetX: 2,
                  shadowOffsetY: 2,
                },
              },
              axisLine: {//槽内颜色
                roundCap: false,
                lineStyle: {
                  width: 30,
                  color: [
                        [1,new echarts.graphic.LinearGradient(0, 0, 1, 0, [
                          {
                            offset: 0,
                            color: "#30C9C9"
                          },
                          {
                            offset: 0.15,
                            color: "#30C9C9"
                          },
                          {
                            offset: 0.2,
                            color: "#46A0FA"
                          },
                          {
                            offset: 0.4,
                            color: "#46A0FA"
                          },
                          {
                            offset: 0.55,
                            color: "#FCE26C"
                          },
                          {
                            offset: 0.75,
                            color: "#FCE26C"
                          },
                          {
                            offset: 1,
                            color: "#FB6C78"
                          }
                        ])
                      ]
                    ]
                }
              },
              axisTick: {//小刻度个数
                splitNumber: 10,//小刻度个数
                lineStyle: {
                  width:1,
                  color:'#5DD9FB'
                }
              },
              splitLine: {//大刻度线
                length: 10,
                lineStyle: {
                  width:1.5,
                  color:'#5DD9FB'
                }
              },
              axisLabel: {//刻度值
                show:true,
                distance: -55,
                color: '#9FD8FD',
                fontSize: 14,
                offsetCenter: [-10, '0%'],
                // formatter: function (value) {
                //   callback(value)
                // },
              },
              title: {
                show: true,
                offsetCenter: [0, '0%'],
                fontSize: 16,
                color:'rgba(159,216,253,0.4)'
              },
              detail: {
                width: '60%',
                lineHeight: 40,
                height: 40,
                borderRadius: 8,
                offsetCenter: [0, '-20%'],
                valueAnimation: true,
                formatter: function (value) {
                  return '{value|' + value.toFixed(0) + '}{unit|kw}';
                },
                rich: {
                  value: {
                    fontSize: 36,
                    fontWeight: 'bolder',
                    color: '#5DD9FB'
                  },
                  unit: {
                    fontSize: 35,
                    color: '#5DD9FB',
                    padding: [0, 0, 0, 0]
                  },
                  name: {
                    fontSize: 35,
                    color: '#5DD9FB',
                    padding: [0, 0, 0, 0]
                  },
                }
              },
              data: [
                {
                  value: 4900,
                  name: '当前负荷'
                }
              ]
            },
            {//内圈的仪表盘刻度
              type: 'gauge',
              startAngle: 180,
              endAngle: 0,
              radius:'140%',
              center:['50%','85%'],
              min: 0,
              max: 6000,
              progress: {
                show: false,
                width: 30
              },
              axisLine: {
                show: false,
                lineStyle: {
                  width: 30
                }
              },
              pointer:{
                show:false
              },
              axisTick: {
                show: false
              },
              splitLine: {
                show: false,
                length: 10,
                lineStyle: {
                  width: 2,
                  color: '#999'
                }
              },
              axisLabel: {
                show: true,
                distance:32,
                color: '#5DD9FB',
                fontSize: 12,
              },
              anchor: {
                show: false,
                showAbove: true,
                size: 10,
                itemStyle: {
                  borderWidth: 5
                }
              },
              title: {
                show: false
              },
              detail: {
                show: false,
                valueAnimation: true,
                fontSize: 80,
                offsetCenter: [0, '50%']
              },
              data: [
                {
                  value: 4900
                }
              ]
            }
          ]
        }
      }
    }
  },
  mounted () {
    //仪表盘刻度值显示--该方法要放在接口返回去计算并渲染,因为刻度值转换为文字显示的是一个范围
    this.heightElectric.option.series[0].axisLabel.formatter=function(value){
          let oneItem=this.heightElectric.option.series[0].max/10
          if (value == oneItem) {
              return '轻载';
            } else if (value == oneItem*3) {
              return '正常';
            } else if (value == oneItem*7) {
              return '重载';
            } else if (value == oneItem*9) {
              return '过载';
            }
            return '';
          }
  },
  methods: {
    
  }
}
</script>

<style lang="scss" scoped>

</style>

看图:

 请注意:

简单说明一下,仪表盘本身就是一组数据,也就是series这个数组里面只有一项,但是如果如上图所示,要显示两个刻度盘,所以我们就要用了两组数据,第一组把刻度值修改成文字,第二组显示刻度值,第二组数据通过位置偏移来调节,图中的指针我是用的官方给的svg矢量图,这个是必须要用矢量图

下面是3d柱状图:

请看图:

 补充一下:我没有显示底部切片,是因为如果数值为0时,底部切片和顶部切片会显示,效果不是很好,所以我选择了不显示底部切片,如果小伙伴有更好的解决办法,欢迎留言,共同进步o

<template>
  <div class="user_protocal_box">
    <!-- 3d柱状图 -->
    <BuildEletricCharts :echartsData="buildEletric" />
  </div>
</template>

<script>
import BuildEletricCharts from "@/components/charts";
let barWidth = 20;
var lastColor = {//3d柱状图柱子两个侧面的颜色
  type: "linear",
  x: 0,
  x2: 1,
  y: 0,
  y2: 0,
  colorStops: [
    {
      offset: 0,
      color: '#1FA6AA',
    },
    {
      offset: 0.45,
      color: '#1FA6AA',
    },
    {
      offset: 0.5,
      color: '#66DFD7',
    },
    {
      offset: 1,
      color: '#30C9C9',
    },
  ],
};
var curColor = {//3d柱状图柱子两个侧面的颜色
  type: "linear",
  x: 0,
  x2: 1,
  y: 0,
  y2: 0,
  colorStops: [
    {
      offset: 0,
      color: '#2B78CF',
    },
    {
      offset: 0.45,
      color: '#2B78CF',
    },
    {
      offset: 0.5,
      color: '#58AFFB',
    },
    {
      offset: 1,
      color: '#46A0FA',
    },
  ],
};
export default {
components: {
    BuildEletricCharts  
  },
  data () {
    return {
      buildEletric: {//建筑用电情况(kwh)
        option: {
          tooltip: {
            trigger: "axis",
            axisPointer: {
              type: "shadow", //鼠标悬停显示样式
              shadowStyle: {
                shadowColor: "rgba(0, 0, 0, 0.5)",
                shadowBlur:2,
              },
            },
            formatter: function(params) {
              var str = params[0].name + ":";
              params.filter(function(item) {
                if (item.componentSubType == "bar") {
                  if(item.seriesName=='昨天'){
                    str += "<div id='id_flex3'>"+
                      "<p id='yesterday_circle1'></p>"+
                      "<p id='id_flex'>"+item.seriesName+ "\u00a0\u00a0" +"<span id='fb'>"+item.value+"</span>"+"</p>"+
                    "</div>"
                  }else{
                    str += "<div id='id_flex4'><p id='yesterday_circle2'></p><p id='id_flex2'>" + item.seriesName + "\u00a0\u00a0" + "<span id='fb'>"+item.value+"</span>"+"</p></div>"
                  }
                }
              });
              return str;
            },
          },
          grid: {
            left:23,
            right:23,
            bottom:12,
            containLabel: true,
          },
          legend: {
            show: false,
            data: ["昨天", "今天"],
            top:20, //标记位置
            right:23, //标记位置
            icon:'rect',
            textStyle: {
              color: "rgba(159,216,253,0.4)",
              fontSize: "13",
            },
          },
          dataZoom:[{//展示不下时显示水平滚动条
              show: true,
              backgroundColor: "rgba(159,216,253,0.15)",
              borderRadius: 5,
              borderColor:"none",
              height: 8,
              startValue: 0, // 从头开始。
              endValue: 3, // 一次性展示n个。
              moveHandleIcon: "none",
              moveHandleSize: 10,
              zoomLock: true,
              brushSelect: false,
              showDataShadow: false,
              fillerColor: "#58AFFB",
              handleIcon: "path://M512,512m-448,0a448,448,0,1,0,896,0a448,448,0,1,0,-896,0Z",//滚动条圆角--官方推荐
              handleSize: "70%",
              handleColor:"#58AFFB",
              textStyle: {
                color: "transparent",
              },
              bottom: 2,
            }
          ],
          xAxis: {
            data: ['高一教学楼', '高二教学楼', '高三教学楼', '女生宿舍楼', '男生宿舍楼', '行政楼', '食堂', '音乐厅', '国际交流中心', '实验楼', '图书馆', '体育馆'],
            boundaryGap: true,
            //坐标轴
            axisLine: {
              show: true,
              lineStyle: {
                width: 1,
                color: "rgba(159,216,253,0.4)"
              },
              textStyle: {
                color: "#000",
                fontSize:20,
              },
            },
            type: "category",
            axisLabel: {
              //坐标轴文字显示样式
              lineHeight: 18, //字体行高
              fontNum: 15, //每行显示字数
              rotate: 0, //文字旋转角度,0不旋转
              textStyle: {
                color: "rgba(159,216,253,0.4)",
                fontWeight: 'normal',
                fontSize: "13",
              },
            },
            axisTick: {
              textStyle: {
                color: "#fff",
                fontSize: "16",
              },
              show: false,
            },
            splitLine: { show: false },
          },
          yAxis: {
            type: "value",
            //坐标轴
            axisLine: {
              show: false,
              lineStyle: {
                width: 1,
                color: "#214776",
              },
              textStyle: {
                color: "#fff",
                fontSize: "10",
              },
            },
            axisTick: {
              show: false,
            },
            //坐标值标注
            axisLabel: {
              show: true,
              textStyle: {
                color: "rgba(159,216,253,0.4)",
              },
            },
            //分格线
            splitLine: {
              lineStyle: {
                color: "#13365f",
              },
            },
          },
          series: [
            {
              z: 1,
              name: "昨天",
              type: "bar",
              barWidth: barWidth,
              barGap: "0%",
              data: [10.43, 23, 25.14, 27.32, 59.9, 35.82, 29.19, 19.32, 0, 2.22, 0.39, 4.1],
              itemStyle: {
                normal: {
                  color: lastColor,
                },
              },
            },
            {
              z: 2,
              name: "昨天",
              type: "pictorialBar",
              data: [10.43, 23, 25.14, 27.32, 59.9, 35.82, 29.19, 19.32, 0, 2.22, 0.39, 4.1],
              symbol: "diamond",
              symbolPosition: "start",
              symbolOffset: ["-75%", "0%"],//底部切片位置,[x,y]
              symbolSize: [0, 0],//底部切片尺寸,设置为0则不显示[宽,高]
              itemStyle: {
                normal: {
                  color: lastColor,
                },
              },
              tooltip: {
                show: false,
              },
            },
            {
              z: 3,
              name: "昨天",
              type: "pictorialBar",
              symbolPosition: "end",
              data: [10.43, 23, 25.14, 27.32, 59.9, 35.82, 29.19, 19.32, 0, 2.22, 0.39, 4.1],
              symbol: "diamond",
              symbolOffset: ["-75%", "-20%"],//底部切片位置,[x,y]
              symbolSize: [barWidth , 5],//底部切片尺寸,设置为0则不显示[宽,高]
              itemStyle: {
                normal: {
                  borderWidth: -5,
                  color: '#BEF4ED',
                },
              },
              tooltip: {
                show: false,
              },
            },
            {
              z: 1,
              name: "今天",
              type: "bar",
              barWidth: barWidth,
              barGap: "50%",
              data: [13.6, 35.43, 39.61, 35.58, 57.8, 56.58, 45.73, 39.77, 0, 2.89, 1.16, 5.93],
              itemStyle: {
                normal: {
                  color: curColor,
                },
              },
            },
            {
              z: 2,
              name: "今天",
              type: "pictorialBar",
              data: [13.6, 35.43, 39.61, 35.58, 57.8, 56.58, 45.73, 39.77, 0, 2.89, 1.16, 5.93],
              symbol: "diamond",
              symbolPosition: "start",
              symbolOffset: ["75%", "0%"],
              symbolSize: [0, 0],
              itemStyle: {
                normal: {
                  color: curColor,
                },
              },
              tooltip: {
                show: false,
              },
            },
            {
              z: 3,
              name: "今天",
              type: "pictorialBar",
              symbolPosition: "end",
              data: [13.6, 35.43, 39.61, 35.58, 57.8, 56.58, 45.73, 39.77, 0, 2.89, 1.16, 5.93],
              symbol: "diamond",
              symbolOffset: ["75%", "-20%"],
              symbolSize: [barWidth , 5],
              itemStyle: {
                normal: {
                  borderWidth: -5,
                  color: '#C4E8FE',
                },
              },
            },
          ],
        },
      },
    }
  },
  mounted () {
    
  },
  methods: {
    
  }
}
</script>

<style lang="scss" scoped>

</style>

说明:

为什么series里面每一类会有重复的数据,因为我们要实现的是3d柱状图,简单理解一下,就是:我们把3d柱状图一分为三份,第一份就是底部的切片,第二份就是中间的柱子,第三份就是顶部的切片,这样就是三份数据

今天的分享就到这里把,如果小伙伴有更好的解决办法,欢迎留言,共同进步o

Logo

前往低代码交流专区

更多推荐