echarts的柱状图的重叠和堆叠实现两个柱体的显示和之前的差值显示

news2024/12/23 8:58:54

效果图
在这里插入图片描述

主要思路

准备三个柱体(原计划,实际进度,差值)
原计划和实际进度设置成重叠

          {
            barWidth: 20,
            // yAxisIndex: 1,
            z: 1,
            name: '原计划',
            type: 'bar',
            stack: 'ab',
            emphasis: { // 点击柱体其他柱体颜色会变浅
              disabled: true
            },
            label: {
              show: true
            },
            itemStyle: {
              emphasis: {
                barBorderRadius: 10
              },
              normal: {
                barBorderRadius: 10
              }
            },
            data: this.planProcessData.map((item) => {
              return {
                value: item,
                label: {
                  show: !(item < 10),
                  formatter: item + '%',
                  position: 'insideRight',
                  textStyle: {
                    color: '#262626',
                    fontSize: 12
                  }
                }
              }
            })
          },
 {
            barGap: '-100%', /* 可以重叠*/
            barWidth: 20,
            yAxisIndex: 0,
            z: 2,
            itemStyle: {
              emphasis: {
                barBorderRadius: 10
              },
              normal: {
                barBorderRadius: 10
              }
            },
            data: this.realityProcessData.map((item) => {
              return {
                value: item,
                label: {
                  show: true,
                  formatter: item + '%',
                  position: item < 10 ? 'right' : 'insideRight',
                  textStyle: {
                    color: '#262626',
                    fontSize: 12
                  }
                }
              }
            }),
            type: 'bar',
            label: {
              show: true
            },
            emphasis: { // 点击柱体其他柱体颜色会变浅
              disabled: true
            },
            name: '实际进度'
          }

将实际进度的 barGap: ‘-100%’, 就可以重叠啦

然后设置差值柱体

{
            barWidth: 20,
            // yAxisIndex: 1,
            z: 1,
            stack: 'ab', // 这个保持一样就可以堆叠
            data: this.differenceData.map((item) => {
              return {
                value: item,
                label: {
                  show: true,
                  formatter: (params) => { // 核心部分 formatter 可以为字符串也可以是回调
                    // var that = this
                    // console.log('0904', this.differenceData)
                    if (params.value) { // 如果当前值存在则拼接
                      return '↓' + ' ' + '-' + params.value + '%'
                    } else { // 否则返回个空
                      return ''
                    }
                  },
                  position: 'insideLeft',
                  textStyle: {
                    color: '#E20000',
                    fontSize: 12
                  }
                }
              }
            }),
            type: 'bar',
            emphasis: { // 点击柱体其他柱体颜色会变浅
              disabled: true
            },
            label: {
              show: true
            },
            name: '差值'
          },

要使差值跟原计划堆叠,他们要是设置 stack: ‘ab’, 这个保持一样就可以堆叠,然后将差值柱体的背景颜色白色
在这里插入图片描述

然后将显示的值的位置position改为insideLeft
在这里插入图片描述

就可以实现上面的效果啦

3.要是重叠的两个柱体不完全重叠

效果在这里插入图片描述

要在原计划设置宽度
在这里插入图片描述

再实际进度中宽度要设置小一点,并且重合度80%
在这里插入图片描述

4.设置最大度是100%,但是内容可以超过

在这里插入图片描述
这样子就可以显示出来
在这里插入图片描述

补充

1.如果你想在这里使用this,一定要弄箭头函数

在这里插入图片描述

2.如果你想要鼠标移到柱体上去,其他一些柱体不会透明

在这里插入图片描述

要在在每个柱体里设置
在这里插入图片描述

3.给柱状图添加点击事件

在这里插入图片描述

点击事件函数里面也是不能直接获取到this,需要let that = this

完整代码

initData() {
      const PieEchartBox = this.$refs.projectChart
      const myPieEchart = this.$echarts.init(PieEchartBox)
      myPieEchart.setOption({
        color: ['#E3F1FF', '#fff', '#1CCBD3'],
        legend: {
          data: ['原计划', '差值', '实际进度'],
          show: false
        },
        tooltip: {
          trigger: 'axis',
          valueFormatter: function(value) { // 里面的值加内容
            return value + '%'
          },
          axisPointer: {
            type: 'shadow'
          },
          formatter: "<div style='display:block;word-break: break-all;word-wrap: break-word;white-space:pre-wrap;margin-bottom: 10px'>" + '{b}' + '</div>' +
                                "<div style='display: flex;justify-content: space-between;'><div style='display: flex;align-items: center;'><div style='border-radius: 50%;width: 8px;height: 8px;background: #7ECAD3;margin-right: 10px'></div>" + '<span>' + '{a0}' + '</span></div><div>{c0}%</div></div>' +
                                "<div style='display: flex;justify-content: space-between;'><div style='display: flex;align-items: center;'><div style='border-radius: 50%;width: 8px;height: 8px;background: #5682cc;margin-right: 10px'></div>" + '<span>' + '{a2}' + '</span></div><div>{c2}%</div></div>'
        },
        grid: {
          left: '10',
          right: '4%',
          bottom: '3%',
          containLabel: true
        },
        yAxis: [{
          type: 'category',
          axisTick: 'none',
          axisLine: 'none',
          data: this.topicNameData,
          axisLabel: {
            margin: 10,
            interval: 0,
            lineHeight: 18,
            textStyle: {
              fontSize: 14,
              color: '#666666'
            },
            formatter: function(value) {
              var ret = ''// 拼接加\n返回的类目项
              var valLength = value.length// X轴类目项的文字个数
              var maxLength = 10 // 每项显示文字个数
              var rowN = Math.ceil(valLength / maxLength) // 类目项需要换行的行数
              if (rowN > 1) { // / 如果类目项的文字大于3,
                for (var i = 0; i < rowN && i < 2; i++) {
                  var temp = ''// 每次截取的字符串
                  var end = ''
                  var start = i * maxLength// 开始截取的位置
                  if (i === 1 && valLength > 20) {
                    end = start + 9// 结束截取的位置
                  } else {
                    end = start + maxLength// 结束截取的位置
                  }
                  // 这里也可以加一个是否是最后一行的判断,但是不加也没有影响,那就不加吧
                  if (i === 1 && valLength > 20) {
                    temp = value.substring(start, end) + '...'// 结束截取的位置
                  } else {
                    temp = value.substring(start, end) + '\n'// 结束截取的位置
                  }
                  ret += temp // 凭借最终的字符串
                }
                return ret
              } else {
                return value
              }
            }
          }
        },
        {
          show: false,
          type: 'category',
          axisTick: 'none',
          data: [],
          axisLine: 'none'
        }],
        xAxis: {
          type: 'value',
          interval: 10,
          max: 100.1, // 为了然差值显示出来
          axisLabel: {
            show: true,
            textStyle: {
              fontSize: 10
            },
            itemWidth: 123,
            formatter: '{value}%' // 给Y轴数值添加百分号
          },
          position: 'top'
        },

        series: [
          {
            barWidth: 20,
            // yAxisIndex: 1,
            z: 1,
            name: '原计划',
            type: 'bar',
            stack: 'ab',
            emphasis: { // 点击柱体其他柱体颜色会变浅
              disabled: true
            },
            label: {
              show: true
            },
            itemStyle: {
              emphasis: {
                barBorderRadius: 10
              },
              normal: {
                barBorderRadius: 10
              }
            },
            data: this.planProcessData.map((item) => {
              return {
                value: item,
                label: {
                  show: !(item < 10),
                  formatter: item + '%',
                  position: 'insideRight',
                  textStyle: {
                    color: '#262626',
                    fontSize: 12
                  }
                }
              }
            })
          },
          {
            barWidth: 20,
            // yAxisIndex: 1,
            z: 1,
            stack: 'ab', // 这个保持一样就可以堆叠
            data: this.differenceData.map((item) => {
              return {
                value: item,
                label: {
                  show: true,
                  formatter: (params) => { // 核心部分 formatter 可以为字符串也可以是回调
                    // var that = this
                    // console.log('0904', this.differenceData)
                    if (params.value) { // 如果当前值存在则拼接
                      return '↓' + ' ' + '-' + params.value + '%'
                    } else { // 否则返回个空
                      return ''
                    }
                  },
                  position: 'insideLeft',
                  textStyle: {
                    color: '#E20000',
                    fontSize: 12
                  }
                }
              }
            }),
            type: 'bar',
            emphasis: { // 点击柱体其他柱体颜色会变浅
              disabled: true
            },
            label: {
              show: true
            },
            name: '差值'
          },
          {
            barGap: '-100%', /* 可以重叠*/
            barWidth: 20,
            yAxisIndex: 0,
            z: 2,
            itemStyle: {
              emphasis: {
                barBorderRadius: 10
              },
              normal: {
                barBorderRadius: 10
              }
            },
            data: this.realityProcessData.map((item) => {
              return {
                value: item,
                label: {
                  show: true,
                  formatter: item + '%',
                  position: item < 10 ? 'right' : 'insideRight',
                  textStyle: {
                    color: '#262626',
                    fontSize: 12
                  }
                }
              }
            }),
            type: 'bar',
            label: {
              show: true
            },
            emphasis: { // 点击柱体其他柱体颜色会变浅
              disabled: true
            },
            name: '实际进度'
          }
        ]
      })
      const that = this
      myPieEchart.on('click', function(param) {
        console.log('1019', that.dictTypeTopicList, param)
        let topicType = ''
        that.dictTypeTopicList.forEach((res) => {
          if (param.name === res.label) {
            topicType = res.value
            return
          }
        })
        that.$router.push({
          path: '/projectDetails',
          query: {
            topicName: param.name,
            topicType: topicType
          }
        })
      })
    }

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

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

相关文章

山西电力市场日前价格预测【2023-10-27】

日前价格预测 预测说明&#xff1a; 如上图所示&#xff0c;预测明日&#xff08;2023-10-27&#xff09;山西电力市场全天平均日前电价为347.06元/MWh。其中&#xff0c;最高日前电价为618.09元/MWh&#xff0c;预计出现在18: 15。最低日前电价为163.49元/MWh&#xff0c;预计…

VM虚拟机的安装与配置及操作系统的安装

目录 一.操作系统 1.简介 2.常见操作系统 2.1 windows操作系统 2.2 UNIX操作系统 2.3 linux操作系统 2.4 mac操作系统 2.5 嵌入式操作系统 3.个人版本和服务器版本的区别 4.Linux的版本介绍 4.1 Debian 4.2 Ubuntu 4.3 Redhat 4.4 Fedora 4.5 centos 二.VM虚拟…

微前端系列-样式隔离、元素隔离

样式隔离问题 各个应用之间可能相互设置标签样式&#xff0c;会相互影响&#xff0c;或者影响全局样式&#xff0c;比如应用A给body设置样式&#xff0c;应用B也给body设置样式 方法一 样式增加不同前缀 每个应用通过前缀独立区分开&#xff0c;京东micro-app默认是采用的这…

pika皮卡丘RCE靶场

pika |拼接命令&#xff0c;直接 find 寻找根目录下的文件&#xff0c;使用 grep 过滤 127.0.0.1 | find / | grep flag

超声电机工作原理

超声波电机的工作原理 在压电陶瓷振子上加高频交流电压时&#xff0c;利用逆压电效应或电致伸缩效应使定子产生微观机械振动。并将这种振动通过共振放大和摩擦耦合变换成旋转或直线型运动。 超声波驱动有两个前提条件&#xff1a; 需在定子表面激励出稳态的质点椭圆运动轨迹…

NTP(Network Time Protocol 网络时间协议)

作用 大数据产生与处理系统是各种计算设备集群的&#xff0c;计算设备将统一、同步的标准时间用于记录各种事件发生时序&#xff0c;如 E-MAIL 信息、文件创建和访问时间、数据库处理时间等。大数据系统内不同计算设备之间控制、计算、处理、应用等数据或操作都具有时序性&…

荣耀推送服务消息分类标准

前言 为了提升终端用户的推送体验、营造良好可持续的通知生态&#xff0c;荣耀推送服务将对推送消息进行分类管理。 消息分类 定义 荣耀推送服务将根据应用类型、消息内容和消息发送场景&#xff0c;将推送消息分成服务通讯和资讯营销两大类别。 服务通讯类&#xff0c;包…

如何在宝塔面板安装配置MySQL数据库并实现公网访问

宝塔安装MySQL数据库&#xff0c;并内网穿透实现公网远程访问 文章目录 宝塔安装MySQL数据库&#xff0c;并内网穿透实现公网远程访问前言1.Mysql服务安装2.创建数据库3.安装cpolar3.2 创建HTTP隧道 4.远程连接5.固定TCP地址5.1 保留一个固定的公网TCP端口地址5.2 配置固定公网…

【科普】干货!带你从0了解移动机器人(六) (底盘结构类型)

牵引式移动机器人&#xff08;AGV/AMR&#xff09;&#xff0c;通常由一个牵引车和一个或多个被牵引的车辆组成。牵引车是机器人的核心部分&#xff0c;它具有自主导航和定位功能&#xff0c;可以根据预先设定的路径或地标进行导航&#xff0c;并通过传感器和视觉系统感知周围环…

音视频开发(一)ffmpeg 简单学习

前言 简单音视频处理。 学习自&#xff1a; 小破站FFmpeg最强教学丨入门FFmpeg看这一篇就够了丨从入门到放弃系列_哔哩哔哩_bilibili 01 下载、配置_哔哩哔哩_bilibili 基础知识 音视频处理基本都是&#xff1a;采样-处理得到帧队列-编码得到包队列-封装得到文件。 视频…

怎么设置禁止使用U盘

怎么设置禁止使用U盘 在工作中&#xff0c;数据对企业来说是尤为重要的&#xff0c;一旦企业或机构的数据泄露&#xff0c;就会给企业或机构带来极大的损失&#xff0c;企业为了保护公司数据的安全&#xff0c;往往禁用公司电脑使用U盘&#xff0c;禁用U盘也成为了企业的必要措…

Allegro电商平台:为卖家打开全球市场,为消费者带来无限选择

Allegro电商平台是一个全球性的在线零售平台&#xff0c;为卖家提供了一个广阔的市场&#xff0c;让他们可以在全球范围内销售产品。这个平台以其丰富的产品类别、便捷的购物体验和优质的客户服务而受到卖家和消费者的欢迎。本文将介绍Allegro电商平台的特点&#xff0c;以及卖…

【@胡锡进】大模型量化分析- 潍柴动力 000338.SZ

对于预测股票价格的问题&#xff0c;有许多不同的方法可以尝试。下面我将为你分别使用SARIMA、简单移动平均线、指数加权移动平均线、Bollinger带、相对强弱指标、随机指标、线性回归、随机森林回归、支持向量回归法、自回归移动平均法和长短期记忆模型来预测潍柴动力未来3天的…

NVM 安装及使用

1.安装 我使用的是解压版&#xff0c;免安装 github下载压缩包 下载后放在一个【没有中文】的文件夹下&#xff0c;解压 然后需要配环境变量&#xff0c; 首先添加两个变量&#xff0c;分别是刚刚nvm解压的路径&#xff0c;和当前node安装的路径。 然后编辑path变量&#x…

将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表

将两个有序顺序表合并为一个新的有序顺序表&#xff0c;并由函数返回结果顺序表 算法思路&#xff1a; 这个其实就是一个归并排序&#xff0c;我们这里两顺序表为升序&#xff0c;要合并成一个升序表 用i和j分别标记顺序表A和顺序表B的元素&#xff0c;然后新表是C 每次从A和…

springboot异步线程池

项目中经常会遇到线程池异步处理一些任务 1.配置信息 # 异步线程配置 # 核心线程数 async:executor:thread:core_pool_size: 10# 最大线程数max_pool_size: 100# 任务队列大小queue_capacity: 20# 线程池中线程的名称前缀name:prefix: kc-async-service-# 缓冲队列中线程的空闲…

玫瑰红葡萄酒的基本知识

在过去的几年里&#xff0c;玫瑰红葡萄酒越来越受欢迎&#xff0c;但是如果你是饮用玫瑰红葡萄酒的新手&#xff0c;你可能想知道它是如何从其他红葡萄酒或白葡萄酒中脱颖而出的。 玫瑰红具有标志性的粉色&#xff0c;很难归类&#xff0c;那它是更适合放在红酒类还是属于白酒…

什么是IGBT测试,igbt动态测试都有哪些指标,纳米软件科普

IGBT测试是指对绝缘栅双极型晶体管(IGBT)的性能进行检测和评估。IGBT是一种复合全控型电压驱动式功率半导体器件&#xff0c;兼有金属氧化物半导体场效应晶体管(MOSFET)的高输入阻抗和电力晶体管(GTR)的低导通压降两方面的优点。 IGBT测试包括电气性能测试、可靠性测试、耐久性…

全能型开源数据库监控平台 - lepus

简 介 Lepus 是一款开源的数据库监控平台&#xff0c;目前已经支持 MySQL、Oracle、SQLserver、MongoDB、Redis 等数据库的基本监控和告警。 Lepus 在监控数据库时&#xff0c;无需在每台数据库服务器上部署脚本或 Agent&#xff0c;只需要在数据库中创建授权账号后&#…

HarmonyOS 自定义抽奖转盘开发(ArkTS)

介绍 本篇 Codelab 是基于画布组件、显式动画&#xff0c;实现的一个自定义抽奖圆形转盘。包含如下功能&#xff1a; 1. 通过画布组件 Canvas&#xff0c;画出抽奖圆形转盘。 2. 通过显式动画启动抽奖功能。 3. 通过自定义弹窗弹出抽中的奖品。 相关概念 ● Stack组件…