Echarts各类图表开发遇到的一些问题集锦

本文总结了在使用Echarts开发过程中遇到的问题,包括点击事件处理、桑基图数据不显示、Vue中数据双向绑定失效、地图显示问题、图表自适应屏幕、K线图tooltip调整等,并给出了相应的解决方案,还提到了前端开发中的一些实用技巧和注意事项。

一、在做echarts点击事件的时候,不仅需要点击标题,进入指定路由页面。而且需要点击某些具体数据,进行下钻。

可以用以下代码实现,注意        let _this = this;否则很可能会出现一些undefined的情况。

//点击下钻
      async drill_down() {
        let myChart = this.chart;
        let _this = this;
        myChart.on('click', async function (onParams) {
            console.log('jinruclick', onParams)//打印点击后的参数值
            console.log('jinruclick', onParams.event.target.style.text)
            if (onParams.event.target.style.text && onParams.event.target.style.text == '就诊人员人次分析') {
              _this.$router.push('/mz');
            }
            var param = onParams;
            //x坐标轴是月份的时候才能下钻
            //x轴数据
            this.xData = [];
            this.xData_day = [];
            //门诊数据
            this.mzData = [];
            this.mzData_day = [];
            //住院数据
            this.zyData = [];
            this.zyData_day = [];
            var paramArr = param.name.toString().split('月');
            var paramYear = param.name.toString().split('-')[0].replace("(", "")//(2019-1-1,2019-1-31)
            var paramMonth = paramArr[0].split('-')[1];//点击得到的月份
            if (paramArr.length == 2) {
              // if (1 == 1) {
              this.isShowBack = true;
              const param_zy = new URLSearchParams();
              param_zy.append('STA_TYPE_CODE', _this.STA_TYPE_CODE);
              param_zy.append('STA_ITEM_DATE', getNowMonthFirstLastDay(paramYear, paramMonth));
              param_zy.append('time_unit', 'Date');
              
              const postUrl = "/api/indexget?model=" + _this.model;
              await axios.post(postUrl, param_zy)
                .then(res => {
                  let detailData = res.data.detail;
                  // _this.resDatas = [];
                  // _this.resDatas = res.data.detail;
                  for (let i = 0; i < detailData.length; i++) {
                    _this.xData_day.push(detailData[i].name.split('-')[2] < 10
                      ? (detailData[i].name.split('-')[2].charAt(1))
                      : (detailData[i].name.split('-')[2]));
                    _this.mzData_day.push(detailData[i].value)
                  }
                  //渲染点击后获取到的门诊数据
                  myChart.setOption({
                    xAxis: {
                      data: _this.xData_day,
                      name: '日期',
                    },
                    series: [
                      {name: _this.legend, data: _this.mzData_day},],
                    toolbox: {
                      left: 8,
                      bottom: 5,
                      feature: {
                        myTool1: {
                          show: true,
                          title: "返回",
                          icon:
                            "path://M853.333333 245.333333H245.333333l93.866667-93.866666c12.8-12.8 12.8-34.133333 0-46.933334-12.8-12.8-34.133333-12.8-46.933333 0l-145.066667 145.066667c-12.8 12.8-12.8 34.133333 0 46.933333l145.066667 145.066667c6.4 6.4 14.933333 10.666667 23.466666 10.666667s17.066667-4.266667 23.466667-10.666667c12.8-12.8 12.8-34.133333 0-46.933333L256 311.466667h597.333333c6.4 0 10.666667 4.266667 10.666667 10.666666v426.666667c0 6.4-4.266667 10.666667-10.666667 10.666667H170.666667c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h682.666666c40.533333 0 74.666667-34.133333 74.666667-74.666667V320c0-40.533333-34.133333-74.666667-74.666667-74.666667z",
                          // 点击返回事件
                          onclick: function (params) {
                            // 点击返回时判断此次的类别  此次类别为二级类别("日"),将其赋值为一级类别的数据,将其返回上一层

                            _this.xData = [];
                            _this.xData_day = [];
                            _this.mzData = [];
                            _this.mzData_day = [];
                            _this.zyData = [];
                            _this.zyData_day = [];
                            _this.chart.dispose();//释放图表实例
                            _this.chart = null;
                            _this.isShowBack = false;
                            _this.initChart();//重新绘制月份
                            _this.show = false;
                          },
                        },
                      },
                    },
                  })


                })
                .catch(error => {
                  // console.log(error)
                });

              //住院数据
              param_zy.set('STA_TYPE_CODE', _this.STA_TYPE_CODE2);
              await axios.post(postUrl, param_zy).then(res => {
                // let dayData = res.data.detail;
                for (let i = 0; i < res.data.detail.length; i++) {
                  _this.zyData_day.push(res.data.detail[i].value)
                }
                myChart.setOption({
                  series: [
                    {},
                    {
                      name: _this.legend2,
                      data: _this.zyData_day
                    }],
                  toolbox: {
                    left: 10,
                    bottom: 20,
                    feature: {
                      myTool1: {
                        show: true,
                        title: "返回",
                        icon:
                          "path://M853.333333 245.333333H245.333333l93.866667-93.866666c12.8-12.8 12.8-34.133333 0-46.933334-12.8-12.8-34.133333-12.8-46.933333 0l-145.066667 145.066667c-12.8 12.8-12.8 34.133333 0 46.933333l145.066667 145.066667c6.4 6.4 14.933333 10.666667 23.466666 10.666667s17.066667-4.266667 23.466667-10.666667c12.8-12.8 12.8-34.133333 0-46.933333L256 311.466667h597.333333c6.4 0 10.666667 4.266667 10.666667 10.666666v426.666667c0 6.4-4.266667 10.666667-10.666667 10.666667H170.666667c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h682.666666c40.533333 0 74.666667-34.133333 74.666667-74.666667V320c0-40.533333-34.133333-74.666667-74.666667-74.666667z",
                        // 点击返回事件
                        onclick: function (params) {
                          console.log('params:' + params.toString())
                          console.log(params.option.xAxis);
                          console.log(params.option.series[0].data);
                          // alert("myToolHandler1");
                          // 点击返回时判断此次的类别  此次类别为二级类别("日"),将其赋值为一级类别的数据,将其返回上一层
                          if (params.option.xAxis[0].name == "日") {
                            console.log(params.option.xAxis[0].name);
                            _this.chart.dispose();
                            _this.chart = null;
                            _this.isShowBack = false;
                            _this.initChart();
                          }
                        },
                      },
                    },
                  },
                })
              }).catch(error => {
                // console.log(error)
              });
            } else {

              //不能下钻
            }
          }
        );
      },

二、 桑基图数据不显示。

检查数据格式是否正确。且links数组中的元素,不存在source和target相同的情况,否则会出现闭环,导致图表不显示。

data: [
                {
                  "name": "a"
                },
                {
                  "name": "b"
                },]

links: [
                {
                  "source": "a",
                  "target": "a1",
                  "value": 39
                },
                {
                  "source": "a",
                  "target": "b",
                  "value": 36
                },]

三、vue+element组件数据双向绑定失效,此处{{THEATER_COMMAND}}怎么都显示不出来。原因在于THEATER_COMMAND在数据进行赋值后,要么在mounted周期里进行复制,要么在每次赋值前先清空THEATER_COMMAND="",这样就能正常显示了。

注意:这也可能会在element ui的Form表单校验,当出现error信息时候,多次点击提交按钮,但error信息只出现一次的时候。同样可以先清空error信息,再对errorMsg进行赋值,得以解决。

 <el-col :span="2" align="center" :model="THEATER_COMMAND">
      <el-dropdown @command="handleCommand" v-show="ROLE_NAME=='超级管理员'">
        <span class="el-dropdown-link">
          {{THEATER_COMMAND}}
          <i class="el-icon-arrow-down el-icon--right"></i></span>
        <el-dropdown-menu slot="dropdown">
          <el-dropdown-item command="全部">全部</el-dropdown-item>
          <el-dropdown-item command="其它">其它</el-dropdown-item>
        </el-dropdown-menu>
      </el-dropdown>
    </el-col>



 mounted() {
      this.THEATER_COMMAND = ‘xxxxx’
    },

四、element日期范围选择器

 <el-date-picker
        v-model="defaultDateRange"
        type="daterange"
        align="center"
        :editable="false"
        unlink-panels
        size="mini"
        range-separator="至"
        start-placeholder="开始日期1"
        end-placeholder="结束日期1"
        value-format="yyyy-MM-dd"
        :picker-options="rangePickerOptions"
        @change="changeData">
      </el-date-picker>


data() {
      return {
        rangePickerOptions: {
          disabledDate: time => {
            return (
              time > new Date() || time < new Date(2020, 0, 1)//日期只能大于指定时间,且小于当前天
            )
          }
        },
        defaultDateRange: ['2020-01-01', '2020-09-30'],//默认日期时间
      }
    },

五、echarts地图不显示或显示超出dom的解决方法:

要先引入地图json文件, 

import china from 'echarts/map/json/china.json'

如需调整地图位置和大小,还要在geo调整地图位置和大小,而不同于其他普通柱状图等通过grid设置。

geo: {
                    layoutCenter: ['48%', '50%'],//距离左右,上下距离的百分比
                    layoutSize: '95%',//map百分比大小

}

grid: {
              top: '18%',
              left: '3%',
              right: '7%',
              bottom: '3%',
              containLabel: true
            },

 _this.chart.setOption(
                {
                  title: {
                    text: '卫生资源分布及突发公共卫生事件',
                    // textStyle: {
                    //   align: 'center',
                    //   color: 'black',
                    //   fontSize: '112%',
                    //   fontWeight: "bold",
                    // },
                    // top: '5%',
                    left: 'center',
                  },
                  tooltip: {
                    triggerOn: "click",
                    formatter: function (e, t, n) {
                      return .5 == e.value ? e.name + ":有疑似病例" : e.seriesName + "<br />" + e.name + ":" + e.value
                    }
                  },
                  grid: {
                    left: "0%",
                    right: "0%",
                    top: "0%",
                    // bottom: "700%",
                  },
                  visualMap: {
                    min: 0,
                    max: 1000,
                    left: 26,
                    bottom: 40,
                    showLabel: !0,
                    text: ["高", "低"],
                    pieces: [{
                      gt: 100,
                      label: "> 100 人",
                      color: "#7f1100"
                    }, {
                      gte: 10,
                      lte: 100,
                      label: "10 - 100 人",
                      color: "#ff5428"
                    }, {
                      gte: 1,
                      lt: 10,
                      label: "1 - 9 人",
                      color: "#ff8c71"
                    }, {
                      gt: 0,
                      lt: 1,
                      label: "疑似",
                      color: "#ffd768"
                    }, {
                      value: 0,
                      color: "#ffffff"
                    }],
                    show: !0
                  },
                  geo: {
                    map: "china",
                    roam: !1,
                    layoutCenter: ['48%', '50%'],//距离左右,上下距离的百分比
                    layoutSize: '95%',//map百分比大小
                    scaleLimit: {
                      min: 1,
                      max: 2
                    },
                    zoom: 1.23,
                    top: 120,
                    label: {
                      normal: {
                        show: !0,
                        fontSize: "14",
                        color: "rgba(0,0,0,0.7)"
                      }
                    },
                    itemStyle: {
                      normal: {
                        //shadowBlur: 50,
                        //shadowColor: 'rgba(0, 0, 0, 0.2)',
                        borderColor: "rgba(0, 0, 0, 0.2)"
                      },
                      emphasis: {
                        areaColor: "#f2d5ad",
                        shadowOffsetX: 0,
                        shadowOffsetY: 0,
                        borderWidth: 0
                      }
                    }
                  },
                  series: [{
                    name: "确诊病例",
                    type: "map",
                    geoIndex: 0,
                    data: detailData,

                  }]
                })

 六、echarts图表经常需要resize一下,才能自适应屏幕。

可以在echarts图表.vue中使用mixins的方式:

  import resize from '@/views/pages/mixins/resize'

 export default {
    name: 'LineDoubleChart',
    mixins: [resize],
}

resize.js

import { debounce } from '@/utils'

export default {
  data() {
    return {
      $_sidebarElm: null,
      $_resizeHandler: null
    }
  },
  mounted() {
    this.$_resizeHandler = debounce(() => {
      if (this.chart) {
        this.chart.resize()
      }
    }, 100)
    this.$_initResizeEvent()
    this.$_initSidebarResizeEvent()
  },
  beforeDestroy() {
    this.$_destroyResizeEvent()
    this.$_destroySidebarResizeEvent()
  },
  // to fixed bug when cached by keep-alive
  // https://github.com/PanJiaChen/vue-element-admin/issues/2116
  activated() {
    this.$_initResizeEvent()
    this.$_initSidebarResizeEvent()
  },
  deactivated() {
    this.$_destroyResizeEvent()
    this.$_destroySidebarResizeEvent()
  },
  methods: {
    // use $_ for mixins properties
    // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
    $_initResizeEvent() {
      window.addEventListener('resize', this.$_resizeHandler)
    },
    $_destroyResizeEvent() {
      window.removeEventListener('resize', this.$_resizeHandler)
    },
    $_sidebarResizeHandler(e) {
      if (e.propertyName === 'width') {
        this.$_resizeHandler()
      }
    },
    $_initSidebarResizeEvent() {
      this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
      this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
    },
    $_destroySidebarResizeEvent() {
      this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
    }
  }
}

七、K线图tooltip默认显示文字调整。

tooltip: {
        trigger: "axis",
        // 修改系统默认的tooltip显示为英文,即“open,close,lowest,highest”
        formatter: function (params) {
          if (params.length > 0) {
            var i = params[0].dataIndex;
            var html = '';
            for(var p in params) {
              // var seriesName = params[p].seriesName;
              var value = params[p].value;
              if (p == 0) {
                // html += seriesName + "<br>";
                var name = params[p].name;
                html +=  name + "<br>";
                var mValue1 = value[1];
                var mValue2 = value[2];
                var mValue3 = value[3];
                var mValue4 = value[4];
                html += "下四分位数: " + mValue1 + "<br>";
                html += "上四分位数: " + mValue2 + "<br>";
                html += "最大值: " + mValue3 + "<br>";
                html += "最小值: " + mValue4 + "<br>";
              } else {
                html += value + "<br>";
              }
            }
            return html;
          } else {
            return "";
          }
        },
        axisPointer: {
          lineStyle: {
            color: "#666666",
            width: this.autoSize( 2 ),
            shadowColor: "#000",
            shadowBlur: this.autoSize( 10 )
          }
        }
      },

其他:

1、全局使用引入的变量问题。
2、echarts必须在mounted函数里面初始化。
3、在发送请求的时候,携带的参数应该用qs.stringify(参数是json串)的方式。
4、在定义了全局数据接口地址的时候,发起axios请求,应该屏蔽接口地址,只需要写接口路径即可。
5、在企业微信认证的时候,不方便调试可以将数据展示在前端页面上,或者使用vconsole插件,来替代console.log打印。
6、axios请求,在开发环境(内网上)必须对应具体的内网ip接口。在外网上,必须对应外网ip接口。否则请求会拿不到数据。
7、在做用户权限判断的适合,要结合页面引用的地址,来解析url参数。
8、合理使用mixins来复用数据。
9、合理使用window.localStorage.setItem和window.localStorage.getItem来存储/读取数据。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值