ECharts 伪 3D 柱状图完整注释 + 实现原理说明

代码注释顶部标注 // 多系列无法定位:该方案只支持单组数据,如果多系列多根柱子并排,pictorialBar 菱形底座 / 顶盖无法精准对齐每一根柱子,会错位。

核心实现原理前置说明

ECharts 没有原生 3D 柱状图 bar3D (echarts-gl 是独立 3D 组件,此代码未引入 gl),本方案是2D 图层叠加模拟立体柱子

  • 底层:普通bar矩形柱体(柱子主体)

  • 下层装饰:pictorialBar菱形(柱子底部切面,模拟立体底座)

  • 上层装饰:pictorialBar菱形(柱子顶部切面,模拟立体封顶) 通过三层 series 设置不同z层级上下叠加,搭配渐变填充、菱形斜面,视觉欺骗出 3D 立体效果。

  • 如果需要支持多系列、真 3D 旋转视角,需要引入 echarts-gl 插件,使用 bar3D 系列,不需要多层 pictorialBar 叠加。

  • 单系列正常逻辑 只有一组 bar 数据时,pictorialBar 的 data 长度、类目位置和 bar 完全匹配,菱形底座 / 顶盖能精准落在每根柱子上下。

  • 多系列失效原因 当存在两组及以上 bar(多组并列柱子):

    • pictorialBar 是全局类目渲染,无法区分第 1 组柱、第 2 组柱;
    • 菱形图形会居中在类目格子中间,和多根并列柱子错位;
    • 没有配置参数可以控制 pictorialBar 偏移到对应系列柱子位置,因此多系列场景该伪 3D 方案不可用。
    javascript 复制代码
    // 全局通用文字线条灰色
    var normalColor = "#94a1a9";
    
    /**
     * 渐变颜色数组,两套线性渐变用于柱子填充
     * 渐变类型:水平线性渐变(x从0到1,y不变=横向渐变)
     */
    var colors = [{
        type: 'linear',       // 渐变类型:线性渐变
        x: 0, x2: 1,          // 渐变起点x=0,终点x=1 → 水平左右渐变
        y: 0, y2: 0,          // y全程不变,无上下渐变
        colorStops: [{         // 渐变分段色标
            offset: 0, color: '#0a4368'
        }, {
            offset: 0.5, color: '#0a4368'
        }, {
            offset: 0.5, color: '#0a4368'
        }, {
            offset: 1, color: '#0a4368'
        }]
    }, {
        type: 'linear',
        x: 0, x2: 1,
        y: 0, y2: 0,
        colorStops: [{
            offset: 0, color: 'rgba(10, 67, 104,0.6)'
        }, {
            offset: 0, color: '#fff'
        }, {
            offset: 0.05, color: 'rgba(10, 67, 104,0.6)'
        }, {
            offset: 0.5, color: 'rgba(10, 67, 104,0.6)'
        }, {
            offset: 0.5, color: '#fff'
        }, {
            offset: 0.55, color: 'rgba(10, 67, 104,0.6)'
        }, {
            offset: 0.95, color: 'rgba(10, 67, 104,0.9)'
        }, {
            offset: 1, color: '#fff'
        }]
    }];
    
    // 柱子宽度统一变量,三层图表共用宽度保证对齐
    var barWidth = 80;
    
    // ECharts 配置项
    option = {
        animation: false, // 关闭图表初始化加载动画,避免立体分层动画错位
        backgroundColor: "#ccc", // 画布背景浅灰色
        title: {
            text: '' // 无图表标题
        },
        // X轴:类目轴,年份分类
        xAxis: {
            type: 'category',
            boundaryGap: true, // 坐标轴两端留白,柱子不会贴紧画布左右边缘
            axisLabel: { // X轴文字样式
                color: normalColor,
                fontSize: 16,
            },
            axisTick: { // 隐藏X轴刻度小短线
                show: false
            },
            axisLine: { // X轴线样式
                show: true,
                lineStyle: {
                    type: "dashed", // 虚线坐标轴
                    color: normalColor
                }
            },
            splitLine: { // X轴纵向分割线
                show: true,
                lineStyle: {
                    type: "dashed",
                    color: normalColor
                }
            },
            data: ['2016', '2017', '2018', '2019'] // X轴类目数据
        },
        // Y轴:数值轴,单根数组表示单Y轴
        yAxis: [{
            name: "",
            type: 'value',
            axisLine: { // Y轴线
                show: true,
                lineStyle: {
                    color: normalColor,
                }
            },
            axisTick: { // 隐藏Y轴刻度短线
                show: false,
            },
            axisLabel: { // Y轴数值文字
                color: normalColor,
                fontSize: 16,
                margin: 25, // 文字距离Y轴线间距
                formatter: '{value}' // 数值原样展示
            },
            splitLine: { // Y轴横向网格分割线
                show: true,
                lineStyle: {
                    type: "dashed",
                    color: normalColor
                }
            },
        }, ],
        /**
         * series三层图层叠加实现伪3D柱子,z值越大层级越靠上
         * z=1:底层主体矩形柱子
         * z=2:底层菱形底座(柱子底部斜面)
         * z=3:顶层菱形顶盖(柱子顶部斜面)
         */
        series: [
            // 第一层:柱状图主体(矩形柱身,核心载体)
            {
                z: 1, // 层级最低,在最下方
                type: 'bar', // 基础柱状图
                barWidth: barWidth, // 柱宽统一80px
                label: { // 柱子顶部数值标签
                    show: true,
                    position: "top", // 文字在柱子上方
                    padding: 10,
                    textStyle: {
                        color:normalColor,
                        fontSize: 30 // 数值放大突出
                    }
                },
                data: [220, 182, 191, 234], // 柱子高度数值
                itemStyle: {
                    normal: {
                        color: colors[1] // 柱子填充为第二套渐变
                    }
                },
            },
            // 第二层:pictorialBar 菱形底座,模拟柱子底部立体切面
            {
                z: 2, // 层级高于柱身,叠在柱子底部上方
                name: '底部',
                type: 'pictorialBar', // 象形柱状图,自定义图形标记
                data: [1, 1, 1, 1, 1, 1, 1], // 数值固定1,只渲染图形不控制高度
                symbol: 'diamond', // 自定义图形:菱形
                symbolOffset: [0, '50%'], // 图形垂直向下偏移50%,贴在柱子底端
                symbolSize: [barWidth, 10], // 菱形宽=柱宽,高度10px(底座厚度)
                itemStyle: {
                    normal: {
                        color: colors[1],
                        borderColor: '#fff', // 白色描边增强立体分割感
                        borderWidth: 2,
                    }
                },
            },
            // 第三层:pictorialBar 菱形顶盖,模拟柱子顶部立体切面
            {
                z: 3, // 层级最高,覆盖在柱子最顶端
                name: '上部1',
                type: 'pictorialBar',
                symbolPosition: 'end', // 图形吸附在数值终点(柱子顶端)
                data: [220, 182, 191, 234], // 和柱身高度数值完全一致,精准对齐顶端
                symbol: 'diamond', // 顶部菱形切面
                symbolOffset: [0, '-50%'], // 垂直向上偏移50%,贴合柱子顶端上沿
                symbolSize: [barWidth - 4, 15 * (barWidth - 4) / barWidth], // 菱形略窄于柱身,比例缩小高度
                itemStyle: {
                    normal: {
                        borderColor: '#fff', // 白色边框区分顶盖和柱身
                        borderWidth: 2,
                        color: '#0a4368' // 顶盖纯色加深,强化立体明暗对比
                    }
                }
            }
        ]
    };
相关推荐
掘金一周1 小时前
看看大家每月的成本有多少 | 沸点周刊 7.30
前端·人工智能·后端
ji_shuke2 小时前
从零深入:基于 Playwright + Pytest + Allure 的企业级 Web 端到端自动化测试框架实战
前端·自动化测试·docker·jenkins·pytest·allure·playwright
陆枫Larry2 小时前
用 CSS Mask + background-color 给图标「换色」
前端
幼儿园技术家3 小时前
原来不用发版也可以做到版本更新
前端·js or ts
亦暖筑序3 小时前
AgentScope-Java 入门:完善 Vue 前端、发布 GitHub,并规划下一步
java·前端·vue.js
北斗落凡尘3 小时前
Vue面试题
前端
程序员黑豆3 小时前
鸿蒙应用开发之父子组件传参:@Param、@Event、@Once 装饰器详解与实战
前端·harmonyos
ClouGence3 小时前
一个人录好的测试用例,团队怎么一起用?
前端·测试
无限压榨切图仔4 小时前
从 Claude Code 切到 Codex:我用 Agent、Skills、MCP 做完了一个内容运营工具
前端·后端