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

echarts使用自定义图形实现3D柱状图

先看下效果吧

custom3dBar

实现思路

  1. 使用graphic创建并注册自定义图形。根据每组的数据值,得到一个对应的点,从点出发用canvas绘制一组图形,分别为
    顶部的菱形
    top
    const CubeTop = echarts.graphic.extendShape({buildPath: function (ctx, shape) {const c1 = [shape.x, shape.y]; // 下const c2 = [shape.x + 9, shape.y - 7]; // 右const c3 = [shape.x, shape.y - 12]; // 上const c4 = [shape.x - 9, shape.y - 7]; // 左ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();}
    });
    
    左侧的四边形 left
    const CubeLeft = echarts.graphic.extendShape({buildPath: function (ctx, shape) {const xAxisPoint = shape.xAxisPoint;const c0 = [shape.x, shape.y]; // 右上const c1 = [shape.x - 9, shape.y - 7]; //左上const c2 = [xAxisPoint[0] - 9, xAxisPoint[1] - 6]; // 左下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();}
    });
    
    右侧的四边形
    right
    const CubeRight = echarts.graphic.extendShape({buildPath: function (ctx, shape) {const xAxisPoint = shape.xAxisPoint;const c1 = [shape.x, shape.y]; // 左上const c2 = [xAxisPoint[0], xAxisPoint[1]]; // 左下const c3 = [xAxisPoint[0] + 9, xAxisPoint[1] - 7]; //右下const c4 = [shape.x + 9, shape.y - 7]; // 右上ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();}
    });
    
  2. 用series自定义系列(custom)的renderItem将这一组图形元素返回,组合形成3D柱状图

代码实现

<template><div id="graphicBar"></div>
</template><script setup>import {reactive, onMounted} from 'vue'import * as echarts from "echarts";const barData = reactive({xAxis: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],data: [200, 180, 120, 220, 80, 160, 150]})const customShape = () => {// 创建自定义的shape类型const CubeLeft = echarts.graphic.extendShape({buildPath: function (ctx, shape) {const xAxisPoint = shape.xAxisPoint;const c0 = [shape.x, shape.y]; // 右上const c1 = [shape.x - 9, shape.y - 7]; //左上const c2 = [xAxisPoint[0] - 9, xAxisPoint[1] - 6]; // 左下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({buildPath: function (ctx, shape) {const xAxisPoint = shape.xAxisPoint;const c1 = [shape.x, shape.y]; // 左上const c2 = [xAxisPoint[0], xAxisPoint[1]]; // 左下const c3 = [xAxisPoint[0] + 9, xAxisPoint[1] - 7]; //右下const c4 = [shape.x + 9, shape.y - 7]; // 右上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({buildPath: function (ctx, shape) {const c1 = [shape.x, shape.y]; // 下const c2 = [shape.x + 9, shape.y - 7]; // 右const c3 = [shape.x, shape.y - 12]; // 上const c4 = [shape.x - 9, shape.y - 7]; // 左ctx.moveTo(c1[0], c1[1]).lineTo(c2[0], c2[1]).lineTo(c3[0], c3[1]).lineTo(c4[0], c4[1]).closePath();}});// 注册创建的自定义的shape类型echarts.graphic.registerShape('CubeLeft', CubeLeft);echarts.graphic.registerShape('CubeRight', CubeRight);echarts.graphic.registerShape('CubeTop', CubeTop);}const draw_bar = () => {customShape()const option = {xAxis: {data: barData.xAxis,axisLabel: {fontSize: 12,color: '#FFFFFF'},axisLine: {lineStyle: {color: '#3A4547',}},axisTick: {show: false}},yAxis: {type: 'value',axisLabel: {fontSize: 12,color: '#A8B5C1'},splitLine: {lineStyle: {color: ['#303638'],type: 'dashed'}}},grid: {containLabel: true,top: 10,bottom: 0,right: 0,left: 0},series: [        {type: 'custom',renderItem: (params, api) => {// coord 将数据值映射到坐标系上// api.value 给定维度的数据值const location = api.coord([api.value(0), api.value(1)]);return {type: 'group',children: [{type: 'CubeLeft',shape: {api,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: 'rgba(35, 153, 254, 1)'},{offset: 1,color: 'rgba(70, 207, 255, 1)'},])}},{type: 'CubeRight',shape: {api,x: location[0], // 中间上的xy: location[1], // 中间上的yxAxisPoint: api.coord([api.value(0), 0]) // 中间下},style: {fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0,color: 'rgba(32, 147, 255, 1)'},{offset: 1,color: 'rgba(71, 237, 255, 1)'},])}},{type: 'CubeTop',shape: {api,x: location[0],y: location[1],},style: {fill: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0,color: 'rgba(107, 230, 254, 1)'},{offset: 1,color: 'rgba(48, 211, 255, 1)'}])}}]};},data: barData.data}]};return option}const chart_init = () => {let curChart = echarts.init(document.getElementById('graphicBar'))const exampleOption = draw_bar()curChart.setOption(exampleOption);}onMounted(() => {chart_init()})
</script><style scoped>#graphicBar{width: 460px;height: 300px;}
</style>

补充说明

  1. 以上内容是vite构建的vue3项目
  2. echarts版本5.5.1

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • (day18) leetcode 204.计数质数
  • 如何在idea安装git,使用gitee?
  • Pip换源:加速Python包安装的神操作,你get了吗?
  • Python与自动化脚本编写
  • 7.16做题总结
  • 昇思25天学习打卡营第19天|基于MobileNetv2的垃圾分类
  • LabVIEW阀门运动PCT测试
  • Knife4j的原理及应用详解(五)
  • [图解]SysML和EA建模住宅安全系统-14-黑盒系统规约
  • Python爬虫速成之路(2):爬天气情况
  • 机器学习——决策树(笔记)
  • 13--memcache与redis
  • 配置Redis时yml的格式导致报错
  • PostgreSQL 中如何处理数据的并发读写和锁等待超时?
  • dxf数据结构
  • 【Amaple教程】5. 插件
  • 0基础学习移动端适配
  • Bootstrap JS插件Alert源码分析
  • css系列之关于字体的事
  • CSS中外联样式表代表的含义
  • express + mock 让前后台并行开发
  • iBatis和MyBatis在使用ResultMap对应关系时的区别
  • Java 23种设计模式 之单例模式 7种实现方式
  • laravel5.5 视图共享数据
  • mysql外键的使用
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • vue中实现单选
  • 阿里云应用高可用服务公测发布
  • 爱情 北京女病人
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 如何使用 JavaScript 解析 URL
  • 入门到放弃node系列之Hello Word篇
  • 小程序测试方案初探
  • 小试R空间处理新库sf
  • 鱼骨图 - 如何绘制?
  • 怎样选择前端框架
  • TPG领衔财团投资轻奢珠宝品牌APM Monaco
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • ​补​充​经​纬​恒​润​一​面​
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #php的pecl工具#
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • (13):Silverlight 2 数据与通信之WebRequest
  • (zt)最盛行的警世狂言(爆笑)
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (接口自动化)Python3操作MySQL数据库
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (一)Docker基本介绍
  • (一)Kafka 安全之使用 SASL 进行身份验证 —— JAAS 配置、SASL 配置
  • (转) Android中ViewStub组件使用
  • (转)VC++中ondraw在什么时候调用的
  • (轉貼) 蒼井そら挑戰筋肉擂台 (Misc)
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全
  • .NET 8.0 发布到 IIS
  • .net framework 4.0中如何 输出 form 的name属性。