Echarts - 3D 柱状图

877 阅读1分钟

官方配置文档

方法一: 使用 series 中的custom

  1. 组册 3个面, 左, 右, 上
// 绘制左侧面
const CubeLeft = element.$echarts.graphic.extendShape({
    shape: {
	x: 0,
	y: 0
    },
    buildPath: function(ctx, shape) {
	// 会canvas的应该都能看得懂,shape是从custom传入的
	const xAxisPoint = shape.xAxisPoint
	const c0 = [shape.x, shape.y + b_hei]
	const c1 = [shape.x - wid, shape.y + 4 + b_hei]
	const c2 = [xAxisPoint[0] - wid, xAxisPoint[1] + 4 + b_hei]
	const c3 = [xAxisPoint[0], xAxisPoint[1] + b_hei]
	ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath()
    }
})

// 绘制右侧面
const CubeRight = element.$echarts.graphic.extendShape({
    shape: {
	x: 0,
	y: 0
    },
    buildPath: function(ctx, shape) {
	// console.log(shape)
	const xAxisPoint = shape.xAxisPoint
	// console.log(xAxisPoint)
	const c1 = [shape.x, shape.y + b_hei]
	const c2 = [xAxisPoint[0], xAxisPoint[1] + b_hei]
	const c3 = [xAxisPoint[0] + wid, xAxisPoint[1] + 4 + b_hei]
	const c4 = [shape.x + wid, shape.y + 4 + b_hei]
	ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
    }
})

// 绘制顶面
const CubeTop = element.$echarts.graphic.extendShape({
    shape: {
	x: 0,
	y: 0
    },
    buildPath: function(ctx, shape) {
	const c1 = [shape.x, shape.y + b_hei]
	const c2 = [shape.x + wid, shape.y + 4 + b_hei] //右点
	const c3 = [shape.x, shape.y + 8 + b_hei]
	const c4 = [shape.x - wid, shape.y + 4 + b_hei]
	ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath()
    }
})

// 注册三个面图形
element.$echarts.graphic.registerShape('CubeLeft', CubeLeft)
element.$echarts.graphic.registerShape('CubeRight', CubeRight)
element.$echarts.graphic.registerShape('CubeTop', CubeTop)
  1. 使用 series 中的custom 绘制柱状图的3个面 renderItem 直接返回类型是group 的(配置中查到)

    coord 展示点的 (x, y), 柱状图的起始点

    series 中的pictorialBar 展示柱状的 数值展示

const coord = api.coord([
	api.value(0, params.dataIndex),
	api.value(1, params.dataIndex)
]);

绘制柱状图 3个面

series: [{
    type: 'custom',
    renderItem: (params, api) => {
    const location = api.coord([api.value(0), api.value(1)])
    return {
	type: 'group',
	children: [{
            type: 'CubeLeft',
            shape: {
                api,
                xValue: api.value(0),
                yValue: api.value(1),
		x: location[0],
		y: location[1],
		xAxisPoint: api.coord([api.value(0), 0])
            },
            style: {
                fill: 'red'
            }
	}, {
            type: 'CubeRight',
            shape: {
		api,
		xValue: api.value(0),
		yValue: api.value(1),
		x: location[0],
		y: location[1],
		xAxisPoint: api.coord([api.value(0), 0])
            },
            style: {
		fill: 'blue'
            }
	}, {
            type: 'CubeTop',
            shape: {
                api,
		xValue: api.value(0),
		yValue: api.value(1),
		x: location[0],
		y: location[1],
		xAxisPoint: api.coord([api.value(0), 0])
            },
            style: {
		fill: 'yellow'
            }
	}]
       }
      },
      data: []
},
{
    type: 'pictorialBar',
    label: {
	show: true,
	position: 'top',
	distance: -b_hei,
	formatter: '{@score}',
	fontSize: 13,
	color: '#999'
    }
}]

方法二: pictorialBar 完成柱状图

image: 图片base64编码

symbol:柱状image 设置, 会拉伸。可以是svg 参看配置文档

label: 柱状上面的数值

series: [
    {
	type: 'pictorialBar',
	symbol: 'image://' + image,
	symbolSize: [20, '100%'],
	label: {
            show: true,
            position: 'top',
            distance: 5,
            formatter: '{@score}',
            fontSize: 13,
            color: '#999'
	}
    }
]