echarts X轴类目名太长时隐藏,hover时显示全部

echarts图表X轴

在柱状图中,X轴类目名如果数据太长;
echarts会默认进行隐藏部分字段;
如果我们想让每一个类目名都显示出来,需要进行额外的处理

X轴类目名太长时,默认只显示一部分类目名

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>4.9.0</title>
    <script src="https://cdn.staticfile.net/echarts/4.9.0-rc.1/echarts-en.common.js"></script>
</head>

<body>
  <div style="width: 400px;height: 300px;"></div>
  <script>
    let myChart = echarts.init(document.querySelector('div'))
    let colors = ['#4C98FB', '#83CCE7', '#26C7C8', '#73DEBD'];
    let option = {
      xAxis: {
        type: 'category',
        data: ['我是字段1cccccccc', '我是字段2', '我是字段3', '我是字段4', '我是字段5', '我是字段6', '我是字段7']
      },
      yAxis: {
        type: 'value'
      },
      series: [
        {
          data: [120, 200, 150, 80, 70, 110, 130],
          type: 'bar'
        }
      ]
    };
    myChart.setOption(option);
  </script>
</body>
</html>

分析原因

makefile 复制代码
通过上面的现象,我们发现:
展示不出来的原因是水平标签过多导致;
我们如果可以让它倾斜的话,说不定可以全部展示出来;
我们可以使用 xAxis下的 axisLabel中的 rotate属性来解决;
rotate:刻度标签旋转角度;这个值在 【90,-90】的范围类
在类目轴的类目标签显示不下的时候可以通过旋转防止标签之间重叠。

使用倾斜角度让每一个类目名显示出来

css 复制代码
xAxis: {
  type: 'category',
  data: ['我是字段1cccccccc2', '我是字段2', '段3', '我是字段4', '我是字段5', '我', '我是字段7'],
  axisLabel: {  
    interval:0,  
    rotate:-20  // 表示倾斜的角度
  }  
},

interval这个属性的简单介绍

typescript 复制代码
interval:坐标轴刻度标签的显示间隔,在类目轴中有效。
默认会采用标签不重叠的策略显示标签。
可以设置成0表示强制显示所有标签。
如果设置为 1,表示『隔一个标签』
可以用数值表示间隔的数据,也可以通过回调函数控制。
回调函数格式如下:
interval:(index:number, value: string) => {
  // index表示该类目名的下标
  // string表示该类目名
  console.log(index,string)
  return 1
},
如果返回的是true,表示显示该类目名;
也就是说:可以返回数字或者布尔值
css 复制代码
let option = {
  xAxis: {
    type: 'category',
    axisLabel: {  
      interval:2, // x轴间隔2个类目名
    },
    data: ['我是1', '我是2', '我是3', '我是4', '我是5', '我是6', '我是7']
  },
}

换行\n来处理这个问题

kotlin 复制代码
我们通过倾斜可以完全的把这个问题处理了;
可是有些时候,我们ui不想倾斜;那还有其他办法吗?可以换行
换行的话我们有两种方式;
第1种:直接在data中通过\n换行
不推荐第1种这样的方式去做;是因为如果图表还有tooltip的话,会影响。
第2种:在formatter函数中去处理
css 复制代码
xAxis: {
  type: 'category',
  data: ['我是\n字段1', '我是\n字段2', '段3', '我是\n字段4', 
    '我是\n字段5', '我是\n字段6', '我是\n字段7'
  ],
},

在data中通过\n换行会在 tooltip 会产生一个空格【不推荐有有副作用】

csharp 复制代码
tooltip: {
  // 使用formatter回调函数自定义显示内容
  formatter: function (params) {
    // params是包含数据信息的对象
    return params.name + ': ' + params.value;
  }
},
xAxis: {
  type: 'category',
  data: ['我是\n字段1', '我是\n字段2', '段3', '我是\n字段4', 
    '我是\n字段5', '我是\n字段6', '我是\n字段7'
  ],
},

通过 axisLabel中的formatter函数来换行 【推荐】没有副作用

我们可以通过xAxis下的axisLabel下的formatter函数来进行换行,
这样做不会改变原始数组,tooltip也不会出现任何问题;
如果像上面那样做;改变原始数据;
csharp 复制代码
 tooltip: {
    // 使用formatter回调函数自定义显示内容
    formatter: function (params) {
      // params是包含数据信息的对象
      return params.name + ': ' + params.value;
    }
  },
 xAxis: {
  interval: 0, 
  type: 'category',
  data: ['我是字段1', '我是字段2', '我是字段3', 
  '我是字段4', '我是字段5', '我是字段6', '我是字段7'],
  axisLabel: {  
    formatter: function (params) {
      console.log('x',params)
      return params.substring(0,2) + '\n' + params.substring(2)
    }
  }
},

超出进行隐藏部分名称,hover显示全部

javascript 复制代码
现在我们要做这样一个效果,
X轴中的类目名默认显示2个字,超出部分隐藏,hover的时候显示全部;
我们需要使用到echarts中的 mouseover 事件;
同时设置xAxis中的triggerEvent为true
xAxis: {
  triggerEvent: true,
  interval: 0, 
  type: 'category',
  ...其他配置项...
}
如果我们不设置triggerEvent: true鼠标移入X轴的类名不会被触发

myChart.on('mouseover', (e) => {
  console.log('鼠标移入X轴的类名不会被触发',e)
})
        

实现的思路

javascript 复制代码
我们需要动态创建一个dom节点,通过createElement来实现
注册鼠标移入事件 myChart.on('mouseover',(e)=>{ })
通过e.event可以拿到offsetX和offsetY
紧接着将这个元素赋值(X轴类的全名称),添加到html页面中
鼠标的移出事件 myChart.on('mouseout',(e)=>{ })
javascript 复制代码
let option = {
  xAxis: {
    // X轴的类目名必须设置这个属性,移入事件才会被触发
    triggerEvent: true,
    interval: 0, 
    type: 'category',
    data: ['我是字段111111', '我是字段222222', '我是字段33333', '我是字段4', '我是字段5', '我是字段6', '我是字段7'],
    axisLabel: {  
      formatter: function (params) {
        return params.substring(0,2) + '...'
      }
    }
  },
  ... 其他配置项
}
myChart.setOption(option);

myChart.on('mouseover', (e) => {
  console.log('鼠标移入',e)
  if(e.componentType === "xAxis"){
    // 我们这里先判断一个创建的dom节点是否存在
    let tipNameDom = document.getElementById('tipNameDom')
    console.log(1, tipNameDom)
    // 如果不存在我们创建一个dom节点
    if(!tipNameDom){
      // 创建一个元素
      var createDivElement = document.createElement('div')
      // 给这个元素设置属性
      createDivElement.setAttribute('id', 'tipNameDom')
      // // 设置元素的位置
      createDivElement.style.display = 'block'
      createDivElement.style.position = 'absolute'
      // 获取当前位置
      createDivElement.style.top =  e.event.offsetY + 15 + 'px'
      createDivElement.style.left = e.event.offsetX - 10 + 'px'
      // 这里需要使用 innerHTML,因为我们设置了一样html的属性
      createDivElement.innerHTML = e.value
      // document.querySelector('body').appendChild(createDivElement)
      document.querySelector('body').appendChild(createDivElement)
    }else {
      tipNameDom.style.display = 'block'
      tipNameDom.style.position = 'absolute'
      // 获取当前位置
      tipNameDom.style.top =  e.event.offsetY + 15 + 'px'
      tipNameDom.style.left = e.event.offsetX - 10 + 'px'
      // 这里需要使用 innerHTML,因为我们设置了一样html的属性
      tipNameDom.innerHTML = e.value
    }
  }
})

//  移入事件如果被多次触发,则hover的时候无法显示全部
myChart.on('mouseout', function(params) {
  console.log('移除元素',params )
  if (params.componentType === 'xAxis') {
    let elementDiv = document.querySelector('#tipNameDom')
    console.log('elementDiv', elementDiv)
    elementDiv.style.display = 'none'
  }  
})

是不是这样就OK了?

ini 复制代码
其实,并不是的;
如果小伙伴们多次移入移出;
偶尔会出现光标明明是移入的状态,但是类目名并没有全部显示出来;
此时已发现了移入事件被多次触发;
怎么解决这个问题呢?
目前的我,并不知道如何去解决。我感觉是echarts的bug;
如果知道的大佬;可以解答一下,万分感激; 

全部代码

xml 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>4.9.0</title>
  <!-- <script src="https://cdn.staticfile.org/echarts/4.3.0/echarts.min.js"></script> -->
  <script src="https://cdn.staticfile.net/echarts/4.9.0-rc.1/echarts-en.common.js"></script>
  <script>
    window.onload =function (){
      let myChart = echarts.init(document.querySelector('.echars'))
      let colors = ['#4C98FB', '#83CCE7', '#26C7C8', '#73DEBD'];
      let option = {
        tooltip: {
          // 使用formatter回调函数自定义显示内容
          formatter: function (params) {
            // params是包含数据信息的对象
            return params.name + ': ' + params.value;
          }
        },
        xAxis: {
          // X轴的类目名必须设置这个属性,移入事件才会被触发
          triggerEvent: true,
          interval: 0, 
          type: 'category',
          data: ['我是字段111111', '我是字段222222', '我是字段33333', '我是字段4', '我是字段5', '我是字段6', '我是字段7'],
          axisLabel: {  
            formatter: function (params) {
              return params.substring(0,2) + '...'
            }
          }
        },
        yAxis: {
          type: 'value'
        },
        series: [
          {
            data: [120, 200, 150, 80, 70, 110, 130],
            type: 'bar'
          }
        ]
      };
      myChart.setOption(option);

      myChart.on('mouseover', (e) => {
        console.log('鼠标移入',e)
        if(e.componentType === "xAxis"){
          // 我们这里先判断一个创建的dom节点是否存在
          let tipNameDom = document.getElementById('tipNameDom')
          console.log(1, tipNameDom)
          // 如果不存在我们创建一个dom节点
          if(!tipNameDom){
            // 创建一个元素
            var createDivElement = document.createElement('div')
            // 给这个元素设置属性
            createDivElement.setAttribute('id', 'tipNameDom')
            // // 设置元素的位置
            createDivElement.style.display = 'block'
            createDivElement.style.position = 'absolute'
            // 获取当前位置
            createDivElement.style.top =  e.event.offsetY + 15 + 'px'
            createDivElement.style.left = e.event.offsetX - 10 + 'px'
            // 这里需要使用 innerHTML,因为我们设置了一样html的属性
            createDivElement.innerHTML = e.value
            // document.querySelector('body').appendChild(createDivElement)
            document.querySelector('body').appendChild(createDivElement)
          }else {
            tipNameDom.style.display = 'block'
            tipNameDom.style.position = 'absolute'
            // 获取当前位置
            tipNameDom.style.top =  e.event.offsetY + 15 + 'px'
            tipNameDom.style.left = e.event.offsetX - 10 + 'px'
            // 这里需要使用 innerHTML,因为我们设置了一样html的属性
            tipNameDom.innerHTML = e.value
          }
        }
      })

      //  移入事件如果被多次触发,则hover的时候无法显示全部
      myChart.on('mouseout', function(params) {
        console.log('移除元素',params )
        if (params.componentType === 'xAxis') {
          let elementDiv = document.querySelector('#tipNameDom')
          console.log('elementDiv', elementDiv)
          elementDiv.style.display = 'none'
        }  
      })
  }
</script>
</head>
<body>
  <div style="width: 400px;height: 300px;" class="echars"></div>
</body>

</html>
相关推荐
gqkmiss30 分钟前
Chrome 浏览器插件获取网页 iframe 中的 window 对象
前端·chrome·iframe·postmessage·chrome 插件
m0_748247553 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php
m0_748255023 小时前
前端常用算法集合
前端·算法
真的很上进3 小时前
如何借助 Babel+TS+ESLint 构建现代 JS 工程环境?
java·前端·javascript·css·react.js·vue·html
web130933203983 小时前
vue elementUI form组件动态添加el-form-item并且动态添加rules必填项校验方法
前端·vue.js·elementui
NiNg_1_2344 小时前
Echarts连接数据库,实时绘制图表详解
前端·数据库·echarts
如若1234 小时前
对文件内的文件名生成目录,方便查阅
java·前端·python
滚雪球~5 小时前
npm error code ETIMEDOUT
前端·npm·node.js
沙漏无语5 小时前
npm : 无法加载文件 D:\Nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本
前端·npm·node.js
supermapsupport5 小时前
iClient3D for Cesium在Vue中快速实现场景卷帘
前端·vue.js·3d·cesium·supermap