Echarts柱状图自定义立体图形

例一:

参考这个大佬:https://zhuanlan.zhihu.com/p/608402859

效果图:

js:

var chartDom = document.getElementById('idName');
        var myChart = echarts.init(chartDom);
        var option;
        const labels = ['<20','20-70','70-160', '160-320','>320'];
        const seriesData = [
            {
                label: '<20',
                value: [32],
            },
            {
                label: '20-70',
                value: [24],
            },
            {
                label: '70-160',
                value: [42],
            },
            {
                label: '160-320',
                value: [20],
            },
            {
                label: '>320',
                value: [20],
            }
        ]
        const colors = [
            [
                { offset: 0, color: 'rgba(52, 163, 224, 1)' },
                { offset: 1, color: 'rgba(52, 163, 224, 0.08)' },
            ],
            [
                { offset: 0, color: 'rgba(255, 209, 92, 1)' },
                { offset: 1, color: 'rgba(137, 163, 164, 0.08)' },
            ],
            [
                { offset: 0, color: 'rgba(255, 157, 59, 1)' },
                { offset: 1, color: 'rgba(44, 166, 166, 0.08)' },
            ],
            [
                { offset: 0, color: 'rgba(236,82,51,1)' },
                { offset: 1, color: 'rgba(34, 66, 186, 0.08)' },
            ],
            [
                { offset: 0, color: 'rgba(117,22,34, 1)' },
                { offset: 1, color: 'rgba(34, 66, 186, 0.08)' },
            ],
        ];

        option = {
            xAxis: {
                axisTick: {
                    show: false
                },
                axisLabel: {
                    color: '#EEEEEE'
                },
                nameTextStyle: {
                    color: '#fff'
                },
                data: labels,
            },
            legend: {
                data: getlegendData(),
                right: '25',
                top: '18',
                icon: 'rect',
                itemHeight: 10,
                itemWidth: 10,
                textStyle: {
                    color: '#EEEEEE'
                }
            },
            yAxis: {
                type: 'value',
                axisLabel: {
                    color: '#EEEEEE'
                },
                splitLine: {
                    show: true,
                    lineStyle: {
                        type: 'dashed',
                        color: ['#ccc']
                    }
                }
            },
            series: getSeriesData()
        };
// 定义柱状图左侧图形元素
        const leftRect = echarts.graphic.extendShape({
            shape: {
                x: 0,
                y: 0,
                width: 19, //柱状图宽
                zWidth: 8, //阴影折角宽
                zHeight: 4 //阴影折角高
            },
            buildPath: function (ctx, shape) {
                const api = shape.api;
                const xAxisPoint = api.coord([shape.xValue, 0]);
                const p0 = [shape.x - shape.width / 2, shape.y - shape.zHeight];
                const p1 = [shape.x - shape.width / 2, shape.y - shape.zHeight];
                const p2 = [xAxisPoint[0] - shape.width / 2, xAxisPoint[1]];
                const p3 = [xAxisPoint[0] + shape.width / 2, xAxisPoint[1]];
                const p4 = [shape.x + shape.width / 2, shape.y];

                ctx.moveTo(p0[0], p0[1]);
                ctx.lineTo(p1[0], p1[1]);
                ctx.lineTo(p2[0], p2[1]);
                ctx.lineTo(p3[0], p3[1]);
                ctx.lineTo(p4[0], p4[1]);
                ctx.lineTo(p0[0], p0[1]);
                ctx.closePath();
            }
        });
// 定义柱状图右侧以及顶部图形元素
        const rightRect = echarts.graphic.extendShape({
            shape: {
                x: 0,
                y: 0,
                width: 18,
                zWidth: 15,
                zHeight: 8
            },
            buildPath: function (ctx, shape) {
                const api = shape.api;
                const xAxisPoint = api.coord([shape.xValue, 0]);
                const p1 = [shape.x - shape.width / 2, shape.y - shape.zHeight / 2];
                const p3 = [xAxisPoint[0] + shape.width / 2, xAxisPoint[1]];
                const p4 = [shape.x + shape.width / 2, shape.y];
                const p5 = [xAxisPoint[0] + shape.width / 2 + shape.zWidth, xAxisPoint[1]];
                const p6 = [
                    shape.x + shape.width / 2 + shape.zWidth,
                    shape.y - shape.zHeight / 2
                ];
                const p7 = [
                    shape.x - shape.width / 2 + shape.zWidth,
                    shape.y - shape.zHeight
                ];
                ctx.moveTo(p4[0], p4[1]);
                ctx.lineTo(p3[0], p3[1]);
                ctx.lineTo(p5[0], p5[1]);
                ctx.lineTo(p6[0], p6[1]);
                ctx.lineTo(p4[0], p4[1]);

                ctx.moveTo(p4[0], p4[1]);
                ctx.lineTo(p6[0], p6[1]);
                ctx.lineTo(p7[0], p7[1]);
                ctx.lineTo(p1[0], p1[1]);
                ctx.lineTo(p4[0], p4[1]);
                ctx.closePath();
            }
        });

// 注册图形元素
        echarts.graphic.registerShape('leftRect', leftRect);
        echarts.graphic.registerShape('rightRect', rightRect);

        function getlegendData() {
            const data = [];
            labels.forEach((item, index) => {
                data.push(
                    {
                        name: item,
                        itemStyle: {
                            color: new echarts.graphic.LinearGradient(1, 0, 0, 0, colors[index]),
                        },
                    }
                )
            })
            return data
        }

        function getSeriesData() {
            const data = [];
            seriesData.forEach((item, index) => {
                data.push(
                    {
                        type: 'custom',
                        name: item.label,
                        renderItem: function (params, api) {
                            return getRenderItem(params, api);
                        },
                        data: item.value,
                        itemStyle: {
                            color: () => {
                                return new echarts.graphic.LinearGradient(0, 0, 0, 1, colors[index]);
                            },
                        },
                    }
                )
            })
            return data
        }

        function getRenderItem(params, api) {
            const index = params.seriesIndex;
            let location = api.coord([api.value(0) + index, api.value(1)]);
            var extent = api.size([0, api.value(1)]);
            return {
                type: 'group',
                children: [
                    {
                        type: 'leftRect',
                        shape: {
                            api,
                            xValue: api.value(0) + index,
                            yValue: api.value(1),
                            x: location[0],
                            y: location[1]
                        },
                        style: api.style()
                    },
                    {
                        type: 'rightRect',
                        shape: {
                            api,
                            xValue: api.value(0) + index,
                            yValue: api.value(1),
                            x: location[0],
                            y: location[1]
                        },
                        style: api.style()
                    }
                ]
            };
        }


        option && myChart.setOption(option);

例二:

第二种方法就是用两个柱或者三个柱拼接出立体图形

效果图:

js:

var chartDom = document.getElementById('main');
var myChart = echarts.init(chartDom);
var option;

const dataList = [
  { name: '周一', value: '50' },
  { name: '周二', value: '70' },
  { name: '周三', value: '60' },
  { name: '周四', value: '51' },
  { name: '周五', value: '40' },
  { name: '周六', value: '80' },
  { name: '周天', value: '70' }
];

option = {
  xAxis: {
    type: 'category',
    data: dataList.map((item) => item.name),
    axisLabel: {
      margin: 20
    }
  },
  yAxis: {
    type: 'value'
  },
  series: [
    {
      // /数据图
      data: dataList.map((item) => item.value),
      type: 'bar',
      barWidth: 40,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(1, 0, 0, 0, [
          { offset: 0, color: '#3398BC' },
          { offset: 1, color: '#3C7AB9' }
        ])
      },
      z: 1
    },
    {
      // 最上面菱形
      data: dataList.map((item) => item.value),
      type: 'pictorialBar',
      symbol: 'diamond',
      symbolSize: ['40', '10'],
      symbolPosition: 'end',
      symbolOffset: ['', '-50%'],
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
          { offset: 0, color: '#3391BC' },
          { offset: 1, color: '#3C71B9' }
        ])
      },
      z: 2
    }
  ]
};

option && myChart.setOption(option);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

和风微凉

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值