echarts 横向渐变格子柱状图 三层

效果图

配置

javascript 复制代码
{
      
        grid: {
            left: '8%',      // 默认通常是 '5%' 或更多,改小它
            top: '20%',
            bottom: '10%',      // 如果有标题,这里需要留空间;没标题可以设为 '3%'
            containLabel: true // 【关键】设为 false,允许标签超出网格区域(需配合手动 margin)
        },
        
      xAxis: {
          type: 'value',
          min: -1,
          max:350,
          axisLine: {
              show: false ,
              lineStyle: { // 改变轴线的颜色
                  color: '#02396E',
                  width: 1,
                  type: 'solid'
              }
          },
         
          splitLine: {
              show: false, // 确保显示网格线
              lineStyle: {
                  color: '#02396E ', // 【核心】设置所有网格线的颜色
                  width: 1,         // 可选:设置线宽
                  type: 'solid'     // 可选:'solid', 'dashed', 'dotted'
              }
          },
          axisLabel: {
              color: '#FFFFFF',
              formatter: function (value) {
           
              return ''; // 其他刻度不显示文字
              }
          }
      },
      yAxis: {
          type: 'category',
          
          axisLine: {
              lineStyle: { // 改变轴线的颜色
                  color: '#FFFFFF',
                  width: 1,
                  type: 'solid'
              }
          },
          
          axisLabel: {
               
              color: '#FFFFFF',
             
          },
          data: ['Printer A', 'Printer B', 'Printer C',  'Printer D'],
      },
     
      series: [
          
          {
            data: [150, 212,300,150],
            type: 'custom',
            renderItem: function (params, api) {
                // api.value(0) 数值
                // api.value(1) 类别
                
                // 当前数值的坐标
                const valueCoord = api.coord([api.value(0), api.value(1)]);
                // 数值为0时的坐标
                const initialCoord = api.coord([0, api.value(1)]);
                // 柱状图的长度 = 当前数值的x坐标 - 数值为0时的x坐标
                const barLength = valueCoord[0] - initialCoord[0];
                const gap = 2; // 格子间的间距
                const height = 8; // 格子的高度
                const width = 4; // 格子的宽度
                // 格子的长度 = 格子的宽度 + 一个间距
                // 格子的数量 ≈ 柱状图的长度 / 单个格子的长度
                const barNum = Math.round(barLength / (width + gap));

                const itemStyle = api.style();
                //轨道层
                const textLength = 60;
                const maxBarLength = api.getWidth() - initialCoord[0] - textLength;
                const track = {
                    type: 'rect',
                    shape: {
                        x: initialCoord[0],
                        y: valueCoord[1] - (height + 16) / 2, // 垂直居中
                        width: maxBarLength,
                        height: height + 16 // 比条纹高 4px,确保露出边缘
                    },
                    style: {
                        fill: 'rgba(100, 100, 100, 0.2)', // 调深一点颜色和透明度,确保可见
                       
                    }
                };
                const rects = Array.from({ length: barNum }, (_, index) => {
                // 第 index 个格子的x坐标 = 数值为0时的坐标 + 前面所有格子的长度和
                const rectX = initialCoord[0] + (width + gap) * index;
                
    
                // 2. 计算位置比例 (0 到 1)
                var ratio = rectX / api.getWidth();

                // 3. 使用颜色混合代替 lift
                // 当 ratio=0 时,取 darkColor;当 ratio=1 时,取 lightColor
                // 这样渐变过程完全保留色相,不会出现发白的情况
                var finalColor = getGradientColorWithOpacity('#000000', '#66E1DF', ratio);
                return {
                    type: 'rect',
                    enterFrom: {
                    // scaleX: 0,
                    // scaleY: 1,
                    style: { opacity: 0 },
                    },
                    shape: {
                    // x,y 是格子左上角的坐标
                    y: valueCoord[1] - height / 2.5,
                    x: rectX,
                    width,
                    height,
                    },
                    style: {
                        fill: finalColor,
                        shadowColor: '#66E1DF', 
                        shadowBlur: 1, // 光晕大小
                        shadowOffsetX: 0,
                        shadowOffsetY: 0,
                        stroke: 'rgba(255, 255, 255, 0.1)', 
                        lineWidth: 1,
                        // 稍微降低整体不透明度,制造朦胧感
                        opacity: 0.8,
                    },
                };
                });

                // 预留 60px,在柱状图右边显示数值
                
                const bgbarNum = Math.round(
                (api.getWidth() - initialCoord[0] - textLength) / (width + gap)
                );

                const bgRects = Array.from({ length: bgbarNum }, (_, index) => {
                return {
                    type: 'rect',
                    shape: {
                    y: valueCoord[1] - height / 2,
                    x: initialCoord[0] + (width + gap) * index,
                    width,
                    height,
                    },
                    style: {
                     fill: 'rgba(204, 204, 204,0.3)',
                    },
                };
                });
               
                return {
                    type: 'group',
                    x: 0,
                    y: 0,
                    children: [track,...bgRects, ...rects],
                    };
            },
                    

                    
        }
          
      ]
  }

参考https://juejin.cn/post/7366071543405985828

相关推荐
踩着两条虫5 小时前
VTJ:技术架构概述
前端·架构·ai编程
吴声子夜歌5 小时前
Vue3——过度和动画效果
前端·vue.js·es6
Via_Neo5 小时前
字符串类型的相互转换
前端
zopple6 小时前
前端三剑客 vs Vue.js:核心区别解析
前端·javascript·vue.js
hsjcjh6 小时前
窗口函数-详细讲解分析
java·服务器·前端
CDN3606 小时前
【踩坑实录】前端开发必看:一次由CSS缓存引发的线上事故与SEO反思
前端·css·缓存
胡志辉的博客6 小时前
本地明明好好的,怎么一上线就跨域了?把同源策略、前后端分工和 CORS 一次讲明白
前端·javascript·vue.js·reactjs·nextjs·跨域
|晴 天|6 小时前
文章系列管理系统:拖拽排序与进度追踪
前端·vue.js·typescript
GISer_Jing6 小时前
AI Agent接口终局:MCP有弊端,CLI凭什么成为主流?
前端·人工智能
jiayong236 小时前
第 17 课:任务选择与批量操作
开发语言·前端·javascript·vue.js·学习