通过Echarts的echarts.graphic.extendShape实现真正的3D柱状图
思路就是通过调整顶部面(CubeTop)、左侧面(CubeLeft)、右侧面(CubeRight)来决定柱状图的宽窄
建议优先调整顶部面,一般c1不需要动
// echarts-3D-bar-config.js
import Vue from "vue";
const echarts = Vue.prototype.echarts;
const CubeLeft = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
const xAxisPoint = shape.xAxisPoint;
// 顶部右侧顶点
const c1 = [shape.x, shape.y];
// 顶部左侧顶点
const c2 = [shape.x - 15, shape.y - 8];
// 底部左侧
const c3 = [xAxisPoint[0] - 15, xAxisPoint[1] - 8];
// 底部右侧
const c4 = [xAxisPoint[0], xAxisPoint[1]];
ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
}
});
const CubeRight = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
const xAxisPoint = shape.xAxisPoint;
// 顶部左侧顶点
const c1 = [shape.x, shape.y];
// 底部左侧顶点
const c2 = [xAxisPoint[0], xAxisPoint[1]];
// 底部右侧顶点
const c3 = [xAxisPoint[0] + 15, xAxisPoint[1] - 8];
// 顶部右侧顶点
const c4 = [shape.x + 15, shape.y - 8];
ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
}
});
const CubeTop = echarts.graphic.extendShape({
shape: {
x: 0,
y: 0
},
buildPath: function (ctx, shape) {
// 底部顶点
const c1 = [shape.x, shape.y];
// 右侧顶点
const c2 = [shape.x + 15, shape.y - 8];
// 顶部顶点
const c3 = [shape.x, shape.y - 15];
// 右侧顶点
const c4 = [shape.x - 15, shape.y - 8];
ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();
}
});
echarts.graphic.registerShape("CubeLeft", CubeLeft);
echarts.graphic.registerShape("CubeRight", CubeRight);
echarts.graphic.registerShape("CubeTop", CubeTop);
然后在build-bar-option中引用即可
这里主要就是把series中的内容复制过来直接用就行了
import Vue from "vue";
import "./echarts-3D-Bar-config"
const echarts = Vue.prototype.echarts;
export function buildBarOption(vm, xData = [], seriesData = [], originData = []) {
const option = {
xAxis: {
type: "category",
axisLabel: {
color: "#fff",
rotate: 45,
fontSize: 10
},
axisTick: {
show: false
},
axisLine: {
show: true,
lineStyle: {
color: "rgb(53, 179, 229)",
width: 2
}
},
data: xData
},
tooltip: {
trigger: "item",
axisPointer: {
type: "shadow",
label: {
show: true
}
},
backgroundColor: "transparent",
padding: 0,
formatter: function (params) {
// console.log(params)
return `
<div style="padding: 15px; background: linear-gradient(180.00deg, rgb(3, 36, 76),rgb(19, 36, 127) 100%)">
<p>test</p>
</div>
`;
}
},
grid: {
left: "15",
bottom: "10",
right: "10",
top: "40",
containLabel: true
},
yAxis: {
type: "value",
axisLabel: {
color: "#fff"
},
splitLine: {
show: true,
lineStyle: {
type: "dotted",
color: "rgb(53, 179, 229)"
}
}
},
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: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#3B80E2"
},
{
offset: 1,
color: "#49BEE5"
}
])
}
},
{
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: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#3B80E2"
},
{
offset: 1,
color: "#49BEE5"
}
])
}
},
{
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: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "#3B80E2"
},
{
offset: 1,
color: "#49BEE5"
}
])
}
}
]
};
},
data: seriesData
},
{
data: seriesData,
type: "bar",
barWidth: 13,
itemStyle: {
color: "transparent"
}
}
]
};
return option;
}