优化界面显示
This commit is contained in:
@@ -22,9 +22,10 @@ import {
|
||||
markRaw,
|
||||
nextTick,
|
||||
onBeforeUnmount,
|
||||
h,
|
||||
} from 'vue';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import { message, Modal } from 'ant-design-vue/es';
|
||||
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
|
||||
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||
@@ -41,6 +42,7 @@ import saveAs from 'file-saver';
|
||||
import { generateColorRGBA } from '@/utils/generate-utils';
|
||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { LineOutlined } from '@ant-design/icons-vue';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
const route = useRoute();
|
||||
const { t, currentLocale } = useI18n();
|
||||
@@ -187,6 +189,51 @@ let state: StateType = reactive({
|
||||
chartLegendSelectedFlag: false,
|
||||
});
|
||||
|
||||
// 存储每个指标的临时固定颜色
|
||||
const kpiColors = new Map<string, string>();
|
||||
//legend表格数据
|
||||
const kpiStats: any = ref([]);
|
||||
|
||||
// 添加表格列定义
|
||||
const statsColumns: TableColumnType<any>[] = [
|
||||
{
|
||||
title: '',
|
||||
key: 'icon',
|
||||
width: 50,
|
||||
customRender: ({ record }: { record: any }) => {
|
||||
return h(LineOutlined, {
|
||||
style: {
|
||||
color: kpiColors.get(record.kpiId) || '#000', // 使用与折线图相同的颜色
|
||||
fontSize: '30px', // 增大图标尺寸到30px
|
||||
fontWeight: 'bold', // 加粗
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.kpiOverView.kpiName'),
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
width: '65%',
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.kpiOverView.maxValue'),
|
||||
dataIndex: 'max',
|
||||
key: 'max',
|
||||
width: '17%',
|
||||
sorter: (a: any, b: any) => a.max - b.max, // 添加排序函数
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.kpiOverView.minValue'),
|
||||
dataIndex: 'min',
|
||||
key: 'min',
|
||||
width: '17%',
|
||||
sorter: (a: any, b: any) => a.min - b.min, // 添加排序函数
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 数据列表导出
|
||||
*/
|
||||
@@ -320,6 +367,7 @@ function fnGetList() {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
tablePagination.total = res.data.length;
|
||||
tableState.data = res.data;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -327,6 +375,27 @@ function fnGetList() {
|
||||
.then(result => {
|
||||
if (result) {
|
||||
fnRanderChartData();
|
||||
//封装legend表格数据
|
||||
kpiStats.value = [];
|
||||
for (const columns of tableColumns.value) {
|
||||
if (
|
||||
columns.key === 'neName' ||
|
||||
columns.key === 'startIndex' ||
|
||||
columns.key === 'timeGroup'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const values = tableState.data.map((item: any) => {
|
||||
return item[columns.key] ? Number(item[columns.key]) : 0;
|
||||
});
|
||||
kpiStats.value.push({
|
||||
kpiId: columns.key,
|
||||
title: columns.title,
|
||||
max: values.length > 0 ? Math.max(...values) : 0,
|
||||
min: values.length > 0 ? Math.min(...values) : 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -362,6 +431,7 @@ function fnRanderChart() {
|
||||
boundaryGap: [0, '100%'],
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
//图例垂直滚动
|
||||
type: 'scroll',
|
||||
orient: 'vertical',
|
||||
@@ -377,22 +447,12 @@ function fnRanderChart() {
|
||||
},
|
||||
grid: {
|
||||
//网格区域边距
|
||||
left: '10%',
|
||||
right: '30%',
|
||||
bottom: '20%',
|
||||
left: '7%',
|
||||
right: '7%',
|
||||
bottom: '7%',
|
||||
containLabel: true,
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
//启用图表的数据缩放,范围90%-100%
|
||||
type: 'inside',
|
||||
start: 90,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 90,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
|
||||
series: [], // 数据y轴
|
||||
};
|
||||
kpiChart.value.setOption(option); //设置图表配置项,应用到kpiChart实例上
|
||||
@@ -433,7 +493,8 @@ function fnRanderChartData() {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const color = generateColorRGBA();
|
||||
const color = kpiColors.get(columns.key) || generateColorRGBA();
|
||||
kpiColors.set(columns.key, color);
|
||||
chartDataYSeriesData.push({
|
||||
name: `${columns.title}`,
|
||||
key: `${columns.key}`,
|
||||
@@ -462,7 +523,6 @@ function fnRanderChartData() {
|
||||
|
||||
// 用降序就反转
|
||||
let orgData = tableState.data;
|
||||
console.log(orgData);
|
||||
if (queryParams.sortOrder === 'desc') {
|
||||
orgData = orgData.toReversed();
|
||||
}
|
||||
@@ -587,6 +647,37 @@ function wsMessage(res: Record<string, any>) {
|
||||
});
|
||||
}
|
||||
|
||||
// 添加一个变量来跟踪当前选中的行
|
||||
const selectedRow = ref<string | null>(null);
|
||||
|
||||
// 添加处理行点击的方法
|
||||
function handleRowClick(record: any) {
|
||||
if (selectedRow.value === record.kpiId) {
|
||||
// 如果点击的是当前选中的行,则取消选中
|
||||
selectedRow.value = null;
|
||||
// 更新图表,显示所有指标
|
||||
for (let key in chartLegendSelected) {
|
||||
chartLegendSelected[key] = true;
|
||||
}
|
||||
} else {
|
||||
// 选中新行
|
||||
selectedRow.value = record.kpiId;
|
||||
// 更新图表,只显示选中的指标
|
||||
for (let key in chartLegendSelected) {
|
||||
if (key === record.title) {
|
||||
chartLegendSelected[key] = true;
|
||||
} else {
|
||||
chartLegendSelected[key] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
kpiChart.value.setOption({
|
||||
legend: {
|
||||
selected: chartLegendSelected,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
|
||||
// 获取网元网元列表
|
||||
@@ -791,7 +882,7 @@ onBeforeUnmount(() => {
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
<a-form layout="inline" v-show="!tableState.showTable">
|
||||
<a-form-item
|
||||
<!-- <a-form-item
|
||||
:label="t('views.perfManage.goldTarget.showChartSelected')"
|
||||
name="chartLegendSelectedFlag"
|
||||
>
|
||||
@@ -803,7 +894,7 @@ onBeforeUnmount(() => {
|
||||
@change="fnLegendSelected"
|
||||
size="small"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form-item> -->
|
||||
<a-form-item
|
||||
:label="t('views.perfManage.goldTarget.realTimeData')"
|
||||
name="chartRealTime"
|
||||
@@ -844,10 +935,105 @@ onBeforeUnmount(() => {
|
||||
|
||||
<!-- 图表 -->
|
||||
<div style="padding: 24px" v-show="!tableState.showTable">
|
||||
<div ref="kpiChartDom" style="height: 450px; width: 100%"></div>
|
||||
<div
|
||||
ref="kpiChartDom"
|
||||
class="chart-container"
|
||||
style="height: 450px; width: 100%"
|
||||
></div>
|
||||
|
||||
<div class="table-container">
|
||||
<a-table
|
||||
:columns="statsColumns"
|
||||
:data-source="kpiStats"
|
||||
:pagination="false"
|
||||
:scroll="{ y: 250 }"
|
||||
size="small"
|
||||
:custom-row="
|
||||
record => ({
|
||||
onClick: () => handleRowClick(record),
|
||||
class: record.kpiId === selectedRow ? 'selected-row' : '',
|
||||
})
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style scoped>
|
||||
.chart-container {
|
||||
height: 800px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
height: 282px;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 表格布局相关样式 */
|
||||
:deep(.ant-table-wrapper),
|
||||
:deep(.ant-table),
|
||||
:deep(.ant-table-container),
|
||||
:deep(.ant-table-content) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body) {
|
||||
flex: 1;
|
||||
overflow-y: auto !important;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 表格行和表头样式 */
|
||||
:deep(.ant-table-thead tr th),
|
||||
:deep(.ant-table-tbody tr td) {
|
||||
padding: 8px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* 美化滚动条样式 */
|
||||
:deep(.ant-table-body::-webkit-scrollbar) {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body::-webkit-scrollbar-thumb) {
|
||||
background: #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body::-webkit-scrollbar-track) {
|
||||
background: #f1f1f1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
[data-theme='dark'] :deep(.ant-table-body::-webkit-scrollbar-thumb) {
|
||||
background: #4c4c4c;
|
||||
}
|
||||
|
||||
[data-theme='dark'] :deep(.ant-table-body::-webkit-scrollbar-track) {
|
||||
background: #2a2a2a;
|
||||
}
|
||||
|
||||
/* 选中行样式 */
|
||||
:deep(.selected-row) {
|
||||
background-color: rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
|
||||
[data-theme='dark'] :deep(.selected-row) {
|
||||
background-color: rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
|
||||
/* 鼠标悬停样式 */
|
||||
:deep(.ant-table-tbody tr:hover) {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -22,9 +22,10 @@ import {
|
||||
markRaw,
|
||||
nextTick,
|
||||
onBeforeUnmount,
|
||||
h,
|
||||
} from 'vue';
|
||||
import { PageContainer } from 'antdv-pro-layout';
|
||||
import { message, Modal } from 'ant-design-vue/es';
|
||||
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
|
||||
import { SizeType } from 'ant-design-vue/es/config-provider';
|
||||
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
|
||||
@@ -41,6 +42,7 @@ import { writeSheet } from '@/utils/execl-utils';
|
||||
import saveAs from 'file-saver';
|
||||
import { generateColorRGBA } from '@/utils/generate-utils';
|
||||
import { OptionsType, WS } from '@/plugins/ws-websocket';
|
||||
import { LineOutlined } from '@ant-design/icons-vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import dayjs, { Dayjs } from 'dayjs';
|
||||
const neInfoStore = useNeInfoStore();
|
||||
@@ -200,6 +202,51 @@ let state: StateType = reactive({
|
||||
chartLegendSelectedFlag: false,
|
||||
});
|
||||
|
||||
// 存储每个指标的临时固定颜色
|
||||
const kpiColors = new Map<string, string>();
|
||||
//legend表格数据
|
||||
const kpiStats: any = ref([]);
|
||||
|
||||
// 添加表格列定义
|
||||
const statsColumns: TableColumnType<any>[] = [
|
||||
{
|
||||
title: '',
|
||||
key: 'icon',
|
||||
width: 50,
|
||||
customRender: ({ record }: { record: any }) => {
|
||||
return h(LineOutlined, {
|
||||
style: {
|
||||
color: kpiColors.get(record.kpiId) || '#000', // 使用与折线图相同的颜色
|
||||
fontSize: '30px', // 增大图标尺寸到30px
|
||||
fontWeight: 'bold', // 加粗
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.kpiOverView.kpiName'),
|
||||
dataIndex: 'title',
|
||||
key: 'title',
|
||||
width: '65%',
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.kpiOverView.maxValue'),
|
||||
dataIndex: 'max',
|
||||
key: 'max',
|
||||
width: '17%',
|
||||
sorter: (a: any, b: any) => a.max - b.max, // 添加排序函数
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
{
|
||||
title: t('views.perfManage.kpiOverView.minValue'),
|
||||
dataIndex: 'min',
|
||||
key: 'min',
|
||||
width: '17%',
|
||||
sorter: (a: any, b: any) => a.min - b.min, // 添加排序函数
|
||||
sortDirections: ['ascend', 'descend'],
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* 数据列表导出
|
||||
*/
|
||||
@@ -342,6 +389,13 @@ function fnGetList() {
|
||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||
tablePagination.total = res.data.length;
|
||||
tableState.data = res.data;
|
||||
if (!res.data.length) {
|
||||
message.warning({
|
||||
content: t('common.noData'),
|
||||
duration: 2,
|
||||
});
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -349,6 +403,27 @@ function fnGetList() {
|
||||
.then(result => {
|
||||
if (result) {
|
||||
fnRanderChartData();
|
||||
//封装legend表格数据
|
||||
kpiStats.value = [];
|
||||
for (const columns of tableColumns.value) {
|
||||
if (
|
||||
columns.key === 'neName' ||
|
||||
columns.key === 'startIndex' ||
|
||||
columns.key === 'timeGroup'
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const values = tableState.data.map((item: any) => {
|
||||
return item[columns.key] ? Number(item[columns.key]) : 0;
|
||||
});
|
||||
kpiStats.value.push({
|
||||
kpiId: columns.key,
|
||||
title: columns.title,
|
||||
max: values.length > 0 ? Math.max(...values) : 0,
|
||||
min: values.length > 0 ? Math.min(...values) : 0,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -381,6 +456,7 @@ function fnRanderChart() {
|
||||
boundaryGap: [0, '100%'],
|
||||
},
|
||||
legend: {
|
||||
show: false,
|
||||
type: 'scroll',
|
||||
orient: 'vertical',
|
||||
top: 40,
|
||||
@@ -394,21 +470,12 @@ function fnRanderChart() {
|
||||
selected: {},
|
||||
},
|
||||
grid: {
|
||||
left: '10%',
|
||||
right: '30%',
|
||||
bottom: '20%',
|
||||
//网格区域边距
|
||||
left: '7%',
|
||||
right: '7%',
|
||||
bottom: '7%',
|
||||
containLabel: true,
|
||||
},
|
||||
dataZoom: [
|
||||
{
|
||||
type: 'inside',
|
||||
start: 90,
|
||||
end: 100,
|
||||
},
|
||||
{
|
||||
start: 90,
|
||||
end: 100,
|
||||
},
|
||||
],
|
||||
series: [], // 数据y轴
|
||||
};
|
||||
kpiChart.value.setOption(option);
|
||||
@@ -449,7 +516,8 @@ function fnRanderChartData() {
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
const color = generateColorRGBA();
|
||||
const color = kpiColors.get(columns.key) || generateColorRGBA();
|
||||
kpiColors.set(columns.key, color);
|
||||
chartDataYSeriesData.push({
|
||||
name: `${columns.title}`,
|
||||
key: `${columns.key}`,
|
||||
@@ -602,6 +670,37 @@ function wsMessage(res: Record<string, any>) {
|
||||
});
|
||||
}
|
||||
|
||||
// 添加一个变量来跟踪当前选中的行
|
||||
const selectedRow = ref<string | null>(null);
|
||||
|
||||
// 添加处理行点击的方法
|
||||
function handleRowClick(record: any) {
|
||||
if (selectedRow.value === record.kpiId) {
|
||||
// 如果点击的是当前选中的行,则取消选中
|
||||
selectedRow.value = null;
|
||||
// 更新图表,显示所有指标
|
||||
for (let key in chartLegendSelected) {
|
||||
chartLegendSelected[key] = true;
|
||||
}
|
||||
} else {
|
||||
// 选中新行
|
||||
selectedRow.value = record.kpiId;
|
||||
// 更新图表,只显示选中的指标
|
||||
for (let key in chartLegendSelected) {
|
||||
if (key === record.title) {
|
||||
chartLegendSelected[key] = true;
|
||||
} else {
|
||||
chartLegendSelected[key] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
kpiChart.value.setOption({
|
||||
legend: {
|
||||
selected: chartLegendSelected,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
|
||||
// 获取网元网元列表
|
||||
@@ -790,7 +889,7 @@ onBeforeUnmount(() => {
|
||||
</a-tooltip>
|
||||
</a-space>
|
||||
<a-form layout="inline" v-show="!tableState.showTable">
|
||||
<a-form-item
|
||||
<!-- <a-form-item
|
||||
:label="t('views.perfManage.goldTarget.showChartSelected')"
|
||||
name="chartLegendSelectedFlag"
|
||||
>
|
||||
@@ -802,7 +901,7 @@ onBeforeUnmount(() => {
|
||||
@change="fnLegendSelected"
|
||||
size="small"
|
||||
/>
|
||||
</a-form-item>
|
||||
</a-form-item> -->
|
||||
<a-form-item
|
||||
:label="t('views.perfManage.goldTarget.realTimeData')"
|
||||
name="chartRealTime"
|
||||
@@ -838,10 +937,105 @@ onBeforeUnmount(() => {
|
||||
|
||||
<!-- 图表 -->
|
||||
<div style="padding: 24px" v-show="!tableState.showTable">
|
||||
<div ref="kpiChartDom" style="height: 450px; width: 100%"></div>
|
||||
<div
|
||||
ref="kpiChartDom"
|
||||
class="chart-container"
|
||||
style="height: 450px; width: 100%"
|
||||
></div>
|
||||
|
||||
<div class="table-container">
|
||||
<a-table
|
||||
:columns="statsColumns"
|
||||
:data-source="kpiStats"
|
||||
:pagination="false"
|
||||
:scroll="{ y: 250 }"
|
||||
size="small"
|
||||
:custom-row="
|
||||
record => ({
|
||||
onClick: () => handleRowClick(record),
|
||||
class: record.kpiId === selectedRow ? 'selected-row' : '',
|
||||
})
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</PageContainer>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped></style>
|
||||
<style scoped>
|
||||
.chart-container {
|
||||
height: 800px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.table-container {
|
||||
height: 282px;
|
||||
width: 100%;
|
||||
margin-top: 20px;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* 表格布局相关样式 */
|
||||
:deep(.ant-table-wrapper),
|
||||
:deep(.ant-table),
|
||||
:deep(.ant-table-container),
|
||||
:deep(.ant-table-content) {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body) {
|
||||
flex: 1;
|
||||
overflow-y: auto !important;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
/* 表格行和表头样式 */
|
||||
:deep(.ant-table-thead tr th),
|
||||
:deep(.ant-table-tbody tr td) {
|
||||
padding: 8px;
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
/* 美化滚动条样式 */
|
||||
:deep(.ant-table-body::-webkit-scrollbar) {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body::-webkit-scrollbar-thumb) {
|
||||
background: #ccc;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
:deep(.ant-table-body::-webkit-scrollbar-track) {
|
||||
background: #f1f1f1;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
[data-theme='dark'] :deep(.ant-table-body::-webkit-scrollbar-thumb) {
|
||||
background: #4c4c4c;
|
||||
}
|
||||
|
||||
[data-theme='dark'] :deep(.ant-table-body::-webkit-scrollbar-track) {
|
||||
background: #2a2a2a;
|
||||
}
|
||||
|
||||
/* 选中行样式 */
|
||||
:deep(.selected-row) {
|
||||
background-color: rgba(24, 144, 255, 0.1);
|
||||
}
|
||||
|
||||
[data-theme='dark'] :deep(.selected-row) {
|
||||
background-color: rgba(24, 144, 255, 0.2);
|
||||
}
|
||||
|
||||
/* 鼠标悬停样式 */
|
||||
:deep(.ant-table-tbody tr:hover) {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user