基于Echarts的大屏可视化

news2024/11/13 7:52:17

效果图

基于vue3+echarts+Tailwind CSS技术实现

实现思路

新建一个新项目

找任一目录进行

pnpm create vite@latest

选择vue和js开始项目

导入tailwindcss

https://tailwindcss.com/

选择vue按照里面的步骤一步一步完成即可

将事先准备好的资料导入到assets包中即可

写入项目的内容

将app.vue中的内容更改为

<template>
  <div class="bg-[url('src/assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-3 flex">
    <!---->
    <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
    </div>
    <!---->
    <div class="w-1/2 mr-5 flex flex-col">
    </div>
    <!---->
    <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
    </div>
  </div>
</template>

此时项目的样式为

页面可被分为八个部分,分别是左边三个(见上完整图示),右边三个,中间两个

此时可以新建八个页面,分别为八个子组件,app.vue是父组件

导入子组件,并且更改每个组件的图占比

<script setup>
import HorizontalBar from './components/HorizontalBar.vue';
import RadarBar from './components/RadarBar.vue';
import Relation from './components/Relation.vue';
import ToatlData from './components/TotalData.vue';
import MapChart from './components/MapChart.vue';
import VerticalBar from './components/VerticalBar.vue';
import RingBar from './components/RingBar.vue';
import WordCloud from './components/WordCloud.vue';
</script>


<template>
  <div>
    <!-- 自定义背景,背景bg,[]中放置图片路径 -->
    <div class="bg-[url('assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-5 flex overflow-hidden">
      <!---->
      <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
        <!-- 横向柱状图 -->
        <HorizontalBar class="h-1/3 box-border pb-4"/>
        <!-- 雷达图 -->
        <RadarBar class="h-1/3 box-border pb-4"/>
        <!-- 关系图 -->
        <Relation class="h-1/3"/>
      </div>
      <!---->
      <div class="w-1/2 mr-5 flex flex-col">
        <!-- 数据总览图 -->
        <ToatlData class="bg-opacity-50 bg-slate-800 p-3"/>
        <!-- 地图可视化 -->
        <MapChart class="bg-opacity-50 bg-slate-800 p-3 mt-4 flex-1"/>
      </div>
      <!---->
      <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
        <!-- 竖向柱状图 -->
        <VerticalBar class="h-1/3 box-border pb-4"/>
        <!-- 环形图 -->
        <RingBar class="h-1/3 box-border pb-4"/>
        <!-- 文档云图 -->
        <WordCloud class="h-1/3"/>
      </div>
    </div>
    
  </div>
</template> 

此时的图片就成了这个样子

配置拦截器,并调接口

在src目录中新建utils/request.js

import axios from 'axios'

const service = axios.create({
    baseURL: 'https://api.imooc-web.lgdsunday.club/api',
    timeout: 5000
})

// 请求拦截器
service.interceptors.request.use(
    (config) => {
        config.headers.icode = 'hellosunday' // 这里的icode关注公众号获得
        return config // 必须返回配置
    },
    (error) => {
        return Promise.reject(error)
    }
)

// 响应拦截器
service.interceptors.response.use((response) => {
    const { success, message, data } = response.data
    //   要根据success的成功与否决定下面的操作
    if (success) {
        return data
    } else {
        return Promise.reject(new Error(message))
    }
})

export default service

在src目录中新建api/visualization.js

import request from "../utils/request.js";
export const getVisualization = () => request({
    url:'/visualization',
    method:'GET'
})

此时就可以获取后台返回的数据了

在app.vue父组件中获取接口返回的数据

// 获取大屏可视化的数据
const data = ref();
const getData = async () => {
  data.value = await getVisualization()
}
getData()

// 每五秒更新一下数据
setInterval(() => {
  getData()
}, 5000)

data.value中的数据是这样的

之后就可以将获取的数据传递给子组件

<template>
  <div class="bg-[url('src/assets/imgs/bg.jpg')] bg-cover bg-center h-screen text-white p-3 flex overflow-hidden ">
    <!---->
    <div class="flex-1 mr-5 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
      <!--横向柱状图-->
      <HorizontalBar class="h-1/3 box-border pb-4" :data="data.regionData"/>
      <!--雷达图-->
      <RadarBar class="h-1/3 box-border pb-4" :data="data.riskData"/>
      <!--关系图-->
      <Relation class="h-1/3" :data="data.relationData"/>
    </div>
    <!---->
    <div class="w-1/2 mr-5 flex flex-col">
      <!--数据总览柱状图-->
      <TotalData class="bg-opacity-50 bg-slate-800 p-3" :data="data.totalData"/>
      <!--地图可视化-->
      <MapChart class="bg-opacity-50 bg-slate-800 p-3 mt-4 flex-1" :data="data.mapData"/>
    </div>
    <!---->
    <div class="flex-1 bg-opacity-50 bg-slate-800 p-3 flex flex-col">
      <!--竖向柱状图-->
      <VerticalBar class="h-1/3 box-border pb-4" :data="data.serverData"/>
      <!--环形图-->
      <RingBar class="h-1/3 box-border pb-4" :data="data.abnormalData"/>
      <!--数据云图-->
      <WordCloud class="h-1/3" :data="data.wordCloudData"/>
    </div>
  </div>
</template>

横竖两个柱状图

在components的HorizontalBar.vue里面进行配置
代码如下

<script setup>
import {onMounted, ref, watch} from "vue";
import * as echarts from 'echarts'

const props = defineProps({
  data: {
    type: Object,
    required: true,
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  mChart = echarts.init(target.value)
  renderChart()
})
// 2.构建option配置对象
const renderChart = () => {
  const options = {
    // X 轴展示数据
    xAxis: {
      // 数据展示
      type: 'value',
      // 不显示轴
      show: false,
      // 最大值(防止触顶)
      max: function (value) {
        // 取整
        return parseInt(value.max * 1.2)
      }
    },
    // Y 轴展示选项
    yAxis: {
      type: 'category',
      // 根据根据服务端数据筛选
      data: props.data.regions.map((item) => item.name),
      // 反向展示
      inverse: true,
      // 不展示轴线
      axisLine: {
        show: false
      },
      // 不展示刻度
      axisTick: {
        show: false // 取消 Y 轴刻度
      },
      // 文字色值
      axisLabel: {
        color: '#9EB1C8'
      }
    },
    // echarts 网格绘制的位置,对应 上、右、下、左
    grid: {
      top: 0,
      right: 0,
      bottom: 0,
      left: 0,
      // 计算边距时,包含标签
      containLabel: true
    },
    // 柱形图核心配置
    series: [
      {
        // 图表类型
        type: 'bar',
        // 数据筛选
        data: props.data.regions.map((item) => ({
          name: item.name,
          value: item.value
        })),
        // 显示背景
        showBackground: true,
        // 背景色
        backgroundStyle: {
          color: 'rgba(180, 180, 180, 0.2)'
        },
        // 每个轴的样式
        itemStyle: {
          color: '#479AD3', // 设置柱子的颜色
          barBorderRadius: 5, // 设置柱子的圆角
          shadowColor: 'rgba(0, 0, 0, 0.3)', // 设置柱子的阴影颜色
          shadowBlur: 5 // 设置柱子的阴影模糊大小
        },
        // 轴宽度
        barWidth: 12,
        // 轴上的字体
        label: {
          show: true,
          // 设置标签位置为右侧
          position: 'right',
          textStyle: {
            // 设置标签文本颜色
            color: '#fff'
          }
        }
      }
    ]
  }

  mChart.setOption(options)
}

watch(
    () => props.data,
    () => {
      renderChart()
    }
)
</script>

<template>
  <div>
    <div>【大区数据信息 - 按行业分类】</div>
    <div ref="target" class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

在components/VerticalBar.vue 中进行配置,代码如下

<script setup>
import {onMounted, ref, watch} from "vue";
import * as echarts from 'echarts'

const props = defineProps({
  data: {
    type: Object,
    required: true,
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  mChart = echarts.init(target.value)
  renderChart()
})
// 2.构建option配置对象
const renderChart = () => {
  const options = {
    // X 轴展示数据
    xAxis: {
      // 数据展示
      type: 'value',
      // 不显示轴
      show: false,
      // 最大值(防止触顶)
      max: function (value) {
        // 取整
        return parseInt(value.max * 1.2)
      }
    },
    // Y 轴展示选项
    yAxis: {
      type: 'category',
      // 根据根据服务端数据筛选
      data: props.data.regions.map((item) => item.name),
      // 反向展示
      inverse: true,
      // 不展示轴线
      axisLine: {
        show: false
      },
      // 不展示刻度
      axisTick: {
        show: false // 取消 Y 轴刻度
      },
      // 文字色值
      axisLabel: {
        color: '#9EB1C8'
      }
    },
    // echarts 网格绘制的位置,对应 上、右、下、左
    grid: {
      top: 0,
      right: 0,
      bottom: 0,
      left: 0,
      // 计算边距时,包含标签
      containLabel: true
    },
    // 柱形图核心配置
    series: [
      {
        // 图表类型
        type: 'bar',
        // 数据筛选
        data: props.data.regions.map((item) => ({
          name: item.name,
          value: item.value
        })),
        // 显示背景
        showBackground: true,
        // 背景色
        backgroundStyle: {
          color: 'rgba(180, 180, 180, 0.2)'
        },
        // 每个轴的样式
        itemStyle: {
          color: '#479AD3', // 设置柱子的颜色
          barBorderRadius: 5, // 设置柱子的圆角
          shadowColor: 'rgba(0, 0, 0, 0.3)', // 设置柱子的阴影颜色
          shadowBlur: 5 // 设置柱子的阴影模糊大小
        },
        // 轴宽度
        barWidth: 12,
        // 轴上的字体
        label: {
          show: true,
          // 设置标签位置为右侧
          position: 'right',
          textStyle: {
            // 设置标签文本颜色
            color: '#fff'
          }
        }
      }
    ]
  }

  mChart.setOption(options)
}

watch(
    () => props.data,
    () => {
      renderChart()
    }
)
</script>

<template>
  <div>
    <div>【大区数据信息 - 按行业分类】</div>
    <div ref="target" class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

雷达图与饼图

  1. 雷达图

RadarBar.vue代码如下

<script setup>
import {onMounted, ref, watch} from "vue";
import * as echarts from 'echarts'
const props = defineProps({
  data: {
    type: Object,
    required: true
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  mChart =  echarts.init(target.value)
  renderChart()
} )
// 2.构建option配置对象
const renderChart = () => {
  const options = {
    // 雷达图坐标系配置
    radar: {
      // 坐标系名
      name: {
        textStyle: {
          color: '#05D5FF',
          fontSize: 14
        }
      },
      // 雷达绘制类型。polygon 多边形
      shape: 'polygon',
      // 居中
      center: ['50%', '50%'],
      // 边境
      radius: '80%',
      // 开始的角度(可以避免绘制到边框之外)
      startAngle: 120,
      // 轴线配置
      axisLine: {
        lineStyle: {
          color: 'rgba(5, 213, 255, .8)'
        }
      },
      // 网格线配置
      splitLine: {
        show: true,
        lineStyle: {
          width: 1,
          color: 'rgba(5, 213, 255, .8)' // 设置网格的颜色
        }
      },
      // 指示器文字
      indicator: props.data.risks.map(item=>({
        name: item.name,
        max: 100
      })),
      // 不展示拆分区域
      splitArea: {
        show: false
      }
    },
    // 坐标居中
    polar: {
      center: ['50%', '50%'], // 默认全局居中
      radius: '0%'
    },
    // 坐标角度
    angleAxis: {
      // 坐标轴刻度最小值
      min: 0,
      // 坐标轴分割间隔
      interval: 5,
      // 刻度增长逆时针
      clockwise: false,
      // 不显示坐标轴刻度
      axisTick: {
        show: false
      },
      // 不显示坐标轴文字
      axisLabel: {
        show: false
      },
      // 不显示坐标轴线
      axisLine: {
        show: false
      },
      // 不显示分割线
      splitLine: {
        show: false
      }
    },
    // 径向轴
    radiusAxis: {
      // 最小值
      min: 0,
      // 间隔
      interval: 20,
      // 不显示分割线
      splitLine: {
        show: true
      }
    },
    // 图表核心配置
    series: [
      {
        // 雷达图
        type: 'radar',
        // 拐点的样式,还可以取值'rect','angle'等
        symbol: 'circle',
        // 拐点的大小
        symbolSize: 10,
        // 折线拐点标志的样式
        itemStyle: {
          normal: {
            color: '#05D5FF'
          }
        },
        // 区域填充样式
        areaStyle: {
          normal: {
            color: '#05D5FF',
            opacity: 0.5
          }
        },
        // 线条样式
        lineStyle: {
          width: 2,
          color: '#05D5FF'
        },
        // 图形上的文本标签
        label: {
          normal: {
            show: true,
            formatter: (params) => {
              return params.value
            },
            color: '#fff'
          }
        },
        // 数据
        data: [
          {
            value: props.data.risks.map(item=>item.value)
          }
        ]
      }
    ]
  }

  mChart.setOption(options)
}

watch(
    () => props.data,
    () => {
      renderChart()
    }
)
</script>

<template>
  <div>
    <div>云端报警风险</div>
    <div ref="target" class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

  1. 饼图

RingBar.vue代码如下

<script setup>
import {onMounted, ref, watch} from "vue";
import * as echarts from 'echarts'
const props = defineProps({
  data: {
    type: Object,
    required: true
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  mChart = echarts.init(target.value)
  renderChart()
})


/**
 * 双环形图绘制原理:
 * 1. 环形图通过饼图绘制。内外边距的距离减小,即为环形。环形中心点需要不断改变,否则会重叠
 * 2. 环形图绘制分为 上层和底层 两部分。上层作为绘制进度,底层作为背景图
 * 3. 依据 getSeriesData 生成对应的 上层和底层 series 数据,进行渲染
 */
const getSeriesData = () => {
  const series = []

  props.data.abnormals.forEach((item, index) => {
    // 上层环形绘制
    series.push({
      name: item.name,
      // 使用饼图绘制,减少饼图宽度即为环形图
      type: 'pie',
      // 逆时针排布
      clockWise: false,
      // 不展示鼠标移入动画
      hoverAnimation: false,
      // 半径位置,需要依次递减,否则会重复在一处进行展示
      radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],
      // 中心点
      center: ['55%', '55%'],
      // 不展示 label
      label: { show: false },
      // 数据配置
      data: [
        // 设置数据与名称
        { value: item.value, name: item.name },
        // 最大数据,展示比例
        {
          value: 1000,
          name: '',
          itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },
          tooltip: { show: false },
          hoverAnimation: false
        }
      ]
    })

    // 底层图
    series.push({
      name: item.name,
      type: 'pie',
      // 图形不响应事件
      silent: true,
      // z-index: 置于底层
      z: 1,
      // 逆时针排布
      clockWise: false,
      // 不展示鼠标移入动画
      hoverAnimation: false,
      // 半径位置,需要依次递减,否则会重复在一处进行展示
      radius: [73 - index * 15 + '%', 68 - index * 15 + '%'],
      // 中心点
      center: ['55%', '55%'],
      // 不展示 label
      label: { show: false },
      // 数据
      data: [
        // 绘制底线 75%
        {
          value: 7.5,
          itemStyle: { color: 'rgb(3, 31, 62)', borderWidth: 0 },
          tooltip: { show: false },
          hoverAnimation: false
        },
        // 绘制底线 25% 透明区域
        {
          value: 2.5,
          name: '',
          itemStyle: { color: 'rgba(0,0,0,0)', borderWidth: 0 },
          tooltip: { show: false },
          hoverAnimation: false
        }
      ]
    })
  })

  return series
}

const renderChart = () => {
  const options = {
    // 图例配置
    legend: {
      show: true,
      // 图例色块
      icon: 'circle',
      // 位置
      top: '14%',
      left: '60%',
      // 展示数据
      data: props.data.abnormals.map((item) => item.name),
      // 总宽度(一列)
      width: -5,
      // 每个色块的宽
      itemWidth: 10,
      // 每个色块的高度
      itemHeight: 10,
      // item 间距
      itemGap: 6,
      // 展示内容
      formatter: function (name) {
        return '{title|' + name + '}'
      },
      // 字体配置
      textStyle: {
        rich: {
          title: {
            fontSize: 12,
            lineHeight: 5,
            color: 'rgba(255,255,255,0.8)'
          }
        }
      }
    },
    // 提示层
    tooltip: {
      show: true,
      trigger: 'item',
      formatter: '{a}<br>{b}:{c}({d}%)'
    },
    // Y 轴展示选项
    yAxis: [
      {
        type: 'category',
        // 反向展示
        inverse: true,
        // 不展示轴线
        axisLine: {
          show: false
        },
        // 不展示刻度
        axisTick: {
          show: false
        }
      }
    ],
    // X 轴不展示
    xAxis: [
      {
        show: false
      }
    ],
    // 每两个标记一条线
    series: getSeriesData()
  }

  mChart.setOption(options)
}

watch(
    () => props.data,
    () => {
      renderChart()
    }
)
</script>

<template>
  <div>
    <div>【大区异常处理】</div>
    <div ref="target"  class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

关系图

Relation.vue中代码如下

<script setup>
import {onMounted, ref, watch} from "vue";
import * as echarts from 'echarts'
const props = defineProps({
  data: {
    type: Object,
    required: true
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  mChart =  echarts.init(target.value)
  renderChart()
} )
// 2.构建option配置对象

// 渲染图表
const renderChart = () => {
  const options = {
    // X 轴不需要展示
    xAxis: {
      show: false,
      type: 'value'
    },
    // X 轴不需要展示
    yAxis: {
      show: false,
      type: 'value'
    },
    // 核心数据配置
    series: [
      {
        // 用于展现节点以及节点之间的关系数据
        type: 'graph',
        // 不采用任何布局
        layout: 'none',
        // 使用二维的直角坐标系
        coordinateSystem: 'cartesian2d',
        // 节点标记的大小
        symbolSize: 26,
        // z-index
        z: 3,
        // 边界标签(线条文字)
        edgeLabel: {
          normal: {
            show: true,
            color: '#fff',
            textStyle: {
              fontSize: 14
            },
            formatter: function (params) {
              let txt = ''
              if (params.data.speed !== undefined) {
                txt = params.data.speed
              }
              return txt
            }
          }
        },
        // 圆饼下文字
        label: {
          normal: {
            show: true,
            position: 'bottom',
            color: '#5e5e5e'
          }
        },
        // 边两端的标记类型
        edgeSymbol: ['none', 'arrow'],
        // 边两端的标记大小
        edgeSymbolSize: 8,
        // 圆数据
        data: props.data.relations.map((item) => {
          // id 为 0 ,表示数据中心,数据中心单独设置
          if (item.id !== 0) {
            return {
              name: item.name,
              category: 0,
              active: true,
              speed: `${item.speed}kb/s`,
              // 位置
              value: item.value
            }
          } else {
            return {
              name: item.name,
              // 位置
              value: item.value,
              // 数据中心圆的大小
              symbolSize: 100,
              // 圆的样式
              itemStyle: {
                normal: {
                  // 渐变色
                  color: {
                    colorStops: [
                      { offset: 0, color: '#157eff' },
                      { offset: 1, color: '#35c2ff' }
                    ]
                  }
                }
              },
              // 字体
              label: { normal: { fontSize: '14' } }
            }
          }
        }),
        // 线
        links: props.data.relations.map((item, index) => ({
          // 方向
          source: item.source,
          target: item.target,
          // 线上的文字
          speed: `${item.speed}kb/s`,
          // 线的样式
          lineStyle: { normal: { color: '#12b5d0', curveness: 0.2 } },
          // 文字位置
          label: {
            show: true,
            position: 'middle',
            offset: [10, 0]
          }
        }))
      },
      {
        // 用于带有起点和终点信息的线数据的绘制
        type: 'lines',
        // 使用二维的直角坐标系
        coordinateSystem: 'cartesian2d',
        // z-index
        z: 1,
        // 线特效的配置
        effect: {
          show: true,
          smooth: false,
          trailLength: 0,
          symbol: 'arrow',
          color: 'rgba(55,155,255,0.5)',
          symbolSize: 12
        },
        // 线的样式
        lineStyle: {
          normal: {
            curveness: 0.2
          }
        },
        // 线的数据级,前后线需要重合。数据固定
        data: [
          [{ coord: [0, 300] }, { coord: [50, 200] }],
          [{ coord: [0, 100] }, { coord: [50, 200] }],
          [{ coord: [50, 200] }, { coord: [100, 100] }],
          [{ coord: [50, 200] }, { coord: [100, 300] }]
        ]
      }
    ]
  }

  mChart.setOption(options)
}
watch(
    () => props.data,
    () => {
      renderChart()
    }
)
</script>

<template>
  <div>
    <div>【关系数据传递图】</div>
    <div ref="target"  class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

词云图

在使用词云图的时候需要安装一个插件echarts-worldcloud

pnpm i --save echarts-wordcloud@2.1.0

在WordClooud.vue代码实现

<script setup>
import {onMounted, ref, watch} from "vue";
import * as echarts from 'echarts'
import 'echarts-wordcloud'

const props = defineProps({
  data: {
    type: Object,
    required: true
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  mChart = echarts.init(target.value)
  renderChart()
})
// 2.构建option配置对象
const randomRGB = () => {
  const r = Math.floor(Math.random() * 256)
  const g = Math.floor(Math.random() * 256)
  const b = Math.floor(Math.random() * 256)
  return `rgb(${r},${g},${b})`
}
const renderChart = () => {
  const options = {
    // 定义一个词云图配置对象
    series: [
      {
        type: 'wordCloud', // 图表类型为词云图
        sizeRange: [12, 60], // 词云图中词语的大小范围
        rotationRange: [0, 0], // 词云图中词语的旋转角度范围
        gridSize: 0, // 词云图中词语之间的网格大小
        layoutAnimation: true, // 是否开启布局动画
        textStyle: {
          color: randomRGB // 词语的样式,颜色为随机RGB颜色
        },
        emphasis: {
          textStyle: {
            fontWeight: 'bold', // 强调时的字体样式,加粗
            color: '#000' // 强调时的颜色,黑色
          }
        },
        data: props.data.datas
      }]
  }

  // 3.通过实例.setOptions(option)
  mChart.setOption(options)
}

watch(
    () => props.data,
    () => {
      renderChart()
    }
)
</script>

<template>
  <div>
    <div>【关键词条】</div>
    <div ref="target" class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

数据展示图

这部分的数据在点开页面的时候会慢慢增长,实现这种效果需要安装另外一个组件countup.js

npm i --save countup.js@2.6.2

TotalData.vue中的代码

<script setup>
import {CountUp} from 'countup.js'
import {onMounted, ref} from 'vue'
const props = defineProps({
  data: {
    type: Object,
    required: true
  }
})

const totalCountTarget = ref(null)
const city1 = ref(null)
const city2 = ref(null)
const city3 = ref(null)
const city4 = ref(null)
const city5 = ref(null)
const city6 = ref(null)

onMounted(() => {
  new CountUp(totalCountTarget.value, props.data.total).start()
  new CountUp(city1.value, props.data.hb).start()
  new CountUp(city2.value, props.data.db).start()
  new CountUp(city3.value, props.data.hd).start()
  new CountUp(city4.value, props.data.zn).start()
  new CountUp(city5.value, props.data.xn).start()
  new CountUp(city6.value, props.data.xb).start()
})
</script>

<template>
  <div class="p-6">
    <div class="text-slate-300 text-center">
      数据总量:
      <span
          ref="totalCountTarget"
          class="text-7xl ml-2 mr-2 font-bold font-[Electronic] text-gradient"
      >
				679,473,929
			</span>
      条记录
    </div>
    <div class="mt-3 flex flex-wrap">
      <div class="w-1/3 text-center text-slate-400 text-sm">
        华北:
        <span ref="city1" class="text-[#5DC5EF] text-3xl font-[Electronic]">
					8,778,988
				</span>
      </div>
      <div class="w-1/3 text-center text-slate-400 text-sm">
        东北:<span
          ref="city2"
          class="text-[#5DC5EF] text-3xl font-[Electronic]"
      >8,778,988</span
      >
      </div>
      <div class="w-1/3 text-center text-slate-400 text-sm">
        华东:<span
          ref="city3"
          class="text-[#5DC5EF] text-3xl font-[Electronic]"
      >8,778,988</span
      >
      </div>
      <div class="w-1/3 text-center text-slate-400 text-sm">
        中南:<span
          ref="city4"
          class="text-[#5DC5EF] text-3xl font-[Electronic]"
      >8,778,988</span
      >
      </div>
      <div class="w-1/3 text-center text-slate-400 text-sm">
        西南:<span
          ref="city5"
          class="text-[#5DC5EF] text-3xl font-[Electronic]"
      >8,778,988</span
      >
      </div>
      <div class="w-1/3 text-center text-slate-400 text-sm">
        西北:<span
          ref="city6"
          class="text-[#5DC5EF] text-3xl font-[Electronic]"
      >8,778,988</span
      >
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>

</style>

五年数据统计图

在MapChart.vue中写入

<script setup>
import {onMounted, ref} from "vue";
import * as echarts from 'echarts'
import mapJson from "../assets/MapData/china.json";
const props = defineProps({
  data: {
    type: Object,
    required: true
  }
})
// 1.初始Echarts实例对象
let mChart = null
const target = ref(null);
onMounted(() => {
  echarts.registerMap('china',mapJson)
  mChart =  echarts.init(target.value)
  renderChart()
} )
// 2.构建option配置对象
const renderChart = () => {
  // echarts 渲染
  echarts.registerMap('china', mapJson)

  let options = {
    // 时间线,提供了在多个 ECharts option 间进行切换
    timeline: {
      // 数据
      data: props.data.voltageLevel,
      // 类目轴
      axisType: 'category',
      // 自动切换
      autoPlay: true,
      // 间隔时间
      playInterval: 3000,
      // 位置
      left: '10%',
      right: '10%',
      bottom: '0%',
      width: '80%',
      // 轴的文本标签
      label: {
        // 默认状态
        normal: {
          textStyle: {
            color: '#ddd'
          }
        },
        // 高亮状态
        emphasis: {
          textStyle: {
            color: '#fff'
          }
        }
      },
      // 文字大小
      symbolSize: 10,
      // 线的样式
      lineStyle: {
        color: '#555'
      },
      // 选中点的样式
      checkpointStyle: {
        borderColor: '#888',
        borderWidth: 2
      },
      // 控件样式
      controlStyle: {
        // 上一步按钮
        showNextBtn: true,
        // 下一步按钮
        showPrevBtn: true,
        // 默认样式
        normal: {
          color: '#666',
          borderColor: '#666'
        },
        // 高亮样式
        emphasis: {
          color: '#aaa',
          borderColor: '#aaa'
        }
      }
    },
    // 柱形图右侧展示
    baseOption: {
      grid: {
        right: '2%',
        top: '15%',
        bottom: '10%',
        width: '20%'
      },

      // 中国地图
      geo: {
        // 展示
        show: true,
        // 中国地图
        map: 'china',
        // 开启缩放
        roam: true,
        // 初始缩放
        zoom: 0.8,
        // 中心点
        center: [113.83531246, 34.0267395887],
        // 默认状态的省份样式
        itemStyle: {
          normal: {
            // 边框色值
            borderColor: 'rgba(147, 235, 248, 1)',
            // 边框宽度
            borderWidth: 1,
            // 区域颜色
            areaColor: {
              // 经向色值
              type: 'radial',
              x: 0.5,
              y: 0.5,
              r: 0.5,
              colorStops: [
                // 0% 处的颜色
                {
                  offset: 0,
                  color: 'rgba(147, 235, 248, 0)'
                },
                // 100% 处的颜色
                {
                  offset: 1,
                  color: 'rgba(147, 235, 248, .2)'
                }
              ],
              // 缺省为 false
              globalCoord: false
            }
          },
          // 鼠标移入的色值
          emphasis: {
            areaColor: '#389BB7',
            borderWidth: 0
          }
        }
      }
    },
    // 绑定时间轴的多个图表
    options: []
  }

  // 为每一年度的图表添加数据
  props.data.voltageLevel.forEach((item, index) => {
    options.options.push({
      // 背景色
      backgroundColor: '#142037',
      title: [
        // 主标题,对应地图
        {
          text: '2019-2023 年度数据统计',
          left: '0%',
          top: '0',
          textStyle: {
            color: '#ccc',
            fontSize: 30
          }
        },
        // 副标题,对应柱形图
        {
          id: 'statistic',
          text: item + '年数据统计情况',
          right: '0%',
          top: '4%',
          textStyle: {
            color: '#ccc',
            fontSize: 20
          }
        }
      ],
      // X 轴配置
      xAxis: {
        // 数据轴
        type: 'value',
        // 脱离 0 值比例
        scale: true,
        // 位置
        position: 'top',
        // 不显示分割线
        splitLine: {
          show: false
        },
        // 不显示轴线
        axisLine: {
          show: false
        },
        // 不显示刻度尺
        axisTick: {
          show: false
        },
        // 类别文字
        axisLabel: {
          margin: 2,
          textStyle: {
            color: '#aaa'
          }
        }
      },
      // Y 轴
      yAxis: {
        // 选项轴
        type: 'category',
        // 轴线
        axisLine: {
          show: true,
          lineStyle: {
            color: '#ddd'
          }
        },
        // 轴刻度
        axisTick: {
          show: false,
          lineStyle: {
            color: '#ddd'
          }
        },
        // 轴标签
        axisLabel: {
          interval: 0,
          textStyle: {
            color: '#ddd'
          }
        },
        // 根据年份,获取对应数据
        data: props.data.categoryData[item].map((item) => item.name)
      },
      // 核心配置
      series: [
        // 柱形图
        {
          zlevel: 1.5,
          // 柱形图
          type: 'bar',
          // 每个柱子的色值
          itemStyle: {
            normal: {
              color: props.data.colors[index]
            }
          },
          // 根据年份,获取对应数据
          data: props.data.categoryData[item].map((item) => item.value)
        },
        // 散点图
        {
          // 散点(气泡)图
          type: 'effectScatter',
          // 使用地理坐标系
          coordinateSystem: 'geo',
          // 数据
          data: props.data.topData[item],
          // 标记大小
          symbolSize: function (val) {
            return val[2] / 4
          },
          // 绘制完成后显示特效
          showEffectOn: 'render',
          // 展示涟漪特效
          rippleEffect: {
            brushType: 'stroke'
          },
          // 文字
          label: {
            normal: {
              formatter: '{b}',
              position: 'right',
              show: true
            }
          },
          // 每一项的配置
          itemStyle: {
            normal: {
              color: props.data.colors[index],
              // 阴影配置
              shadowBlur: 5,
              shadowColor: props.data.colors[index]
            }
          },
          zlevel: 1
        }
      ]
    })
  })

  mChart.setOption(options)
}

</script>

<template>
  <div>
    <div ref="target" class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

a[item].map((item) => item.name)
      },
      // 核心配置
      series: [
        // 柱形图
        {
          zlevel: 1.5,
          // 柱形图
          type: 'bar',
          // 每个柱子的色值
          itemStyle: {
            normal: {
              color: props.data.colors[index]
            }
          },
          // 根据年份,获取对应数据
          data: props.data.categoryData[item].map((item) => item.value)
        },
        // 散点图
        {
          // 散点(气泡)图
          type: 'effectScatter',
          // 使用地理坐标系
          coordinateSystem: 'geo',
          // 数据
          data: props.data.topData[item],
          // 标记大小
          symbolSize: function (val) {
            return val[2] / 4
          },
          // 绘制完成后显示特效
          showEffectOn: 'render',
          // 展示涟漪特效
          rippleEffect: {
            brushType: 'stroke'
          },
          // 文字
          label: {
            normal: {
              formatter: '{b}',
              position: 'right',
              show: true
            }
          },
          // 每一项的配置
          itemStyle: {
            normal: {
              color: props.data.colors[index],
              // 阴影配置
              shadowBlur: 5,
              shadowColor: props.data.colors[index]
            }
          },
          zlevel: 1
        }
      ]
    })
  })

  mChart.setOption(options)
}

</script>

<template>
  <div>
    <div ref="target" class="w-full h-full"></div>
  </div>
</template>

<style lang="scss" scoped>

</style>

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

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

相关文章

Android setText不生效问题(文字不显示)

1.直接说解决方案&#xff1a; 在代码没问题的情况下&#xff0c;将你的TextView的Id改一下&#xff0c;然后再重启编译器即可(注意&#xff0c;不修改TextView的ID&#xff0c;单独重启是没有作用的&#xff01;) 2.出现问题的过程&#xff1a; 新增的一个页面与之前做好的界…

“workon不是内部命令“/virtualenvwrapper-win安装配置

如果出现“workon不是内部命令”&#xff0c;先卸载 pip uninstall virtualenvwrapper-win -y 一&#xff0c;指定所有虚拟环境存放路径&#xff1a; # “E:/Python_Envs_List”换成自己想要的路径 setx WORKON_HOME "E:/Python_Envs_List"二&#xff0c;增加pytho…

【轻松掌握】Jenkins入门指南:构建高效的CI/CD Pipeline

文章目录 前言安装部署安装JDK安装Jenkins下载Jenkins运行Jenkins访问页面填写管理员密码安装推荐的插件 Maven安装下载上传到Linux解压配置镜像运行查看Maven使用的JDK版本 Jenkins安装Maven插件 创建Demo项目创建Jenkins任务填写代码仓库地址Linux安装GIT解决报错配置Maven版…

一文吃透SpringMVC

一、SpringMVC简介 1、什么是MVC MVC是一种软件架构模式&#xff08;是一种软件架构设计思想&#xff0c;不止Java开发中用到&#xff0c;其它语言也需要用到&#xff09;&#xff0c;它将应用分为三块&#xff1a; M&#xff1a;Model&#xff08;模型&#xff09;&#xf…

Phone X│“齐刘海”里到底搭载了哪些传感器?

揭开 “齐刘海”面纱 随着iPhone X的发布&#xff0c;3D人脸识别功能一度成为人们口中津津乐道的新科技&#xff0c;下面就让SITRI的专业团队带领大家揭开人脸识别的神秘面纱。 先从苹果iPhone X说起&#xff0c;让我们看一看这个可爱的“齐刘海”里到底搭载了哪些传感器&am…

杀软对抗 ----> 简简单单免杀某60

在开始之前还是宇宙免责 本Blog讨论的技术问题仅限于学习用&#xff0c;严禁用于非授权情况下执行攻击活动&#xff0c;如未授权攻击所造成一切后果由攻击者独自承担&#xff0c;所展示的代码仅用于杀软对抗学习&#xff0c;测试环境并非真实环境&#xff0c;并无对任何杀软有任…

我的sql我做主!Mysql 的集群架构详解之组从复制、半同步模式、MGR、Mysql路由和MHA管理集群组

目录 Mysql 集群技术一、Mysql 在服务器中的部署方法1.1 在Linux下部署mysql1.1.1 安装依赖性&#xff1a;1.1.2 下载并解压源码包1.1.3 源码编译安装mysql1.1.4 部署mysql 二、Mysql的组从复制2.1 配置mastesr2.2 配置salve2.3 当有数据时添加slave22.4 延迟复制2.5 慢查询日志…

医疗器械法规标准相关资料

文章目录 前言如何查找法规文件与标准1. 法规清单2. 医疗器械法规文件汇编常用链接常见网站微信公众号前言 在前文 医疗器械软件相关法律法规与标准 中介绍了在软件设计过程常见的法规与标准,并给出部分标准如何查找和下载的方法,但是上文中列举的部分不全面,真实在产品设计…

springboot公众号模板消息推送

文章目录 参考1、微信公众平台测试号管理1.1 访问微信公众平台测试账号页面1.2 获取appID和appsecret1.3 扫码二维码添加测试号1.4 添加模版消息 2、集成微信SDK2.1 引入微信工具包2.2 添加配置文件 3、API调用3.1 发送消息模版的实现3.2 测试类调用3.3 效果展示 4、回调配置回…

通过IMB看高效裁员

高效裁员是企业在面临经营压力或战略调整时不得不采取的措施之一。为了确保裁员过程既高效又尽量减少负面影响,可以遵循以下步骤和策略: 一、明确裁员目标和计划 分析需求:首先,企业需要明确裁员的原因,比如经营困难、业务重组、技术升级等,并基于这些原因确定裁员的范…

Centos系统二进制安装mysql5.7.44、添加环境变量、复制启动脚本、初始化数据库、设置用户密码

MySQL :: Download MySQL Community Server (Archived Versions) https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz 删除默认存在的mariadb-libs rpm -e mariadb-libs --nodeps 安装mysql cd /usr/local/src/ && …

Redis中的 大/热 key问题 ,如何解决(面试版)

big key 什么是 big key? big key&#xff1a;就是指一个内存空间占用比较大的键(Key) 造成的问题&#xff1a; 内存分布不均。在集群模式下&#xff0c;不同 slot分配到不同实例中&#xff0c;如果大 key 都映射到一个实例&#xff0c;则分布不均&#xff0c;查询效率也…

拿下英语翻译!这四款在线翻译功不可没!

作为一个刚踏入职场的小白&#xff0c;我最近在为工作中的英语翻译问题头疼不已。不过&#xff0c;经过一番尝试和比较&#xff0c;我找到了几款翻译工具&#xff0c;它们在帮我解决翻译难题上表现得相当不错。今天&#xff0c;就让我以一个职场新手的身份&#xff0c;来跟大家…

OpenCV几何图像变换(6)计算反转仿射变换函数invertAffineTransform()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 反转一个仿射变换。 该函数计算由 23 矩阵 M 表示的逆仿射变换&#xff1a; [ a 11 a 12 b 1 a 21 a 22 b 2 ] \begin{bmatrix} a_{11} & a…

【超音速 专利 CN202110438812.4】广州超音速自动化科技股份有限公司

申请号CN202110438812.4公开号&#xff08;公开&#xff09;CN113390879A申请日2021.09.14申请人&#xff08;公开&#xff09;广州超音速自动化科技股份有限公司(833753)发明人&#xff08;公开&#xff09;张俊峰&#xff08;总); 罗国和; 陈夏 原文摘要 本发明公开了一种涂…

【上】王树森《搜索引擎技术》- 课程笔记(概要、相关性)

课程合集&#xff1a;ShusenWang的个人空间-ShusenWang个人主页-哔哩哔哩视频 (bilibili.com) 课件地址&#xff1a;GitHub - wangshusen/SearchEngine: 搜索引擎原理 目录 概要 1、搜索引擎的基本概念 曝光和点击 垂搜vs通搜 课程安排 2、决定搜索满意度的因素&#…

某音作品列表,视频列表

声明&#xff1a;文章仅用于学习交流,如有侵权请联系删除 今天分享下某音app作品列表采集方法&#xff0c;我只详细说一下大步骤&#xff0c;细节就不多说了&#xff0c;留着大家去试吧 我们通过Fiddler 快捷方式 配置好代理 打开抖音进行抓包&#xff0c;随便找个达人打开主…

喜羊羊让你Pyecharts快速上手(实例+代码)

以下内容&#xff0c;皆为原创&#xff0c;制作实属不易&#xff0c;感谢大家的关注和点赞。 一.Pyecharts是什么 具体网址&#xff1a;pyecharts - A Python Echarts Plotting Library built with love. Pyecharts 是一个用于生成 Echarts 图表的 Python 库。Echarts 是由百度…

行业级API集成案例,巩固你的知识

在当今高度互联的世界&#xff0c;企业依靠无缝数据交换和简化的工作流程蓬勃发展。API&#xff08;应用程序编程接口&#xff09;已成为实现这一目标的秘密武器&#xff0c;可实现各种应用程序之间的强大集成。本文深入探讨了不同行业中 API 集成的真实示例&#xff0c;让您更…

四、5 下标引用、函数调用、结构成员(操作符)

&#xff08;1&#xff09;下标引用 [ ] (2)函数调用 ( ) (3)结构成员