Commit 04060e06 authored by liwei's avatar liwei

新建了API监控页面

parent 05482702
...@@ -11,27 +11,27 @@ export const columns1: BasicColumn[] = [ ...@@ -11,27 +11,27 @@ export const columns1: BasicColumn[] = [
{ {
title: 'gateway', title: 'gateway',
dataIndex: 'gateway', dataIndex: 'gateway',
width: 150, width: 100,
}, },
{ {
title: 'executor', title: 'executor',
dataIndex: 'executor', dataIndex: 'executor',
width: 150, width: 100,
}, },
{ {
title: '调用者', title: '调用者',
dataIndex: 'caller', dataIndex: 'caller',
width: 150, width: 100,
}, },
{ {
title: '开始时间', title: '开始时间',
dataIndex: 'startTime', dataIndex: 'startTime',
width: 150, width: 100,
}, },
{ {
title: '已耗时', title: '已耗时',
dataIndex: 'consume', dataIndex: 'consume',
width: 150, width: 100,
}, },
]; ];
export const searchFormSchema: FormSchema[] = [ export const searchFormSchema: FormSchema[] = [
......
<template> <template>
<Card :loading="loading"> <Card :loading="loading">
333 <div style="display: flex">
<div ref="chartRef1" style="width: 80%; height: 400px"></div>
<div ref="chartRef2" style="width: 20%;height: 400px"></div>
</div>
</Card> </Card>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref } from 'vue'; import {onMounted, ref} from 'vue';
import { Tag, Card,Select } from 'ant-design-vue'; import { Tag, Card,Select } from 'ant-design-vue';
import { BasicTable, useTable, TableAction } from '@/components/Table'; import { BasicTable, useTable, TableAction } from '@/components/Table';
import {} from "./ApiMonitor.data";
import {} from "./ApiMonitorData";
import Icon from '@/components/Icon/Icon.vue'; import Icon from '@/components/Icon/Icon.vue';
import {useECharts} from "@/hooks/web/useECharts";
const chartRef1 = ref<HTMLDivElement | null>(null);
const { setOptions: setOptions1 } = useECharts(chartRef1 as Ref<HTMLDivElement>);
const chartRef2 = ref<HTMLDivElement | null>(null);
const { setOptions: setOptions2 } = useECharts(chartRef2 as Ref<HTMLDivElement>);
function getEchartsData1() {
setOptions1({
title: {
text: '业务错误码趋势统计',
left: 'left', // 将标题放在左侧
top: '10', // 距离顶部10px
textStyle: {
color: '#333', // 标题文字颜色
fontSize: 16, // 标题字体大小
fontWeight: 'bold' // 标题字体加粗
}
},
tooltip: {
trigger: 'axis',
axisPointer: {
lineStyle: {
width: 1,
color: '#019680',
},
},
},
legend: {
orient: 'vertical', // 垂直方向
right: '2%', // 图例放置在右侧
top: 'center', // 图例垂直居中
itemWidth: 15, // 图例标记宽度
itemHeight: 15, // 图例标记高度
textStyle: {
color: '#333', // 图例文字颜色
fontSize: 12, // 图例文字大小
},
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [...new Array(8)].map((_item, index) => `10/0${index + 1}`),
splitLine: {
show: true,
lineStyle: {
width: 1,
type: 'solid',
color: 'rgba(226,226,226,0.5)',
},
},
axisTick: {
show: false,
},
},
yAxis: [
{
type: 'value',
max: 5000, // 设置最大值以适应所有数据
splitNumber: 6, // 分割线数量
axisTick: {
show: false,
},
splitArea: {
show: true,
areaStyle: {
color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
},
},
},
],
grid: {
left: '1%',
right: '35%', // 给图例留出空间
top: '70px',
bottom: '5%',
containLabel: true,
},
series: [
{ name: '62101(服务参数解析异常)', data: [450, 675, 450, 1125, 1800, 1575, 1800, 2025], type: 'line', itemStyle: { color: 'rgb(90, 143, 240)' } }, // 番茄红
{ name: '62102(缺少必要的服务参数)', data: [675, 900, 675, 1350, 2025, 1800, 2025, 2250], type: 'line', itemStyle: { color: 'rgb(153, 205, 255)' } }, // 金黄色
{ name: '62201(数据库异常,无法获取JDBC连接)', data: [900, 1125, 900, 1575, 2250, 2025, 2250, 2475], type: 'line', itemStyle: { color: 'rgb(250, 225, 200)' } }, // 柠檬绿
{ name: '62202(数据库异常,没有劝返访问)', data: [1125, 1350, 1125, 1800, 2475, 2250, 2475, 2700], type: 'line', itemStyle: { color: 'rgb(237, 200, 109)' } }, // 青色
{ name: '62301(查询异常,不存在的数据列)', data: [1350, 1575, 1350, 2025, 2700, 2475, 2700, 2925], type: 'line', itemStyle: { color: 'rgb(136, 231, 226)' } }, // 蓝色
{ name: '62302(查询异常,不存在的数据列)', data: [1575, 1800, 1575, 2250, 2925, 2700, 2925, 3150], type: 'line', itemStyle: { color: 'rgb(170, 233, 240)' } }, // 蓝紫色
{ name: '62303(查询异常,无法解析SQL)', data: [1800, 2025, 1800, 2475, 3150, 2925, 3150, 3375], type: 'line', itemStyle: { color: 'rgb(246, 185, 148)' } }, // 紫罗兰
{ name: '62401(服务异常,没有对应服务)', data: [2025, 2250, 2025, 2700, 3375, 3150, 3375, 3600], type: 'line', itemStyle: { color: 'rgb(156, 140, 249)' } }, // 深粉红色
{ name: '62501(SQL拼接异常)', data: [2250, 2475, 2250, 2925, 3600, 3375, 3600, 3825], type: 'line', itemStyle: { color: 'rgb(227, 129, 129)' } }, // 橙红色
{ name: '62601(服务实现版本查询异常)', data: [2475, 2700, 2475, 3150, 3825, 3600, 3825, 4050], type: 'line', itemStyle: { color: 'rgb(174, 182, 192)' } }, // 巧克力色
],
});
}
function getEchartsData2() {
setOptions2({
title: {
text: '业务错误码分布统计',
left: 'left', // 标题居中
top: '5%', // 距离图表顶部5%
textStyle: {
fontSize: 15, // 标题字体大小
fontWeight: 'bold' // 加粗
}
},
tooltip: {
trigger: 'item',
},
series: [
{
color: ['rgb(255, 210, 163)', 'rgb(142, 228, 237)', 'rgb(113, 213, 166)', 'rgb(248, 161, 59)', 'rgb(224, 97, 97)', 'rgb(93, 177, 255)', 'rgb(53, 119, 241)', 'rgb(138, 146, 160)', 'rgb(224, 180, 18)', 'rgb(130, 106, 249)'],
name: '访问来源',
type: 'pie',
radius: ['70%', '100%'],
avoidLabelOverlap: false,
itemStyle: {
borderRadius: 5,
borderColor: '#fff',
borderWidth: 2,
},
label: {
show: true,
position: 'center',
formatter: function (params) {
return '总数: ' + 957;
},
textStyle: {
fontSize: 16,
fontWeight: 'bold'
}
},
emphasis: {
label: {
show: true,
fontSize: '12',
fontWeight: 'bold',
},
},
labelLine: {
show: false,
},
data: [
{ value: 110, name: '62101' },
{ value: 120, name: '62102' },
{ value: 130, name: '62201' },
{ value: 50, name: '62202' },
{ value: 50, name: '62301' },
{ value: 50, name: '62302' },
{ value: 80, name: '62303' },
{ value: 100, name: '62401' },
{ value: 120, name: '62501' },
{ value: 150, name: '62601' },
],
animationType: 'scale',
animationEasing: 'exponentialInOut',
animationDelay: function () {
return Math.random() * 100;
},
},
],
});
}
onMounted(() => {
getEchartsData1()
getEchartsData2()
})
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
......
<template> <template>
<div class="charts-container"> <Card :loading="loading">
<div class="header"> <div style="display: flex">
<span>API调用统计</span> <div ref="chartRef1" style="width: 80%; height: 400px"></div>
<div ref="chartRef2" style="width: 20%;height: 400px"></div>
</div> </div>
<div class="charts"> </Card>
<div id="chart1" class="chart"></div>
<div id="chart2" class="chart"></div>
</div>
</div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from 'vue'; import {onMounted, ref} from 'vue';
import * as echarts from 'echarts'; import { Tag, Card,Select } from 'ant-design-vue';
import { import { BasicTable, useTable, TableAction } from '@/components/Table';
totalApiData, import Icon from '@/components/Icon/Icon.vue';
totalApiFailedData, import {useECharts} from "@/hooks/web/useECharts";
totalApiSucessData, const chartRef1 = ref<HTMLDivElement | null>(null);
totalGetApiData, const { setOptions: setOptions1 } = useECharts(chartRef1 as Ref<HTMLDivElement>);
totalPostApiData, const chartRef2 = ref<HTMLDivElement | null>(null);
} from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData'; const { setOptions: setOptions2 } = useECharts(chartRef2 as Ref<HTMLDivElement>);
function getEchartsData1() {
onMounted(() => { setOptions1({
{ title: {
// 获取图表容器 text: 'Http错误码趋势统计',
const chart1Container = document.getElementById('chart1'); left: 'left', // 将标题放在左侧
const chart2Container = document.getElementById('chart2'); top: '10', // 距离顶部10px
textStyle: {
// 初始化图表实例 color: '#333', // 标题文字颜色
const chart1Instance = echarts.init(chart1Container); fontSize: 16, // 标题字体大小
const chart2Instance = echarts.init(chart2Container); fontWeight: 'bold' // 标题字体加粗
}
// 设置图表选项 },
chart1Instance.setOption({ tooltip: {
title: { trigger: 'axis',
text: 'API调用统计', // 修改了标题文字 axisPointer: {
lineStyle: {
width: 1,
color: '#019680',
}, },
legend: { },
data: ['总量', '成功', '失败'], },
top: '8%', // 图例位置调整 legend: {
left: '5%', orient: 'vertical', // 垂直方向
right: '2%', // 图例放置在右侧
top: 'center', // 图例垂直居中
itemWidth: 15, // 图例标记宽度
itemHeight: 15, // 图例标记高度
textStyle: {
color: '#333', // 图例文字颜色
fontSize: 12, // 图例文字大小
},
},
xAxis: {
type: 'category',
boundaryGap: false,
data: [...new Array(8)].map((_item, index) => `10/0${index + 1}`),
splitLine: {
show: true,
lineStyle: {
width: 1,
type: 'solid',
color: 'rgba(226,226,226,0.5)',
}, },
xAxis: { },
type: 'category', axisTick: {
boundaryGap: false, // 坐标轴两边留白策略 show: false,
data: totalApiData.map((item) => item.date), // 假设每个数据点有日期属性 },
axisLabel: { },
rotate: 45, // 旋转x轴标签以避免重叠 yAxis: [
}, {
type: 'value',
max: 5000, // 设置最大值以适应所有数据
splitNumber: 6, // 分割线数量
axisTick: {
show: false,
}, },
yAxis: { splitArea: {
min: 0, show: true,
max: 5000, areaStyle: {
splitNumber: 5, color: ['rgba(255,255,255,0.2)', 'rgba(226,226,226,0.2)'],
nameTextStyle: {
padding: [0, 0, 10, 0], // 调整y轴名称与轴线的距离
}, },
}, },
series: [ },
{ ],
name: '总量', grid: {
type: 'line', left: '1%',
color: '#67a6f1', right: '35%', // 给图例留出空间
areaStyle: { top: '70px',
color: { bottom: '5%',
type: 'linear', containLabel: true,
x: 0, },
y: 0, series: [
x2: 0, { name: '400(错误的请求)', data: [450, 675, 450, 1125, 1800, 1575, 1800, 2025], type: 'line', itemStyle: { color: 'rgb(90, 143, 240)' } }, // 番茄红
y2: 1, { name: '401(权限认证异常)', data: [675, 900, 675, 1350, 2025, 1800, 2025, 2250], type: 'line', itemStyle: { color: 'rgb(153, 205, 255)' } }, // 金黄色
colorStops: [ { name: '403(禁止访问)', data: [900, 1125, 900, 1575, 2250, 2025, 2250, 2475], type: 'line', itemStyle: { color: 'rgb(250, 225, 200)' } }, // 柠檬绿
{ { name: '404(无法找到请求匹配的服务)', data: [1125, 1350, 1125, 1800, 2475, 2250, 2475, 2700], type: 'line', itemStyle: { color: 'rgb(237, 200, 109)' } }, // 青色
offset: 0, { name: '405(请求方法不匹配)', data: [1350, 1575, 1350, 2025, 2700, 2475, 2700, 2925], type: 'line', itemStyle: { color: 'rgb(136, 231, 226)' } }, // 蓝色
color: 'rgba(173,204,236,0.8)', // 顶部颜色较深 { name: '500(数据服务处理异常)', data: [1575, 1800, 1575, 2250, 2925, 2700, 2925, 3150], type: 'line', itemStyle: { color: 'rgb(170, 233, 240)' } }, // 蓝紫色
}, ],
{ });
offset: 1, }
color: 'rgba(173,204,236,0)', // 底部颜色透明 function getEchartsData2() {
}, setOptions2({
], title: {
global: false, text: 'Http错误码分布统计',
}, left: 'left', // 标题居中
}, top: '5%', // 距离图表顶部5%
data: totalApiData.map((item) => item.value), textStyle: {
}, fontSize: 15, // 标题字体大小
{ fontWeight: 'bold' // 加粗
name: '成功', }
type: 'line', },
color: '#6fe3e3', tooltip: {
areaStyle: { trigger: 'item',
color: { },
type: 'linear', series: [
x: 0, {
y: 0, color: ['rgb(187, 255, 255)', 'rgb(136, 231, 226)', 'rgb(113, 213, 166)', 'rgb(255, 220, 119)', 'rgb(255, 247, 220)', 'rgb(168, 225, 255)'],
x2: 0, name: '访问来源',
y2: 1, type: 'pie',
colorStops: [ radius: ['70%', '100%'],
{ avoidLabelOverlap: false,
offset: 0, itemStyle: {
color: 'rgba(153,236,233,0.8)', // 顶部颜色较深 borderRadius: 5,
}, borderColor: '#fff',
{ borderWidth: 2,
offset: 1,
color: 'rgba(153,236,233,0)', // 底部颜色透明
},
],
global: false,
},
},
data: totalApiSucessData.map((item) => item.value),
},
{
name: '失败',
type: 'line',
color: '#90ed7d',
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(144,237,125,0.8)', // 顶部颜色较深
},
{
offset: 1,
color: 'rgba(144,237,125,0)', // 底部颜色透明
},
],
global: false,
},
},
data: totalApiFailedData.map((item) => item.value),
},
],
});
chart2Instance.setOption({
title: {
text: '请求方式调用量', // 修改了标题文字
},
legend: {
data: ['Get', 'Post'],
top: '8%', // 图例位置调整
left: '5%',
}, },
xAxis: { label: {
type: 'category', show: true,
boundaryGap: false, // 坐标轴两边留白策略 position: 'center',
data: totalApiData.map((item) => item.date), // 假设每个数据点有日期属性 formatter: function (params) {
axisLabel: { return '总数: ' + 757;
rotate: 45, // 旋转x轴标签以避免重叠
}, },
textStyle: {
fontSize: 16,
fontWeight: 'bold'
}
}, },
yAxis: { emphasis: {
min: 0, label: {
max: 500, show: true,
splitNumber: 5, fontSize: '12',
nameTextStyle: { fontWeight: 'bold',
padding: [0, 0, 10, 0], // 调整y轴名称与轴线的距离
}, },
}, },
series: [ labelLine: {
{ show: false,
name: 'Get', },
type: 'line', data: [
color: '#f3a770', { value: 110, name: '400' },
areaStyle: { { value: 120, name: '401' },
color: { { value: 130, name: '403' },
type: 'linear', // 渐变类型,可选 'linear' 或 'radial' { value: 200, name: '404' },
x: 0, // 渐变起始位置,x轴方向 { value: 150, name: '405' },
y: 0, // 渐变起始位置,y轴方向 { value: 50, name: '500' },
x2: 0, // 渐变结束位置,x轴方向
y2: 1, // 渐变结束位置,y轴方向
colorStops: [
// 颜色停止位
{
offset: 0,
color: 'rgba(246,208,170,0.5)', // 0% 处的颜色
},
{
offset: 1,
color: 'rgba(246,208,170,0)', // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
},
data: totalGetApiData.map((item) => item.value),
},
{
name: 'Post',
type: 'line',
color: '#ce9be5',
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(212,184,229,0.5)', // 0% 处的颜色
},
{
offset: 1,
color: 'rgba(212,184,229,0)', // 100% 处的颜色
},
],
global: false,
},
},
data: totalPostApiData.map((item) => item.value),
},
], ],
}); animationType: 'scale',
} animationEasing: 'exponentialInOut',
animationDelay: function () {
return Math.random() * 100;
},
},
],
}); });
}
onMounted(() => {
getEchartsData1()
getEchartsData2()
})
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.charts-container {
background-color: white; /* 设置容器背景为白色 */
padding: 20px; /* 给容器添加内边距 */
border-radius: 10px; /* 可选:给容器添加圆角 */
width: 100%; /* 确保容器宽度适应父级元素 */
}
.header {
font-size: 20px;
margin-bottom: 20px;
text-align: left;
color: #333;
}
.charts {
display: flex;
justify-content: space-between;
gap: 20px;
}
.chart {
width: calc(50% - 10px); /* 确保两个图表并排显示 */
height: 400px;
background-color: transparent; /* 使图表的背景透明 */
}
</style> </style>
<template> <template>
<div class="charts-container"> <div class="charts-container">
<div class="header"> <div class="header">
<span>响应时长统计</span> <span>API调用统计</span>
</div> </div>
<div class="charts"> <div class="charts">
<div id="chart3" class="chart"></div> <div id="chart1" class="chart"></div>
<div id="chart4" class="chart"></div> <div id="chart2" class="chart"></div>
</div> </div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted } from 'vue'; import { onMounted } from 'vue';
import * as echarts from 'echarts'; import * as echarts from 'echarts';
import { fieldChangeData } from '@/views/metadata/metadataData'; import {
import { totalApiData,
responseData, totalApiFailedData,
second1Data, totalApiSucessData,
second2Data, totalGetApiData,
second3Data, totalPostApiData,
second4Data, } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData';
totalApiData,
totalApiFailedData,
totalApiSucessData,
} from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData';
function parseValue(value) { onMounted(() => {
return parseFloat(value); // This will convert '3.5ms' to 3.5 {
} // 获取图表容器
const chart1Container = document.getElementById('chart1');
onMounted(() => { const chart2Container = document.getElementById('chart2');
{
// 获取图表容器
const chart3Container = document.getElementById('chart3');
const chart4Container = document.getElementById('chart4');
// 初始化图表实例 // 初始化图表实例
const chart3Instance = echarts.init(chart3Container); const chart1Instance = echarts.init(chart1Container);
const chart4Instance = echarts.init(chart4Container); const chart2Instance = echarts.init(chart2Container);
// 设置图表选项 // 设置图表选项
chart3Instance.setOption({ chart1Instance.setOption({
title: { title: {
text: '平均响应时长', text: 'API调用统计', // 修改了标题文字
},
legend: {
data: ['总量', '成功', '失败'],
top: '8%', // 图例位置调整
left: '5%',
},
xAxis: {
type: 'category',
boundaryGap: false, // 坐标轴两边留白策略
data: totalApiData.map((item) => item.date), // 假设每个数据点有日期属性
axisLabel: {
rotate: 45, // 旋转x轴标签以避免重叠
}, },
tooltip: { },
formatter: function (params) { yAxis: {
return `${params.name}: ${params.value} ms`; min: 0,
}, max: 5000,
splitNumber: 5,
nameTextStyle: {
padding: [0, 0, 10, 0], // 调整y轴名称与轴线的距离
}, },
xAxis: { },
data: responseData.map((item) => item.date), series: [
boundaryGap: false, // 数据点与标签对齐 {
name: '总量',
type: 'line',
color: '#67a6f1',
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(173,204,236,0.8)', // 顶部颜色较深
},
{
offset: 1,
color: 'rgba(173,204,236,0)', // 底部颜色透明
},
],
global: false,
},
},
data: totalApiData.map((item) => item.value),
}, },
yAxis: { {
min: 0, // 设置 Y 轴的最小值 name: '成功',
max: 6, // 设置 Y 轴的最大值为 6 type: 'line',
splitNumber: 7, color: '#6fe3e3',
axisLabel: { areaStyle: {
formatter: '{value} ms', // 在 Y 轴标签上添加 "ms" color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: 'rgba(153,236,233,0.8)', // 顶部颜色较深
},
{
offset: 1,
color: 'rgba(153,236,233,0)', // 底部颜色透明
},
],
global: false,
},
}, },
data: totalApiSucessData.map((item) => item.value),
}, },
series: [ {
{ name: '失败',
name: '数据表变更', type: 'line',
type: 'line', color: '#90ed7d',
color: '#48bdf3', areaStyle: {
areaStyle: { color: {
color: { type: 'linear',
type: 'linear', x: 0,
x: 0, y: 0,
y: 0, x2: 0,
x2: 0, y2: 1,
y2: 1, colorStops: [
colorStops: [ {
{ offset: 0,
offset: 0, color: 'rgba(144,237,125,0.8)', // 顶部颜色较深
color: '#48bdf3', // 渐变起始颜色 },
}, {
{ offset: 1,
offset: 1, color: 'rgba(144,237,125,0)', // 底部颜色透明
color: '#ffffff', // 渐变结束颜色 },
}, ],
], global: false,
global: false, // 缺省为 false
},
}, },
data: responseData.map((item) => parseValue(item.value)), // Convert to number
}, },
], data: totalApiFailedData.map((item) => item.value),
});
chart4Instance.setOption({
title: {
text: '响应时长大于X秒的请求量',
}, },
tooltip: { ],
trigger: 'axis', // 使用坐标轴触发提示框,默认为 true });
chart2Instance.setOption({
title: {
text: '请求方式调用量', // 修改了标题文字
},
legend: {
data: ['Get', 'Post'],
top: '8%', // 图例位置调整
left: '5%',
},
xAxis: {
type: 'category',
boundaryGap: false, // 坐标轴两边留白策略
data: totalApiData.map((item) => item.date), // 假设每个数据点有日期属性
axisLabel: {
rotate: 45, // 旋转x轴标签以避免重叠
}, },
legend: { },
// 显示图例 yAxis: {
data: ['< 1秒', '1 ~ 30秒', '11 ~ 60秒', '> 60秒'], min: 0,
orient: 'horizontal', max: 500,
left: '5%', splitNumber: 5,
top: '8%', nameTextStyle: {
padding: [0, 0, 10, 0], // 调整y轴名称与轴线的距离
}, },
xAxis: { },
type: 'category', // 类目轴 series: [
data: totalApiData.map((item) => item.date), {
boundaryGap: true, // 柱状图默认是 true,即柱子有间距 name: 'Get',
axisLabel: { type: 'line',
rotate: 45, // 如果日期较长可以旋转标签以避免重叠 color: '#f3a770',
areaStyle: {
color: {
type: 'linear', // 渐变类型,可选 'linear' 或 'radial'
x: 0, // 渐变起始位置,x轴方向
y: 0, // 渐变起始位置,y轴方向
x2: 0, // 渐变结束位置,x轴方向
y2: 1, // 渐变结束位置,y轴方向
colorStops: [
// 颜色停止位
{
offset: 0,
color: 'rgba(246,208,170,0.5)', // 0% 处的颜色
},
{
offset: 1,
color: 'rgba(246,208,170,0)', // 100% 处的颜色
},
],
global: false, // 缺省为 false
},
}, },
data: totalGetApiData.map((item) => item.value),
}, },
yAxis: { {
type: 'value', // 数值轴 name: 'Post',
min: 0, // 设置 Y 轴的最小值 type: 'line',
max: 600, color: '#ce9be5',
splitNumber: 7, // 分割段数,可以根据需要调整 areaStyle: {
}, color: {
barWidth: 20, type: 'linear',
series: [ x: 0,
{ y: 0,
name: '> 60秒', x2: 0,
type: 'bar', y2: 1,
stack: 'total', // 设置相同的 stack 值以合并柱状图 colorStops: [
color: '#36e385', {
data: second1Data.map((item) => item.value), offset: 0,
}, color: 'rgba(212,184,229,0.5)', // 0% 处的颜色
{ },
name: '11 ~ 60秒', {
type: 'bar', offset: 1,
stack: 'total', // 设置相同的 stack 值以合并柱状图 color: 'rgba(212,184,229,0)', // 100% 处的颜色
color: '#135adc', },
data: second2Data.map((item) => item.value), ],
}, global: false,
{ },
name: '1 ~ 30秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#7dc6ed',
data: second3Data.map((item) => item.value),
},
{
name: '< 1秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#da9bfd',
data: second4Data.map((item) => item.value),
}, },
], data: totalPostApiData.map((item) => item.value),
}); },
} ],
}); });
}
});
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
.charts-container { .charts-container {
background-color: white; /* 设置容器背景为白色 */ background-color: white; /* 设置容器背景为白色 */
padding: 20px; /* 给容器添加内边距 */ padding: 20px; /* 给容器添加内边距 */
border-radius: 10px; /* 可选:给容器添加圆角 */ border-radius: 10px; /* 可选:给容器添加圆角 */
width: 100%; /* 确保容器宽度适应父级元素 */ width: 100%; /* 确保容器宽度适应父级元素 */
} }
.header { .header {
font-size: 20px; font-size: 20px;
margin-bottom: 20px; margin-bottom: 20px;
text-align: left; text-align: left;
color: #333; color: #333;
} }
.charts { .charts {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
gap: 20px; gap: 20px;
} }
.chart { .chart {
width: calc(50% - 10px); /* 确保两个图表并排显示 */ width: calc(50% - 10px); /* 确保两个图表并排显示 */
height: 400px; height: 400px;
background-color: transparent; /* 使图表的背景透明 */ background-color: transparent; /* 使图表的背景透明 */
} }
</style> </style>
<template> <template>
<BasicTable @register="registerPartitionTable"> <div class="charts-container">
<template #bodyCell="{ column }"> <div class="header">
<template v-if="column.key === 'action'"> <span>响应时长统计</span>
<TableAction </div>
:actions="[ <div class="charts">
{ <div id="chart3" class="chart"></div>
label: '查看日志', <div id="chart4" class="chart"></div>
}, </div>
]" </div>
/>
</template>
</template>
</BasicTable>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { BasicTable, TableAction, useTable } from '@/components/Table'; import { onMounted } from 'vue';
import { partitionColumns } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitor.data'; import * as echarts from 'echarts';
import { partitionData } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData'; import { fieldChangeData } from '@/views/metadata/metadataData';
import {
const [registerPartitionTable] = useTable({ responseData,
title: '调用失败记录', second1Data,
dataSource: partitionData, second2Data,
columns: partitionColumns, second3Data,
showIndexColumn: false, second4Data,
pagination: true, totalApiData,
actionColumn: { totalApiFailedData,
width: 120, totalApiSucessData,
title: '操作', } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData';
dataIndex: 'action',
fixed: 'right', function parseValue(value) {
}, return parseFloat(value); // This will convert '3.5ms' to 3.5
scroll: { y: 300 }, }
});
onMounted(() => {
{
// 获取图表容器
const chart3Container = document.getElementById('chart3');
const chart4Container = document.getElementById('chart4');
// 初始化图表实例
const chart3Instance = echarts.init(chart3Container);
const chart4Instance = echarts.init(chart4Container);
// 设置图表选项
chart3Instance.setOption({
title: {
text: '平均响应时长',
},
tooltip: {
formatter: function (params) {
return `${params.name}: ${params.value} ms`;
},
},
xAxis: {
data: responseData.map((item) => item.date),
boundaryGap: false, // 数据点与标签对齐
},
yAxis: {
min: 0, // 设置 Y 轴的最小值
max: 6, // 设置 Y 轴的最大值为 6
splitNumber: 7,
axisLabel: {
formatter: '{value} ms', // 在 Y 轴标签上添加 "ms"
},
},
series: [
{
name: '数据表变更',
type: 'line',
color: '#48bdf3',
areaStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,
color: '#48bdf3', // 渐变起始颜色
},
{
offset: 1,
color: '#ffffff', // 渐变结束颜色
},
],
global: false, // 缺省为 false
},
},
data: responseData.map((item) => parseValue(item.value)), // Convert to number
},
],
});
chart4Instance.setOption({
title: {
text: '响应时长大于X秒的请求量',
},
tooltip: {
trigger: 'axis', // 使用坐标轴触发提示框,默认为 true
},
legend: {
// 显示图例
data: ['< 1秒', '1 ~ 30秒', '11 ~ 60秒', '> 60秒'],
orient: 'horizontal',
left: '5%',
top: '8%',
},
xAxis: {
type: 'category', // 类目轴
data: totalApiData.map((item) => item.date),
boundaryGap: true, // 柱状图默认是 true,即柱子有间距
axisLabel: {
rotate: 45, // 如果日期较长可以旋转标签以避免重叠
},
},
yAxis: {
type: 'value', // 数值轴
min: 0, // 设置 Y 轴的最小值
max: 600,
splitNumber: 7, // 分割段数,可以根据需要调整
},
barWidth: 20,
series: [
{
name: '> 60秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#36e385',
data: second1Data.map((item) => item.value),
},
{
name: '11 ~ 60秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#135adc',
data: second2Data.map((item) => item.value),
},
{
name: '1 ~ 30秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#7dc6ed',
data: second3Data.map((item) => item.value),
},
{
name: '< 1秒',
type: 'bar',
stack: 'total', // 设置相同的 stack 值以合并柱状图
color: '#da9bfd',
data: second4Data.map((item) => item.value),
},
],
});
}
});
</script> </script>
<style lang="less" scoped></style> <style lang="less" scoped>
.charts-container {
background-color: white; /* 设置容器背景为白色 */
padding: 20px; /* 给容器添加内边距 */
border-radius: 10px; /* 可选:给容器添加圆角 */
width: 100%; /* 确保容器宽度适应父级元素 */
}
.header {
font-size: 20px;
margin-bottom: 20px;
text-align: left;
color: #333;
}
.charts {
display: flex;
justify-content: space-between;
gap: 20px;
}
.chart {
width: calc(50% - 10px); /* 确保两个图表并排显示 */
height: 400px;
background-color: transparent; /* 使图表的背景透明 */
}
</style>
<template>
<BasicTable @register="registerPartitionTable">
<template #bodyCell="{ column }">
<template v-if="column.key === 'action'">
<TableAction
:actions="[
{
label: '查看日志',
},
]"
/>
</template>
</template>
</BasicTable>
</template>
<script lang="ts" setup>
import { BasicTable, TableAction, useTable } from '@/components/Table';
import { partitionColumns } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitor.data';
import { partitionData } from '@/views/dataSharingAndExchange/ApiMonitor/ApiMonitorData';
const [registerPartitionTable] = useTable({
title: '调用失败记录',
dataSource: partitionData,
columns: partitionColumns,
showIndexColumn: false,
pagination: true,
actionColumn: {
width: 120,
title: '操作',
dataIndex: 'action',
fixed: 'right',
},
scroll: { y: 300 },
});
</script>
<style lang="less" scoped></style>
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<RightContent4 class="!my-4 w-full" :loading="loading" /> <RightContent4 class="!my-4 w-full" :loading="loading" />
<RightContent5 class="!my-4 w-full" :loading="loading" /> <RightContent5 class="!my-4 w-full" :loading="loading" />
<RightContent6 class="!my-4 w-full" :loading="loading" /> <RightContent6 class="!my-4 w-full" :loading="loading" />
<RightContent7 class="!my-4 w-full" :loading="loading" />
</div> </div>
</PageWrapper> </PageWrapper>
</template> </template>
...@@ -27,7 +28,7 @@ ...@@ -27,7 +28,7 @@
import RightContent4 from './RightContent4.vue'; import RightContent4 from './RightContent4.vue';
import RightContent5 from './RightContent5.vue'; import RightContent5 from './RightContent5.vue';
import RightContent6 from './RightContent6.vue'; import RightContent6 from './RightContent6.vue';
import RightContent7 from './RightContent7.vue';
defineOptions({ name: 'AccountManagement' }); defineOptions({ name: 'AccountManagement' });
const { createMessage, createConfirm } = useMessage(); const { createMessage, createConfirm } = useMessage();
const route = useRoute(); const route = useRoute();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment