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

echarts图表X轴

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

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

<!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>

分析原因

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

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

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

interval这个属性的简单介绍

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

换行\n来处理这个问题

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

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

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也不会出现任何问题;
如果像上面那样做;改变原始数据;
 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显示全部

现在我们要做这样一个效果,
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)
})
        

实现的思路

我们需要动态创建一个dom节点,通过createElement来实现
注册鼠标移入事件 myChart.on('mouseover',(e)=>{ })
通过e.event可以拿到offsetX和offsetY
紧接着将这个元素赋值(X轴类的全名称),添加到html页面中
鼠标的移出事件 myChart.on('mouseout',(e)=>{ })
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了?

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


2025-01-19 发现了如何解决

今天下午研究了一下。
我们把上面那一部分重写了。然后就解决了。
大家请使用下面的代码
为啥会出现上面一种情况。因为使用了 e.event.offsetX这种获取坐标的方式。
myChart.on('mouseover', (e) => {
 // 需要注意: event.pageX 和 e.event.offsetX 的区别;
 // 如果使用  e.event.offsetX 就会出现上面哪一种问题。而自己使用 event.pageX 就不会
 // Y轴的位置也是一样的
})
所以下面我们优化一下代码,并且使用  event.pageX  来获取坐标

解决:鼠标偶尔移入无法显示全部名称的解决办法[全部代码,放下食用]

<!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.jsdelivr.net/npm/echarts@5.3.0/dist/echarts.min.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);
      function mouseHoverShowAllCont(){
        /**
         * 先获取是否有这样1个元素存在
         * 如果不存在,我们就创建一个
         * 给这个元素设置属性id,等其他眼神
         * 最后把这个元素添加到body中去
         * */ 
        let tipNameDom = document.getElementById('tipNameDom')
        if(!tipNameDom){
          let createDivElement = document.createElement('div')
          createDivElement.setAttribute('id', 'tipNameDom')
          createDivElement.style.display = 'block'
          document.querySelector('body').appendChild(createDivElement)
        }
        /**
         * 给echarts注册移入事件
         * 获取这个提示的元素
         * 给这个提示元素设置定位-层级-显示的内容-显示出来
         * 这个echarts注册移动事件(移动事件是在满足xAxis下触发的),然后做下面2件事情
         * 1,在移动事件下:获取获取鼠标的位置坐标(x,y)
         * 2,移动事件下:给这个提示元素实时更改它要显示的位置
         * */ 
        myChart.on('mouseover', mouseoverFunction)
        function mouseoverFunction(params){
          console.log('移入', params)
          if(params.componentType == 'xAxis'){
            let tipNameDomElement = document.getElementById('tipNameDom')
            tipNameDomElement.style.position = 'absolute'
            tipNameDomElement.style.zIndex = 9999;
            tipNameDomElement.innerHTML =  params.value
            tipNameDomElement.style.display = 'block'
            let xx = event.pageX
            let yy = event.pageY + 25
            tipNameDomElement.style.top = yy + 'px'
            tipNameDomElement.style.left = xx + 'px'
          }
        }
        // 注册echarts的移出事件,当移出的时候我们就隐藏掉这个显示全部的元素,同时销毁echarts的移动事件
        myChart.on('mouseout', mouseoutFunction)
        function mouseoutFunction(params){
          console.log('移出', params)
          if (params.componentType == 'xAxis') {
            console.log('移出xAxis=====', params)
            let tipNameDomElement = document.getElementById('tipNameDom')
            tipNameDomElement.style.display = 'none'
          }
          
        }
      }
      mouseHoverShowAllCont()
  }
</script>
</head>
<body>
  <div style="width: 400px;height: 300px;" class="echars"></div>
</body>
</html>

鼠标移动实时更新显示的位置

鼠标移入的时候,我们就获取了位置。
如果我们想鼠标的位置可以根据移动实时更新显示的位置。
此时我们则需要在移入事件下面在新增一个移动事件
根据移动事件实时获取位置然后赋值就可以了
移出的时候清空移动事件就行啦

鼠标移动实时更新显示的位置的相关代码

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);

function mouseHoverShowAllCont(){
  /**
    * 先获取是否有这样1个元素存在
    * 如果不存在,我们就创建一个
    * 给这个元素设置属性id,等其他眼神
    * 最后把这个元素添加到body中去
    * */ 
  let tipNameDom = document.getElementById('tipNameDom')
  if(!tipNameDom){
    let createDivElement = document.createElement('div')
    createDivElement.setAttribute('id', 'tipNameDom')
    createDivElement.style.display = 'block'
    document.querySelector('body').appendChild(createDivElement)
  }
  /**
    * 给echarts注册移入事件
    * 获取这个提示的元素
    * 给这个提示元素设置定位-层级-显示的内容-显示出来
    * 这个echarts注册移动事件(移动事件是在满足xAxis下触发的),然后做下面2件事情
    * 1,在移动事件下:获取获取鼠标的位置坐标(x,y)
    * 2,移动事件下:给这个提示元素实时更改它要显示的位置
    * */ 
  myChart.on('mouseover', mouseoverFunction)
  function mouseoverFunction(params){
    console.log('移入',  params, params.offsetX)
    if(params.componentType == 'xAxis'){
      let tipNameDomElement = document.getElementById('tipNameDom')
      tipNameDomElement.style.position = 'absolute'
      tipNameDomElement.style.zIndex = 9999;
      tipNameDomElement.innerHTML =  params.value
      tipNameDomElement.style.display = 'block'
      // let xx = event.pageX
      // let yy = event.pageY + 25
      // tipNameDomElement.style.top = yy + 'px'
      // tipNameDomElement.style.left = xx + 'px'
      document.querySelector('.echars').onmousemove = function (event) {
        var xx = event.pageX
        var yy = event.pageY + 25
        tipNameDomElement.style.top = yy + 'px'
        tipNameDomElement.style.left = xx + 'px'
      }
    }
  }
  // 注册echarts的移出事件,当移出的时候我们就隐藏掉这个显示全部的元素,同时销毁echarts的移动事件
  myChart.on('mouseout', mouseoutFunction)
  function mouseoutFunction(params){
    console.log('移出', params)
    if (params.componentType == 'xAxis') {
      console.log('移出xAxis=====', params)
      let tipNameDomElement = document.getElementById('tipNameDom')
      tipNameDomElement.style.display = 'none'
    }
    // 清除移动事件
    document.querySelector('.echars').onmousemove = null
  }
}
mouseHoverShowAllCont()

尾声

如果你觉得我写的不错的话,点一下推荐。感谢了
我已经几个月没有人给我推荐了。
听说打赏的小哥哥都追到女朋友了,
咦!你不信,不信你给我打赏看一下!
保准你追到到喜欢的Ta
posted @   南风晚来晚相识  阅读(1006)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
点击右上角即可分享
微信分享提示