|
|
@@ -64,40 +64,481 @@
|
|
|
</div>
|
|
|
<div class="flex">
|
|
|
<div style="width: 48%; height: 400px">
|
|
|
- <EchartsDome title="服务调用趋势(近30天)" />
|
|
|
+ <EchartsDome
|
|
|
+ :chartOption="chartOptions['服务调用趋势(近30天)']"
|
|
|
+ title="服务调用趋势(近30天)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div style="width: 48%; height: 400px">
|
|
|
+ <EchartsDome title="服务类别分布" :chartOption="chartOptions['服务类别分布']" />
|
|
|
</div>
|
|
|
- <div style="width: 48%; height: 400px">echarts2</div>
|
|
|
</div>
|
|
|
- <div style="width: 100%; height: 400px">tables</div>
|
|
|
+ <div style="width: 100%; height: 400px">
|
|
|
+ <Table title="服务调用" :tableData="tableDatas" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
<!-- 用户信息统计 -->
|
|
|
- <div class="bigCard">用户信息统计</div>
|
|
|
+ <div class="bigCard">
|
|
|
+ <div class="bigCard_title">用户信息统计</div>
|
|
|
+ <div class="flex">
|
|
|
+ <div style="width: 28%; height: 400px">
|
|
|
+ <EchartsDome :chartOption="chartOptions['用户角色分布']" title="用户角色分布" />
|
|
|
+ </div>
|
|
|
+ <div style="width: 68%; height: 400px">
|
|
|
+ <EchartsDome
|
|
|
+ :chartOption="chartOptions['用户活跃度趋势']"
|
|
|
+ title="用户活跃度趋势"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div style="width: 100%; height: 400px">
|
|
|
+ <EchartsDome :chartOption="chartOptions['用户部门分布']" title="用户部门分布" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<!-- 应用类信息统计 -->
|
|
|
- <div class="bigCard">应用类信息统计</div>
|
|
|
+ <div class="bigCard">
|
|
|
+ <div class="bigCard_title">应用类信息统计</div>
|
|
|
+ <div class="flex">
|
|
|
+ <div style="width: 58%; height: 400px">
|
|
|
+ <EchartsDome
|
|
|
+ :chartOption="chartOptions['用户部门分布']"
|
|
|
+ title="热点应用TOP10排名"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div style="width: 38%; height: 400px">
|
|
|
+ <EchartsDome :chartOption="chartOptions['服务类别分布']" title="应用状态分布" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<!-- 数据类信息统计 -->
|
|
|
- <div class="bigCard">数据类信息统计</div>
|
|
|
+ <div class="bigCard">
|
|
|
+ <div class="bigCard_title">数据类信息统计</div>
|
|
|
+ <div class="flex">
|
|
|
+ <div style="width: 50%; height: 400px">
|
|
|
+ <EchartsDome :chartOption="chartOptions['数据类别分布']" title="数据类别分布" />
|
|
|
+ </div>
|
|
|
+ <div style="width: 50%; height: 400px">
|
|
|
+ <EchartsDome :chartOption="chartOptions['数据质量评分']" title="数据质量评分" />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
<!-- 区级特色信息统计 -->
|
|
|
- <div class="bigCard">区级特色信息统计</div>
|
|
|
+ <div class="bigCard" style="background: #00000000">
|
|
|
+ <div class="bigCard_title">区级特色信息统计</div>
|
|
|
+ <div class="flex" style="margin-top: 20px">
|
|
|
+ <div class="flex_column" style="width: 28%; height: 420px">
|
|
|
+ <card
|
|
|
+ class="card2 flex"
|
|
|
+ :title="'服务机构总数'"
|
|
|
+ :value="8"
|
|
|
+ :growth="'较上个月增长了12%'"
|
|
|
+ iconColor="#2563db"
|
|
|
+ :upStatus="1"
|
|
|
+ />
|
|
|
+ <card
|
|
|
+ class="card2 flex"
|
|
|
+ :title="'服务总数'"
|
|
|
+ :value="100"
|
|
|
+ :growth="'较上个月下降了12%'"
|
|
|
+ iconColor="#16a34a"
|
|
|
+ :upStatus="-1"
|
|
|
+ />
|
|
|
+ <card
|
|
|
+ class="card2 flex"
|
|
|
+ :title="'服务调用总次数'"
|
|
|
+ :value="1000"
|
|
|
+ :growth="'较上个月增长了12%'"
|
|
|
+ iconColor="#9333ea"
|
|
|
+ :upStatus="1"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div style="width: 68%; height: 420px">
|
|
|
+ <EchartsDome
|
|
|
+ :chartOption="chartOptions['服务调用趋势(近30天)']"
|
|
|
+ title="服务调用趋势(近30天)"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import card from "@/components/yxgl/card.vue";
|
|
|
import EchartsDome from "@/components/yxgl/EchartsDome.vue";
|
|
|
+import Table from "@/components/yxgl/table.vue";
|
|
|
export default {
|
|
|
name: "",
|
|
|
components: {
|
|
|
card,
|
|
|
EchartsDome,
|
|
|
+ Table,
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
dateValue: "",
|
|
|
shortcuts: this.shortcuts(),
|
|
|
+ chartOptions: {},
|
|
|
+ tableDatas: [],
|
|
|
};
|
|
|
},
|
|
|
- mounted() {},
|
|
|
+ mounted() {
|
|
|
+ let datas = [
|
|
|
+ { value: 1048, name: "调用次数", value2: 3, date: "12/17" },
|
|
|
+ { value: 735, name: "平均响应时间", value2: 3, date: "12/18" },
|
|
|
+ ];
|
|
|
+
|
|
|
+ let datas2 = [
|
|
|
+ {
|
|
|
+ value: 20,
|
|
|
+ name: "业务数据",
|
|
|
+ children: [
|
|
|
+ { value: 7, name: "交通数据" },
|
|
|
+ { value: 5, name: "环保数据" },
|
|
|
+ { value: 5, name: "水务数据" },
|
|
|
+ { value: 3, name: "教育数据" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 13,
|
|
|
+ name: "基础数据",
|
|
|
+ children: [
|
|
|
+ { value: 5, name: "人口数据" },
|
|
|
+ { value: 5, name: "地理数据" },
|
|
|
+ { value: 3, name: "企业数据" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 9,
|
|
|
+ name: "专题数据",
|
|
|
+ children: [
|
|
|
+ { value: 4, name: "规划数据" },
|
|
|
+ { value: 3, name: "医疗数据" },
|
|
|
+ { value: 2, name: "文旅数据" },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ];
|
|
|
+
|
|
|
+ this.dataToOption("数据类别分布", "sunburst", datas2, null);
|
|
|
+ this.dataToOption("数据质量评分", "radar", datas2, null);
|
|
|
+ this.dataToOption("服务调用趋势(近30天)", "line", datas, {
|
|
|
+ xData: [],
|
|
|
+ xKey: "date",
|
|
|
+ yAxis: [
|
|
|
+ {
|
|
|
+ type: "value",
|
|
|
+ name: "调用次数",
|
|
|
+ axisLine: { lineStyle: { color: "#42a5f5" } }, // 区分样式
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: "value",
|
|
|
+ name: "响应时间(ms)",
|
|
|
+ axisLine: { lineStyle: { color: "#4caf50" } }, // 区分样式
|
|
|
+ position: "right",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ yData: [
|
|
|
+ {
|
|
|
+ key: "value",
|
|
|
+ name: "调用次数",
|
|
|
+ color: "#42a5f5",
|
|
|
+ data: [],
|
|
|
+ yAxisIndex: 0,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: "value2",
|
|
|
+ name: "响应时间(ms)",
|
|
|
+ color: "#4caf50",
|
|
|
+ data: [],
|
|
|
+ ifDashed: true,
|
|
|
+ yAxisIndex: 1,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ this.dataToOption("用户活跃度趋势", "line", datas, {
|
|
|
+ xData: [],
|
|
|
+ xKey: "date",
|
|
|
+ yData: [
|
|
|
+ {
|
|
|
+ key: "value",
|
|
|
+ name: "调用次数",
|
|
|
+ color: "#42a5f5",
|
|
|
+ data: [],
|
|
|
+ },
|
|
|
+ {
|
|
|
+ key: "value2",
|
|
|
+ name: "响应时间(ms)",
|
|
|
+ color: "#4caf50",
|
|
|
+ data: [],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+
|
|
|
+ this.dataToOption("服务类别分布", "pie", datas, {
|
|
|
+ pieKey: { value: "value", name: "name" },
|
|
|
+ pieData: [],
|
|
|
+ });
|
|
|
+
|
|
|
+ this.dataToOption("用户角色分布", "pie", datas, {
|
|
|
+ pieKey: { value: "value", name: "name" },
|
|
|
+ pieData: [],
|
|
|
+ legend: {
|
|
|
+ bottom: 10,
|
|
|
+ },
|
|
|
+ radius: "60%",
|
|
|
+ padAngle: 0,
|
|
|
+ borderRadius: 0,
|
|
|
+ label: {},
|
|
|
+ });
|
|
|
+ this.dataToOption("用户部门分布", "bar", datas, {
|
|
|
+ showLegend: false,
|
|
|
+ xData: [],
|
|
|
+ xKey: "date",
|
|
|
+ yData: [
|
|
|
+ {
|
|
|
+ key: "value",
|
|
|
+ name: "调用次数",
|
|
|
+ color: "#42a5f5",
|
|
|
+ data: [],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ });
|
|
|
+ // 表格数据初始化
|
|
|
+ this.initTableDatas();
|
|
|
+ },
|
|
|
methods: {
|
|
|
+ dataToOption(title, type, datas, keyRule) {
|
|
|
+ // 根据规则解析数据
|
|
|
+ if (keyRule) {
|
|
|
+ datas.forEach((item) => {
|
|
|
+ // 有的图表没有X轴
|
|
|
+ if (keyRule.xKey) {
|
|
|
+ keyRule.xData.push(item[keyRule.xKey]);
|
|
|
+ }
|
|
|
+ if (keyRule.yData) {
|
|
|
+ keyRule.legend = [];
|
|
|
+ keyRule.yData.forEach((dataItem) => {
|
|
|
+ dataItem.data.push(item[dataItem.key]);
|
|
|
+ keyRule.legend.push(dataItem.name);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ if (keyRule.pieKey) {
|
|
|
+ keyRule.pieData.push({
|
|
|
+ value: item[keyRule.pieKey.value],
|
|
|
+ name: item[keyRule.pieKey.name],
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ let _option = {};
|
|
|
+ switch (type) {
|
|
|
+ case "line":
|
|
|
+ // 折线图基础
|
|
|
+ _option = {
|
|
|
+ legend: {
|
|
|
+ data: keyRule.legend,
|
|
|
+ },
|
|
|
+ tooltip: {
|
|
|
+ show: true,
|
|
|
+ trigger: "axis",
|
|
|
+ axisPointer: { type: "shadow" },
|
|
|
+ },
|
|
|
+ // 默认样式
|
|
|
+ xAxis: {
|
|
|
+ type: "category",
|
|
|
+ data: keyRule.xData,
|
|
|
+ axisTick: { show: false }, // 隐藏刻度
|
|
|
+ splitLine: { show: false }, // 隐藏分割线
|
|
|
+ },
|
|
|
+ yAxis: keyRule.yAxis ? keyRule.yAxis : { type: "value" },
|
|
|
+ series: [],
|
|
|
+ };
|
|
|
+ // 补充数据
|
|
|
+ keyRule.yData.forEach((item) => {
|
|
|
+ // 补充server
|
|
|
+ _option.series.push({
|
|
|
+ name: item.name,
|
|
|
+ type: "line",
|
|
|
+ smooth: true,
|
|
|
+ data: item.data, // 模拟数据
|
|
|
+ lineStyle: {
|
|
|
+ color: item.color ? item.color : "",
|
|
|
+ type: item.ifDashed ? "dashed" : "",
|
|
|
+ }, // 蓝色线条
|
|
|
+ itemStyle: item.color ? { color: item.color } : {}, // 节点颜色
|
|
|
+ symbol: "circle", // 节点形状
|
|
|
+ symbolSize: 6, // 节点大小
|
|
|
+ yAxisIndex: item.yAxisIndex != undefined ? item.yAxisIndex : 0, // 绑定Y轴
|
|
|
+ });
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ case "pie":
|
|
|
+ // 饼状图
|
|
|
+ _option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: "item",
|
|
|
+ },
|
|
|
+ legend: keyRule.legend
|
|
|
+ ? keyRule.legend
|
|
|
+ : {
|
|
|
+ orient: "vertical",
|
|
|
+ top: "50%",
|
|
|
+ right: 10,
|
|
|
+ },
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ name: title,
|
|
|
+ type: "pie",
|
|
|
+ radius: keyRule.radius ? keyRule.radius : ["40%", "70%"],
|
|
|
+ avoidLabelOverlap: false,
|
|
|
+ padAngle: keyRule.padAngle != undefined ? keyRule.padAngle : 5,
|
|
|
+ itemStyle: {
|
|
|
+ borderRadius:
|
|
|
+ keyRule.borderRadius != undefined ? keyRule.borderRadius : 10,
|
|
|
+ },
|
|
|
+ label:
|
|
|
+ keyRule.label != undefined
|
|
|
+ ? keyRule.label
|
|
|
+ : {
|
|
|
+ show: false,
|
|
|
+ position: "center",
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ fontSize: 20,
|
|
|
+ fontWeight: "bold",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ labelLine: {
|
|
|
+ show: true,
|
|
|
+ },
|
|
|
+ data: keyRule.pieData,
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ break;
|
|
|
+ case "bar":
|
|
|
+ // 柱状图
|
|
|
+ _option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: "axis",
|
|
|
+ axisPointer: {
|
|
|
+ type: "shadow",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ show: keyRule.showLegend ? keyRule.showLegend : false,
|
|
|
+ data: keyRule.legend,
|
|
|
+ },
|
|
|
+ xAxis: {
|
|
|
+ type: "value",
|
|
|
+ },
|
|
|
+ yAxis: {
|
|
|
+ type: "category",
|
|
|
+ data: keyRule.xData,
|
|
|
+ },
|
|
|
+ series: [],
|
|
|
+ };
|
|
|
+ keyRule.yData.forEach((item) => {
|
|
|
+ _option.series.push({
|
|
|
+ name: item.name,
|
|
|
+ type: "bar",
|
|
|
+ label: {
|
|
|
+ show: true,
|
|
|
+ },
|
|
|
+ emphasis: {
|
|
|
+ focus: "series",
|
|
|
+ },
|
|
|
+ data: item.data,
|
|
|
+ });
|
|
|
+ });
|
|
|
+ break;
|
|
|
+ case "sunburst":
|
|
|
+ // 旭日图
|
|
|
+ _option = {
|
|
|
+ series: {
|
|
|
+ type: "sunburst",
|
|
|
+ emphasis: {
|
|
|
+ focus: "ancestor",
|
|
|
+ },
|
|
|
+ data: datas,
|
|
|
+ radius: [0, "90%"],
|
|
|
+ label: {
|
|
|
+ rotate: "radial",
|
|
|
+ },
|
|
|
+ },
|
|
|
+ };
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ // 雷达图
|
|
|
+ _option = {
|
|
|
+ tooltip: {
|
|
|
+ trigger: "axis",
|
|
|
+ },
|
|
|
+ legend: {
|
|
|
+ show: false,
|
|
|
+ left: "center",
|
|
|
+ },
|
|
|
+ radar: [
|
|
|
+ {
|
|
|
+ indicator: [
|
|
|
+ { text: "完整性", max: 100 },
|
|
|
+ { text: "可用性", max: 100 },
|
|
|
+ { text: "一致性", max: 100 },
|
|
|
+ { text: "及时性", max: 100 },
|
|
|
+ { text: "准确性", max: 100 },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ series: [
|
|
|
+ {
|
|
|
+ type: "radar",
|
|
|
+ areaStyle: {},
|
|
|
+ data: [
|
|
|
+ {
|
|
|
+ value: [85, 90, 90, 95, 95],
|
|
|
+ name: "A Phone",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: [95, 80, 95, 90, 93],
|
|
|
+ name: "Another Phone",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ };
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ this.chartOptions[title] = _option;
|
|
|
+ },
|
|
|
+ // 服务调用列表
|
|
|
+ initTableDatas() {
|
|
|
+ this.tableDatas = [
|
|
|
+ {
|
|
|
+ serviceName: "服务A",
|
|
|
+ serviceType: "类别A",
|
|
|
+ callCount: 100,
|
|
|
+ successRate: "90%",
|
|
|
+ avgResponseTime: "100ms",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ serviceName: "服务B",
|
|
|
+ serviceType: "类别B",
|
|
|
+ callCount: 200,
|
|
|
+ successRate: "80%",
|
|
|
+ avgResponseTime: "150ms",
|
|
|
+ },
|
|
|
+ {
|
|
|
+ serviceName: "服务C",
|
|
|
+ serviceType: "类别C",
|
|
|
+ callCount: 300,
|
|
|
+ successRate: "70%",
|
|
|
+ avgResponseTime: "200ms",
|
|
|
+ },
|
|
|
+ ];
|
|
|
+ },
|
|
|
+ // 时间范围自定义时间
|
|
|
shortcuts() {
|
|
|
return [
|
|
|
{
|
|
|
@@ -149,13 +590,21 @@ export default {
|
|
|
& > div {
|
|
|
margin: 20px 0;
|
|
|
display: flex;
|
|
|
- overflow: hidden;
|
|
|
}
|
|
|
.card {
|
|
|
width: calc(25% - 56px);
|
|
|
border-radius: 5px;
|
|
|
padding: 20px 18px;
|
|
|
background: #ffffff;
|
|
|
+ box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.15);
|
|
|
+ }
|
|
|
+
|
|
|
+ .card2 {
|
|
|
+ width: 100%;
|
|
|
+ border-radius: 5px;
|
|
|
+ padding: 20px 18px;
|
|
|
+ background: #ffffff;
|
|
|
+ box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.15);
|
|
|
}
|
|
|
|
|
|
.bigCard {
|
|
|
@@ -165,6 +614,7 @@ export default {
|
|
|
background: #ffffff;
|
|
|
position: relative;
|
|
|
flex-direction: column;
|
|
|
+ box-shadow: 0 0 15px 1px rgba(0, 0, 0, 0.15);
|
|
|
.tools {
|
|
|
position: absolute;
|
|
|
top: 20px;
|
|
|
@@ -184,6 +634,13 @@ export default {
|
|
|
flex-direction: row;
|
|
|
justify-content: space-between;
|
|
|
}
|
|
|
+ .flex_column {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: flex-start;
|
|
|
+ box-sizing: border-box;
|
|
|
+ }
|
|
|
|
|
|
.searchBox {
|
|
|
width: 100%;
|