优化界面显示

This commit is contained in:
lai
2024-11-15 15:48:54 +08:00
parent 31bca2b98f
commit 9b9c0b39fd
2 changed files with 423 additions and 43 deletions

View File

@@ -22,9 +22,10 @@ import {
markRaw, markRaw,
nextTick, nextTick,
onBeforeUnmount, onBeforeUnmount,
h,
} from 'vue'; } from 'vue';
import { PageContainer } from 'antdv-pro-layout'; 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 { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
@@ -41,7 +42,8 @@ import saveAs from 'file-saver';
import { generateColorRGBA } from '@/utils/generate-utils'; import { generateColorRGBA } from '@/utils/generate-utils';
import { OptionsType, WS } from '@/plugins/ws-websocket'; import { OptionsType, WS } from '@/plugins/ws-websocket';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
const neInfoStore = useNeInfoStore(); import { LineOutlined } from '@ant-design/icons-vue';
const neInfoStore = useNeInfoStore();
const route = useRoute(); const route = useRoute();
const { t, currentLocale } = useI18n(); const { t, currentLocale } = useI18n();
const ws = new WS(); const ws = new WS();
@@ -187,6 +189,51 @@ let state: StateType = reactive({
chartLegendSelectedFlag: false, 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)) { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
tablePagination.total = res.data.length; tablePagination.total = res.data.length;
tableState.data = res.data; tableState.data = res.data;
return true; return true;
} }
return false; return false;
@@ -327,6 +375,27 @@ function fnGetList() {
.then(result => { .then(result => {
if (result) { if (result) {
fnRanderChartData(); 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%'], boundaryGap: [0, '100%'],
}, },
legend: { legend: {
show: false,
//图例垂直滚动 //图例垂直滚动
type: 'scroll', type: 'scroll',
orient: 'vertical', orient: 'vertical',
@@ -377,22 +447,12 @@ function fnRanderChart() {
}, },
grid: { grid: {
//网格区域边距 //网格区域边距
left: '10%', left: '7%',
right: '30%', right: '7%',
bottom: '20%', bottom: '7%',
containLabel: true,
}, },
dataZoom: [
{
//启用图表的数据缩放范围90%-100%
type: 'inside',
start: 90,
end: 100,
},
{
start: 90,
end: 100,
},
],
series: [], // 数据y轴 series: [], // 数据y轴
}; };
kpiChart.value.setOption(option); //设置图表配置项应用到kpiChart实例上 kpiChart.value.setOption(option); //设置图表配置项应用到kpiChart实例上
@@ -433,7 +493,8 @@ function fnRanderChartData() {
) { ) {
continue; continue;
} }
const color = generateColorRGBA(); const color = kpiColors.get(columns.key) || generateColorRGBA();
kpiColors.set(columns.key, color);
chartDataYSeriesData.push({ chartDataYSeriesData.push({
name: `${columns.title}`, name: `${columns.title}`,
key: `${columns.key}`, key: `${columns.key}`,
@@ -462,7 +523,6 @@ function fnRanderChartData() {
// 用降序就反转 // 用降序就反转
let orgData = tableState.data; let orgData = tableState.data;
console.log(orgData);
if (queryParams.sortOrder === 'desc') { if (queryParams.sortOrder === 'desc') {
orgData = orgData.toReversed(); 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(() => { onMounted(() => {
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF // 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
// 获取网元网元列表 // 获取网元网元列表
@@ -791,7 +882,7 @@ onBeforeUnmount(() => {
</a-tooltip> </a-tooltip>
</a-space> </a-space>
<a-form layout="inline" v-show="!tableState.showTable"> <a-form layout="inline" v-show="!tableState.showTable">
<a-form-item <!-- <a-form-item
:label="t('views.perfManage.goldTarget.showChartSelected')" :label="t('views.perfManage.goldTarget.showChartSelected')"
name="chartLegendSelectedFlag" name="chartLegendSelectedFlag"
> >
@@ -803,7 +894,7 @@ onBeforeUnmount(() => {
@change="fnLegendSelected" @change="fnLegendSelected"
size="small" size="small"
/> />
</a-form-item> </a-form-item> -->
<a-form-item <a-form-item
:label="t('views.perfManage.goldTarget.realTimeData')" :label="t('views.perfManage.goldTarget.realTimeData')"
name="chartRealTime" name="chartRealTime"
@@ -844,10 +935,105 @@ onBeforeUnmount(() => {
<!-- 图表 --> <!-- 图表 -->
<div style="padding: 24px" v-show="!tableState.showTable"> <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> </div>
</a-card> </a-card>
</PageContainer> </PageContainer>
</template> </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>

View File

@@ -22,9 +22,10 @@ import {
markRaw, markRaw,
nextTick, nextTick,
onBeforeUnmount, onBeforeUnmount,
h,
} from 'vue'; } from 'vue';
import { PageContainer } from 'antdv-pro-layout'; 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 { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface'; import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
@@ -41,6 +42,7 @@ import { writeSheet } from '@/utils/execl-utils';
import saveAs from 'file-saver'; import saveAs from 'file-saver';
import { generateColorRGBA } from '@/utils/generate-utils'; import { generateColorRGBA } from '@/utils/generate-utils';
import { OptionsType, WS } from '@/plugins/ws-websocket'; import { OptionsType, WS } from '@/plugins/ws-websocket';
import { LineOutlined } from '@ant-design/icons-vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import dayjs, { Dayjs } from 'dayjs'; import dayjs, { Dayjs } from 'dayjs';
const neInfoStore = useNeInfoStore(); const neInfoStore = useNeInfoStore();
@@ -200,6 +202,51 @@ let state: StateType = reactive({
chartLegendSelectedFlag: false, 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)) { if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
tablePagination.total = res.data.length; tablePagination.total = res.data.length;
tableState.data = res.data; tableState.data = res.data;
if (!res.data.length) {
message.warning({
content: t('common.noData'),
duration: 2,
});
return false;
}
return true; return true;
} }
return false; return false;
@@ -349,6 +403,27 @@ function fnGetList() {
.then(result => { .then(result => {
if (result) { if (result) {
fnRanderChartData(); 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%'], boundaryGap: [0, '100%'],
}, },
legend: { legend: {
show: false,
type: 'scroll', type: 'scroll',
orient: 'vertical', orient: 'vertical',
top: 40, top: 40,
@@ -394,21 +470,12 @@ function fnRanderChart() {
selected: {}, selected: {},
}, },
grid: { grid: {
left: '10%', //网格区域边距
right: '30%', left: '7%',
bottom: '20%', right: '7%',
bottom: '7%',
containLabel: true,
}, },
dataZoom: [
{
type: 'inside',
start: 90,
end: 100,
},
{
start: 90,
end: 100,
},
],
series: [], // 数据y轴 series: [], // 数据y轴
}; };
kpiChart.value.setOption(option); kpiChart.value.setOption(option);
@@ -449,7 +516,8 @@ function fnRanderChartData() {
) { ) {
continue; continue;
} }
const color = generateColorRGBA(); const color = kpiColors.get(columns.key) || generateColorRGBA();
kpiColors.set(columns.key, color);
chartDataYSeriesData.push({ chartDataYSeriesData.push({
name: `${columns.title}`, name: `${columns.title}`,
key: `${columns.key}`, 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(() => { onMounted(() => {
// 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF // 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
// 获取网元网元列表 // 获取网元网元列表
@@ -790,7 +889,7 @@ onBeforeUnmount(() => {
</a-tooltip> </a-tooltip>
</a-space> </a-space>
<a-form layout="inline" v-show="!tableState.showTable"> <a-form layout="inline" v-show="!tableState.showTable">
<a-form-item <!-- <a-form-item
:label="t('views.perfManage.goldTarget.showChartSelected')" :label="t('views.perfManage.goldTarget.showChartSelected')"
name="chartLegendSelectedFlag" name="chartLegendSelectedFlag"
> >
@@ -802,7 +901,7 @@ onBeforeUnmount(() => {
@change="fnLegendSelected" @change="fnLegendSelected"
size="small" size="small"
/> />
</a-form-item> </a-form-item> -->
<a-form-item <a-form-item
:label="t('views.perfManage.goldTarget.realTimeData')" :label="t('views.perfManage.goldTarget.realTimeData')"
name="chartRealTime" name="chartRealTime"
@@ -838,10 +937,105 @@ onBeforeUnmount(() => {
<!-- 图表 --> <!-- 图表 -->
<div style="padding: 24px" v-show="!tableState.showTable"> <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> </div>
</a-card> </a-card>
</PageContainer> </PageContainer>
</template> </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>