初步完成分布统计页面

This commit is contained in:
hdk1999
2024-01-22 23:00:35 +08:00
parent 26cfa5b09b
commit 5551c19ced
6 changed files with 1552 additions and 73 deletions

View File

@@ -26,6 +26,7 @@
},
"dependencies": {
"@antv/graphin": "^2.7.27",
"@antv/l7plot": "^0.5.7",
"@element-plus/icons-vue": "2.3.1",
"@vueuse/core": "^10.7.1",
"antv-graphin-vue": "^2.6.10",
@@ -36,6 +37,7 @@
"js-cookie": "3.0.5",
"lodash-es": "4.17.21",
"mitt": "3.0.1",
"neovis.js": "^2.1.0",
"normalize.css": "8.0.1",
"nprogress": "0.2.0",
"path-browserify": "1.0.1",

966
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -61,41 +61,55 @@ export const constantRoutes: RouteRecordRaw[] = [
}
]
},
{
path: "/data",
component: Layouts,
redirect: "/data",
children: [
{
path: "data",
component: () => import("@/views/data/index.vue"),
name: "Data",
meta: {
title: "数据检索",
elIcon: "Grid",
affix: true
}
}
]
},
{
path: "/stats",
component: Layouts,
redirect: "/stats",
redirect: "/stats/stats",
meta: {
title: "分析统计",
svgIcon: "link"
},
children: [
{
path: "stats",
component: () => import("@/views/stats/index.vue"),
name: "Stats",
meta: {
title: "分统计",
title: "分统计",
elIcon: "DataAnalysis",
affix: true
}
},
{
path: "fx",
component: () => import("@/views/fx/index.vue"),
name: "FX",
meta: {
title: "风险评估",
elIcon: "BellFilled",
affix: true
}
}
]
}
// {
// path: "/data",
// component: Layouts,
// redirect: "/data",
// children: [
// {
// path: "data",
// component: () => import("@/views/data/index.vue"),
// name: "Data",
// meta: {
// title: "数据检索",
// elIcon: "Grid",
// affix: true
// }
// }
// ]
// }
// {
// path: "/unocss",
// component: Layouts,
// redirect: "/unocss/index",

View File

@@ -1,11 +1,12 @@
<script lang="ts" setup>
import { ref, onMounted, reactive, toRefs } from "vue"
import { ref } from "vue"
import { use } from "echarts/core"
import { LineChart } from "echarts/charts"
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent } from "echarts/components"
import { SVGRenderer } from "echarts/renderers"
import VChart from "vue-echarts"
import * as sys from "@/api/sys"
import { useNow } from "@vueuse/core"
// 系统运行时间数据
const workday = ref(0)
@@ -57,20 +58,7 @@ const option = ref({
})
// 当前时间
const state = reactive({
nowTime: new Date().toLocaleString()
})
function getnowTime(nowTime: any): any {
setInterval(() => {
const date = new Date()
nowTime.value = date.toLocaleString()
}, 1000)
}
onMounted(() => {
getnowTime(nowTime)
})
const { nowTime } = toRefs(state)
const nowTime = useNow()
</script>
<template>
@@ -129,7 +117,6 @@ const { nowTime } = toRefs(state)
</el-card>
</el-col>
</el-row>
<!-- <el-empty description="Admin 权限可见" /> -->
</div>
</template>

295
src/views/fx/index.vue Normal file
View File

@@ -0,0 +1,295 @@
<!-- 分析统计页面 -->
<script lang="ts" setup>
import { ref, onMounted } from "vue"
import { use } from "echarts/core"
import { BarChart, PieChart } from "echarts/charts"
import {
DatasetComponent,
TransformComponent,
TooltipComponent,
GridComponent,
ToolboxComponent,
LegendComponent
} from "echarts/components"
import { SVGRenderer } from "echarts/renderers"
import VChart from "vue-echarts"
import { SuitcaseLine, Histogram, MapLocation } from "@element-plus/icons-vue"
import { Choropleth } from "@antv/l7plot"
// echart 图表
use([
PieChart,
BarChart,
DatasetComponent,
ToolboxComponent,
TransformComponent,
GridComponent,
TooltipComponent,
SVGRenderer,
LegendComponent
])
const ispoption = ref({
tooltip: [
{
trigger: "item",
formatter: "<b>{a}</b> </br> {c} (<b>{d}%</b>)"
}
],
toolbox: [
{
feature: {
saveAsImage: { show: true } // 保存图表
}
}
],
legend: [
{
orient: "vertical",
x: "left"
}
],
dataset: [
{
dimensions: ["name", "count"],
source: [
["Hannah Krause", 41],
["Zhao Qian", 20],
["Jasmin Krause ", 52],
["Li Lei", 37],
["Karle Neumann", 25],
["Adrian Groß", 19],
["Mia Neumann", 71],
["Böhm Fuchs", 36],
["Han Meimei", 67]
]
}
],
series: [
{
name: "IPv6 DNS数量统计",
type: "pie",
// 最小显示角度
minShowLabelAngle: 1,
encode: { itemName: "name", value: "count" }
}
]
})
const asnoption = ref({
toolbox: [
{
feature: {
saveAsImage: { show: true } // 保存图表
}
}
],
dataset: [
{
dimensions: ["name", "count"],
source: [
["Hannah Krause", 41],
["Zhao Qian", 20],
["Jasmin Krause ", 52],
["Li Lei", 37],
["Karle Neumann", 25],
["Adrian Groß", 19],
["Mia Neumann", 71],
["Böhm Fuchs", 36],
["Han Meimei", 67]
]
},
{
transform: {
type: "sort",
config: { dimension: "count", order: "desc" }
}
}
],
xAxis: {
type: "category",
axisLabel: { interval: 0, rotate: 30 }
},
yAxis: {},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
series: [
{
name: "IPv6 DNS数量统计",
type: "bar",
encode: { x: "name", y: "count" },
datasetIndex: 1
}
]
})
// L7Plot
onMounted(() => {
new Choropleth("mapcontainer", {
map: {
type: "map",
// style: 'blank',
center: [120.19382669582967, 30.258134],
zoom: 3,
pitch: 0
},
source: {
//"Russian Federation",
data: [
{ name: "China", value: 200 },
{ name: "Colombia", value: 250 },
{ name: "United States", value: 180 },
{ name: "Germany", value: 120 },
{ name: "Russia", value: 130 },
{ name: "澳大利亚", value: 130 },
{ name: "新加坡", value: 170 },
{ name: "巴西", value: 80 }
],
joinBy: {
sourceField: "name",
geoField: "english"
}
},
viewLevel: {
level: "world",
adcode: "all"
},
autoFit: true,
color: {
field: "value",
value: ["#B8E1FF", "#7DAAFF", "#3D76DD", "#0047A5", "#001D70"],
scale: { type: "quantize" }
},
style: {
opacity: 1,
stroke: "#ccc",
lineWidth: 0.6,
lineOpacity: 1
},
chinaBorder: false,
label: {
visible: true,
field: "value",
style: {
fill: "#000",
opacity: 0.8,
fontSize: 10,
stroke: "#fff",
strokeWidth: 1.5,
textAllowOverlap: false,
padding: [5, 5]
}
},
state: {
active: true,
select: {
stroke: "black",
lineWidth: 1.5,
lineOpacity: 0.8
}
},
tooltip: {
items: ["name", "value"],
trigger: "mousemove"
},
zoom: {
position: "bottomright"
},
legend: {
position: "bottomleft"
}
})
})
</script>
<template>
<div class="app-container">
<!-- Top 10厂商 -->
<el-row justify="center">
<el-col class="icenter">
<el-card class="box-card" style="width: 92%" shadow="hover">
<template #header>
<div class="fig-title">
<SuitcaseLine style="width: 2em; height: 2em; margin-right: 8px" />
<div style="font-size: 24px; font-weight: 900">IPv6 DNS分布厂商统计</div>
</div>
</template>
<!-- 饼图展示厂商 -->
<v-chart class="chart" :option="ispoption" autoresize />
</el-card>
</el-col>
</el-row>
<el-row justify="center">
<el-col class="icenter">
<el-card class="box-card" style="width: 92%" shadow="hover">
<template #header>
<div class="fig-title">
<Histogram style="width: 2em; height: 2em; margin-right: 8px" />
<div style="font-size: 24px; font-weight: 900">IPv6 DNS分布自治域统计</div>
</div>
</template>
<!-- 柱状图展示ASN -->
<v-chart class="chart" :option="asnoption" autoresize />
</el-card>
</el-col>
</el-row>
<!-- 地理可视化 -->
<el-row justify="center">
<el-col class="icenter">
<el-card class="box-card" style="width: 92%" shadow="hover">
<template #header>
<div class="fig-title">
<MapLocation style="width: 2em; height: 2em; margin-right: 8px" />
<div style="font-size: 24px; font-weight: 900">IPv6 DNS分布国家统计</div>
</div>
</template>
<!-- 地理 -->
<div id="mapcontainer" style="position: relative; height: 100%; min-height: 500px" />
</el-card>
</el-col>
</el-row>
</div>
</template>
<style lang="scss" scoped>
.chart {
height: 60vh;
}
.el-row {
margin-bottom: 20px;
}
.card-title {
font-size: 24px;
margin: 10px;
font-weight: 900;
color: aliceblue;
}
.count-num {
font-size: 36px;
font-weight: 900;
color: azure;
}
.icenter {
display: flex;
justify-content: center;
align-items: center;
}
.fig-title {
margin-top: 13px;
line-height: 12px;
display: flex;
justify-content: start;
align-items: center;
}
.box-card {
height: auto;
width: 80%;
}
</style>

View File

@@ -1,6 +1,295 @@
<!-- 分析统计页面 -->
<script lang="ts" setup>
import { ref, onMounted } from "vue"
import { use } from "echarts/core"
import { BarChart, PieChart } from "echarts/charts"
import {
DatasetComponent,
TransformComponent,
TooltipComponent,
GridComponent,
ToolboxComponent,
LegendComponent
} from "echarts/components"
import { SVGRenderer } from "echarts/renderers"
import VChart from "vue-echarts"
import { SuitcaseLine, Histogram, MapLocation } from "@element-plus/icons-vue"
import { Choropleth } from "@antv/l7plot"
// echart 图表
use([
PieChart,
BarChart,
DatasetComponent,
ToolboxComponent,
TransformComponent,
GridComponent,
TooltipComponent,
SVGRenderer,
LegendComponent
])
const ispoption = ref({
tooltip: [
{
trigger: "item",
formatter: "<b>{a}</b> </br> {c} (<b>{d}%</b>)"
}
],
toolbox: [
{
feature: {
saveAsImage: { show: true } // 保存图表
}
}
],
legend: [
{
orient: "vertical",
x: "left"
}
],
dataset: [
{
dimensions: ["name", "count"],
source: [
["Hannah Krause", 41],
["Zhao Qian", 20],
["Jasmin Krause ", 52],
["Li Lei", 37],
["Karle Neumann", 25],
["Adrian Groß", 19],
["Mia Neumann", 71],
["Böhm Fuchs", 36],
["Han Meimei", 67]
]
}
],
series: [
{
name: "IPv6 DNS数量统计",
type: "pie",
// 最小显示角度
minShowLabelAngle: 1,
encode: { itemName: "name", value: "count" }
}
]
})
const asnoption = ref({
toolbox: [
{
feature: {
saveAsImage: { show: true } // 保存图表
}
}
],
dataset: [
{
dimensions: ["name", "count"],
source: [
["Hannah Krause", 41],
["Zhao Qian", 20],
["Jasmin Krause ", 52],
["Li Lei", 37],
["Karle Neumann", 25],
["Adrian Groß", 19],
["Mia Neumann", 71],
["Böhm Fuchs", 36],
["Han Meimei", 67]
]
},
{
transform: {
type: "sort",
config: { dimension: "count", order: "desc" }
}
}
],
xAxis: {
type: "category",
axisLabel: { interval: 0, rotate: 30 }
},
yAxis: {},
tooltip: {
trigger: "axis",
axisPointer: {
type: "shadow"
}
},
series: [
{
name: "IPv6 DNS数量统计",
type: "bar",
encode: { x: "name", y: "count" },
datasetIndex: 1
}
]
})
// L7Plot
onMounted(() => {
new Choropleth("mapcontainer", {
map: {
type: "map",
// style: 'blank',
center: [120.19382669582967, 30.258134],
zoom: 3,
pitch: 0
},
source: {
//"Russian Federation",
data: [
{ name: "China", value: 200 },
{ name: "Colombia", value: 250 },
{ name: "United States", value: 180 },
{ name: "Germany", value: 120 },
{ name: "Russia", value: 130 },
{ name: "澳大利亚", value: 130 },
{ name: "新加坡", value: 170 },
{ name: "巴西", value: 80 }
],
joinBy: {
sourceField: "name",
geoField: "english"
}
},
viewLevel: {
level: "world",
adcode: "all"
},
autoFit: true,
color: {
field: "value",
value: ["#B8E1FF", "#7DAAFF", "#3D76DD", "#0047A5", "#001D70"],
scale: { type: "quantize" }
},
style: {
opacity: 1,
stroke: "#ccc",
lineWidth: 0.6,
lineOpacity: 1
},
chinaBorder: false,
label: {
visible: true,
field: "value",
style: {
fill: "#000",
opacity: 0.8,
fontSize: 10,
stroke: "#fff",
strokeWidth: 1.5,
textAllowOverlap: false,
padding: [5, 5]
}
},
state: {
active: true,
select: {
stroke: "black",
lineWidth: 1.5,
lineOpacity: 0.8
}
},
tooltip: {
items: ["name", "value"],
trigger: "mousemove"
},
zoom: {
position: "bottomright"
},
legend: {
position: "bottomleft"
}
})
})
</script>
<template>
<div class="app-container">
<el-card />
<!-- Top 10厂商 -->
<el-row justify="center">
<el-col class="icenter">
<el-card class="box-card" style="width: 92%" shadow="hover">
<template #header>
<div class="fig-title">
<SuitcaseLine style="width: 2em; height: 2em; margin-right: 8px" />
<div style="font-size: 24px; font-weight: 900">IPv6 DNS分布厂商统计</div>
</div>
</template>
<!-- 饼图展示厂商 -->
<v-chart class="chart" :option="ispoption" autoresize />
</el-card>
</el-col>
</el-row>
<el-row justify="center">
<el-col class="icenter">
<el-card class="box-card" style="width: 92%" shadow="hover">
<template #header>
<div class="fig-title">
<Histogram style="width: 2em; height: 2em; margin-right: 8px" />
<div style="font-size: 24px; font-weight: 900">IPv6 DNS分布自治域统计</div>
</div>
</template>
<!-- 柱状图展示ASN -->
<v-chart class="chart" :option="asnoption" autoresize />
</el-card>
</el-col>
</el-row>
<!-- 地理可视化 -->
<el-row justify="center">
<el-col class="icenter">
<el-card class="box-card" style="width: 92%" shadow="hover">
<template #header>
<div class="fig-title">
<MapLocation style="width: 2em; height: 2em; margin-right: 8px" />
<div style="font-size: 24px; font-weight: 900">IPv6 DNS分布国家统计</div>
</div>
</template>
<!-- 地理 -->
<div id="mapcontainer" style="position: relative; height: 100%; min-height: 500px" />
</el-card>
</el-col>
</el-row>
</div>
</template>
<style lang="scss" scoped>
.chart {
height: 60vh;
}
.el-row {
margin-bottom: 20px;
}
.card-title {
font-size: 24px;
margin: 10px;
font-weight: 900;
color: aliceblue;
}
.count-num {
font-size: 36px;
font-weight: 900;
color: azure;
}
.icenter {
display: flex;
justify-content: center;
align-items: center;
}
.fig-title {
margin-top: 13px;
line-height: 12px;
display: flex;
justify-content: start;
align-items: center;
}
.box-card {
height: auto;
width: 80%;
}
</style>