当前位置:   article > 正文

ECharts 数据可视化大屏项目学习_用ucharts制作大屏

用ucharts制作大屏

ECharts 数据可视化大屏项目学习

可视化大屏项目b站学习视频https://www.bilibili.com/video/BV1yu411E7cm?p=2&vd_source=75e802e2bcd560c954f9ac55668a5935

一、步骤

1、创建一个文件夹存放该项目的代码文件,打开VScode,点击打开文件夹,打开刚刚创建的文件夹。

2、打开终端(快捷键ctrl+`)

3、创建项目

npm create vite@latest

4、安装依赖

npm i

5、运行程序,打开网页,查看效果

npm run dev

6、查看tailwindcss教程,导入tailwindcss

https://tailwindcss.com/

ctrl+c关掉终端的运行项目,输入命令,导入tailwindcss

  1. npm install -D tailwindcss postcss autoprefixer
  2. npx tailwindcss init -p

7、修改tailwind.config.js

  1. content: [
  2. "./index.html",
  3. "./src/**/*.{vue,js,ts,jsx,tsx}",
  4. ],

8、修改style.css

  1. @tailwind base;
  2. @tailwind components;
  3. @tailwind utilities;

9、修改App.vue

  1. <template>
  2. <div class="text-red-600 text-3xl">hello tailwind</div>
  3. </template>
  4. <script setup></script>
  5. <style lang="scss" scoped></style>

成功导入tailwindcss

10、导入项目所需的资料

11、修改App.vue

  1. <template>
  2. <div>
  3. <!-- 自定义背景,背景bg,[]中放置图片路径 -->
  4. <div class="bg-[url('assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-5 flex overflow-hidden">
  5. <!-- 左 -->
  6. <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  7. </div>
  8. <!-- 中 -->
  9. <div class="w-1/2 mr-5 flex flex-col">
  10. </div>
  11. <!-- 右 -->
  12. <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  13. </div>
  14. </div>
  15. </div>
  16. </template>
  17. <script setup>
  18. </script>
  19. <style lang="scss" scoped>
  20. </style>

  1. <template>
  2. <div>
  3. <!-- 自定义背景,背景bg,[]中放置图片路径 -->
  4. <div class="bg-[url('assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-5 flex overflow-hidden">
  5. <!-- 左 -->
  6. <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  7. <!-- 横向柱状图 -->
  8. <HorizontalBar/>
  9. <!-- 雷达图 -->
  10. <RadarBar/>
  11. <!-- 关系图 -->
  12. <Relation class="h-1/3"/>
  13. </div>
  14. <!-- 中 -->
  15. <div class="w-1/2 mr-5 flex flex-col">
  16. <!-- 数据总览图 -->
  17. <ToatlData/>
  18. <!-- 地图可视化 -->
  19. <MapChart/>
  20. </div>
  21. <!-- 右 -->
  22. <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  23. <!-- 竖向柱状图 -->
  24. <VerticalBar/>
  25. <!-- 环形图 -->
  26. <RingBar/>
  27. <!-- 文档云图 -->
  28. <WordCloud/>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script setup>
  34. import HorizontalBar from './components/HorizontalBar.vue';
  35. import RadarBar from './components/RadarBar.vue';
  36. import Relation from './components/Relation.vue';
  37. import ToatlData from './components/TotalData.vue';
  38. import MapChart from './components/MapChart.vue';
  39. import VerticalBar from './components/VerticalBar.vue';
  40. import RingBar from './components/RingBar.vue';
  41. import WordCloud from './components/WordCloud.vue';
  42. </script>
  43. <style lang="scss" scoped>
  44. </style>

  1. <template>
  2. <div>
  3. <!-- 自定义背景,背景bg,[]中放置图片路径 -->
  4. <div class="bg-[url('assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-5 flex overflow-hidden">
  5. <!-- 左 -->
  6. <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  7. <!-- 横向柱状图 -->
  8. <HorizontalBar class="h-1/3 box-border pb-4"/>
  9. <!-- 雷达图 -->
  10. <RadarBar class="h-1/3 box-border pb-4"/>
  11. <!-- 关系图 -->
  12. <Relation class="h-1/3"/>
  13. </div>
  14. <!-- 中 -->
  15. <div class="w-1/2 mr-5 flex flex-col">
  16. <!-- 数据总览图 -->
  17. <ToatlData class="bg-opacity-50 bg-slate-800 p-3"/>
  18. <!-- 地图可视化 -->
  19. <MapChart class="bg-opacity-50 bg-slate-800 p-3 mt-4 flex-1"/>
  20. </div>
  21. <!-- 右 -->
  22. <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  23. <!-- 竖向柱状图 -->
  24. <VerticalBar class="h-1/3 box-border pb-4"/>
  25. <!-- 环形图 -->
  26. <RingBar class="h-1/3 box-border pb-4"/>
  27. <!-- 文档云图 -->
  28. <WordCloud class="h-1/3"/>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script setup>
  34. import HorizontalBar from './components/HorizontalBar.vue';
  35. import RadarBar from './components/RadarBar.vue';
  36. import Relation from './components/Relation.vue';
  37. import ToatlData from './components/TotalData.vue';
  38. import MapChart from './components/MapChart.vue';
  39. import VerticalBar from './components/VerticalBar.vue';
  40. import RingBar from './components/RingBar.vue';
  41. import WordCloud from './components/WordCloud.vue';
  42. </script>
  43. <style lang="scss" scoped>
  44. </style>

12、定时获取数据

安装axios

npm i --save axios@1.4.0 echarts@5.4.2

创建文件夹

创建request.js

  1. import axios from 'axios'
  2. const service = axios.create({
  3. baseURL: 'https://api.imooc-web.lgdsunday.club/api',
  4. timeout: 5000
  5. })
  6. // 请求拦截器
  7. service.interceptors.request.use(
  8. (config) => {
  9. config.headers.icode = 'input you icode'
  10. return config // 必须返回配置
  11. },
  12. (error) => {
  13. return Promise.reject(error)
  14. }
  15. )
  16. // 响应拦截器
  17. service.interceptors.response.use((response) => {
  18. const { success, message, data } = response.data
  19. // 要根据success的成功与否决定下面的操作
  20. if (success) {
  21. return data
  22. } else {
  23. return Promise.reject(new Error(message))
  24. }
  25. })
  26. export default service

13、创建visualization.js定义请求接口,数据请求模块

import request from '@/utils/request.js'

import './api/visualization.js'

14、修改vite.config.js

  1. resolve: {
  2. alias: {
  3. '@': '/src'
  4. }
  5. },
  6. server: {
  7. hmr: true
  8. }

修改visualization.js

  1. export const getVisualization = () => {
  2. return request({
  3. url: '/visualization'
  4. })
  5. }

修改App.vue

import { getVisualization } from './api/visualization.js'

  1. import { ref } from 'vue'
  2. // 获取数据
  3. const data = ref(null)
  4. // 定义方法
  5. const loadData = async () => {
  6. // 触发方法
  7. data.value = await getVisualization()
  8. // 打印
  9. console.log(data.value)
  10. }
  11. // 调用
  12. loadData()

15、数据动态变化,获取数据

  1. setInterval(() => {
  2. loadData()
  3. }, 3000)

此时,以获取到数据

16、echarts的使用

https://echarts.apache.org/handbook/zh/get-started/

echarts使用的基本结构

17、绘制图

词云图需安装wordcloud

npm i --save echarts-wordcloud@2.1.0

数据展示图需安装countup.js

npm i --save countup.js@2.6.2

二、代码

App.vue

  1. <template>
  2. <div>
  3. <!-- 自定义背景,背景bg,[]中放置图片路径 -->
  4. <div class="bg-[url('assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-5 flex overflow-hidden" v-if="data">
  5. <!-- 左 -->
  6. <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  7. <!-- 横向柱状图 -->
  8. <HorizontalBar class="h-1/3 box-border pb-4" :data="data.regionData"/>
  9. <!-- 雷达图 -->
  10. <RadarBar class="h-1/3 box-border pb-4" :data="data.riskData"/>
  11. <!-- 关系图 -->
  12. <Relation class="h-1/3" :data="data.relationData"/>
  13. </div>
  14. <!-- 中 -->
  15. <div class="w-1/2 mr-5 flex flex-col">
  16. <!-- 数据总览图 -->
  17. <ToatlData class="bg-opacity-50 bg-slate-800 p-3" :data="data.totalData"/>
  18. <!-- 地图可视化 -->
  19. <MapChart class="bg-opacity-50 bg-slate-800 p-3 mt-4 flex-1" :data="data.mapData"/>
  20. </div>
  21. <!-- 右 -->
  22. <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
  23. <!-- 竖向柱状图 -->
  24. <VerticalBar class="h-1/3 box-border pb-4" :data="data.serverData"/>
  25. <!-- 环形图 -->
  26. <RingBar class="h-1/3 box-border pb-4" :data="data.abnormalData"/>
  27. <!-- 文档云图 -->
  28. <WordCloud class="h-1/3" :data="data.wordCloudData"/>
  29. </div>
  30. </div>
  31. </div>
  32. </template>
  33. <script setup>
  34. import HorizontalBar from './components/HorizontalBar.vue';
  35. import RadarBar from './components/RadarBar.vue';
  36. import Relation from './components/Relation.vue';
  37. import ToatlData from './components/TotalData.vue';
  38. import MapChart from './components/MapChart.vue';
  39. import VerticalBar from './components/VerticalBar.vue';
  40. import RingBar from './components/RingBar.vue';
  41. import WordCloud from './components/WordCloud.vue';
  42. import { getVisualization } from './api/visualization.js'
  43. import { ref } from 'vue'
  44. // 获取数据
  45. const data = ref(null)
  46. // 定义方法
  47. const loadData = async () => {
  48. // 触发方法
  49. data.value = await getVisualization()
  50. // 打印
  51. console.log(data.value)
  52. }
  53. // 调用
  54. loadData()
  55. // 数据动态变化,间隔一定时间统计一次数据
  56. setInterval(() => {
  57. loadData()
  58. }, 3000)
  59. </script>
  60. <style lang="scss" scoped>
  61. </style>

HorizontalBar.vue

  1. <template>
  2. <!-- 承载当前echarts的容器 -->
  3. <div>
  4. <div>【大区数据信息】</div>
  5. <div ref="target" class="w-full h-full"></div>
  6. </div>
  7. </template>
  8. <script setup>
  9. import { onMounted, ref, watch } from 'vue'
  10. import * as echarts from 'echarts'
  11. // 接收
  12. const props = defineProps({
  13. data: {
  14. type: Object,//数据类型
  15. required: true
  16. }
  17. })
  18. // 打印
  19. console.log(props.data)
  20. // 1.初始化echarts实例
  21. // 获取 dom 实例
  22. const target = ref(null)
  23. // echarts 实例变量
  24. let mChart = null
  25. // 在 mounted 生命周期之后,实例化 echarts
  26. onMounted(() => {
  27. mChart = echarts.init(target.value)
  28. // 渲染 echarts
  29. renderChart()
  30. })
  31. // 渲染图表
  32. const renderChart = () => {
  33. const options = {
  34. // 添加属性
  35. // X 轴展示数据
  36. xAxis: {
  37. // 数据展示
  38. type: 'value',
  39. // 不显示轴
  40. show: false,
  41. // 最大值(防止触顶)
  42. max: function (value) {
  43. // 取整
  44. return parseInt(value.max * 1.2)
  45. }
  46. },
  47. // Y 轴展示选项
  48. yAxis: {
  49. type: 'category',
  50. // 根据根据服务端数据筛选
  51. data: props.data.regions.map((item) => item.name),
  52. // 反向展示
  53. inverse: true,
  54. // 不展示轴线
  55. axisLine: {
  56. show: false
  57. },
  58. // 不展示刻度
  59. axisTick: {
  60. show: false // 取消 Y 轴刻度
  61. },
  62. // 文字色值
  63. axisLabel: {
  64. color: '#9EB1C8'
  65. }
  66. },
  67. // echarts 网格绘制的位置,对应 上、右、下、左
  68. grid: {
  69. top: 0,
  70. right: 0,
  71. bottom: 0,
  72. left: 0,
  73. // 计算边距时,包含标签
  74. containLabel: true
  75. },
  76. // 柱形图核心配置
  77. series: [
  78. {
  79. // 图表类型
  80. type: 'bar',
  81. // 数据筛选
  82. data: props.data.regions.map((item) => ({
  83. name: item.name,
  84. value: item.value
  85. })),
  86. // 显示背景
  87. showBackground: true,
  88. // 背景色
  89. backgroundStyle: {
  90. color: 'rgba(180, 180, 180, 0.2)'
  91. },
  92. // 每个轴的样式
  93. itemStyle: {
  94. color: '#479AD3', // 设置柱子的颜色
  95. barBorderRadius: 5, // 设置柱子的圆角
  96. shadowColor: 'rgba(0, 0, 0, 0.3)', // 设置柱子的阴影颜色
  97. shadowBlur: 5 // 设置柱子的阴影模糊大小
  98. },
  99. // 轴宽度
  100. barWidth: 12,
  101. // 轴上的字体
  102. label: {
  103. show: true,
  104. // 设置标签位置为右侧
  105. position: 'right',
  106. textStyle: {
  107. // 设置标签文本颜色
  108. color: '#fff'
  109. }
  110. }
  111. }
  112. ]
  113. }
  114. mChart.setOption(options)
  115. }
  116. // 监听数据的变化,重新渲染图表
  117. watch(
  118. () => props.data,
  119. () => {
  120. renderChart()
  121. }
  122. )
  123. </script>
  124. <style lang="scss" scoped>
  125. </style>

MapChart.vue

  1. <template>
  2. <div>
  3. <div ref="target" class="w-full h-full"></div>
  4. </div>
  5. </template>
  6. <script setup>
  7. import { onMounted, ref } from 'vue'
  8. import * as echarts from 'echarts'
  9. import mapJson from '@/assets/MapData/china.json'
  10. const props = defineProps({
  11. data: {
  12. type: Object,
  13. required: true
  14. }
  15. })
  16. const target = ref(null)
  17. let mChart = null
  18. onMounted(() => {
  19. mChart = echarts.init(target.value)
  20. renderChart()
  21. })
  22. const renderChart = () => {
  23. // echarts 渲染
  24. echarts.registerMap('china', mapJson)
  25. let options = {
  26. // 时间线,提供了在多个 ECharts option 间进行切换
  27. timeline: {
  28. // 数据
  29. data: props.data.voltageLevel,
  30. // 类目轴
  31. axisType: 'category',
  32. // 自动切换
  33. autoPlay: true,
  34. // 间隔时间
  35. playInterval: 3000,
  36. // 位置
  37. left: '10%',
  38. right: '10%',
  39. bottom: '0%',
  40. width: '80%',
  41. // 轴的文本标签
  42. label: {
  43. // 默认状态
  44. normal: {
  45. textStyle: {
  46. color: '#ddd'
  47. }
  48. },
  49. // 高亮状态
  50. emphasis: {
  51. textStyle: {
  52. color: '#fff'
  53. }
  54. }
  55. },
  56. // 文字大小
  57. symbolSize: 10,
  58. // 线的样式
  59. lineStyle: {
  60. color: '#555'
  61. },
  62. // 选中点的样式
  63. checkpointStyle: {
  64. borderColor: '#888',
  65. borderWidth: 2
  66. },
  67. // 控件样式
  68. controlStyle: {
  69. // 上一步按钮
  70. showNextBtn: true,
  71. // 下一步按钮
  72. showPrevBtn: true,
  73. // 默认样式
  74. normal: {
  75. color: '#666',
  76. borderColor: '#666'
  77. },
  78. // 高亮样式
  79. emphasis: {
  80. color: '#aaa',
  81. borderColor: '#aaa'
  82. }
  83. }
  84. },
  85. // 柱形图右侧展示
  86. baseOption: {
  87. grid: {
  88. right: '2%',
  89. top: '15%',
  90. bottom: '10%',
  91. width: '20%'
  92. },
  93. // 中国地图
  94. geo: {
  95. // 展示
  96. show: true,
  97. // 中国地图
  98. map: 'china',
  99. // 开启缩放
  100. roam: true,
  101. // 初始缩放
  102. zoom: 0.8,
  103. // 中心点
  104. center: [113.83531246, 34.0267395887],
  105. // 默认状态的省份样式
  106. itemStyle: {
  107. normal: {
  108. // 边框色值
  109. borderColor: 'rgba(147, 235, 248, 1)',
  110. // 边框宽度
  111. borderWidth: 1,
  112. // 区域颜色
  113. areaColor: {
  114. // 经向色值
  115. type: 'radial',
  116. x: 0.5,
  117. y: 0.5,
  118. r: 0.5,
  119. colorStops: [
  120. // 0% 处的颜色
  121. {
  122. offset: 0,
  123. color: 'rgba(147, 235, 248, 0)'
  124. },
  125. // 100% 处的颜色
  126. {
  127. offset: 1,
  128. color: 'rgba(147, 235, 248, .2)'
  129. }
  130. ],
  131. // 缺省为 false
  132. globalCoord: false
  133. }
  134. },
  135. // 鼠标移入的色值
  136. emphasis: {
  137. areaColor: '#389BB7',
  138. borderWidth: 0
  139. }
  140. }
  141. }
  142. },
  143. // 绑定时间轴的多个图表
  144. options: []
  145. }
  146. // 为每一年度的图表添加数据
  147. props.data.voltageLevel.forEach((item, index) => {
  148. options.options.push({
  149. // 背景色
  150. backgroundColor: '#142037',
  151. title: [
  152. // 主标题,对应地图
  153. {
  154. text: '2019-2023 年度数据统计',
  155. left: '0%',
  156. top: '0',
  157. textStyle: {
  158. color: '#ccc',
  159. fontSize: 30
  160. }
  161. },
  162. // 副标题,对应柱形图
  163. {
  164. id: 'statistic',
  165. text: item + '年数据统计情况',
  166. right: '0%',
  167. top: '4%',
  168. textStyle: {
  169. color: '#ccc',
  170. fontSize: 20
  171. }
  172. }
  173. ],
  174. // X 轴配置
  175. xAxis: {
  176. // 数据轴
  177. type: 'value',
  178. // 脱离 0 值比例
  179. scale: true,
  180. // 位置
  181. position: 'top',
  182. // 不显示分割线
  183. splitLine: {
  184. show: false
  185. },
  186. // 不显示轴线
  187. axisLine: {
  188. show: false
  189. },
  190. // 不显示刻度尺
  191. axisTick: {
  192. show: false
  193. },
  194. // 类别文字
  195. axisLabel: {
  196. margin: 2,
  197. textStyle: {
  198. color: '#aaa'
  199. }
  200. }
  201. },
  202. // Y 轴
  203. yAxis: {
  204. // 选项轴
  205. type: 'category',
  206. // 轴线
  207. axisLine: {
  208. show: true,
  209. lineStyle: {
  210. color: '#ddd'
  211. }
  212. },
  213. // 轴刻度
  214. axisTick: {
  215. show: false,
  216. lineStyle: {
  217. color: '#ddd'
  218. }
  219. },
  220. // 轴标签
  221. axisLabel: {
  222. interval: 0,
  223. textStyle: {
  224. color: '#ddd'
  225. }
  226. },
  227. // 根据年份,获取对应数据
  228. data: props.data.categoryData[item].map((item) => item.name)
  229. },
  230. // 核心配置
  231. series: [
  232. // 柱形图
  233. {
  234. zlevel: 1.5,
  235. // 柱形图
  236. type: 'bar',
  237. // 每个柱子的色值
  238. itemStyle: {
  239. normal: {
  240. color: props.data.colors[index]
  241. }
  242. },
  243. // 根据年份,获取对应数据
  244. data: props.data.categoryData[item].map((item) => item.value)
  245. },
  246. // 散点图
  247. {
  248. // 散点(气泡)图
  249. type: 'effectScatter',
  250. // 使用地理坐标系
  251. coordinateSystem: 'geo',
  252. // 数据
  253. data: props.data.topData[item],
  254. // 标记大小
  255. symbolSize: function (val) {
  256. return val[2] / 4
  257. },
  258. // 绘制完成后显示特效
  259. showEffectOn: 'render',
  260. // 展示涟漪特效
  261. rippleEffect: {
  262. brushType: 'stroke'
  263. },
  264. // 文字
  265. label: {
  266. normal: {
  267. formatter: '{b}',
  268. position: 'right',
  269. show: true
  270. }
  271. },
  272. // 每一项的配置
  273. itemStyle: {
  274. normal: {
  275. color: props.data.colors[index],
  276. // 阴影配置
  277. shadowBlur: 5,
  278. shadowColor: props.data.colors[index]
  279. }
  280. },
  281. zlevel: 1
  282. }
  283. ]
  284. })
  285. })
  286. mChart.setOption(options)
  287. }
  288. </script>
  289. <style lang="scss" scoped></style>

RadarBar.vue

  1. <template>
  2. <div>
  3. <div>【云端报警风险】</div>
  4. <div ref="target" class="w-full h-full"></div>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { onMounted, ref, watch } from 'vue'
  9. import * as echarts from 'echarts'
  10. const props = defineProps({
  11. data: {
  12. type: Object,
  13. required: true
  14. }
  15. })
  16. const target = ref(null)
  17. let mChart = null
  18. onMounted(() => {
  19. mChart = echarts.init(target.value)
  20. renderChart()
  21. })
  22. const renderChart = () => {
  23. const options = {
  24. // 雷达图坐标系配置
  25. radar: {
  26. // 坐标系名
  27. name: {
  28. textStyle: {
  29. color: '#05D5FF',
  30. fontSize: 14
  31. }
  32. },
  33. // 雷达绘制类型。polygon 多边形
  34. shape: 'polygon',
  35. // 居中
  36. center: ['50%', '50%'],
  37. // 边境
  38. radius: '80%',
  39. // 开始的角度(可以避免绘制到边框之外)
  40. startAngle: 120,
  41. // 轴线配置
  42. axisLine: {
  43. lineStyle: {
  44. color: 'rgba(5, 213, 255, .8)'
  45. }
  46. },
  47. // 网格线配置
  48. splitLine: {
  49. show: true,
  50. lineStyle: {
  51. width: 1,
  52. color: 'rgba(5, 213, 255, .8)' // 设置网格的颜色
  53. }
  54. },
  55. // 指示器文字
  56. indicator: props.data.risks.map((item) => ({
  57. name: item.name,
  58. max: 100
  59. })),
  60. // 不展示拆分区域
  61. splitArea: {
  62. show: false
  63. }
  64. },
  65. // 坐标居中
  66. polar: {
  67. center: ['50%', '50%'], // 默认全局居中
  68. radius: '0%'
  69. },
  70. // 坐标角度
  71. angleAxis: {
  72. // 坐标轴刻度最小值
  73. min: 0,
  74. // 坐标轴分割间隔
  75. interval: 5,
  76. // 刻度增长逆时针
  77. clockwise: false,
  78. // 不显示坐标轴刻度
  79. axisTick: {
  80. show: false
  81. },
  82. // 不显示坐标轴文字
  83. axisLabel: {
  84. show: false
  85. },
  86. // 不显示坐标轴线
  87. axisLine: {
  88. show: false
  89. },
  90. // 不显示分割线
  91. splitLine: {
  92. show: false
  93. }
  94. },
  95. // 径向轴
  96. radiusAxis: {
  97. // 最小值
  98. min: 0,
  99. // 间隔
  100. interval: 20,
  101. // 不显示分割线
  102. splitLine: {
  103. show: true
  104. }
  105. },
  106. // 图表核心配置
  107. series: [
  108. {
  109. // 雷达图
  110. type: 'radar',
  111. // 拐点的样式,还可以取值'rect','angle'
  112. symbol: 'circle',
  113. // 拐点的大小
  114. symbolSize: 10,
  115. // 折线拐点标志的样式
  116. itemStyle: {
  117. normal: {
  118. color: '#05D5FF'
  119. }
  120. },
  121. // 区域填充样式
  122. areaStyle: {
  123. normal: {
  124. color: '#05D5FF',
  125. opacity: 0.5
  126. }
  127. },
  128. // 线条样式
  129. lineStyle: {
  130. width: 2,
  131. color: '#05D5FF'
  132. },
  133. // 图形上的文本标签
  134. label: {
  135. normal: {
  136. show: true,
  137. formatter: (params) => {
  138. return params.value
  139. },
  140. color: '#fff'
  141. }
  142. },
  143. // 数据
  144. data: [
  145. {
  146. value: props.data.risks.map((item) => item.value)
  147. }
  148. ]
  149. }
  150. ]
  151. }
  152. mChart.setOption(options)
  153. }
  154. // 监听数据的变化,重新渲染图表
  155. watch(
  156. () => props.data,
  157. () => {
  158. renderChart()
  159. }
  160. )
  161. </script>

Relation.vue

  1. <template>
  2. <div>
  3. <div>【数据传递信息】</div>
  4. <div ref="target" class="w-full h-full"></div>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { onMounted, ref, watch } from 'vue'
  9. import * as echarts from 'echarts'
  10. const props = defineProps({
  11. data: {
  12. type: Object,
  13. required: true
  14. }
  15. })
  16. // 获取 dom 实例
  17. const target = ref(null)
  18. // echarts 实例变量
  19. let mChart = null
  20. // 在 mounted 生命周期之后,实例化 echarts
  21. onMounted(() => {
  22. mChart = echarts.init(target.value)
  23. // 渲染 echarts
  24. renderChart()
  25. })
  26. // 渲染图表
  27. const renderChart = () => {
  28. const options = {
  29. // X 轴不需要展示
  30. xAxis: {
  31. show: false,
  32. type: 'value'
  33. },
  34. // X 轴不需要展示
  35. yAxis: {
  36. show: false,
  37. type: 'value'
  38. },
  39. // 核心数据配置
  40. series: [
  41. {
  42. // 用于展现节点以及节点之间的关系数据
  43. type: 'graph',
  44. // 不采用任何布局
  45. layout: 'none',
  46. // 使用二维的直角坐标系
  47. coordinateSystem: 'cartesian2d',
  48. // 节点标记的大小
  49. symbolSize: 26,
  50. // z-index
  51. z: 3,
  52. // 边界标签(线条文字)
  53. edgeLabel: {
  54. normal: {
  55. show: true,
  56. color: '#fff',
  57. textStyle: {
  58. fontSize: 14
  59. },
  60. formatter: function (params) {
  61. let txt = ''
  62. if (params.data.speed !== undefined) {
  63. txt = params.data.speed
  64. }
  65. return txt
  66. }
  67. }
  68. },
  69. // 圆饼下文字
  70. label: {
  71. normal: {
  72. show: true,
  73. position: 'bottom',
  74. color: '#5e5e5e'
  75. }
  76. },
  77. // 边两端的标记类型
  78. edgeSymbol: ['none', 'arrow'],
  79. // 边两端的标记大小
  80. edgeSymbolSize: 8,
  81. // 圆数据
  82. data: props.data.relations.map((item) => {
  83. // id 为 0 ,表示数据中心,数据中心单独设置
  84. if (item.id !== 0) {
  85. return {
  86. name: item.name,
  87. category: 0,
  88. active: true,
  89. speed: `${item.speed}kb/s`,
  90. // 位置
  91. value: item.value
  92. }
  93. } else {
  94. return {
  95. name: item.name,
  96. // 位置
  97. value: item.value,
  98. // 数据中心圆的大小
  99. symbolSize: 100,
  100. // 圆的样式
  101. itemStyle: {
  102. normal: {
  103. // 渐变色
  104. color: {
  105. colorStops: [
  106. { offset: 0, color: '#157eff' },
  107. { offset: 1, color: '#35c2ff' }
  108. ]
  109. }
  110. }
  111. },
  112. // 字体
  113. label: { normal: { fontSize: '14' } }
  114. }
  115. }
  116. }),
  117. // 线
  118. links: props.data.relations.map((item, index) => ({
  119. // 方向
  120. source: item.source,
  121. target: item.target,
  122. // 线上的文字
  123. speed: `${item.speed}kb/s`,
  124. // 线的样式
  125. lineStyle: { normal: { color: '#12b5d0', curveness: 0.2 } },
  126. // 文字位置
  127. label: {
  128. show: true,
  129. position: 'middle',
  130. offset: [10, 0]
  131. }
  132. }))
  133. },
  134. {
  135. // 用于带有起点和终点信息的线数据的绘制
  136. type: 'lines',
  137. // 使用二维的直角坐标系
  138. coordinateSystem: 'cartesian2d',
  139. // z-index
  140. z: 1,
  141. // 线特效的配置
  142. effect: {
  143. show: true,
  144. smooth: false,
  145. trailLength: 0,
  146. symbol: 'arrow',
  147. color: 'rgba(55,155,255,0.5)',
  148. symbolSize: 12
  149. },
  150. // 线的样式
  151. lineStyle: {
  152. normal: {
  153. curveness: 0.2
  154. }
  155. },
  156. // 线的数据级,前后线需要重合。数据固定
  157. data: [
  158. [{ coord: [0, 300] }, { coord: [50, 200] }],
  159. [{ coord: [0, 100] }, { coord: [50, 200] }],
  160. [{ coord: [50, 200] }, { coord: [100, 100] }],
  161. [{ coord: [50, 200] }, { coord: [100, 300] }]
  162. ]
  163. }
  164. ]
  165. }
  166. mChart.setOption(options)
  167. }
  168. // 监听数据的变化,重新渲染图表
  169. watch(
  170. () => props.data,
  171. () => {
  172. renderChart()
  173. }
  174. )
  175. </script>
  176. <style lang="scss" scoped></style>

RingBar.vue

  1. <template>
  2. <div>
  3. <div>【大区异常处理】</div>
  4. <div ref="target" class="w-full h-full"></div>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { onMounted, ref, watch } from 'vue'
  9. import * as echarts from 'echarts'
  10. const props = defineProps({
  11. data: {
  12. type: Object,
  13. required: true
  14. }
  15. })
  16. const target = ref(null)
  17. let mChart = null
  18. onMounted(() => {
  19. mChart = echarts.init(target.value)
  20. renderChart()
  21. })
  22. /**
  23. * 双环形图绘制原理:
  24. * 1. 环形图通过饼图绘制。内外边距的距离减小,即为环形。环形中心点需要不断改变,否则会重叠
  25. * 2. 环形图绘制分为 上层和底层 两部分。上层作为绘制进度,底层作为背景图
  26. * 3. 依据 getSeriesData 生成对应的 上层和底层 series 数据,进行渲染
  27. */
  28. const getSeriesData = () => {
  29. const series = []
  30. props.data.abnormals.forEach((item, index) => {
  31. // 上层环形绘制
  32. series.push({
  33. name: item.name,
  34. // 使用饼图绘制,减少饼图宽度即为环形图
  35. type: 'pie',
  36. // 逆时针排布
  37. clockWise: false,
  38. // 不展示鼠标移入动画
  39. hoverAnimation: false,
  40. // 半径位置,需要依次递减,否则会重复在一处进行展示
  41. radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],
  42. // 中心点
  43. center: ['55%', '55%'],
  44. // 不展示 label
  45. label: { show: false },
  46. // 数据配置
  47. data: [
  48. // 设置数据与名称
  49. { value: item.value, name: item.name },
  50. // 最大数据,展示比例
  51. {
  52. value: 1000,
  53. name: '',
  54. itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },
  55. tooltip: { show: false },
  56. hoverAnimation: false
  57. }
  58. ]
  59. })
  60. // 底层图
  61. series.push({
  62. name: item.name,
  63. type: 'pie',
  64. // 图形不响应事件
  65. silent: true,
  66. // z-index: 置于底层
  67. z: 1,
  68. // 逆时针排布
  69. clockWise: false,
  70. // 不展示鼠标移入动画
  71. hoverAnimation: false,
  72. // 半径位置,需要依次递减,否则会重复在一处进行展示
  73. radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],
  74. // 中心点
  75. center: ['55%', '55%'],
  76. // 不展示 label
  77. label: { show: false },
  78. // 数据
  79. data: [
  80. // 绘制底线 75%
  81. {
  82. value: 7.5,
  83. itemStyle: { color: 'rgb(3, 31, 62)', borderWidth: 0 },
  84. tooltip: { show: false },
  85. hoverAnimation: false
  86. },
  87. // 绘制底线 25% 透明区域
  88. {
  89. value: 2.5,
  90. name: '',
  91. itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },
  92. tooltip: { show: false },
  93. hoverAnimation: false
  94. }
  95. ]
  96. })
  97. })
  98. return series
  99. }
  100. const renderChart = () => {
  101. const options = {
  102. // 图例配置
  103. legend: {
  104. show: true,
  105. // 图例色块
  106. icon: 'circle',
  107. // 位置
  108. top: '14%',
  109. left: '60%',
  110. // 展示数据
  111. data: props.data.abnormals.map((item) => item.name),
  112. // 总宽度(一列)
  113. width: -5,
  114. // 每个色块的宽
  115. itemWidth: 10,
  116. // 每个色块的高度
  117. itemHeight: 10,
  118. // item 间距
  119. itemGap: 6,
  120. // 展示内容
  121. formatter: function (name) {
  122. return '{title|' + name + '}'
  123. },
  124. // 字体配置
  125. textStyle: {
  126. rich: {
  127. title: {
  128. fontSize: 12,
  129. lineHeight: 5,
  130. color: 'rgba(255,255,255,0.8)'
  131. }
  132. }
  133. }
  134. },
  135. // 提示层
  136. tooltip: {
  137. show: true,
  138. trigger: 'item',
  139. formatter: '{a}<br>{b}:{c}({d}%)'
  140. },
  141. // Y 轴展示选项
  142. yAxis: [
  143. {
  144. type: 'category',
  145. // 反向展示
  146. inverse: true,
  147. // 不展示轴线
  148. axisLine: {
  149. show: false
  150. },
  151. // 不展示刻度
  152. axisTick: {
  153. show: false
  154. }
  155. }
  156. ],
  157. // X 轴不展示
  158. xAxis: [
  159. {
  160. show: false
  161. }
  162. ],
  163. // 每两个标记一条线
  164. series: getSeriesData()
  165. }
  166. mChart.setOption(options)
  167. }
  168. // 监听数据的变化,重新渲染图表
  169. watch(
  170. () => props.data,
  171. () => {
  172. renderChart()
  173. }
  174. )
  175. </script>
  176. <style lang="scss" scoped></style>

TotalData.vue

  1. <template>
  2. <div class="p-6">
  3. <div class="text-slate-300 text-center">
  4. 数据总量:
  5. <span
  6. ref="totalCountTarget"
  7. class="text-7xl ml-2 mr-2 font-bold font-[Electronic] text-gradient"
  8. >
  9. 679,473,929
  10. </span>
  11. 条记录
  12. </div>
  13. <div class="mt-3 flex flex-wrap">
  14. <div class="w-1/3 text-center text-slate-400 text-sm">
  15. 华北:
  16. <span ref="city1" class="text-[#5DC5EF] text-3xl font-[Electronic]">
  17. 8,778,988
  18. </span>
  19. </div>
  20. <div class="w-1/3 text-center text-slate-400 text-sm">
  21. 东北:<span
  22. ref="city2"
  23. class="text-[#5DC5EF] text-3xl font-[Electronic]"
  24. >8,778,988</span
  25. >
  26. </div>
  27. <div class="w-1/3 text-center text-slate-400 text-sm">
  28. 华东:<span
  29. ref="city3"
  30. class="text-[#5DC5EF] text-3xl font-[Electronic]"
  31. >8,778,988</span
  32. >
  33. </div>
  34. <div class="w-1/3 text-center text-slate-400 text-sm">
  35. 中南:<span
  36. ref="city4"
  37. class="text-[#5DC5EF] text-3xl font-[Electronic]"
  38. >8,778,988</span
  39. >
  40. </div>
  41. <div class="w-1/3 text-center text-slate-400 text-sm">
  42. 西南:<span
  43. ref="city5"
  44. class="text-[#5DC5EF] text-3xl font-[Electronic]"
  45. >8,778,988</span
  46. >
  47. </div>
  48. <div class="w-1/3 text-center text-slate-400 text-sm">
  49. 西北:<span
  50. ref="city6"
  51. class="text-[#5DC5EF] text-3xl font-[Electronic]"
  52. >8,778,988</span
  53. >
  54. </div>
  55. </div>
  56. </div>
  57. </template>
  58. <script setup>
  59. import { onMounted, ref } from 'vue'
  60. import { CountUp } from 'countup.js'
  61. const props = defineProps({
  62. data: {
  63. type: Object,
  64. required: true
  65. }
  66. })
  67. const totalCountTarget = ref(null)
  68. const city1 = ref(null)
  69. const city2 = ref(null)
  70. const city3 = ref(null)
  71. const city4 = ref(null)
  72. const city5 = ref(null)
  73. const city6 = ref(null)
  74. onMounted(() => {
  75. new CountUp(totalCountTarget.value, props.data.total).start()
  76. new CountUp(city1.value, props.data.hb).start()
  77. new CountUp(city2.value, props.data.db).start()
  78. new CountUp(city3.value, props.data.hd).start()
  79. new CountUp(city4.value, props.data.zn).start()
  80. new CountUp(city5.value, props.data.xn).start()
  81. new CountUp(city6.value, props.data.xb).start()
  82. })
  83. </script>
  84. <style lang="scss" scoped></style>

VerticalBar.vue

  1. <template>
  2. <div>
  3. <div>【服务资源占用比】</div>
  4. <div ref="target" class="w-full h-full"></div>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { onMounted, ref, watch } from 'vue'
  9. import * as echarts from 'echarts'
  10. const props = defineProps({
  11. data: {
  12. type: Object,
  13. required: true
  14. }
  15. })
  16. const target = ref(null)
  17. let mChart = null
  18. onMounted(() => {
  19. mChart = echarts.init(target.value)
  20. renderChart()
  21. })
  22. const renderChart = () => {
  23. const options = {
  24. // X 轴展示选项
  25. xAxis: {
  26. type: 'category',
  27. // 根据根据服务端数据筛选
  28. data: props.data.servers.map((item) => item.name),
  29. // 文字色值
  30. axisLabel: {
  31. color: '#9EB1C8'
  32. }
  33. },
  34. // Y 轴展示数据
  35. yAxis: {
  36. // 数据展示
  37. type: 'value',
  38. // 不显示轴
  39. show: false,
  40. // 最大值(防止触顶)
  41. max: function (value) {
  42. // 取整
  43. return parseInt(value.max * 1.2)
  44. }
  45. },
  46. // echarts 网格绘制的位置,对应 上、右、下、左
  47. grid: {
  48. top: 16,
  49. right: 0,
  50. bottom: 26,
  51. left: -26,
  52. // 计算边距时,包含标签
  53. containLabel: true
  54. },
  55. // 柱形图核心配置
  56. series: {
  57. // 柱形图
  58. type: 'bar',
  59. // 数据筛选
  60. data: props.data.servers.map((item) => ({
  61. name: item.name,
  62. value: item.value
  63. })),
  64. // 每个轴的样式
  65. itemStyle: {
  66. color: '#479AD3', // 设置柱子的颜色
  67. barBorderRadius: 5, // 设置柱子的圆角
  68. shadowColor: 'rgba(0, 0, 0, 0.3)', // 设置柱子的阴影颜色
  69. shadowBlur: 5 // 设置柱子的阴影模糊大小
  70. },
  71. // 柱子宽度
  72. barWidth: 12,
  73. // 文本
  74. label: {
  75. show: true,
  76. // 设置标签位置为右侧
  77. position: 'top',
  78. textStyle: {
  79. // 设置标签文本颜色
  80. color: '#fff'
  81. },
  82. formatter: '{c}%'
  83. }
  84. }
  85. }
  86. mChart.setOption(options)
  87. }
  88. // 监听数据的变化,重新渲染图表
  89. watch(
  90. () => props.data,
  91. () => {
  92. renderChart()
  93. }
  94. )
  95. </script>
  96. <style lang="scss" scoped></style>

WordCloud.vue

  1. <template>
  2. <div>
  3. <div>【关键词条】</div>
  4. <div ref="target" class="w-full h-full"></div>
  5. </div>
  6. </template>
  7. <script setup>
  8. import { onMounted, ref, watch } from 'vue'
  9. import * as echarts from 'echarts'
  10. import 'echarts-wordcloud'
  11. const props = defineProps({
  12. data: {
  13. type: Object,
  14. required: true
  15. }
  16. })
  17. // 获取 dom 实例
  18. const target = ref(null)
  19. // echarts 实例变量
  20. let mChart = null
  21. // 在 mounted 生命周期之后,实例化 echarts
  22. onMounted(() => {
  23. mChart = echarts.init(target.value)
  24. // 渲染 echarts
  25. renderChart()
  26. })
  27. /**
  28. * 生成随机色值
  29. */
  30. const randomRGB = () => {
  31. const r = Math.floor(Math.random() * 255)
  32. const g = Math.floor(Math.random() * 255)
  33. const b = Math.floor(Math.random() * 255)
  34. return `rgb(${r}, ${g}, ${b})`
  35. }
  36. // 渲染图表
  37. const renderChart = () => {
  38. const options = {
  39. series: [
  40. {
  41. // 类型
  42. type: 'wordCloud',
  43. // 数据映射文本的大小范围
  44. sizeRange: [8, 46],
  45. // 文字旋转范围
  46. rotationRange: [0, 0],
  47. // 单词之间的间距
  48. gridSize: 0,
  49. // 渲染动画
  50. layoutAnimation: true,
  51. // 字体
  52. textStyle: {
  53. // 随机色值
  54. color: randomRGB
  55. },
  56. // 高亮字体
  57. emphasis: {
  58. textStyle: {
  59. fontWeight: 'bold',
  60. color: '#000'
  61. }
  62. },
  63. // 数据
  64. data: props.data.datas
  65. }
  66. ]
  67. }
  68. mChart.setOption(options)
  69. }
  70. // 监听数据的变化,重新渲染图表
  71. watch(
  72. () => props.data,
  73. () => {
  74. renderChart()
  75. }
  76. )
  77. </script>
  78. <style lang="scss" scoped></style>

api/visualization.js

  1. import request from '@/utils/request.js'
  2. // 默认不支持@,需配置vite.config.js
  3. export const getVisualization = () => {
  4. return request({
  5. url: '/visualization'
  6. })
  7. }

utils/request.js

  1. import axios from 'axios'
  2. const service = axios.create({
  3. baseURL: 'https://api.imooc-web.lgdsunday.club/api',
  4. timeout: 5000
  5. })
  6. // 请求拦截器
  7. service.interceptors.request.use(
  8. (config) => {
  9. config.headers.icode = 'input you icode'
  10. return config // 必须返回配置
  11. },
  12. (error) => {
  13. return Promise.reject(error)
  14. }
  15. )
  16. // 响应拦截器
  17. service.interceptors.response.use((response) => {
  18. const { success, message, data } = response.data
  19. // 要根据success的成功与否决定下面的操作
  20. if (success) {
  21. return data
  22. } else {
  23. return Promise.reject(new Error(message))
  24. }
  25. })
  26. export default service

style.css

  1. @tailwind base;
  2. @tailwind components;
  3. @tailwind utilities;
  4. @font-face {
  5. font-family: 'Electronic';
  6. src: url('./assets/fonts/FX-LED.ttf') format('truetype');
  7. }
  8. .text-gradient {
  9. /* 背景渐变 */
  10. background-image: linear-gradient(to bottom, #e5e4ea, #5EA8F2);
  11. /* 元素背景延伸到文本 */
  12. -webkit-background-clip: text;
  13. /* 文本字符填充颜色透明 */
  14. -webkit-text-fill-color: transparent;
  15. }

tailwind.config.js

  1. /** @type {import('tailwindcss').Config} */
  2. export default {
  3. content: [
  4. "./index.html",
  5. "./src/**/*.{vue,js,ts,jsx,tsx}",
  6. ],
  7. theme: {
  8. extend: {},
  9. },
  10. plugins: [],
  11. }

vite.config.js

  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. // https://vitejs.dev/config/
  4. export default defineConfig({
  5. plugins: [vue()],
  6. // visualizaation.js中用到了@,因此这里需要配置
  7. // 添加别名
  8. resolve: {
  9. alias: {
  10. '@': '/src'
  11. }
  12. },
  13. server: {
  14. hmr: true
  15. }
  16. })

三、效果

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/801657
推荐阅读
相关标签
  

闽ICP备14008679号