說明
該文章是屬於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裡的內容替換成
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], }, ], };
在頁面新增
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
關注公眾號:傳送【許可權】,獲取前後端程式碼
有興趣的朋友,請關注我微信公眾號吧(*^▽^*)。
關注我:一個全棧多端的寶藏博主,定時分享技術文章,不定時分享開源專案。關注我,帶你認識不一樣的程式世界