20vue3实战-----使用echarts搭建各种图表

20vue3实战-----使用echarts搭建各种图表

  • 1.实现目标
  • 2.实现步骤
    • 2.1封装组件
    • 2.2使用组件

1.实现目标

在这里插入图片描述
如上,页面上有各种各样类型的图标。这时候需要用到echarts库作为辅助。

2.实现步骤

首先安装echarts库的步骤就不用多说。

2.1封装组件

在这里插入图片描述
page-echarts/index.ts:

import BaseEchart from './src/base-echart.vue'
import PieEchart from './src/pie-echart.vue'
import LineEchart from './src/line-echart.vue'
import RoseEchart from './src/rose-echart.vue'
import BarEchart from './src/bar-echart.vue'
import MapEchart from './src/map-echart.vue'

export { PieEchart, LineEchart, RoseEchart, BarEchart, MapEchart }

export default BaseEchart

page-echarts/src/bar-echart.vue:

<template>
  <div class="bar-echart">
    <base-echart :option="option"></base-echart>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import * as echarts from 'echarts'
import BaseEchart from './base-echart.vue'
import type { EChartsOption } from 'echarts'

const props = defineProps<{
  labels: string[]
  values: string[]
}>()

const option = computed<EChartsOption>(() => {
  return {
    title: {
      text: '支持鼠标滚动缩放'
    },
    grid: {
      bottom: '5%'
    },
    xAxis: {
      data: props.labels,
      axisLabel: {
        inside: true,
        color: '#fff'
      },
      z: 10
    },
    yAxis: {
      axisLabel: {
        color: '#999'
      }
    },
    dataZoom: [
      {
        type: 'inside'
      }
    ],
    series: [
      {
        type: 'bar',
        showBackground: true,
        // 系列图形的样式(每个item的样式)
        // 可以被放到每一项中,针对每一项设置
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: '#83bff6' },
            { offset: 0.5, color: '#188df0' },
            { offset: 1, color: '#188df0' }
          ])
        },
        // 图形的高亮: 鼠标悬浮时候的状态: hover
        emphasis: {
          itemStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: '#2378f7' },
              { offset: 0.7, color: '#2378f7' },
              { offset: 1, color: '#83bff6' }
            ])
          }
        },
        data: props.values
      }
    ]
  }
})
</script>
<style scoped></style>

page-echarts/src/line-echart.vue:

<template>
  <div class="line-echart">
    <base-echart :option="option" />
  </div>
</template>

<script setup lang="ts">
import { defineProps, computed } from 'vue'
import BaseEchart from './base-echart.vue'
import type { EChartsOption } from 'echarts'

const props = defineProps<{
  labels: string[]
  values: string[]
}>()

const option = computed<EChartsOption>(() => {
  return {
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        }
      }
    },
    legend: {},
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: [
      {
        type: 'category',
        boundaryGap: false,
        data: props.labels
      }
    ],
    yAxis: [
      {
        type: 'value'
      }
    ],
    series: [
      {
        name: '分类销量统计',
        type: 'line',
        stack: '总量',
        areaStyle: {},
        emphasis: {
          focus: 'series'
        },
        data: props.values
      }
    ]
  }
})
</script>

<style lang="less" scoped></style>

page-echarts/src/map-echart.vue:

<template>
  <div class="map-echart">
    <base-echart :option="option"></base-echart>
  </div>
</template>

<script setup lang="ts">
import { defineProps, computed } from 'vue'

import BaseEchart from './base-echart.vue'
import { convertData } from '../utils/convert-data'
import type { IEchartValueType } from '../types'
import type { EChartsOption } from 'echarts'

const props = defineProps<{
  mapData: IEchartValueType[]
}>()

const option = computed<EChartsOption>(() => {
  return {
    backgroundColor: '#fff',
    title: {
      text: '全国销量统计',
      left: 'center',
      textStyle: {
        color: '#fff'
      }
    },
    tooltip: {
      trigger: 'item',
      formatter: function (params: any) {
        return params.name + ' : ' + params.value[2]
      }
    },
    visualMap: {
      min: 0,
      max: 60000,
      left: 20,
      bottom: 20,
      calculable: true,
      text: ['高', '低'],
      inRange: {
        color: ['rgb(70, 240, 252)', 'rgb(250, 220, 46)', 'rgb(245, 38, 186)']
      },
      textStyle: {
        color: '#fff'
      }
    },
    geo: {
      // 设置使用的地图(注册过的china地址)
      map: 'china',
      // 漫步: 支持鼠标缩放效果
      roam: 'scale',
      emphasis: {
        areaColor: '#f4cccc',
        borderColor: 'rgb(9, 54, 95)',
        itemStyle: {
          areaColor: '#f4cccc'
        }
      }
    },
    series: [
      {
        name: '销量',
        // 散点图在地图上展示数据
        type: 'scatter',
        coordinateSystem: 'geo',
        data: convertData(props.mapData),
        // 散点的大小(可以根据数据不同显示不同的大小, 设置为一个函数)
        symbolSize: 12,
        emphasis: {
          itemStyle: {
            borderColor: '#fff',
            borderWidth: 1
          }
        }
      },
      {
        // 会自动生成geo地理坐标系统
        type: 'map',
        // 设置使用的地图名称, 复用的是第0个坐标系统
        map: 'china',
        geoIndex: 0,
        // 缩放地图
        aspectScale: 0.75,
        tooltip: {
          show: false
        }
      }
    ]
  }
})
</script>

<style scoped></style>

page-echarts/src/pie-echart.vue:

<template>
  <div class="pie-echart">
    <base-echart :option="option" />
  </div>
</template>

<script setup lang="ts">
import BaseEchart from './base-echart.vue'
import type { EChartsOption } from 'echarts'
import { computed } from 'vue'
import type { IEchartValueType } from '../types'

interface IProps {
  pieData: IEchartValueType[]
}

const props = defineProps<IProps>()
const option = computed<EChartsOption>(() => {
  return {
    // 手指放上去的时候显示的文本
    tooltip: {
      trigger: 'item'
    },
    // 图例:
    legend: {
      orient: 'horizontal',
      left: 'left'
    },
    series: [
      {
        name: '访问来源',
        type: 'pie',
        radius: '50%',
        bottom: '-10%',
        data: props.pieData,
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }
    ]
  }
})
</script>

<style lang="less" scoped>
.pie-echart {
  color: red;
}
</style>

page-echarts/src/rose-echart.vue:

<template>
  <div class="rose-echart">
    <base-echart :option="option" />
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import BaseEchart from './base-echart.vue'
import type { EChartsOption } from 'echarts'
import type { IEchartValueType } from '../types'

interface IProps {
  roseData: IEchartValueType[]
}

const props = defineProps<IProps>()

const option = computed<EChartsOption>(() => {
  return {
    toolbox: {
      show: true,
      feature: {
        mark: { show: true },
        dataView: { show: true, readOnly: false },
        restore: { show: true },
        saveAsImage: { show: true }
      }
    },
    tooltip: {
      trigger: 'item'
    },
    series: [
      {
        name: '访问来源',
        type: 'pie',
        // 内半径/外半径的大小
        radius: [10, 160],
        // 设置区域的位置
        center: ['50%', '50%'],
        bottom: '-15%',
        roseType: 'area', // 圆心角一样, 通过半径的不同表示大小
        itemStyle: {
          borderRadius: 8
        },
        data: props.roseData,
        label: {
          show: false
        }
      }
    ]
  }
})
</script>

<style lang="less" scoped>
.rose-echart {
  color: red;
}
</style>

page-echarts/src/base-echart.vue:

<template>
  <div class="base-echart">
    <div class="echart" ref="echartRef"></div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watchEffect } from 'vue'
import * as echarts from 'echarts'
import type { EChartsOption } from 'echarts'
import ChinaJSON from '../data/china.json'

echarts.registerMap('china', ChinaJSON as any)

interface IProps {
  option: EChartsOption
}

const props = defineProps<IProps>()

const echartRef = ref<HTMLElement>()
onMounted(() => {
  // 1.初始化echarts实例
  const echartInstance = echarts.init(echartRef.value!, 'light', {
    renderer: 'canvas'
  })
  // 2.第一次进行setOption
  // watchEffect监听option变化, 重新执行
  watchEffect(() => echartInstance.setOption(props.option))
  // 3.监听window缩放
  window.addEventListener('resize', () => {
    echartInstance.resize()
  })
})

onMounted(() => {})
</script>

<style lang="less" scoped>
.base-echart {
  color: red;
}

.echart {
  height: 300px;
}
</style>

2.2使用组件

<template>
  <div class="dashboard">
    <!-- 1.顶部数字的数据展示 -->
    <el-row :gutter="10">
      <template v-for="item in amountList" :key="item.amount">
        <el-col :span="6" :xs="24" :sm="12" :md="8" :lg="6">
          <count-card v-bind="item" />
        </el-col>
      </template>
    </el-row>

    <!-- 2.中间部分的图表 -->
    <el-row :gutter="10">
      <el-col :span="7">
        <chart-card>
          <pie-echart :pie-data="showGoodsCategoryCount" />
        </chart-card>
      </el-col>
      <el-col :span="10">
        <chart-card>
          <map-echart :map-data="showGoodsAddressSale" />
        </chart-card>
      </el-col>
      <el-col :span="7">
        <chart-card>
          <rose-echart :rose-data="showGoodsCategoryCount" />
        </chart-card>
      </el-col>
    </el-row>

    <!-- 3.底部部分的图表 -->
    <el-row :gutter="10">
      <el-col :span="12">
        <chart-card>
          <line-echart v-bind="showGoodsCategorySale" />
        </chart-card>
      </el-col>
      <el-col :span="12">
        <chart-card>
          <bar-echart v-bind="showGoodsCategoryFavor" />
        </chart-card>
      </el-col>
    </el-row>
  </div>
</template>

<script setup lang="ts">
import { computed } from 'vue'
import { storeToRefs } from 'pinia'
import CountCard from './c-cpns/count-card/count-card.vue'
import ChartCard from './c-cpns/chart-card/chart-card.vue'
import useAnalysisStore from '@/store/main/analysis/analysis'

// import BaseChart from '@/components/page-echarts'
import {
  PieEchart,
  LineEchart,
  RoseEchart,
  BarEchart,
  MapEchart
} from '@/components/page-echarts'

// 1.发起数据的请求
const analysisStore = useAnalysisStore()
analysisStore.fetchAnalysisDataAction()

// 2.从store获取数据
const {
  amountList,
  goodsCategoryCount,
  goodsCategorySale,
  goodsCategoryFavor,
  goodsAddressSale
} = storeToRefs(analysisStore)

// 3.获取数据
const showGoodsCategoryCount = computed(() => {
  return goodsCategoryCount.value.map((item) => ({
    name: item.name,
    value: item.goodsCount
  }))
})
const showGoodsCategorySale = computed(() => {
  const labels = goodsCategorySale.value.map((item) => item.name)
  const values = goodsCategorySale.value.map((item) => item.goodsCount)
  return { labels, values }
})
const showGoodsCategoryFavor = computed(() => {
  const labels = goodsCategoryFavor.value.map((item) => item.name)
  const values = goodsCategoryFavor.value.map((item) => item.goodsFavor)
  return { labels, values }
})
const showGoodsAddressSale = computed(() => {
  return goodsAddressSale.value.map((item) => ({
    name: item.address,
    value: item.count
  }))
})
</script>

<style lang="less" scoped>
...
</style>

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Qt 常用控件】多元素控件(QListWidget、QTableWidgt、QTreeWidget)

**View和**Widget的区别&#xff1f; **View的实现更底层&#xff0c;**Widget是基于**View封装实现的更易用的类型。 **View使用MVC结构 MVC是软件开发中 经典的 软件结构 组织形式&#xff0c;软件设计模式。 M&#xff08;model&#xff09;模型。管理应用程序的核心数据和…

Flappy Bird开发学习记录

概述 为了了解一下Unity的开发过程&#xff0c;或者说感受&#xff1f;先搞简单的练练手。 工具 Unity:2022.3.51f1c1 visual studio 2022 开发过程 项目基本设置 新建2d项目&#xff0c;游戏画面设置为1080*1920&#xff08;9&#xff1a;16&#xff09;。 图片素材设…

35~37.ppt

目录 35.张秘书-《会计行业中长期人才发展规划》 题目​ 解析 36.颐和园公园&#xff08;25张PPT) 题目​ 解析 37.颐和园公园&#xff08;22张PPT) 题目 解析 35.张秘书-《会计行业中长期人才发展规划》 题目 解析 插入自定义的幻灯片&#xff1a;新建幻灯片→重用…

19.4.6 读写数据库中的二进制数据

版权声明&#xff1a;本文为博主原创文章&#xff0c;转载请在显著位置标明本文出处以及作者网名&#xff0c;未经作者允许不得用于商业目的。 需要北风数据库的请留言自己的信箱。 北风数据库中&#xff0c;类别表的图片字段在【数据表视图】中显示为Bitmap Image&#xff1…

sqli-lab靶场学习(六)——Less18-22(User-Agent、Referer、Cookie注入)

前言 前面的关卡&#xff0c;都是直接在输入框或者浏览器的地址栏上做文章即可。但本文这几关&#xff0c;需要用工具拦截请求修改请求头部才行。 Less18&#xff08;User-Agent注入&#xff09; 本关的注入点在User-Agent。我们在用户名和密码框中输入admin/admin后&#xf…

uniapp 使用 鸿蒙开源字体

uniapp vue3 使用 鸿蒙开源字体 我的需求是全局使用鸿蒙字体。 所以&#xff1a; 0. 首先下载鸿蒙字体&#xff1a; 鸿蒙资源 下载后解压&#xff0c;发现里面有几个文件夹&#xff1a; 字体名称说明Sans默认的鸿蒙字体&#xff0c;支持基本的多语言字符&#xff08;包括字…

【ESP32指向鼠标】——icm20948与esp32通信

【ESP32指向鼠标】——icm20948与esp32通信 ICM-20948介绍 ICM-20948 是一款由 InvenSense&#xff08;现为 TDK 的一部分&#xff09;生产的 9 轴传感器集成电路。它结合了 陀螺仪、加速度计和磁力计。 内置了 DMP&#xff08;Digital Motion Processor&#xff09;即负责执…

机器学习(李宏毅)——BERT

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记&#xff0c;感谢台湾大学李宏毅教授的课程&#xff0c;respect&#xff01;&#xff01;&#xff01; 读这篇文章必须先了解self-attention、Transformer&#xff0c;可参阅我其他文章。 二、大纲 BERT简介self-…

NO.12十六届蓝桥杯备战|关系操作符|操作符连用|浮点数比较|练习2道(C++)

关系操作符 关系操作符介绍 ⽤于⽐较的表达式&#xff0c;称为“关系表达式”&#xff08;relational expression&#xff09;&#xff0c;⾥⾯使⽤的运算符就称为“关 系运算符”&#xff08;relational operator&#xff09;&#xff0c;主要有下⾯6个。 运算符描述>⼤…

JVM组成

JVM是什么&#xff1f; JVM&#xff08;Java Virtual Machine&#xff09;&#xff1a;Java程序的运行环境(java二进制字节码的运行环境) 好处&#xff1a; 1.一次编写&#xff0c;到处运行 Java代码是如何做到一次编写&#xff0c;到处运行&#xff1f; 计算机的最底层是计…

不小心删除服务[null]后,git bash出现错误

不小心删除服务[null]后&#xff0c;git bash出现错误&#xff0c;如何解决&#xff1f; 错误描述&#xff1a;打开 git bash、msys2都会出现错误「bash: /dev/null: No such device or address」 问题定位&#xff1a; 1.使用搜索引擎搜索「bash: /dev/null: No such device o…

130,[1] 攻防世界 very_easy_sql

进入靶场 典型SQL注入页面 先查看源码 访问 试试http://127.0.0.1/ 还尝试了其他都是nonono 回归第一个登录页面 提交的内容不在url处显示&#xff0c;反而第二个url页面会在url处显示 明白第一个页面是通过post方式提交&#xff0c;反正没得到什么信息&#xff0c;去抓…

Android10 音频参数导出合并

A10 设备录音时底噪过大&#xff0c;让音频同事校准了下&#xff0c;然后把校准好的参数需要导出来&#xff0c;集成到项目中&#xff0c;然后出包&#xff0c;导出方式在此记录 设备安装debug系统版本调试好后&#xff0c; adb root adb remount adb shell 进入设备目录 导…

django中间件,中间件给下面传值

1、新建middleware.py文件 # myapp/middleware.py import time from django.http import HttpRequest import json from django.http import JsonResponse import urllib.parse from django.core.cache import cache from comm.Db import Db class RequestTimeMiddleware:def …

24电子信息类研究生复试面试问题汇总 电子信息类专业知识问题最全!电子信息复试全流程攻略 电子信息考研复试真题汇总

你是不是在为电子信息考研复试焦虑&#xff1f;害怕被老师问到刁钻问题、担心专业面答不上来&#xff1f;别慌&#xff01;作为复试面试92分逆袭上岸的学姐&#xff0c;今天手把手教你拆解电子信息类复试通关密码&#xff01;看完这篇&#xff0c;让你面试现场直接开大&#xf…

LVDS接口总结--(1)LVDS硬件电路接口

1.LVDS差分信号电路原理 LVDS指的是低压差分信号&#xff0c;是一种电平标准。 差分信号在串行通信中有着非常广泛的应用&#xff0c;典型应用有PCIE中的gen1&#xff0c;gen2&#xff0c;gen3&#xff0c;gen4&#xff0c;gen5&#xff0c;SATA接口&#xff0c;USB接口等。 …

【STM32】HAL库Host MSC读写外部U盘及FatFS文件系统的USB Disk模式

【STM32】HAL库Host MSC读写外部U盘及FatFS文件系统的USB Disk模式 在先前 分别介绍了FatFS文件系统和USB虚拟U盘MSC配置 前者通过MCU读写Flash建立文件系统 后者通过MSC连接电脑使其能够被操作 这两者可以合起来 就能够实现同时在MCU、USB中操作Flash的文件系统 【STM32】通过…

第四期书生大模型实战营-第5关-L2G5000

1 Web 版茴香豆 助教说这趴先跳过&#xff0c;那我就跳过 2 茴香豆本地标准版搭建 2.1 环境搭建 2.2 安装茴香豆 2.3 知识库创建 2.4 测试知识助手 2.4.1 命令行运行 2.4.2 Gradio UI 界面测试 确认一下是否正常 完美。 至于选做&#xff0c;我这么懒&#xff0c;怎么可能…

Elastic Cloud Serverless 现已在 Microsoft Azure 上提供技术预览版

作者&#xff1a;来自 Elastic Yuvi Gupta Elastic Cloud Serverless 提供了启动和扩展安全性、可观察性和搜索解决方案的最快方法 — 无需管理基础设施。 今天&#xff0c;我们很高兴地宣布 Microsoft Azure 上的 Elastic Cloud Serverless 技术预览版现已在美国东部地区推出。…

go语言简单快速的按顺序遍历kv结构(map)

文章目录 需求描述用map实现按照map的key排序用二维切片实现用结构体实现 需求描述 在go语言中&#xff0c;如果需要对map遍历&#xff0c;每次输出的顺序是不固定的&#xff0c;可以考虑存储为二维切片或结构体。 假设现在需要在页面的下拉菜单中展示一些基础的选项&#xff…