这次涉及的效果,和之前发布的文章(如何自定义echarts悬浮窗echarts的tooltip悬浮窗的自定义_zero00122的博客-CSDN博客)是一个图。
这次则是把堆叠柱状图变为3D效果并且还要有个同样3D效果的柱状背景
思路:用顶部小圆盖+带下侧圆角边框的柱体组成一个伪3D柱子。堆叠在上的柱子底部就不需要圆角边框了。难点是x轴每个单位上都要有一个3D柱状的阴影背景。
大家仔细看这个阴影背景头顶上也有一个小圆盖子。其实实现也很简单,不要把这个想成背景,把这个同样看成一个柱子就行了,只不过它的高度是y轴最大值减去其他柱子高度的合。
let option = {
//鼠标移入柱子不会有高亮效果
emphasis: {
disabled: true,
},
series: [
{
name: "存量(兆瓦)",
legendHoverLink: false,
type: "bar",
stack: "Ad",
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#785BE4", // 0% 处的颜色
},
{
offset: 1,
color: "#A7CCF8", // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
itemStyle: {
normal: {
barBorderRadius: [0, 0, 5, 5], // 让柱形上下变成圆角
opacity: 0.5,
},
},
emphasis: {
focus: "series",
},
data: this.dataList3,
},
//存量顶部的圆盘
{
name: "存量(兆瓦)",
legendHoverLink: false,
symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
tooltip: {
show: false,
},
type: "pictorialBar",
color: "#785BE4",
itemStyle: {
opacity: 0.75,
},
symbol: "circle",
symbolSize: ["83%", 20 / 2.5],
symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
data: [
30,
40,
50,
70,
90,
140,
200,
300,
//数据为0就通过这种方式把圆盖给隐藏
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
], // 数据要跟主体柱形一致
z: 4, // 数值越大,层级越高,可以盖住下面的图形
},
{
name: "增量(兆瓦)",
legendHoverLink: false,
type: "bar",
stack: "Ad",
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#1ADBC7", // 0% 渐变顶部色
},
{
offset: 1,
color: "#2D6CE9", // 100% // 渐变底部色
},
],
global: false, // 缺省为 false
},
itemStyle: {
normal: {
// barBorderRadius: [20 / 3.5, 20 / 3.5, 0, 0], // 让柱形上下变成圆角
opacity: 0.75,
},
},
// showBackground:"true",
emphasis: {
focus: "series",
},
data: this.dataList6
? this.datalist6
: [40, 10, 20, 20, 50, 60, 100, 150, 0, 0, 0, 0], //有bug,已解决
},
//增量顶部圆盘
{
name: "增量(兆瓦)",
legendHoverLink: false,
symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
tooltip: {
show: false,
},
type: "pictorialBar",
color: "#26A4FF",
itemStyle: {
opacity: 1,
},
symbol: "circle",
symbolSize: ["83%", 20 / 2.5],
symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
data: [
70,
50,
70,
90,
140,
200,
300,
450,
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
], // 数据要跟主体柱形一致
z: 4, // 数值越大,层级越高,可以盖住下面的图形
},
{
name: "“十四五”目标",
legendHoverLink: false,
type: "bar",
stack: "Ad",
itemStyle: {
color: {
type: "linear",
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: "#82E547", // 渐变顶部色
},
{
offset: 1,
color: "#2FE8E8", // 渐变底部色
},
],
global: false, // 缺省为 false
},
barBorderRadius: [0, 0, 5, 5],
opacity: 0.5,
},
// emphasis: {
// focus: "series",
// },
data: this.data_shisiwu,
},
//十四五顶部圆盘
{
name: "“十四五”目标",
legendHoverLink: false,
symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
tooltip: {
show: false,
},
type: "pictorialBar",
color: "#1ccd88",
itemStyle: {
opacity: 1,
},
symbol: "circle",
symbolSize: ["83%", 20 / 2.5],
symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
data: [
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
{
value: 0,
itemStyle: {
color: "transparent",
},
},
800,
], // 数据要跟主体柱形一致
z: 4, // 数值越大,层级越高,可以盖住下面的图形
},
{
name: "",
type: "bar",
stack: "Ad",
color: "#2d3e53",
legendHoverLink: false,
itemStyle: {
normal: {
barBorderRadius: 20 / 3.5, // 让柱形上下变成圆角
opacity: 0.25,
},
},
emphasis: {
focus: "series",
},
data: [730, 750, 730, 710, 660, 600, 500, 350, 800, 800, 800, 0],
},
//背景阴影圆盘
{
name: "purple",
legendHoverLink: false,
symbolOffset: [0, -3], // 椭圆水平偏移,垂直偏移. 因为不一定正好盖住柱形,所以可能要移动一点点
tooltip: {
show: false,
},
type: "pictorialBar",
color: "#2d3e53",
itemStyle: {
opacity: 0.25,
},
symbol: "circle",
symbolSize: ["83%", 20 / 2.5],
symbolPosition: "end", // 图形边缘与柱子结束的地方内切。
data: [
800,
800,
800,
800,
800,
800,
800,
800,
800,
800,
800,
{
value: 0,
itemStyle: {
color: "transparent",
},
},
], // 数据要跟主体柱形一致
z: 10, // 数值越大,层级越高,可以盖住下面的图形
},
],
tooltip: {
trigger: "axis",
formatter: (item) => {
//将复用的模板字符串封装成函数,这里就相当于tooltip中显示的一行数据如下图
//通过输入val,就能判断这个是series的第几个数据,0 是存量,1是增量,2是十四五
//字符串中出入了三个数据分别用处是:小圆点颜色、数据名、数值,都是能在formatter的params中获取的,我这里命名为item
function str(val) {
return `
<div class='hang'>
<div style="display:flex;align-items: baseline;">
<div class="small" style='background-color:${item[val].color.colorStops[0].color};'></div>
<div style:"float:left">${item[val].seriesName}</div>
</div>
<div style='font-weight:700'>${item[val].value}</div>
</div>
`;
}
//这里判断如果不是2025年就显示 存量和增量
if (item[0].name != "2025") {
return `
<div class='echarts-tooltip'>
${item[0].name}<br>
${str(0)}
${str(1)}
`;
} else {
//如果是2025年就显示 十四五
return `
<div class='echarts-tooltip'>
${item[0].name}<br>
${str(2)}
`;
}
},
},
legend: {
left: "1%",
textStyle: {
fontSize: 10, //字体大小
color: "rgba(255, 255, 255, 0.75)", //字体颜色
},
formatter: (params) => {
if (params == "存量(兆瓦)") {
return "存量";
} else if (params == "增量(兆瓦)") {
return "增量";
} else if (params == "“十四五”目标") {
return params;
}
console.log(params);
},
data: [
{
name: "存量(兆瓦)",
},
{ name: "增量(兆瓦)" },
{ name: "“十四五”目标" },
],
},
grid: {
left: "5%",
right: "",
bottom: "3%",
containLabel: true,
},
xAxis: [
{
type: "category",
axisLabel: {
interval: 0, //数据间隔
// 改变x文字轴颜色
textStyle: {
color: "rgba(255, 255, 255, 0.75)",
fontSize: 10,
},
},
data: [
"2014",
"2015",
"2016",
"2017",
"2018",
"2019",
"2020",
"2021",
"2022",
"2023",
"2024",
"2025",
],
},
],
yAxis: [
{
name: "装机容量(兆瓦)",
nameGap: 28,
nameLocation: "center",
nameTextStyle: {
color: "rgba(255, 255, 255, 0.75)",
fontSize: 10,
// padding: [0, 0, 20, 0],
},
splitLine: {
lineStyle: {
opacity: 0.25,
},
},
type: "value",
axisLabel: {
// 改变x轴文字颜色
textStyle: {
color: "rgba(255, 255, 255, 0.75)",
fontSize: 10,
},
},
},
],
};
后期如果变为动态数据,这里面的data值还要进行变化。
欢迎大家来评论区留言,或者告诉我有那些可以优化的地方(感觉肯定有更方便的方法,只是我没有发现),谢谢大家。