立体堆叠柱图的实现

news2025/1/23 22:41:02

立体堆叠柱图实现的实现

实现效果示例:
在这里插入图片描述

1、技术原理

1.1、技术分析

  • 平面上的立体柱图可以看作是由4个平行四边形拼接而成的图形,分别是:
    • 1、顶部菱形
    • 2和3、左右矩形,他们两个色值相同但亮度不同,从而产生立体阴影效果
    • 4、底部菱形,用于产生柱体中间的填角

在这里插入图片描述

  • 分析了立体柱图的组成后,接下来就是如何使用echart提供的配置能力分别渲染出对应的图形,其中:

    • 组成2和3的两个矩形可以看作使用了两种背景色(线性渐变)的普通柱图,因此只需要使用echarts提供的Color对象定义普通柱图的颜色填充即可实现,即series.itemStyle.color

    • 1和4的菱形可以通过echarts提供的象形柱图(pictorialBar)的diamond菱形实现,底部的菱形是为了产生折角效果。

  • 另外,如果是堆叠柱图,为了使上下柱连接处也呈现立体折角效果,还需要在连接处也添加一个菱形,该菱形的颜色与上柱颜色相同。

在这里插入图片描述

1.2、pictorialBar象形柱图

象形柱图是echarts提供的一种2d图表,它以标准的矩形柱图为容器,允许我们通过配置symbol的方式在容器中实现个性化的图形效果,类比起来相当于图标按钮或图片按钮的实现思路。象形柱图的主要配置项如下:

  • symbol:图形类型,echarts提供了多种symbol类型标记,包括内置的cicle圆rect矩形diamond菱形arrow箭头等,还支持自定义的图片url和svg图形。

  • symbolSize:图形尺寸,值为 [w, h] 分别表示宽和高,可以是具体值,也可以是百分百值。当为百分百值是基于基准柱尺寸(的宽和高)计算,基准柱就是原始的矩形柱图。

  • symbolPosition:基于基准柱的图形对齐定位,可取值start(默认),end,center,与flex的justfy-content效果类似,基准柱相当于flex容器。

  • symbolOffset:图形相对与基准定位的偏移量,值为 [left, top] ,可以是具体值,也可以是(相对自身尺寸的)百分比。

  • symbolRotate:图形绕自身旋转角度

  • symbolRepeat:图形是否可以重复,如果为true可以产生类似rate评分的效果

  • symbolRepeatDirection:重复方向

  • symbolClip:是否剪切图形,如果为true,则根据基准值symbolBoundingData进行比例裁剪显示。echarts的示例人体含水比例即采用了本属性。

1.3、Color对象

Color是echarts提供的通用调色板对象,echarts实例可以配置全局color数组作为图表的默认颜色集,用于诸如饼图等多色场景。同时Color也用在各种可以独立设置的颜色的场合,如series的itemStyle中。

color支持RGBA的纯色和渐变/纹理填充两种格式。

线性渐变配置说明

  • type:linear

  • x,y,x2,y2:取值范围 0 - 1,表示颜色在图形容器中的百分比,用于表示渐变方向,也就是css linear-gradient的第一个参数,其中x表示左,x2表示右,y表示上,y2表示下。例如:

    • x:0,y:0,x2:0,y2:1:表示从上到下

    • x:0,y:1,x2:0,y2:0:表示从下到上

    • x:0,y:0,x2:1,y2:0:从左到右

    • x:1,y:0,x2:0,y2:0:从右到左

  • colorStops:颜色段点,也就是css linear-gradient后面的参数组

2、实现过程

以下代码演示包含两段柱的立体堆叠柱图的实现。

  • 1、计算堆叠柱图总高度,目的是为了获得顶部菱形的位置

  • 2、声明普通堆叠柱图的颜色,要一半深色一半浅色,从而模拟柱子的两条边

  • 3、处理当上半柱或者下半柱高度为0的特殊情况下顶部和底部菱形的展示形态,当要堆叠的柱子超过两个时,情况会更加复杂一些,本示例不涉及。

  • 4、声明图形的series集合,整个立体堆叠柱图由两个普通堆叠柱图和3个象形柱图(菱形)构成,要注意各图的z-index值(z)

完整示例代码如下:

  import * as echarts from 'echarts';

  const ups = [80, 200, 90, 140, 70, 80, 0];
  const downs = [120, 300, 150, 300, 270, 0, 100];
  const xData = ['1月', '2月', '3月', '4月', '5月', '6月', '7月'];

  // 声明柱图基准宽度
  const baseWidth = 40;

  // 1、计算柱图总高度
  const sum = ups.map((item, index) => item + downs[index]);

  // 2、声明主体柱图的同色值不同亮度的线性渐变,由于要配合菱形,
  // 双色渐变的两色各占一半
  const color = [
    {
      type: "linear",
      x: 0,
      x2: 1,
      y: 0,
      y2: 0,
      colorStops: [
        {
          offset: 0,
          color: "#54a2d3", // 青蓝
        },
        {
          offset: 0.5,
          color: "#54a2d3",
        },
        {
          offset: 0.5,
          color: "#7ed1e3", // 青绿
        },
        {
          offset: 1,
          color: "#7ed1e3",
        },
      ],
    },
    {
      type: "linear",
      x: 0,
      x2: 1,
      y: 0,
      y2: 0,
      colorStops: [
        {
          offset: 0,
          color: "#a3a418", // 深棕
        },
        {
          offset: 0.5,
          color: "#a3a418",
        },
        {
          offset: 0.5,
          color: "#cdbf38", // 浅棕
        },
        {
          offset: 1,
          color: "#cdbf38",
        },
      ],
    },
  ];

  const bottomDiamond = [];
  const midDiamond = [...downs];
  const topDiamond = [];

  // 3、计算顶部菱形和底部菱形颜色及位置
  for (let i = 0; i < sum.length; i++) {
    // 总长度等于0,则什么上下菱形都不显示
    if (sum[i] <= 0) {
      bottomDiamond.push(0);
      topDiamond.push({
        value: 1,
        itemStyle: {
          borderColor: '#rgba(0,0,0,0)',
          borderWidth: 2,
          color: '#rgba(0,0,0,0)'
        }
      });
    } else {
      // ↓计算底部折角
      // 如果柱子只有上半段,则底部菱形颜色要与上段颜色相同
      if (sum[i] === ups[i]) {
        bottomDiamond.push({
          value: 1, // 底部菱形高度为1
          itemStyle: {
            normal: {
              color: color[1] // 专门设置颜色
            }
          }
        })
      } else {
        // 否则底部菱形颜色与下段颜色相同
        bottomDiamond.push(1);
      }

      // ↓计算顶部菱形
      // 如果柱子存在上半段,则顶部菱形颜色与上段相近
      if (ups[i] > 0) {
        topDiamond.push({
          value: sum[i], // 顶部菱形所属标准柱的高度为堆叠柱图总高度
          itemStyle: {
            normal: {
              borderColor: "#e9d86c", // 黄棕
              borderWidth: 2,
              color: "#e9d86c",
            }
          }
        });
      } else {
        // 如果柱子只有下半段,则顶部菱形颜色与下段相近
        topDiamond.push({
          value: sum[i],
          itemStyle: {
            normal: {
              borderColor: "#89e3ec", // 浅绿
              borderWidth: 2,
              color: "#89e3ec",
            }
          }
        });

        // 去掉中间菱形
        midDiamond[i] = '';
      }
    }
  }

    const dom = document.getElementById('chart');
    const chart = echarts.init(dom);

    const option = {
      xAxis: {
        type: 'category',
        data: xData
      },
      yAxis: {
        type: 'value'
      },
      legend: {
        data: [
          {
            name: '已处理',
            itemStyle: {
              color: '#a3a418'
            }
          },  
          {
            name: '未处理',
            itemStyle: {
              color: '#54a2d3'
            }
          }
        ],
        right: 20,
        selectedMode: false // 关闭图例可点击功能,防止菱形被晾出来
      },
      series: [
        // 基础下段
        {
          z: 1,
          name: '已处理',
          type: 'bar',
          barWidth: baseWidth,
          stack: 'sum',
          itemStyle: {
            color: color[0]
          },
          data: downs
        },
        // 基础上段
        {
          z: 2,
          name: '未处理',
          type: 'bar',
          barWidth: baseWidth,
          stack: 'sum',
          itemStyle: {
            color: color[1]
          },
          data: ups
        },
        // 底部菱形,用于产生底座处的折线效果
        {
          z: 3,
          name: 'all',
          type: 'pictorialBar',
          data: bottomDiamond,
          symbol: 'diamond',
          symbolOffset: ['0%', '50%'], // 下移50%,产生底部填角
          symbolSize: [baseWidth, 10], // 上下菱形的尺寸保持一致
          itemStyle: {
            color: color[0] // 颜色与下段柱保持一致
          },
          tooltip: {
            show: false
          }
        },
        // 中间连接处菱形,用于产生上下段连接处的折线效果
        {
          z: 4,
          name: 'all',
          type: 'pictorialBar',
          data: midDiamond,
          symbol: 'diamond',
          symbolPosition: 'end',
          symbolOffset: ['0%', '-50%'],
          symbolSize: [baseWidth, 10],
          itemStyle: {
            normal: {
              color: color[1]
            }
          }
        },
        // 顶部菱形
        {
          z: 5,
          name: 'all',
          type: 'pictorialBar',
          data: topDiamond,
          symbol: 'diamond',
          symbolPosition: 'end',
          symbolOffset: ['0%', '-65%'],
          symbolSize: [baseWidth - 4, (10 * (baseWidth - 4)) / baseWidth],
          tooltip: {
            show: false,
          }
        }
      ]
    };

    chart.setOption(option);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/468443.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国内也能畅玩gptchat,游玩攻略分享

看到很多人都不知道怎么玩gptchat&#xff0c;小编就不能忍了&#xff0c;其实要玩chatgpt是非常的简单的&#xff0c;完全是能免费体验chatgpt的强大的。下面我们一起来了解一下国内也能畅玩gptchat&#xff0c;游玩攻略分享。 一.Chatgpt国内为啥能玩 其实现在很多的程序都接…

人人都能升薪?深扒Android开发中的通天神器Framework

近年来&#xff0c;客户端领域的竞争日益激烈&#xff0c;很多安卓开发者抱怨内卷现象普遍存在。在这种背景下&#xff0c;开发者们面对的压力越来越大&#xff0c;很难掌握足够的技能去顺利发展。解决内卷&#xff0c;突破迷茫&#xff0c;是许多开发者面临的挑战。小米的高管…

win 10电脑无法修改etc下文件的解决方法

不说废话&#xff0c;直接用etc下面的networks文件来举例子&#xff0c;当我想要修改该文件并重新保存的时候提示与管理员联系获得权限&#xff0c;解决方式如下&#xff1a; 首先&#xff0c;选中需要修改的networs文件&#xff0c;右键“属性”&#xff1b; 找到“安全”&…

3.软考——操作系统章节

操作系统章节 1.进程管理 银行家算法见博客 2.存储管理 1.页式存储 状态位为0的表示不在内存中&#xff0c;状态位为1的表示在内存中 如果不在内存中的要进入内存&#xff0c;需要去干掉再内存中的 原则&#xff1a; 1.一定是状态位位1的&#xff1b;然后再看访问位&#…

玩转smardaten | 探秘画布能力,搞定无代码复杂页面设计

下面这些是你印象中无代码能配置出的页面吗&#xff1f;“条条框框”、“一板一眼”的基础表单、列表、详情是无代码页面开发的全部吗&#xff1f; 当然不是&#xff01;花样排版与自由布局的展示页、交互丰富与多模块嵌套的首页&#xff0c;也是企业级软件页面中不可或缺的一部…

mybatis generator自定义model的代码注释

mbg相信大家都比较熟悉&#xff0c;可以自动化的生成数据库表对应的model&#xff0c;mapper。但是最近在使用mbg的时候遇到了这样的问题&#xff1a; 1、生成的model虽然可以根据数据库字段的comment生成注释&#xff0c;但这些注释仅对后端开发人员可见&#xff0c;如果想让前…

HNU-计算机系统-实验3-BombLab

写在前面 首先要感谢A橙_大佬&#xff0c;在之前的实验以及学习中&#xff0c;许多地方参考与学习了大佬的思路。 本次实验也是听取了A橙_大佬的建议&#xff0c;先自己做一遍&#xff0c;再看答案&#xff0c;有了更进一步的深入理解。 最后在验收的时候&#xff0c;发现验…

“豪”秀上演——莱佛士学生作品精彩亮相施华蔻发布会

4月12日&#xff0c;一场美轮美奂的视觉盛宴——施华蔻专业2023春夏新季风发布会&#xff0c;在广州珠江琶醍啤酒文化创意艺术区盛大举行。 ▲施华蔻专业2023春夏新季风发布会现场 当天发布会以《重组新生》为主题&#xff0c;施华蔻将潮流趋势、前沿发艺与先锋科技相结合&…

c++中set_difference这个函数的意义和用法

今天正好碰到了这个函数&#xff0c;虽然大概可以猜出这个函数的作用&#xff0c;但是仍然期待一个通俗易懂的解释&#xff0c;网上搜索了一下&#xff0c;搜到百度百科&#xff0c;感觉没有抓住重点&#xff0c;虽然示例也勉强可以理解&#xff0c;但是总感觉讲究不够直观。 …

【PLC】贝加莱PLC理论及实操年度培训

最近在进行PLC培训&#xff0c;主要是贝加莱PLC产品的学习&#xff0c;学习了上下位机的一些基本操作&#xff0c;能够进行一些简单的实践&#xff0c;最后顺利通过年度考核。 0 引言 PLC&#xff1a;可编程逻辑控制器&#xff0c;由CPU、存储器、输入输出接口、电影以及外部设…

冬奥会传统文化管理系统【GUI/Swing+MySQL】(Java课设)

系统类型 Swing窗口类型Mysql数据库存储数据 使用范围 适合作为Java课设&#xff01;&#xff01;&#xff01; 部署环境 jdk1.8Mysql8.0Idea或eclipsejdbc 运行效果 本系统源码地址&#xff1a;https://download.csdn.net/download/qq_50954361/87720226 更多系统资源库…

Access Token 访问令牌 的获取与使用

一、引用 三方库导入时&#xff0c;通常需要输入账号和令牌进行鉴权。账号为指定平台的 HTTP 克隆账号&#xff0c;访问令牌即 Access Token&#xff0c;本文介绍如何获取常见三方代码平台的Access Token。 Access Token 通常在代码平台的个人账号设置内进行管理和配置&#xf…

C++ 树进阶系列之探讨深度搜索算法查找环的细枝末节

1. 前言 对于基环树的讲解&#xff0c;分上、下 2 篇&#xff0c;上篇以理解连通分量、环以及使用深度搜索算法检查连通性和环为主&#xff0c;下篇以基于基环树结构的应用为主。 什么是基环树&#xff1f; 所谓基环树指由n个节点n条边所构建而成的连通图。 如下图所示&…

[Java 数据结构] 反射、枚举和lambda表达式

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了 博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点!人生格言&#xff1a;当你的才华撑不起你的野心的时候,你就应该静下心来学习! 欢迎志同道合的朋友一起加油喔&#x1f9be;&am…

集成学习随机森林

集成学习 集成学习分为三类算法&#xff1a; 装袋法&#xff08;Bagging&#xff09;&#xff0c;提升法&#xff08;Boosting&#xff09;和融合stacking。 Bagging&#xff1a;核心思想是构建多个相互独立的评估器&#xff0c;然后对其预测进行平均或多数表决原则来决定集成…

极客星球|数据分析引擎黑马ClickHouse技术研究与实践

ClickHouse 在近几年是大数据分析引擎界的一匹黑马&#xff0c;从默默无闻到一路起飞&#xff0c;在 DB engine Rank 上进入前50名&#xff0c;成为全球数据引擎界耀眼的一颗明星。在全球范围内&#xff0c;ClickHouse 单表查询比其他引擎要快数倍以上&#xff0c;在过去的几年…

Vue+Echart实现利用率表盘效果【组件已封装,可直接使用】

效果演示 当利用超过70%&#xff08;可以自行设置&#xff09;&#xff0c;表盘变红 组件 里面对应两个图片资源&#xff0c;panelBackground_red.png 和 panelBackground_green.png&#xff0c;请前往百度网盘进行下载。如果喜欢其他颜色&#xff0c;可以使用.psd来修改导出…

redis从头开始【一】--面试的小伙伴必看

一 什么是NoSQL&#xff1f; Nosql not only sql&#xff08;不仅仅是SQL&#xff09; 关系型数据库&#xff1a;列行&#xff0c;同一个表下数据的结构是一样的。 非关系型数据库&#xff1a;数据存储没有固定的格式&#xff0c;并且可以进行横向扩展。 NoSQL泛指非关系型…

10.Yarn概述

如果说HDFS是存储&#xff0c;则Yarn就是cpu和内存&#xff0c;mapreduce就是程序。 1.基础架构 复习&#xff1a; 1.Container就是一个容器&#xff0c;其中封装了需要使用的内存与cpu 2.每当提交一个job,就会产生一个appMaster(总指挥),app Master负责其他container里面的…

【分布式技术专题】「分布式技术架构」手把手教你如何开发一个属于自己的Redis延时队列的功能组件

手把手教你如何开发一个属于自己的延时队列的功能组件 前提介绍解决痛点延时队列组件的架构延时队列组件的初始化流程延时队列组件的整体核心类架构延时队列组件的整体核心类功能 延时队列的开发组件延迟队列的机制配置初始化类源码 - DelayedQueueConfigurationRedission客户端…