首页 > 其他分享 >(系列十三)Vue3+Echarts搭建超好看的系统面板

(系列十三)Vue3+Echarts搭建超好看的系统面板

时间:2024-12-02 14:46:02浏览次数:6  
标签:name any myChart value Echarts Vue3 面板 data echarts

说明

    该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。

    该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。

    说明:OverallAuth2.0 是一个简单、易懂、功能强大的权限+可视化流程管理系统。

友情提醒:本篇文章是属于系列文章,看该文章前,建议先看之前文章,可以更好理解项目结构。

qq群:801913255,进群有什么不懂的尽管问,群主都会耐心解答。

有兴趣的朋友,请关注我吧(*^▽^*)。

关注我,学不会你来打我

实现功能

  1、系统登录后的可视化面板页面

  原本不想写这篇文章,因为它和我们的系统权限、框架没有实质性的关系,但耐不住群友的软磨硬泡,便答应了下来。

  我起初的设想,这块功能直接上传到码云上,群友可以根据自己搭建的系统,酌情修改。

安装echarts

  npm install echarts --save

搭建面板页面

在panel文件夹,打开index页面,编写布局代码

<template>
  <div style="display: flex; height: 1080px">
    <div style="width: 80%">
      <div
        style="height: 25%; display: flex; margin-bottom: 5px"
        class="boxStyle"
      >
        <div style="width: 50%" class="boxStyle">
        </div>
        <div
          style="width: 50%; margin-left: 5px;"
          class="boxStyle"
        >
         2
        </div>
      </div>
      <div style="height: 45% ;margin-bottom: 5px"  class="boxStyle">
       3
      </div>
      <div style="height: 28%" class="boxStyle">
        4
      </div>
    </div>
    <div
      style="width: 20%; margin-left: 5px; display: flow-root"
      class="panelContent boxStyle"
    >
      <div
        style="width: 100%; height: 50%; margin-bottom: 5px"
        class="boxStyle"
      >
        特色功能
      </div>
      <div style="width: 100%; height: 50%" class="boxStyle">关于作者</div>
    </div>
  </div>
</template>
<script  lang="ts" >
import * as echarts from "echarts";
import { defineComponent } from "vue";
export default defineComponent({
  props: {
    // openPageData: {
    //   type: Object as PropType<buttonModel>,
    //   required: true,
    // },
  },

  setup(props, context) {  
    
    return {};
  },
  components: {},
});
</script>
<style scoped>
.panelContent {
  font-size: 12px;
  justify-content: right;
  align-items: center;
}
.boxStyle {
  border: 1px solid #00152914;
  box-shadow: 0 1px 4px #00152914;
}
</style>

    

布局样式如下

填充盒子1的内容

在api文件夹下,创建一个文件夹panel,然后再该文件夹下创建一个echarts.ts的文件,编写如下代码

export const echartsOne = {
    title: {
      text: "系统六芒星图",
    },
    color: ['#67F9D8'],
    //backgroundColor: "#013954",  //背景样式
    radar: {
      // 雷达图的指示器,表示多个变量的标签
      indicator: [
        { name: "好用", max: 5 },
        { name: "易懂", max: 5 },
        { name: "简单", max: 5 },
        { name: "通用", max: 5 },
        { name: "灵活", max: 5 },
        { name: "学习", max: 5 },
      ],
      splitArea: {
        areaStyle: {
          color: ['#adbecf','#77EADF', '#26C3BE', '#64AFE9', '#428BD4','#2177cd'],
          shadowColor: 'rgba(0, 0, 0, 0.2)',
          shadowBlur: 10
        }
      },
      axisName: {
        formatter: '【{value}】',
        color: '#428BD4'
      },
    },
    series: [
      {
        type: "radar",
        // 雷达图的数据
        data: [
          {
            value: [5, 5, 5, 5, 5, 5],
          },
        ],
      },
    ],
  };

该代码是echarts的雷达图代码。

回到页面,我们把盒子1里的内容替换成

   <div id="echarts-one" style="width: 100%; height: 100%"></div> 然后再setup下添加如下代码
  onMounted(() => {
      GetEchartsOneData();
    });
    function GetEchartsOneData() {
      var myChart = echarts.init(document.getElementById("echarts-one"));
      myChart.setOption(echartsOne);
    }

注意这里的onMounted钩子函数需要添加引用,echartsOne也需要导入。点击vue的提示即可。

完成以上代码,我们预览看下效果

照葫芦画瓢,我们开始编写盒子2、3、4的内容

在echarts.ts中添加

//南丁格尔玫瑰图
export const echartsTWO = {
    title: {
        text: "模块访问占比",
    },
    toolbox: {
        show: true,
    },
    legend: {
        bottom: "10",
    },
    // backgroundColor: "#013954",  //背景样式
    series: [
        {
            name: "Nightingale Chart",
            type: "pie",
            radius: [25, 80],
            center: ["50%", "50%"],
            roseType: "area",
            // itemStyle: {
            //   borderRadius: 8,
            // },
            data: [
                { value: 40, name: "菜单权限" },
                { value: 38, name: "角色权限" },
                { value: 32, name: "列权限" },
                { value: 30, name: "行权限" },
                { value: 28, name: "按钮权限" },
                { value: 18, name: "接口权限" },
                { value: 26, name: "流程" },
                { value: 22, name: "表单" },
            ],
        },
    ],
};

//中国地图
export const chinaGeoCoordMap = ref<any>({
    黑龙江: [127.9688, 45.368],
    内蒙古: [110.3467, 41.4899],
    吉林: [125.8154, 44.2584],
    北京市: [116.4551, 40.2539],
    辽宁: [123.1238, 42.1216],
    河北: [114.4995, 38.1006],
    天津: [117.4219, 39.4189],
    山西: [112.3352, 37.9413],
    陕西: [109.1162, 34.2004],
    甘肃: [103.5901, 36.3043],
    宁夏: [106.3586, 38.1775],
    青海: [101.4038, 36.8207],
    新疆: [87.9236, 43.5883],
    西藏: [91.11, 29.97],
    四川: [103.9526, 30.7617],
    重庆: [108.384366, 30.439702],
    山东: [117.1582, 36.8701],
    河南: [113.4668, 34.6234],
    江苏: [118.8062, 31.9208],
    安徽: [117.29, 32.0581],
    湖北: [114.3896, 30.6628],
    浙江: [119.5313, 29.8773],
    福建: [119.4543, 25.9222],
    江西: [116.0046, 28.6633],
    湖南: [113.0823, 28.2568],
    贵州: [106.6992, 26.7682],
    云南: [102.9199, 25.4663],
    广东: [113.12244, 23.009505],
    广西: [108.479, 23.1152],
    海南: [110.3893, 19.8516],
    上海: [121.4648, 31.2891],
});
export const chinaDatas = [
    [
        {
            name: "黑龙江",
            value: 0,
        },
    ],
    [
        {
            name: "内蒙古",
            value: 0,
        },
    ],
    [
        {
            name: "吉林",
            value: 0,
        },
    ],
    [
        {
            name: "辽宁",
            value: 0,
        },
    ],
    [
        {
            name: "河北",
            value: 0,
        },
    ],
    [
        {
            name: "天津",
            value: 0,
        },
    ],
    [
        {
            name: "山西",
            value: 0,
        },
    ],
    [
        {
            name: "陕西",
            value: 0,
        },
    ],
    [
        {
            name: "甘肃",
            value: 0,
        },
    ],
    [
        {
            name: "宁夏",
            value: 0,
        },
    ],
    [
        {
            name: "青海",
            value: 0,
        },
    ],
    [
        {
            name: "新疆",
            value: 0,
        },
    ],
    [
        {
            name: "西藏",
            value: 0,
        },
    ],
    [
        {
            name: "四川",
            value: 0,
        },
    ],
    [
        {
            name: "重庆",
            value: 0,
        },
    ],
    [
        {
            name: "山东",
            value: 0,
        },
    ],
    [
        {
            name: "河南",
            value: 0,
        },
    ],
    [
        {
            name: "江苏",
            value: 0,
        },
    ],
    [
        {
            name: "安徽",
            value: 0,
        },
    ],
    [
        {
            name: "湖北",
            value: 0,
        },
    ],
    [
        {
            name: "浙江",
            value: 0,
        },
    ],
    [
        {
            name: "福建",
            value: 0,
        },
    ],
    [
        {
            name: "江西",
            value: 0,
        },
    ],
    [
        {
            name: "湖南",
            value: 0,
        },
    ],
    [
        {
            name: "贵州",
            value: 0,
        },
    ],
    [
        {
            name: "广西",
            value: 0,
        },
    ],
    [
        {
            name: "海南",
            value: 0,
        },
    ],
    [
        {
            name: "上海",
            value: 1,
        },
    ],
];
var convertData = function (data: string | any[]) {
    var res = [];
    for (var i = 0; i < data.length; i++) {
        var dataItem = data[i];
        var fromCoord = chinaGeoCoordMap.value[dataItem[0].name];
        var toCoord = [103.9526, 30.7617];
        if (fromCoord && toCoord) {
            res.push([
                {
                    coord: fromCoord,
                    value: dataItem[0].value,
                },
                {
                    coord: toCoord,
                },
            ]);
        }
    }
    return res;
};
export const series: {
    type: string;
    zlevel: number;
    coordinateSystem: string;
    effect: {
        show: boolean;
        period: number; //箭头指向速度,值越小速度越快
        trailLength: number; //特效尾迹长度[0,1]值越大,尾迹越长重
        symbol: string; //箭头图标
        symbolSize: number;
        brushType: string;
        scale: number
    };
    rippleEffect:any;
    label: {},
    symbol: string;
    symbolSize: {},
    itemStyle: {},
    lineStyle: {
        normal: {
            width: number; //尾迹线条宽度
            opacity: number; //尾迹线条透明度
            curveness: number; //尾迹线条曲直度
        };
    };
    data: any
}[] = [];
[["四川", chinaDatas as any]].forEach(function (item, i) {
    series.push(
        {
            type: "lines",
            coordinateSystem: "geo",
            zlevel: 2,
            rippleEffect:[],
            effect: {
                show: true,
                period: 4, //箭头指向速度,值越小速度越快
                trailLength: 0.02, //特效尾迹长度[0,1]值越大,尾迹越长重
                symbol: "arrow", //箭头图标
                symbolSize: 5, //图标大小
                brushType: "",
                scale: 0
            },
            label: [],
            symbol: "",
            symbolSize: [],
            itemStyle: [],
            lineStyle: {
                normal: {
                    width: 1, //尾迹线条宽度
                    opacity: 1, //尾迹线条透明度
                    curveness: 0.3, //尾迹线条曲直度
                },
            },
            data: convertData(item[1]),
        },
        {
            type: "effectScatter",
            coordinateSystem: "geo".toString(),
            zlevel: 2,
            effect:{} as any,
            rippleEffect: {
                //涟漪特效
                period: 4, //动画时间,值越小速度越快
                brushType: "stroke", //波纹绘制方式 stroke, fill
                scale: 4,
                show: false,
                trailLength: 0,
                symbol: "",
                symbolSize: 0
            },
            label: {
                normal: {
                    show: true,
                    position: "right", //显示位置
                    offset: [5, 0], //偏移设置
                    formatter: function (params: { data: { name: any } }) {
                        //圆环显示文字
                        return params.data.name;
                    },
                    fontSize: 13,
                },
                emphasis: {
                    show: true,
                },
            },
            symbol: "circle",
            symbolSize: function (val: number[]) {
                return 5 + val[2] * 5; //圆环大小
            },
            itemStyle: {
                normal: {
                    show: false,
                    color: "#f00",
                },
            },
            lineStyle: {
                normal: {
                    width: 1, //尾迹线条宽度
                    opacity: 1, //尾迹线条透明度
                    curveness: 0.3, //尾迹线条曲直度
                },
            },
            data: item[1].map(function (
                dataItem: {
                    name: any;
                    value: any;
                }[]
            ) {
                return {
                    name: dataItem[0].name,
                    value: chinaGeoCoordMap.value[dataItem[0].name].concat([dataItem[0].value]),
                };
            }),
        },
        //被攻击点
        {
            type: "scatter",
            coordinateSystem: "geo",
            zlevel: 2,
            rippleEffect:{} as any,
            effect: {
                period: 4,
                brushType: "stroke",
                scale: 4,
                show: false,
                trailLength: 0,
                symbol: "",
                symbolSize: 0
            },
            label: {
                normal: {
                    show: true,
                    position: "right",
                    //offset:[5, 0],
                    color: "#0f0",
                    formatter: "{b}",
                    textStyle: {
                        color: "#0f0",
                    },
                },
                emphasis: {
                    show: true,
                    color: "#f60",
                },
            },
            symbol: "pin",
            symbolSize: 50,
            itemStyle: [],
            lineStyle: '' as any,
            data: [
                {
                    name: item[0],
                    value: chinaGeoCoordMap.value[item[0].toString()].concat([10]),
                },
            ],
        }
    );
});
export const echartsThree = {
    title: {
        text: "各省访问数量",
    },
    tooltip: {
      trigger: "item",
      backgroundColor: "rgba(166, 200, 76, 0.82)",
      borderColor: "#FFFFCC",
      showDelay: 0,
      hideDelay: 0,
      enterable: true,
      transitionDuration: 0,
      extraCssText: "z-index:100",
      formatter: function (
        params: { name: any; value: { [x: string]: any }; seriesIndex: number },
        ticket: any,
        callback: any
      ) {
        //根据业务自己拓展要显示的内容
        var res = "";
        var name = params.name;
        var value = params.value[params.seriesIndex + 1];
        res =
          "<span style='color:#fff;'>" + name + "</span><br/>数据:" + value;
        return res;
      },
    },
    //backgroundColor: "#013954",
    visualMap: {
      //图例值控制
      min: 0,
      max: 1,
      calculable: true,
      show: true,
      color: ["#f44336", "#fc9700", "#ffde00", "#ffde00", "#00eaff"],
      textStyle: {
        color: "#fff",
      },
    },
    geo: {
      map: "china",
      zoom: 1.2,
      label: {
        emphasis: {
          show: false,
        },
      },
      roam: false, //是否允许缩放
      itemStyle: {
        normal: {
          color: "rgba(51, 69, 89, .5)", //地图背景色
          borderColor: "#516a89", //省市边界线00fcff 516a89
          borderWidth: 1,
        },
        emphasis: {
          color: "rgba(37, 43, 61, .5)", //悬浮背景
        },
      },
    },
    series: series,
  };

  //堆叠图
  export const echartsFour = {
    title: {
      text: "系统访问量走势图",
    },
   // backgroundColor: "#6a7985",  //背景样式
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "cross",
        label: {
          backgroundColor: "#6a7985",
        },
      },
    },
    legend: {
      data: ["菜单权限", "角色权限", "按钮权限", "行权限", "列权限"],
    },
    toolbox: {
      // feature: {
      //   saveAsImage: {},
      // },
    },
    grid: {
      left: "3%",
      right: "4%",
      bottom: "3%",
      containLabel: true,
    },
    xAxis: [
      {
        type: "category",
        boundaryGap: false,
        data: ["星期一", "星期二", "星期三", "星期四", "星期五", "星期六", "星期天"],
      },
    ],
    yAxis: [
      {
        type: "value",
      },
    ],
    series: [
      {
        name: "菜单权限",
        type: "line",
        stack: "Total",
        areaStyle: {},
        emphasis: {
          focus: "series",
        },
        data: [120, 132, 101, 134, 90, 230, 210],
      },
      {
        name: "角色权限",
        type: "line",
        stack: "Total",
        areaStyle: {},
        emphasis: {
          focus: "series",
        },
        data: [220, 182, 191, 234, 290, 330, 310],
      },
      {
        name: "按钮权限",
        type: "line",
        stack: "Total",
        areaStyle: {},
        emphasis: {
          focus: "series",
        },
        data: [150, 232, 201, 154, 190, 330, 410],
      },
      {
        name: "行权限",
        type: "line",
        stack: "Total",
        areaStyle: {},
        emphasis: {
          focus: "series",
        },
        data: [320, 332, 301, 334, 390, 330, 320],
      },
      {
        name: "列权限",
        type: "line",
        stack: "Total",
        label: {
          show: true,
          position: "top",
        },
        areaStyle: {},
        emphasis: {
          focus: "series",
        },
        data: [820, 932, 901, 934, 1290, 1330, 1320],
      },
    ],
  };

在页面添加

把盒子2所在的地方替换成<div id="echarts-tow" style="width: 100%; height: 100%"></div> 把盒子3所在的地方替换成<div id="echarts-three" style="width: 100%; height: 100%"></div> 把盒子4所在的地方替换成<div id="echarts-four" style="width: 100%; height: 100%"></div>
 onMounted(() => {
      GetEchartsOneData();
      GetEchartsTwoData();
      GetEchartsThreeData();
      GetEchartsFourData();
    });

    //六芒星图
    function GetEchartsOneData() {
      var myChart = echarts.init(document.getElementById("echarts-one"));
      myChart.setOption(echartsOne);
    }

    //南丁格尔玫瑰图
    function GetEchartsTwoData() {
      var myChart = echarts.init(document.getElementById("echarts-tow"));
      myChart.setOption(echartsTWO);
    }

    //中国地图
    function GetEchartsThreeData() {
      var myChart = echarts.init(document.getElementById("echarts-three"));
      echarts.registerMap("china", chinaJson as any); //注册可用的地图
      myChart.setOption(echartsThree);
    }

    //堆叠图
    function GetEchartsFourData() {
      var myChart = echarts.init(document.getElementById("echarts-four"));
      myChart.setOption(echartsFour);
    }

特别注意

  1、在添加中国地图时,需要下载一个中国地图的json包,放在项目中(我是放在和echarts.ts同级目录下)。下载地址:https://datav.aliyun.com/portal/school/atlas/area_selector

  2、在tsconfig.json文件中需要添加"resolveJsonModule": true,的配置,该配置可以让系统允许导入json。

预览

兼容性调整

  对应echarts来说,每个图表,它是固定的,就算设置的是百分比,也不随着窗体的大小而自适应屏幕,如下图

要解决以上问题,我们只需要添加一个方法即可

 //图标兼容性调整
    function resizeEchart(myChart:any)
    {
      //监听窗口大小变化(适用于一个页面多个图形)
      window.addEventListener('resize',()=>{myChart.resize();})
    }

然后再myChart.setOption()方法后面添加resizeEchart(myChart);即可解决兼容性问题,如图

  //堆叠图
    function GetEchartsFourData() {
      var myChart = echarts.init(document.getElementById("echarts-four"));
      myChart.setOption(echartsFour);
      resizeEchart(myChart);
    }

结语

我们的OverallAuth2.0项目也正式迈入功能开发阶段,可能文章内容逐渐开始复杂化,如果你感兴趣的话,也有跟着博主从0到1搭建权限管理系统的兴趣。

那么请加qq群:801913255,进群有什么不懂的尽管问,群主都会耐心解答。

后端WebApi 预览地址:http://139.155.137.144:8880/swagger/index.html

前端vue 预览地址:http://139.155.137.144:8881

关注公众号:发送【权限】,获取前后端代码

有兴趣的朋友,请关注我微信公众号吧(*^▽^*)。

关注我:一个全栈多端的宝藏博主,定时分享技术文章,不定时分享开源项目。关注我,带你认识不一样的程序世界

标签:name,any,myChart,value,Echarts,Vue3,面板,data,echarts
From: https://www.cnblogs.com/cyzf/p/18578342

相关文章

  • vue3 + pnpm 打造一个 monorepo 项目
    Monorepo和Multirepo单一仓库(Monorepo)架构,可以理解为:利用单一仓库来管理多个packages的一种策略或手段;与其相对的是多仓库(Multirepo)架构Monorepo目录中除了会有公共的package.json依赖以外,在每个sub-package子包下面,也会有其特有的package.json依赖。兄弟模块之间可以通过模......
  • vue3 原生 JS canvas 封装获取验证码组件
    前言由于开发中,产品有需求,要求开发一个可以自定义字符的随机获取4个字符的验证码组件,然后我就仿照流行的验证码功能写了一个 运行效果HTML<template><!--验证码画布容器,点击后会触发验证码刷新--><spanclass="s-canvas"@click="changeCode"><canvas......
  • vue3 数字自增长组件
    前言当做数字大屏的时候,就需要做一个数字传入后,可以自增长的组件,可以根据数据大小算每一次跳动的数字运行效果 会从0开始自动增加到9000(录屏好麻烦)HTML<template><divclass="counter"><div:style="{color:fontColor,fontSize:fontSize}"><span......
  • 3.vue3+openlayers加载Mapbox地图
    1.注册Mapbox账户访问Mapbox官网,并点击右上角的SignUp按钮,创建一个新的账户。如果你已有Mapbox账户,可以直接登录。2.创建一个Mapbox项目登录后,进入Mapbox的AccountDashboard页面。在页面上,你会看到一个Createanewtoken或者Accesstokens的按钮。点......
  • ECharts柱状图-极坐标系下的堆叠柱状图2,附视频讲解与代码下载
    引言: 在数据可视化的世界里,ECharts凭借其丰富的图表类型和强大的配置能力,成为了众多开发者的首选。今天,我将带大家一起实现一个柱状图图表,通过该图表我们可以直观地展示和分析数据。此外,我还将提供详细的视频讲解和代码下载链接,帮助大家快速上手。一、图表效果预览二、视......
  • 2000-2020年 全国省、市、县农业机械总动力统计面板数据
    2000-2020年全国省、市、县农业机械总动力统计面板数据.r.rar                             从2000年到2020年,我国农业机械化水平显著提升,这一变化可以通过农业机械总动力的增长来衡量。农业机械总动力是指在农业......
  • vue3实现自定义导航菜单
    一、创建项目    1.打开HBuilderX图1    2.新建一个空项目        文件->新建->项目->uni-app        填写项目名称:vue3demo        选择项目存放目录:D:/HBuilderProjects        一定要注意vue的版本,当前选择的版......
  • uni-app vue3 获取 package.json 自定义环境变量
    一、初始化项目 二、添加 package.json 文件(必须)注意:文件里面不要写备注{ "uni-app":{ "scripts":{ "dev":{ "title":"开发版", "env":{ "ENV_TYPE":"dev", "UNI_PLATFORM&q......
  • SpringBoot3+Vue3+NaiveUI主流前端分离开发框架 | 小蚂蚁云
     项目介绍基于SpringBoot3、SpringSecurity、MybatisPlus、Vue3、TypeScript、Vite、NaiveUI、MySQL等技术栈实现的单体前后端分离后台管理系统;后端基于Java语言采用SpringBoot3、SpringSecurity、MybatisPlus、MySQL等主流技术栈,前端基于Vue3、TypeScript、Vite等技术栈实现......
  • SpringBoot3+Vue3+NaiveUI项目实例源码 | 小蚂蚁云
     项目介绍基于SpringBoot3、SpringSecurity、MybatisPlus、Vue3、TypeScript、Vite、NaiveUI、MySQL等技术栈实现的单体前后端分离后台管理系统;后端基于Java语言采用SpringBoot3、SpringSecurity、MybatisPlus、MySQL等主流技术栈,前端基于Vue3、TypeScript、Vite等技术栈实现......