各卧唯 发表于 2025-6-6 10:20:35

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

说明

    该文章是属于OverallAuth2.0系列文章,每周更新一篇该系列文章(从0到1完成系统开发)。
    该系统文章,我会尽量说的非常详细,做到不管新手、老手都能看懂。
    说明:OverallAuth2.0 是一个简单、易懂、功能强大的权限+可视化流程管理系统。
友情提醒:本篇文章是属于系列文章,看该文章前,建议先看之前文章,可以更好理解项目结构。
qq群:801913255,进群有什么不懂的尽管问,群主都会耐心解答。
有兴趣的朋友,请关注我吧(*^▽^*)。

关注我,学不会你来打我
实现功能
  1、系统登录后的可视化面板页面
  原本不想写这篇文章,因为它和我们的系统权限、框架没有实质性的关系,但耐不住群友的软磨硬泡,便答应了下来。

  我起初的设想,这块功能直接上传到码云上,群友可以根据自己搭建的系统,酌情修改。
安装echarts
  npm install echarts --save
搭建面板页面
在panel文件夹,打开index页面,编写布局代码
<template>

   
      
      
      
      
         2
      
      
      
       3
      
      
      4
      
   
   
      
      特色功能
      
      关于作者
   

</template>



    布局样式如下

填充盒子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: ,
          },
      ],
      },
    ],
};该代码是echarts的雷达图代码。
回到页面,我们把盒子1里的内容替换成
   然后再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: ,
            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({
    黑龙江: ,
    内蒙古: ,
    吉林: ,
    北京市: ,
    辽宁: ,
    河北: ,
    天津: ,
    山西: ,
    陕西: ,
    甘肃: ,
    宁夏: ,
    青海: ,
    新疆: ,
    西藏: ,
    四川: ,
    重庆: ,
    山东: ,
    河南: ,
    江苏: ,
    安徽: ,
    湖北: ,
    浙江: ,
    福建: ,
    江西: ,
    湖南: ,
    贵州: ,
    云南: ,
    广东: ,
    广西: ,
    海南: ,
    上海: ,
});
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;
      var fromCoord = chinaGeoCoordMap.value.name];
      var toCoord = ;
      if (fromCoord && toCoord) {
            res.push([
                {
                  coord: fromCoord,
                  value: dataItem.value,
                },
                {
                  coord: toCoord,
                },
            ]);
      }
    }
    return res;
};
export const series: {
    type: string;
    zlevel: number;
    coordinateSystem: string;
    effect: {
      show: boolean;
      period: number; //箭头指向速度,值越小速度越快
      trailLength: number; //特效尾迹长度值越大,尾迹越长重
      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, //特效尾迹长度值越大,尾迹越长重
                symbol: "arrow", //箭头图标
                symbolSize: 5, //图标大小
                brushType: "",
                scale: 0
            },
            label: [],
            symbol: "",
            symbolSize: [],
            itemStyle: [],
            lineStyle: {
                normal: {
                  width: 1, //尾迹线条宽度
                  opacity: 1, //尾迹线条透明度
                  curveness: 0.3, //尾迹线条曲直度
                },
            },
            data: convertData(item),
      },
      {
            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: , //偏移设置
                  formatter: function (params: { data: { name: any } }) {
                        //圆环显示文字
                        return params.data.name;
                  },
                  fontSize: 13,
                },
                emphasis: {
                  show: true,
                },
            },
            symbol: "circle",
            symbolSize: function (val: number[]) {
                return 5 + val * 5; //圆环大小
            },
            itemStyle: {
                normal: {
                  show: false,
                  color: "#f00",
                },
            },
            lineStyle: {
                normal: {
                  width: 1, //尾迹线条宽度
                  opacity: 1, //尾迹线条透明度
                  curveness: 0.3, //尾迹线条曲直度
                },
            },
            data: item.map(function (
                dataItem: {
                  name: any;
                  value: any;
                }[]
            ) {
                return {
                  name: dataItem.name,
                  value: chinaGeoCoordMap.value.name].concat(.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:,
                  color: "#0f0",
                  formatter: "{b}",
                  textStyle: {
                        color: "#0f0",
                  },
                },
                emphasis: {
                  show: true,
                  color: "#f60",
                },
            },
            symbol: "pin",
            symbolSize: 50,
            itemStyle: [],
            lineStyle: '' as any,
            data: [
                {
                  name: item,
                  value: chinaGeoCoordMap.value.toString()].concat(),
                },
            ],
      }
    );
});
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: { : any }; seriesIndex: number },
      ticket: any,
      callback: any
      ) {
      //根据业务自己拓展要显示的内容
      var res = "";
      var name = params.name;
      var value = params.value;
      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: ,
      },
      {
      name: "角色权限",
      type: "line",
      stack: "Total",
      areaStyle: {},
      emphasis: {
          focus: "series",
      },
      data: ,
      },
      {
      name: "按钮权限",
      type: "line",
      stack: "Total",
      areaStyle: {},
      emphasis: {
          focus: "series",
      },
      data: ,
      },
      {
      name: "行权限",
      type: "line",
      stack: "Total",
      areaStyle: {},
      emphasis: {
          focus: "series",
      },
      data: ,
      },
      {
      name: "列权限",
      type: "line",
      stack: "Total",
      label: {
          show: true,
          position: "top",
      },
      areaStyle: {},
      emphasis: {
          focus: "series",
      },
      data: ,
      },
    ],
};在页面添加
把盒子2所在的地方替换成把盒子3所在的地方替换成把盒子4所在的地方替换成 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。
预览
https://img2024.cnblogs.com/blog/1158526/202412/1158526-20241202110301526-377678714.png
兼容性调整
  对应echarts来说,每个图表,它是固定的,就算设置的是百分比,也不随着窗体的大小而自适应屏幕,如下图
https://img2024.cnblogs.com/blog/1158526/202412/1158526-20241202110627706-821347007.png
要解决以上问题,我们只需要添加一个方法即可
//图标兼容性调整
    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
关注公众号:发送【权限】,获取前后端代码
有兴趣的朋友,请关注我微信公众号吧(*^▽^*)。

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

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: (系列十三)Vue3+Echarts搭建超好看的系统面板