当前位置: 首页 > news >正文

3D柱状图--自定义柱子颜色与legend一致(Vue3)

效果图:

功能:

1、实现3D柱状图

2、自定义柱状图颜色&legend 颜色一致

3、多条柱子展示

代码:

<template><div class="go-bar-3d"><v-chartref="vChartRef":option="option"style="width: 100%; height: 800px"></v-chart></div>
</template><script setup lang="ts">
import { ref, reactive, onMounted } from "vue";
import VChart from "vue-echarts";
import { use } from "echarts/core";
import { CanvasRenderer } from "echarts/renderers";
import { BarChart } from "echarts/charts";
import {DatasetComponent,GridComponent,TooltipComponent,LegendComponent,
} from "echarts/components";
import * as echarts from "echarts";use([DatasetComponent,CanvasRenderer,BarChart,GridComponent,TooltipComponent,LegendComponent,
]);// 获取图表实例
const vChartRef = ref();// 定义数据类型
interface ChartDataItem {x: string;y: number;s: string;
}// 模拟接口数据数组
const chartData = ref<ChartDataItem[]>([{x: "拖欠克扣工资",y: 1700,s: "2022年",},{x: "拖欠克扣工资",y: 1200,s: "2023年",},{x: "街面秩序",y: 2800,s: "2022年",},{x: "街面秩序",y: 2000,s: "2023年",},{x: "房屋交易监管",y: 3700,s: "2022年",},{x: "房屋交易监管",y: 3000,s: "2023年",},{x: "施工管理",y: 3600,s: "2022年",},{x: "施工管理",y: 3000,s: "2023年",},{x: "物管纠纷",y: 4800,s: "2022年",},{x: "物管纠纷",y: 4000,s: "2023年",},{x: "产品质量问题",y: 5700,s: "2022年",},{x: "产品质量问题",y: 5000,s: "2023年",},{x: "事业待遇",y: 1700,s: "2022年",},{x: "事业待遇",y: 1000,s: "2023年",},
]);const offsetX = 10;
const offsetY = 5;// 绘制左侧面
const CubeLeft = echarts.graphic.extendShape({shape: {x: 0,y: 0,},buildPath: (ctx: any, shape: any) => {const xAxisPoint = shape.xAxisPoint;const c0 = [shape.x, shape.y];const c1 = [shape.x - offsetX, shape.y - offsetY];const c2 = [xAxisPoint[0] - offsetX, xAxisPoint[1] - offsetY];const c3 = [xAxisPoint[0], xAxisPoint[1]];ctx.moveTo(c0[0], c0[1]).lineTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).closePath();},
});// 绘制右侧面
const CubeRight = echarts.graphic.extendShape({shape: {x: 0,y: 0,},buildPath: (ctx: any, shape: any) => {const xAxisPoint = shape.xAxisPoint;const c1 = [shape.x, shape.y];const c2 = [xAxisPoint[0], xAxisPoint[1]];const c3 = [xAxisPoint[0] + offsetX, xAxisPoint[1] - offsetY];const c4 = [shape.x + offsetX, shape.y - offsetY];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: (ctx: any, shape: any) => {const c1 = [shape.x, shape.y];const c2 = [shape.x + offsetX, shape.y - offsetY];const c3 = [shape.x, shape.y - offsetX];const c4 = [shape.x - offsetX, shape.y - offsetY];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);// 获取系列名称
const getUniqueSeries = () => {return [...new Set(chartData.value.map((item) => item.s))];
};// 获取X轴值
const getUniqueXValues = () => {return [...new Set(chartData.value.map((item) => item.x))];
};// 定义颜色配置接口
interface ColorConfig {left: [string, string];right: [string, string];top: [string, string];
}// 颜色池
const colorPool: ColorConfig[] = [{left: ["#B8CDE6", "#2963A6"],right: ["#CDE4FF", "#447DBF"],top: ["#CCE4FF", "#CCE4FF"],},{left: ["#FFB6C1", "#FF69B4"],right: ["#FFC0CB", "#FF1493"],top: ["#FFC0CB", "#FFC0CB"],},{left: ["#98FB98", "#3CB371"],right: ["#90EE90", "#2E8B57"],top: ["#AFEEEE", "#AFEEEE"],},{left: ["#FFA07A", "#FF4500"],right: ["#FF7F50", "#FF6347"],top: ["#FFA500", "#FFA500"],},
];// 返回主颜色用于 legend
const getSeriesConfig = (index: number) => {const colorIndex = index % colorPool.length;const offset =index - Math.floor(index / 2) * 2 === 0? -(10 + Math.floor(index / 2) * 5): 10 + Math.floor(index / 2) * 5;return {colors: colorPool[colorIndex],offset: offset,// 提取主颜色用于 legend 显示mainColor: colorPool[colorIndex].top[0],};
};// 获取系列数据
const getSeries = () => {const seriesNames = getUniqueSeries();const xValues = getUniqueXValues();return seriesNames.map((seriesName, index) => {const config = getSeriesConfig(index);return {type: "custom",name: seriesName,// 添加 legend 相关配置legendHoverLink: true,// 为 legend 图标设置颜色itemStyle: {color: config.mainColor,},renderItem: (params: any, api: any) => {const location = api.coord([api.value(0), api.value(1)]);// 根据系列索引调整柱子位置避免重叠const adjustedLocation = [location[0] + config.offset, location[1]];return {type: "group",children: [{type: "CubeLeft",shape: {api,xValue: api.value(0),yValue: api.value(1),x: adjustedLocation[0],y: adjustedLocation[1],xAxisPoint: api.coord([api.value(0), 0]),},style: {fill: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: config.colors.left[0],},{offset: 1,color: config.colors.left[1],},],globalCoord: false,},},},{type: "CubeRight",shape: {api,xValue: api.value(0),yValue: api.value(1),x: adjustedLocation[0],y: adjustedLocation[1],xAxisPoint: api.coord([api.value(0), 0]),},style: {fill: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: config.colors.right[0],},{offset: 1,color: config.colors.right[1],},],globalCoord: false,},},},{type: "CubeTop",shape: {api,xValue: api.value(0),yValue: api.value(1),x: adjustedLocation[0],y: adjustedLocation[1],xAxisPoint: api.coord([api.value(0), 0]),},style: {fill: {type: "linear",x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: config.colors.top[0],},{offset: 1,color: config.colors.top[1],},],globalCoord: false,},},},],};},data: xValues.map((x, i) => {const item = chartData.value.find((d) => d.x === x && d.s === seriesName);return [x, item ? item.y : null];}),};});
};const option = reactive({grid: {top: "15%",left: "10%",bottom: "14%",right: "5%",},tooltip: {trigger: "axis",backgroundColor: "rgba(0,0,0,0.7)",borderWidth: 0,padding: 10,textStyle: {color: "#fff",},axisPointer: {type: "shadow",},},legend: {show: true,textStyle: {color: "#000",},top: "top",// 可选:自定义 legend 图标itemWidth: 30,itemHeight: 18,// 使用自定义 SVG 路径创建圆角矩形icon: "path://M 0 4 C 0 2 2 0 4 0 L 21 0 C 23 0 25 2 25 4 L 25 11 C 25 13 23 15 21 15 L 4 15 C 2 15 0 13 0 11 Z",},xAxis: {type: "category",axisLabel: {textStyle: {color: "#000",fontWeight: 400,fontSize: 12,fontFamily: "PingFangSC-Regular",},interval: 0,},axisTick: {show: false,},axisLine: {show: true,lineStyle: {type: "solid",color: "#DEDEDE",},},data: <any>[],},yAxis: {name: "单位:受理量",nameTextStyle: {color: "#000",fontSize: 12,fontFamily: "AlibabaPuHuiTi_2_55_Regular",fontWeight: 400,},type: "value",splitLine: {show: true,lineStyle: {color: "#ffffff4d",type: "dashed",},},axisTick: {show: false,inside: true,length: 7,},axisLine: {show: true,lineStyle: {color: "rgb(195,213,248)",},},axisLabel: {show: true,textStyle: {color: "#000",fontSize: 14,fontFamily: "ArialMT",fontWeight: 400,},},},series: <any>[],
});// 在组件挂载后初始化图表
onMounted(() => {// 填充xAxis数据option.xAxis.data = getUniqueXValues();// 填充series数据option.series = getSeries();
});
</script><style lang="scss" scoped>
.go-bar-3d {width: 100%;height: 800px;
}
</style>


文章转载自:

http://YJpu9NDp.fmkbk.cn
http://xbMGeP1i.fmkbk.cn
http://BTPw8Fy7.fmkbk.cn
http://ggONzW7J.fmkbk.cn
http://o9fVYyNr.fmkbk.cn
http://PpqyQsep.fmkbk.cn
http://YlEF06Ns.fmkbk.cn
http://mSMQIfS6.fmkbk.cn
http://OSXcEYsT.fmkbk.cn
http://AUP6JvV2.fmkbk.cn
http://DVVRxmFO.fmkbk.cn
http://tzR9GgFd.fmkbk.cn
http://kjqvjyWY.fmkbk.cn
http://SAPGmY0h.fmkbk.cn
http://gPkZ2DA5.fmkbk.cn
http://lXoxcQ5L.fmkbk.cn
http://lgurld3O.fmkbk.cn
http://WkqFemYP.fmkbk.cn
http://7oemEyJI.fmkbk.cn
http://uET3Yzl9.fmkbk.cn
http://3Pv9QvWi.fmkbk.cn
http://0r8c9i9I.fmkbk.cn
http://sGOXair9.fmkbk.cn
http://2OWFLNqV.fmkbk.cn
http://NRWsCPsR.fmkbk.cn
http://VorNjOIe.fmkbk.cn
http://p7m6Kbyn.fmkbk.cn
http://rZalF259.fmkbk.cn
http://PyiIg8W4.fmkbk.cn
http://n9FMeH0x.fmkbk.cn
http://www.dtcms.com/a/377497.html

相关文章:

  • LeetCode热题100--199. 二叉树的右视图--中等
  • Next系统学习(三)
  • Python深度学习:NumPy数组库
  • Django时区感知
  • PostgreSQL15——Java访问PostgreSQL
  • Shell 函数详解
  • 【系统分析师】第21章-论文:系统分析师论文写作要点(核心总结)
  • Linux 命令(top/ps/netstat/vmstat/grep/sed/awk)及服务管理(systemd)
  • 【图像生成】提示词技巧
  • 揭秘Linux:开源多任务操作系统的强大基因
  • (ICLR-2025)深度压缩自动编码器用于高效高分辨率扩散模型
  • 《Why Language Models Hallucinate》论文解读
  • 【机器学习】通过tensorflow实现猫狗识别的深度学习进阶之路
  • AD5362BSTZ电子元器件 ADI 高精度数字模拟转换器DAC 集成电路IC
  • DMA-M2M存储器与存储器之间读写
  • Mistral Document AI已正式登陆Azure AI Foundry(国际版)
  • 机器学习实战(二):Pandas 特征工程与模型协同进阶
  • Flutter 朦胧效果布局大全:5种方法实现优雅视觉层次
  • 【CVPR2023】奔跑而非行走:追求更高FLOPS以实现更快神经网络
  • PHP学习(第三天)
  • 数仓简要笔记-1
  • 机器人商业化落地需要突破的关键性技术
  • AI 技术体系核心概念
  • STM32H750 I2C介绍及应用
  • 计算机网络---物理层
  • 【freemarker】创建html页面
  • 【华为OD】区块链文件转储系统
  • sprintf不是像printf一样的打印函数吗
  • Js 图片加载完成 与 图片缓存加载的区别
  • 汽车动力电池管理系统(BMS):电动汽车的“智能大脑”