优化界面显示

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,
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>

View File

@@ -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>