说明

该文章是属于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

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

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

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

(系列十三)Vue3+Echarts搭建超好看的系统面板的更多相关文章

  1. 从零开始搭建前端监控系统(三)——实现控制iframe前进后退

    前言 本系列文章旨在讲解如何从零开始搭建前端监控系统. 项目已经开源 项目地址: https://github.com/bombayjs/bombayjs (web sdk) https://gith ...

  2. SLAM+语音机器人DIY系列:(五)树莓派3开发环境搭建——1.安装系统ubuntu_mate_16.04

    摘要 通过前面一系列的铺垫,相信大家对整个miiboo机器人的DIY有了一个清晰整体的认识.接下来就正式进入机器人大脑(嵌入式主板:树莓派3)的开发.本章将从树莓派3的开发环境搭建入手,为后续ros开 ...

  3. ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建

    原文:ASP.NET MVC+EF框架+EasyUI实现权限管理系列(14)-主框架搭建    ASP.NET MVC+EF框架+EasyUI实现权限管系列 (开篇)   (1):框架搭建    (2 ...

  4. 【转】RHadoop实践系列之一:Hadoop环境搭建

    RHadoop实践系列之一:Hadoop环境搭建 RHadoop实践系列文章,包含了R语言与Hadoop结合进行海量数据分析.Hadoop主要用来存储海量数据,R语言完成MapReduce 算法,用来 ...

  5. MyBatis学习系列一之环境搭建

    目录 MyBatis学习系列一之环境搭建 MyBatis学习系列二——增删改查 MyBatis学习系列三——结合Spring 学习一个新的知识,首先做一个简单的例子使用一下,然后再逐步深入.MyBat ...

  6. 简简单单的Vue3(插件开发,路由系统,状态管理)

    既然选择了远方,便只顾风雨兼程 __ HANS许 系列:零基础搭建前后端分离项目 系列:零基础搭建前后端分离项目 插件 路由(vue-router) 状态管理模式(Vuex) 那在上篇文章,我们讲了, ...

  7. vue 快速入门 系列 —— 使用 vue-cli 3 搭建一个项目(上)

    其他章节请看: vue 快速入门 系列 使用 vue-cli 3 搭建一个项目(上) 前面我们已经学习了一个成熟的脚手架(vue-cli),笔者希望通过这个脚手架快速搭建系统(或项目).而展开搭建最好 ...

  8. vue 快速入门 系列 —— 使用 vue-cli 3 搭建一个项目(下)

    其他章节请看: vue 快速入门 系列 使用 vue-cli 3 搭建一个项目(下) 上篇 我们已经成功引入 element-ui.axios.mock.iconfont.nprogress,本篇继续 ...

  9. 如何使用laravel搭建后台登录系统

    今天想用laravel搭建一个后台系统,就需要最简单的那种,有用户登录系统,试用了下,觉得laravel的用户登录这块做的还真happy.当然,前提就是,你要的用户管理系统是最简单的那种,就是没有用户 ...

  10. 超强教程:如何搭建一个 iOS 系统的视频直播 App?

    现今,直播市场热火朝天,不少人喜欢在手机端安装各类直播 App,便于随时随地观看直播或者自己当主播.作为开发者来说,搭建一个稳定性强.延迟率低.可用性强的直播平台,需要考虑到部署视频源.搭建聊天室.优 ...

随机推荐

  1. Go runtime 调度器精讲(一):Go 程序初始化

    原创文章,欢迎转载,转载请注明出处,谢谢. 0. 前言 本系列将介绍 Go runtime 调度器.要学好 Go 语言,runtime 运行时是绕不过去的,它相当于一层"操作系统" ...

  2. idea运行java项目main方法报build failure错误的解决方法

    当在使用 IntelliJ IDEA 运行 Java 项目的 main 方法时遇到 "Build Failure" 错误,这通常意味着在项目的构建过程中遇到了问题.解决这类问题通常 ...

  3. NOIP2023 游记 初见曙光

    NOIP2023 游记 Day 0 明天就考 NOIP 了,今天还是得扎实的复习一下. 安排一下我的复习计划: 上午&&下午 复习线段树 复习权值线段树 学习带权并查集 复习 lca ...

  4. 【赵渝强老师】搭建Hadoop环境

    说明:这里我们以本地模式和伪分布模式伪列,为大家介绍如何搭建Hadoop环境.有了这个基础,大家可以自行搭建Hadoop的全分布模式. 需要使用的安装介质: hadoop-2.7.3.tar.gz j ...

  5. 简单上手 Vue Router

    Vue Router 也随着 Vue3 的更新来到了 4 版本,来看一下怎么使用吧!(这里使用的是 composition API 和 TypeScript 模式) 安装 vue-router4 np ...

  6. Java实用小工具系列2---使用StopWatch统计多个任务耗时分布

    在Java中经常需要统计程序的使用时间,如果只是一个时间段统计比较好处理,可以直接使用System.currentTimeMillis().但如果一个程序中包含多个步骤,需要统计每个步骤耗时,并且需要 ...

  7. 使用 vuex 和 本地存储实现永久性token存在 并且在请求拦截统一添加headers token 避免重复代码

    在 vuex 仓库中设置state的token值:从本地中取值: 登录的时候调用唯一可以修改state数据的mutations方法设置token : export default new Vuex.S ...

  8. 03 什么是预训练(Transformer 前奏)

    博客配套视频链接: https://space.bilibili.com/383551518?spm_id_from=333.1007.0.0 b 站直接看 配套 github 链接:https:// ...

  9. OpenFunction v1.1.0 发布:新增 v1beta2 API,支持 Dapr 状态管理

    OpenFunction 是一个开源的云原生 FaaS(Function as a Service,函数即服务)平台,旨在帮助开发者专注于业务逻辑的研发.在过去的几个月里,OpenFunction 社 ...

  10. OpenGL with GLFW GLAD and CMAKE

    0. 前言 首先,无论是在youtube还是网站上,许多OpenGL的环境配置都是在VS studio里配置的,个人比较喜欢使用VS code,以及Cmake. 下文给出了一个Cmake版本关于 GL ...