【可视化大屏系列】Echarts之柱图绘制

news2024/11/16 7:35:30

本文为个人近期学习总结,若有错误之处,欢迎指出!

Echarts之柱图绘制

  • 前言
  • 需求
  • 实现效果
  • 大概思路
  • 具体实现
    • 实现思路
    • 具体代码
      • 1.父组件写法
      • 2.子组件写法
  • 附加
    • 1.同坐标系下,并排柱图绘制
    • 2.柱图下钻功能实现

前言

在前文页面布局、DataV 的使用、Echarts 的基础使用的基础上,开始绘制大屏中的基础柱图。

需求

柱图展示四类蔬菜的销售量,且销售量数据每隔十分钟自动刷新。

实现效果

在这里插入图片描述

大概思路

1.将这一模块作为一个组件抽取出来,简化代码量;
2.边框使用 DataV 里的 dv-border-Box-13 元素实现;
3.柱图Echarts 绘制(因为柱图的数据可能是实时刷新的,保险起见,选择 echarts)

具体实现

实现思路

1.子组件中写边框和柱图代码,供父组件调用;
2.父组件中引用子组件,同时向子组件传递柱图的标题和横纵坐标(这里是为了增加子组件的可复用性);
3.子组件的行为:
(1)子组件接收柱图标题,放在标题位置
(2)子组件接收横纵坐标
(3)由于横坐标不变,所以子组件监测接收数据中纵坐标值的变化,绘制柱图

具体代码

1.父组件写法

<template>
  <bar-chart :bar-title="barTitle" :x-data="barX" :y-data="barY" />
</template>
<script>
import BarChart from '../components/BarChart.vue'
export default {
  components:{
    BarChart
  },
  data(){
    return {
      //向子组件传递三个数据
      barTitle: '销售量',
      barX: [],
      barY: [],   
    }
  },
  mounted () {
    this.InitBar()
    setTimeout(() => { // 模拟数据实时刷新调用后端接口
      this.barY = [1514, 1729, 1337, 1810]
    }, 10000)
  },
  methods:{
    InitBar () {
      setTimeout(() => { // 模拟调用后端接口,进行初始化
        this.barY = [514, 729, 337, 810]
        this.barX = [
          '萝卜',
          '玉米',
          '白菜',
          '芹菜'
        ]
      }, 3000)
    }
  }
}
</script>

2.子组件写法

代码较长,拆为三块:
(1)html

<template>
  <div class="block" style="height:100%;">
    <dv-border-box-13>
      <div class="title" style="height:20%;">
        {{ barTitle }}
      </div>
      <div ref="barArea" :style="{width: '100%',height: '80%'}" />
    </dv-border-box-13>
  </div>
</template>

注意: 这里样式高度采用百分比(非固定像素 px),是为了使子组件自适应父组件的高度
(2)JavaScript

<script>
export default {
  name: 'bar-chart',
  //子组件用 props 接收父组件传递过来的三个数据
  props: {
    barTitle: {
      type: String,
      default: ''
    },
    xData: {
      type: Array,
      default: () => []
    },
    yData: {
      type: Array,
      default: () => []
    }
  },
  // eslint-disable-next-line max-lines-per-function
  data () {
    return {
      option: {
        color: ['#2f89cf'], // 柱子的颜色
        tooltip: { // 悬浮提示框
          trigger: 'axis', // 坐标轴触发
          axisPointer: { // 坐标轴指示器,坐标轴触发有效
            type: 'shadow' // 默认为直线,可选为:'line' | 'shadow'
          },
          backgroundColor: 'rgba(83,164,230,.6)',
          borderColor: 'rgba(83,164,230,1)', // 边框颜色
          textStyle: {// 设置文字样式
            color: 'rgba(255,255,255,1)',
            fontSize: 10
          }
        },
        grid: { // 图表大小,直角坐标系绘图网格
          left: '13%',
          bottom: '14%',
          top: '13%',
          containLabel: false // grid 区域是否包含刻度标签
        },
        xAxis: [// x 轴
          {
            name: '种类', // 坐标轴名称
            type: 'category',
            boundaryGap: true, // 坐标轴两边留白(默认就是 true)
            data: this.xData,
            axisTick: { // 坐标轴刻度相关设置
              alignWithLabel: true // 刻度线和标签对齐
            },
            axisLabel: { // 坐标轴刻度标签
              color: 'rgba(255,255,255,.6)',
              fontSize: '12'
            },
            axisLine: { // 坐标轴轴线
              show: true // 不显示
            }
          }
        ],
        yAxis: [// y 轴
          {
            name: '单位:斤', // 坐标轴名称
            type: 'value', // 坐标轴类型,这里是 数值轴,适用于连续数据
            nameTextStyle: { // 坐标轴名称文字样式
              color: 'rgba(255,255,255,.6)',
              fontSize: 12,
              padding: [10, 50, 7, 10] // name 文字位置 对应 上右下左
            },
            axisLabel: {
              color: 'rgba(255,255,255,.6)',
              fontSize: '12'
            },
            axisLine: {
              show: true,
              lineStyle: {
                color: 'rgba(255,255,255,.6)',
                type: 'solid'
              }
            },
            axisTick: {
              show: true
            },
            splitLine: { // 坐标轴在 grid 区域中的分隔线(默认数值轴显示,类目轴不显示)
              show: false
            }
          }
        ],

        // 系列(只有一个系列,所以数组内只有一个对象元素)
        series: [
          {
            name: '售出', // 系列名称,用于 tooltip 的显示
            type: 'bar',
            barWidth: '20%', // 柱子的宽度
            tooltip: { // 提示框浮层内容格式器
              valueFormatter (value) { // tooltip 中数值显示部分的格式化回调函数
                return value + ' 个'
              }
            },
            data: this.yData, // 系列中的数据内容数组。
            itemStyle: { // 图形样式
              borderRadius: 5 // 圆角
            },
            label: { // 柱子上方的文字
              color: 'rgba(255,255,255,.6)',
              fontSize: '12',
              show: true,
              position: 'top'
            }
          }
        ]
      }
    }
  },
  
  // 监测 yData 属性的变化
  watch: {
    yData: {
      handler (newVal, oldVal) {
        console.log('yChange', newVal, oldVal, this.xData)

        // 将变化后的新值赋给柱图的纵坐标,再重新绘制图表
        this.option.series[0].data = newVal
        this.option.xAxis[0].data = this.xData
        this.drawBar()
      }
    }
  },
  mounted () {
    this.drawBar()
  },
  methods: {
    drawBar () {
      // 检测是否已经存在 echarts 实例
      let myBar = this.$echarts.getInstanceByDom(this.$refs.barArea)

      // 如果为空 则正常进行渲染 反之 不再进行初始化
      if (myBar === undefined) {
        myBar = this.$echarts.init(this.$refs.barArea)
      }
   
      myBar.setOption(this.option, true)
      window.addEventListener('resize', () => {
        myBar.resize()
      })
    }
  }
}
</script>

注意:
这里 watch 监测 ydata 的变化,其中 ydata 至少变化了两次(这里只有俩次):
①由[]变为初始化后的数据[514, 729, 337, 810];
②再变为实时刷新后的模拟数据[1514, 1729, 1337, 1810]
因此,调用了两次 handler 函数。
(3)css

<style lang="less" scoped>
.block {
  background-color: rgba(10, 30, 56);
  .title {
    display: flex;
    align-items: center;
    margin-left:15px;
    color: rgb(250, 212, 0);
    font-size: 13px;
  }
}
</style>

附加

1.同坐标系下,并排柱图绘制

比如:实现以下柱图:
在这里插入图片描述
option关键点
(1)两个柱子的颜色

color:['rgb(84,112,198)', 'rgb(115,192,222)']

(2)图例

legend:{
  data:['支出','收入'],
  //其它图例属性配置
}

注意:若series系列的name属性已经有值,则这里的data可不配置
(3)共用一个xAxis[0].data

xAxis:[{
  data:['胡萝卜', '蒜台', '土豆', '豆角']
}]

因此父组件给子组件传值时,传递的数据格式为:[‘胡萝卜’, ‘蒜台’, ‘土豆’, ‘豆角’]
(4)series里有两个系列,所以series数组里有两个对象。

series:[{
	 data:[20,49,70,232],
	  //其它系列属性配置 
	},
	{
	  data:[26,59,90,244],
	  barGap:0.5,//柱子之间的间距
	  //其它系列属性配置
}]

因此父组件给子组件传值时,传递的数据格式为:[[20,49,70,232],[26,59,90,244]]
注意:两个柱子之间的间隔属性,写在最后一个柱子系列对象里,才会起作用

2.柱图下钻功能实现

需求:点击某个菜品,查看五个市的某菜品售出详情。(以白菜为例)

在这里插入图片描述
在这里插入图片描述
实现:
(1)在柱图组件,画图函数的地方,加上事件处理函数

myBar.on('click', params => {
  this.$emit('BarClick', params, 'hello')
})

点击柱子,就会触发BarClick事件,并向父组件传递2个参数,一个是params,一个是字符串hello
(2)父组件使用柱图组件
html

<!-- 父组件第一次调用子组件 -->
<bar-chart :bar-title="barTitle" :x-data="barX" :y-data="barY" @BarClick="LookDetail" />

<!-- 柱图下钻后的弹框 --> 
<el-dialog
  :visible.sync="dialogVisible"
  width="50%"
>
  <div style="height:100%">
    <div style="height:200px">
      <!-- 父组件第二次调用子组件 -->
      <bar-chart :bar-title="cityChild" :x-data="cityX" :y-data="cityY" />
    </div>
  </div>
</el-dialog>

js

<script>
export default{
  data(){
    return {
      dialogVisible: false,
      cityChild: '',
      cityX: [],
      cityY: []
    }
  },
  methods:{
    LookDetail (arg1, arg2) {
      //arg1, arg2就是从子组件传递过来的数据
      console.log('args', arg1, arg2)
   
      this.dialogVisible = true
    
      // 数据暂时为模拟假数据
      // 这块可将arg1.name作为参数去调用接口拿后端数据
      this.cityChild = arg1.name
      this.cityX = [
        '西安',
        '咸阳',
        '安康',
        '铜川',
        '榆林'
      ],
      this.cityY = [35, 30, 63, 17, 28]
    }
  }
}
</script>

传递的两个参数,打开控制台可看到内容如下:
在这里插入图片描述

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

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

相关文章

HW期间——应急响应

01HW中应急响应的流程 001应急响应所处位置&#xff08;应急处置组&#xff09; 监控研判组发现的一些安全时间提供给应急处置组&#xff0c;应急处置组通过上机取证把线索给到溯源反制组。但是溯源反制组可能已经没有了&#xff0c;有些单位有&#xff0c;有些单位取消了。有…

标准扩散模型(standard diffusion)和潜在(latent diffusion)扩散模型的关键区别、对潜在扩散模型的认识

标准扩散模型(standard diffusion)和潜在(latent diffusion)扩散模型的关键区别、对潜在扩散模型的认识 1.两者的关键区别 潜在扩散模型通过在低维潜在空间的扩散过程&#xff0c;可以减少内存和计算的复杂性。而standard diffusion是在像素级别的空间(actual pixel space)进…

CSS上下悬浮特效

要实现一个上下悬浮的特效&#xff0c;可以使用CSS的keyframes规则和动画属性。以下是一个简单的示例&#xff1a; 代码示例 /* 定义一个名为floating的动画 */ keyframes floating {0% {transform: translateY(0); /* 初始位置 */}50% {transform: translateY(-4px); /* 向上…

吴恩达机器学习笔记2.1 - 什么是机器学习

吴恩达机器学习笔记2.1 - 什么是机器学习 最早的机器学习 1959年&#xff0c;亚瑟塞缪尔(Arthur Samuel)将机器学习定义为“Field of study that gives computers the ability to learn without being explicitly programmed”&#xff08;无需编程即可学习的研究领域&#xf…

ABAP BAPI_INCOMINGINVOICE_CREATE dump

在执行BAPI_INCOMINGINVOICE_CREATE 之后&#xff0c;正常生成了发票号&#xff0c;但是系统会dump 数据会回滚 dump如下 查阅后得知相关note:1894901 原因是在填写税行的时候&#xff0c;输入了多行&#xff0c;将数据合并为一行后即可 代码如下&#xff1a; ls_headerdat…

openlayers更改点坐标

我现在的需求是无人机点位根据ws传输的经纬度改变位置&#xff0c;在网上查了很多资料&#xff0c;终于是做出来了&#xff0c;如果有问题请指出。 效果图&#xff0c;无人机可以来回移动 这里是核心代码 // 添加飞机点位图层let vectorLayerpointfunction DronepointLayer()…

vscode设置左侧窗口字体大小

vscode设置左侧窗口字体大小 打开设置 在搜索框输入Zoom 修改这个值即可放大相关字体

从数字化营销与运营视角:看流量效果的数据分析

基于数据打通的“全链路”营销是当下的“时髦”&#xff0c;应用它的前提是什么&#xff1f;深度营销和运营的关键数据如何获得&#xff1f;如何利用数据进行更精准的营销投放&#xff1f;如何利用数据优化投放的效果&#xff1f;如何促进消费者的转化&#xff0c;以及激活留存…

【js面试题】深入理解尾递归及其在JavaScript中的应用

面试题&#xff1a;举例说明尾递归的理解&#xff0c;以及应用场景 引言&#xff1a; 在编程中&#xff0c;递归是一种常见的解决问题的方法&#xff0c;它允许函数调用自身来解决问题。然而&#xff0c;递归如果不当使用&#xff0c;可能会导致栈溢出错误&#xff0c;特别是在…

无损音频格式 FLAC 转 MP3 音频图文教程

音频文件的格式多样&#xff0c;每种格式都有其独特的特点与适用场景。FLAC&#xff08;Free Lossless Audio Codec&#xff09;&#xff0c;作为一种无损音频压缩格式&#xff0c;因其能够完美保留原始音频数据的每一个细节而备受音频发烧友和专业人士的青睐。 然而&#xff0…

代码随想录打卡第十八天

代码随想录–二叉树部分 day 17 休息日 day 18 二叉树第五天 文章目录 代码随想录--二叉树部分一、力扣654--最大二叉树二、力扣617--合并二叉树三、力扣700--二乘树中的搜素四、力扣98--验证二叉搜索树 一、力扣654–最大二叉树 代码随想录题目链接&#xff1a;代码随想录 给…

双系统ubuntu20.04扩容

windows端 打开磁盘管理器&#xff0c;选择需要的盘点击压缩卷 点击未分配的盘&#xff0c;新建简单卷&#xff0c;一致点击下一步即可&#xff0c;记住分配的大小容量 ubuntu端 lsblk 查看所有的磁盘&#xff0c;可以看到新增为nvme0n1p4、nvme1n1p2 win分配的格式为NTFS&a…

Idea-单个窗口导入并开启多个module项目

前言 大家是否有过这样的困扰&#xff0c;我们每次打开一个项目就需要单开一个idea窗口&#xff0c;项目少时了还好&#xff0c;一旦涉及多个项目间服务调用&#xff0c;特别是再包括网关、注册中心、前端web服务&#xff0c;需要开启的窗口就会是一大批&#xff0c;每次切换的…

antd a-select下拉框样式修改 vue3 亲测有效

记录一下遇到的问题 1.遇到问题&#xff1a; 使用到Vue3 Ant Design of Vue 3.2.20&#xff0c;但因为项目需求样式&#xff0c;各种查找资料都未能解决; 2.解决问题&#xff1a; ①我们审查元素可以看到&#xff0c;下拉框是在body中的; ①在a-select 元素上添加dropdownCla…

在Linux下使用Docker部署chirpstack

目录 一、前言 二、chirpstack 1、chirpstack是什么 2、chirpstack组件 3、为什么选择Docker部署 三、Linux下部署过程 四、web界面部署过程 一、前言 本篇文章我是在Linux下使用 Docker 进行部署chirpstack&#xff0c;chirpstack采用的是v4 版本&#xff0c;v4 版本 与…

AMEYA360荣登2024电子元器件分销商30强!

2024年7月4日&#xff0c;“2024(第二届)电子产业供应链生态大会”在东莞顺利召开。 本次大会由中国物流与采购联合会和东莞市人民政府联合主办&#xff0c;由中国物流与采购联合会电子产业供应链分会承办&#xff0c;该会议以“智链端生态 互链芯未来”为主题&#xff0c;旨在…

你最近想通了什么事情?这10条职场经验帮助你活得更通透

1别总当老好人 记得刚步入职场那会儿&#xff0c;我简直是“老好人”的代名词。 无论是同事的额外任务&#xff0c;还是朋友的小忙&#xff0c;我总是二话不说就接下来&#xff0c;结果自己累得半死&#xff0c;换来的却是别人的理所当然和偶尔的忽视。 直到有一次&#xff…

蓝牙信标是什么?蓝牙信标好不好用?

说到蓝牙大家应该都非常熟悉&#xff0c;有很多通信设备都可以经过蓝牙而取得联系。但是说到蓝牙信标很多人可能就比较陌生了&#xff0c;毕竟这样的说法太少见了&#xff0c;很多人也不知道这到底是什么。那么究竟我们应该怎么去理解&#xff0c;蓝牙信标是什么&#xff0c;另…

TikTok海外运营,云手机多种变现方法

从现阶段来看&#xff0c;TikTok 的用户基数不断增长&#xff0c;已然成为全球创业者和品牌的全新竞争舞台。其用户数量近乎 20 亿&#xff0c;年轻用户占据主导&#xff0c;市场渗透率也逐年提高。不管是大型企业、著名品牌&#xff0c;还是个体创业者&#xff0c;都绝不能小觑…

进程地址空间(初)

1.遗留问题 前面在fork创建子进程的内容中遗留了一个问题&#xff0c;一个 变量既等于0又大于0. 2.地址空间的概念 (仅有栈区从高地址处向低地址处&#xff09; &#xff08;堆区和栈区之间有一大块的镂空&#xff0c;这里暂时不作介绍&#xff09; 使用代码验证上图的大…