(系列十三)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]