Merge branch 'multi-tenant' of http://192.168.2.166:3180/OMC/ems_frontend_vue3 into multi-tenant
This commit is contained in:
@@ -447,17 +447,13 @@ function fnGetListTitle() {
|
|||||||
// 获取表头文字,只传递纯网元类型
|
// 获取表头文字,只传递纯网元类型
|
||||||
getKPITitle(state.neType)
|
getKPITitle(state.neType)
|
||||||
.then(res => {
|
.then(res => {
|
||||||
//处理getKPITitle返回的结果
|
|
||||||
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
|
||||||
//检查值
|
|
||||||
tableColumns.value = []; //设为空数组
|
tableColumns.value = []; //设为空数组
|
||||||
const columns: any[] = []; //初始化,构建新表头
|
const columns: any[] = [];
|
||||||
for (const item of res.data) {
|
for (const item of res.data) {
|
||||||
//遍历res.data
|
const kpiDisplay = item[`${language}Title`];
|
||||||
const kpiDisplay = item[`${language}Title`]; //提取标题kpiDisplay和ID标识kpiValue
|
|
||||||
const kpiValue = item[`kpiId`];
|
const kpiValue = item[`kpiId`];
|
||||||
columns.push({
|
columns.push({
|
||||||
//
|
|
||||||
title: kpiDisplay,
|
title: kpiDisplay,
|
||||||
dataIndex: kpiValue,
|
dataIndex: kpiValue,
|
||||||
align: 'left',
|
align: 'left',
|
||||||
@@ -486,6 +482,9 @@ function fnGetListTitle() {
|
|||||||
});
|
});
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
tableColumns.value = columns;
|
tableColumns.value = columns;
|
||||||
|
nextTick(() => {
|
||||||
|
fnGetList();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
@@ -495,10 +494,6 @@ function fnGetListTitle() {
|
|||||||
});
|
});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
//result是前一个.then返回的值(true or false)
|
|
||||||
result && fnGetList();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,7 +503,10 @@ async function fnGetList() {
|
|||||||
tableState.loading = true;
|
tableState.loading = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 获取所有网元数据
|
// 第一步:根据指标信息和网元数量,创建完整的默认数据结构
|
||||||
|
fnCreateDefaultDataStructure();
|
||||||
|
|
||||||
|
// 第二步:获取所有网元数据
|
||||||
let allNeData: any[] = [];
|
let allNeData: any[] = [];
|
||||||
|
|
||||||
// 每个选中的网元ID发送一个请求
|
// 每个选中的网元ID发送一个请求
|
||||||
@@ -541,55 +539,8 @@ async function fnGetList() {
|
|||||||
tablePagination.total = allNeData.length;
|
tablePagination.total = allNeData.length;
|
||||||
tableState.data = allNeData;
|
tableState.data = allNeData;
|
||||||
|
|
||||||
// 调用图表渲染函数
|
// 第三步:用真实数据更新默认值
|
||||||
fnRanderChartData();
|
fnUpdateDataWithRealValues(allNeData);
|
||||||
|
|
||||||
// 封装legend表格数据
|
|
||||||
kpiStats.value = [];
|
|
||||||
|
|
||||||
// 为每个指标和每个网元创建统计数据
|
|
||||||
for (const columns of tableColumns.value) {
|
|
||||||
if (
|
|
||||||
columns.key === 'neName' ||
|
|
||||||
columns.key === 'startIndex' ||
|
|
||||||
columns.key === 'timeGroup'
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理每个网元
|
|
||||||
for (const neId of state.neIds) {
|
|
||||||
// 过滤该网元的数据
|
|
||||||
const neData = tableState.data.filter(item => item._neId === neId);
|
|
||||||
|
|
||||||
if (neData.length === 0) continue;
|
|
||||||
|
|
||||||
const values = neData.map((item: any) => {
|
|
||||||
return item[columns.key] ? Number(item[columns.key]) : 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算总值
|
|
||||||
const total = Number(
|
|
||||||
values.reduce((sum, val) => sum + val, 0).toFixed(2)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 计算平均值
|
|
||||||
const avg =
|
|
||||||
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
|
|
||||||
|
|
||||||
kpiStats.value.push({
|
|
||||||
kpiId: `${columns.key}_${neId}`, // 使用组合ID来唯一标识指标-网元对
|
|
||||||
title: `${columns.title}(${neId})`, // 在标题中显示网元ID
|
|
||||||
rawKpiId: columns.key,
|
|
||||||
rawKpiTitle: columns.title,
|
|
||||||
neId: neId,
|
|
||||||
max: values.length > 0 ? Math.max(...values) : 0,
|
|
||||||
min: values.length > 0 ? Math.min(...values) : 0,
|
|
||||||
avg: avg,
|
|
||||||
total: total,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -604,6 +555,260 @@ async function fnGetList() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**创建默认数据结构 */
|
||||||
|
function fnCreateDefaultDataStructure() {
|
||||||
|
// 重置
|
||||||
|
chartLegendSelected = {};
|
||||||
|
chartDataXAxisData = [];
|
||||||
|
chartDataYSeriesData = [];
|
||||||
|
kpiStats.value = [];
|
||||||
|
|
||||||
|
// 创建默认的时间点(当前时间)
|
||||||
|
const defaultTimePoint = Date.now();
|
||||||
|
chartDataXAxisData = [parseDateToStr(defaultTimePoint)];
|
||||||
|
|
||||||
|
// 为每个网元的每个指标创建默认数据结构
|
||||||
|
for (const columns of tableColumns.value) {
|
||||||
|
if (
|
||||||
|
columns.key === 'neName' ||
|
||||||
|
columns.key === 'startIndex' ||
|
||||||
|
columns.key === 'timeGroup'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (const neId of state.neIds) {
|
||||||
|
const kpiId = `${columns.key}_${neId}`;
|
||||||
|
const seriesName = `${columns.title}(${neId})`;
|
||||||
|
// 获取或生成颜色
|
||||||
|
const color = kpiColors.get(kpiId) || generateColorRGBA();
|
||||||
|
kpiColors.set(kpiId, color);
|
||||||
|
// 创建图表系列,包含默认数据点
|
||||||
|
const seriesData = {
|
||||||
|
name: seriesName,
|
||||||
|
key: kpiId,
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'none',
|
||||||
|
symbolSize: 6,
|
||||||
|
smooth: 0.6,
|
||||||
|
showSymbol: true,
|
||||||
|
sampling: 'lttb',
|
||||||
|
itemStyle: {
|
||||||
|
color: color,
|
||||||
|
},
|
||||||
|
areaStyle: {
|
||||||
|
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||||
|
{
|
||||||
|
offset: 0,
|
||||||
|
color: color.replace(')', ',0.8)'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
offset: 1,
|
||||||
|
color: color.replace(')', ',0.3)'),
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
},
|
||||||
|
data: [0], // 默认值为0,确保tooltip能显示指标信息
|
||||||
|
};
|
||||||
|
chartDataYSeriesData.push(seriesData);
|
||||||
|
chartLegendSelected[seriesName] = true;
|
||||||
|
// 创建统计表格项,默认值为0
|
||||||
|
kpiStats.value.push({
|
||||||
|
kpiId: `${columns.key}_${neId}`,
|
||||||
|
title: `${columns.title}(${neId})`,
|
||||||
|
rawKpiId: columns.key,
|
||||||
|
rawKpiTitle: columns.title,
|
||||||
|
neId: neId,
|
||||||
|
max: 0,
|
||||||
|
min: 0,
|
||||||
|
avg: 0,
|
||||||
|
total: 0,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建默认的原始数据(用于表格显示)
|
||||||
|
const defaultTableData: any[] = [];
|
||||||
|
for (const neId of state.neIds) {
|
||||||
|
const defaultRow: any = {
|
||||||
|
_neId: neId,
|
||||||
|
neName: `${state.neType}-${neId}`,
|
||||||
|
timeGroup: defaultTimePoint,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 为每个指标添加默认值0
|
||||||
|
for (const columns of tableColumns.value) {
|
||||||
|
if (
|
||||||
|
columns.key === 'neName' ||
|
||||||
|
columns.key === 'startIndex' ||
|
||||||
|
columns.key === 'timeGroup'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
defaultRow[columns.key] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultTableData.push(defaultRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
tableState.data = defaultTableData;
|
||||||
|
tablePagination.total = defaultTableData.length;
|
||||||
|
|
||||||
|
// 渲染默认的图表和表格
|
||||||
|
if (kpiChart.value && kpiChartDom.value) {
|
||||||
|
kpiChart.value.setOption(
|
||||||
|
{
|
||||||
|
legend: {
|
||||||
|
selected: chartLegendSelected,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
axisLabel: {
|
||||||
|
color:
|
||||||
|
document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333',
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: getSplitLineColor(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: chartDataXAxisData,
|
||||||
|
},
|
||||||
|
series: chartDataYSeriesData,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
replaceMerge: ['xAxis', 'series'],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**用真实数据更新默认值 */
|
||||||
|
function fnUpdateDataWithRealValues(allNeData: any[]) {
|
||||||
|
if (allNeData.length === 0) {
|
||||||
|
// 如果没有真实数据,保持默认值
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新原始数据表格
|
||||||
|
tableState.data = allNeData;
|
||||||
|
tablePagination.total = allNeData.length;
|
||||||
|
|
||||||
|
// 获取所有时间点并格式化
|
||||||
|
const timePoints = [
|
||||||
|
...new Set(allNeData.map(item => item.timeGroup)),
|
||||||
|
].sort();
|
||||||
|
chartDataXAxisData = timePoints.map(time => parseDateToStr(+time));
|
||||||
|
|
||||||
|
// 更新图表数据
|
||||||
|
for (const series of chartDataYSeriesData) {
|
||||||
|
const [kpiKey, neId] = series.key.split('_');
|
||||||
|
const neData = allNeData.filter(item => item._neId === neId);
|
||||||
|
|
||||||
|
// 为每个时间点填充数据
|
||||||
|
series.data = timePoints.map(time => {
|
||||||
|
const dataPoint = neData.find(item => item.timeGroup === time);
|
||||||
|
return dataPoint ? +dataPoint[kpiKey] : null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新统计数据
|
||||||
|
for (const columns of tableColumns.value) {
|
||||||
|
if (
|
||||||
|
columns.key === 'neName' ||
|
||||||
|
columns.key === 'startIndex' ||
|
||||||
|
columns.key === 'timeGroup'
|
||||||
|
) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理每个网元
|
||||||
|
for (const neId of state.neIds) {
|
||||||
|
// 过滤该网元的数据
|
||||||
|
const neData = allNeData.filter(item => item._neId === neId);
|
||||||
|
|
||||||
|
// 找到对应的统计项并更新
|
||||||
|
const statsItem = kpiStats.value.find(
|
||||||
|
(item: KPIStats) => item.kpiId === `${columns.key}_${neId}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (statsItem) {
|
||||||
|
if (neData.length === 0) {
|
||||||
|
// 没有数据时保持默认值0
|
||||||
|
statsItem.max = 0;
|
||||||
|
statsItem.min = 0;
|
||||||
|
statsItem.avg = 0;
|
||||||
|
statsItem.total = 0;
|
||||||
|
} else {
|
||||||
|
// 有数据时计算统计值
|
||||||
|
const values = neData.map((item: any) => {
|
||||||
|
return item[columns.key] ? Number(item[columns.key]) : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
const total = Number(
|
||||||
|
values.reduce((sum, val) => sum + val, 0).toFixed(2)
|
||||||
|
);
|
||||||
|
const avg =
|
||||||
|
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
|
||||||
|
|
||||||
|
statsItem.max = values.length > 0 ? Math.max(...values) : 0;
|
||||||
|
statsItem.min = values.length > 0 ? Math.min(...values) : 0;
|
||||||
|
statsItem.avg = avg;
|
||||||
|
statsItem.total = total;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新图表
|
||||||
|
if (kpiChart.value && kpiChartDom.value) {
|
||||||
|
// 如果有选中的行,只显示选中的指标
|
||||||
|
if (selectedRows.value.length > 0) {
|
||||||
|
Object.keys(chartLegendSelected).forEach(key => {
|
||||||
|
chartLegendSelected[key] = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
kpiStats.value.forEach((item: KPIStats) => {
|
||||||
|
if (selectedRows.value.includes(item.kpiId)) {
|
||||||
|
chartLegendSelected[item.title] = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
kpiChart.value.setOption(
|
||||||
|
{
|
||||||
|
legend: {
|
||||||
|
selected: chartLegendSelected,
|
||||||
|
},
|
||||||
|
xAxis: {
|
||||||
|
type: 'category',
|
||||||
|
boundaryGap: false,
|
||||||
|
axisLabel: {
|
||||||
|
color:
|
||||||
|
document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
? '#CACADA'
|
||||||
|
: '#333',
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: getSplitLineColor(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: chartDataXAxisData,
|
||||||
|
},
|
||||||
|
series: chartDataYSeriesData,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
replaceMerge: ['xAxis', 'series'],
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**切换显示类型 图或表格 */
|
/**切换显示类型 图或表格 */
|
||||||
function fnChangShowType() {
|
function fnChangShowType() {
|
||||||
tableState.showTable = !tableState.showTable;
|
tableState.showTable = !tableState.showTable;
|
||||||
@@ -700,11 +905,13 @@ function fnRanderChart() {
|
|||||||
},
|
},
|
||||||
series: [], // 数据y轴
|
series: [], // 数据y轴
|
||||||
};
|
};
|
||||||
kpiChart.value.setOption(option); //设置图表配置项,应用到kpiChart实例上
|
if (kpiChart.value && kpiChartDom.value) {
|
||||||
|
kpiChart.value.setOption(option); //设置图表配置项,应用到kpiChart实例上
|
||||||
|
}
|
||||||
|
|
||||||
// 创建 ResizeObserver 实例 监听图表容器大小变化,并在变化时调整图表大小
|
// 创建 ResizeObserver 实例 监听图表容器大小变化,并在变化时调整图表大小
|
||||||
var observer = new ResizeObserver(entries => {
|
var observer = new ResizeObserver(entries => {
|
||||||
if (kpiChart.value) {
|
if (kpiChart.value && kpiChartDom.value) {
|
||||||
kpiChart.value.resize();
|
kpiChart.value.resize();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -721,125 +928,10 @@ let chartDataYSeriesData: Record<string, any>[] = [];
|
|||||||
|
|
||||||
/**图表数据渲染 */
|
/**图表数据渲染 */
|
||||||
function fnRanderChartData() {
|
function fnRanderChartData() {
|
||||||
if (kpiChart.value == null || tableState.data.length <= 0) {
|
if (!kpiChart.value || !kpiChartDom.value || tableState.data.length <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
fnUpdateDataWithRealValues(tableState.data);
|
||||||
// 重置
|
|
||||||
chartLegendSelected = {};
|
|
||||||
chartDataXAxisData = [];
|
|
||||||
chartDataYSeriesData = [];
|
|
||||||
|
|
||||||
// 为每个网元的每个指标创建一条线
|
|
||||||
for (const neId of state.neIds) {
|
|
||||||
for (const columns of tableColumns.value) {
|
|
||||||
if (
|
|
||||||
columns.key === 'neName' ||
|
|
||||||
columns.key === 'startIndex' ||
|
|
||||||
columns.key === 'timeGroup'
|
|
||||||
) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const kpiId = `${columns.key}_${neId}`;
|
|
||||||
const seriesName = `${columns.title}(${neId})`;
|
|
||||||
|
|
||||||
// 获取或生成颜色
|
|
||||||
const color = kpiColors.get(kpiId) || generateColorRGBA();
|
|
||||||
kpiColors.set(kpiId, color);
|
|
||||||
|
|
||||||
const seriesData = {
|
|
||||||
name: seriesName,
|
|
||||||
key: kpiId,
|
|
||||||
type: 'line',
|
|
||||||
symbol: 'none',
|
|
||||||
symbolSize: 6,
|
|
||||||
smooth: 0.6,
|
|
||||||
showSymbol: true,
|
|
||||||
sampling: 'lttb',
|
|
||||||
itemStyle: {
|
|
||||||
color: color,
|
|
||||||
},
|
|
||||||
areaStyle: {
|
|
||||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
|
||||||
{
|
|
||||||
offset: 0,
|
|
||||||
color: color.replace(')', ',0.8)'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
offset: 1,
|
|
||||||
color: color.replace(')', ',0.3)'),
|
|
||||||
},
|
|
||||||
]),
|
|
||||||
},
|
|
||||||
data: [] as (number | null)[],
|
|
||||||
};
|
|
||||||
|
|
||||||
chartDataYSeriesData.push(seriesData);
|
|
||||||
|
|
||||||
// 默认所有指标都显示
|
|
||||||
chartLegendSelected[seriesName] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取所有时间点并格式化
|
|
||||||
const timePoints = [
|
|
||||||
...new Set(tableState.data.map(item => item.timeGroup)),
|
|
||||||
].sort();
|
|
||||||
chartDataXAxisData = timePoints.map(time => parseDateToStr(+time));
|
|
||||||
|
|
||||||
// 填充数据
|
|
||||||
for (const series of chartDataYSeriesData) {
|
|
||||||
const [kpiKey, neId] = series.key.split('_');
|
|
||||||
const neData = tableState.data.filter(item => item._neId === neId);
|
|
||||||
series.data = timePoints.map(time => {
|
|
||||||
const dataPoint = neData.find(item => item.timeGroup === time);
|
|
||||||
return dataPoint ? +dataPoint[kpiKey] : null;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果有选中的行,只显示选中的指标
|
|
||||||
if (selectedRows.value.length > 0) {
|
|
||||||
Object.keys(chartLegendSelected).forEach(key => {
|
|
||||||
chartLegendSelected[key] = false;
|
|
||||||
});
|
|
||||||
|
|
||||||
kpiStats.value.forEach((item: KPIStats) => {
|
|
||||||
if (selectedRows.value.includes(item.kpiId)) {
|
|
||||||
chartLegendSelected[item.title] = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新图表
|
|
||||||
kpiChart.value.setOption(
|
|
||||||
{
|
|
||||||
legend: {
|
|
||||||
selected: chartLegendSelected,
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
axisLabel: {
|
|
||||||
color:
|
|
||||||
document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
? '#CACADA'
|
|
||||||
: '#333',
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: getSplitLineColor(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: chartDataXAxisData,
|
|
||||||
},
|
|
||||||
series: chartDataYSeriesData,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
replaceMerge: ['xAxis', 'series'],
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**图表折线显示全部 */
|
/**图表折线显示全部 */
|
||||||
@@ -869,89 +961,8 @@ function fnRealTimeSwitch(bool: any) {
|
|||||||
chartDataXAxisData = [];
|
chartDataXAxisData = [];
|
||||||
chartDataYSeriesData = [];
|
chartDataYSeriesData = [];
|
||||||
|
|
||||||
// 重新初始化图表配置
|
// 先创建默认数据结构
|
||||||
const option = {
|
fnCreateDefaultDataStructure();
|
||||||
tooltip: {
|
|
||||||
trigger: 'axis',
|
|
||||||
position: function (pt: any) {
|
|
||||||
return [pt[0], '10%'];
|
|
||||||
},
|
|
||||||
confine: true,
|
|
||||||
backgroundColor:
|
|
||||||
document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
? 'rgba(48, 48, 48, 0.8)'
|
|
||||||
: 'rgba(255, 255, 255, 0.9)',
|
|
||||||
borderColor:
|
|
||||||
document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
? '#555'
|
|
||||||
: '#ddd',
|
|
||||||
textStyle: {
|
|
||||||
color:
|
|
||||||
document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
? '#CACADA'
|
|
||||||
: '#333',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
xAxis: {
|
|
||||||
type: 'category',
|
|
||||||
boundaryGap: false,
|
|
||||||
data: [],
|
|
||||||
axisLabel: {
|
|
||||||
color:
|
|
||||||
document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
? '#CACADA'
|
|
||||||
: '#333',
|
|
||||||
},
|
|
||||||
splitLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: getSplitLineColor(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
yAxis: {
|
|
||||||
type: 'value',
|
|
||||||
boundaryGap: [0, '100%'],
|
|
||||||
axisLabel: {
|
|
||||||
formatter: '{value}',
|
|
||||||
color:
|
|
||||||
document.documentElement.getAttribute('data-theme') === 'dark'
|
|
||||||
? '#CACADA'
|
|
||||||
: '#333',
|
|
||||||
},
|
|
||||||
splitNumber: 5,
|
|
||||||
scale: true,
|
|
||||||
splitLine: {
|
|
||||||
show: true,
|
|
||||||
lineStyle: {
|
|
||||||
color: getSplitLineColor(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
legend: {
|
|
||||||
show: false,
|
|
||||||
type: 'scroll',
|
|
||||||
orient: 'vertical',
|
|
||||||
top: 40,
|
|
||||||
right: 20,
|
|
||||||
itemWidth: 20,
|
|
||||||
itemGap: 25,
|
|
||||||
textStyle: {
|
|
||||||
color: '#646A73',
|
|
||||||
},
|
|
||||||
icon: 'circle',
|
|
||||||
selected: {},
|
|
||||||
},
|
|
||||||
grid: {
|
|
||||||
left: '3%',
|
|
||||||
right: '4%',
|
|
||||||
bottom: '3%',
|
|
||||||
containLabel: true,
|
|
||||||
},
|
|
||||||
series: [],
|
|
||||||
};
|
|
||||||
|
|
||||||
kpiChart.value.setOption(option);
|
|
||||||
|
|
||||||
// 建立链接
|
// 建立链接
|
||||||
const options: OptionsType = {
|
const options: OptionsType = {
|
||||||
@@ -1051,7 +1062,7 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
|
|
||||||
// 使用 requestAnimationFrame 更新图表
|
// 使用 requestAnimationFrame 更新图表
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
if (!kpiChart.value) return;
|
if (!kpiChart.value || !kpiChartDom.value) return;
|
||||||
|
|
||||||
// 重新生成 series 数据
|
// 重新生成 series 数据
|
||||||
const series = [];
|
const series = [];
|
||||||
@@ -1139,6 +1150,7 @@ function wsMessage(res: Record<string, any>) {
|
|||||||
|
|
||||||
// 添加更新统计数据的函数
|
// 添加更新统计数据的函数
|
||||||
function updateKpiStats() {
|
function updateKpiStats() {
|
||||||
|
// 清空现有统计数据
|
||||||
kpiStats.value = [];
|
kpiStats.value = [];
|
||||||
|
|
||||||
// 为每个指标和每个网元创建统计数据
|
// 为每个指标和每个网元创建统计数据
|
||||||
@@ -1156,32 +1168,41 @@ function updateKpiStats() {
|
|||||||
// 过滤该网元的数据
|
// 过滤该网元的数据
|
||||||
const neData = tableState.data.filter(item => item._neId === neId);
|
const neData = tableState.data.filter(item => item._neId === neId);
|
||||||
|
|
||||||
if (neData.length === 0) continue;
|
// 创建统计项(即使没有数据也创建)
|
||||||
|
const statsItem = {
|
||||||
const values = neData.map((item: any) => {
|
|
||||||
return item[columns.key] ? Number(item[columns.key]) : 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
// 计算总值
|
|
||||||
const total = Number(
|
|
||||||
values.reduce((sum, val) => sum + val, 0).toFixed(2)
|
|
||||||
);
|
|
||||||
|
|
||||||
// 计算平均值
|
|
||||||
const avg =
|
|
||||||
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
|
|
||||||
|
|
||||||
kpiStats.value.push({
|
|
||||||
kpiId: `${columns.key}_${neId}`,
|
kpiId: `${columns.key}_${neId}`,
|
||||||
title: `${columns.title}(${neId})`,
|
title: `${columns.title}(${neId})`,
|
||||||
rawKpiId: columns.key,
|
rawKpiId: columns.key,
|
||||||
rawKpiTitle: columns.title,
|
rawKpiTitle: columns.title,
|
||||||
neId: neId,
|
neId: neId,
|
||||||
max: values.length > 0 ? Math.max(...values) : 0,
|
max: 0,
|
||||||
min: values.length > 0 ? Math.min(...values) : 0,
|
min: 0,
|
||||||
avg: avg,
|
avg: 0,
|
||||||
total: total,
|
total: 0,
|
||||||
});
|
};
|
||||||
|
|
||||||
|
if (neData.length > 0) {
|
||||||
|
// 有数据时计算统计值
|
||||||
|
const values = neData.map((item: any) => {
|
||||||
|
return item[columns.key] ? Number(item[columns.key]) : 0;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 计算总值
|
||||||
|
const total = Number(
|
||||||
|
values.reduce((sum, val) => sum + val, 0).toFixed(2)
|
||||||
|
);
|
||||||
|
|
||||||
|
// 计算平均值
|
||||||
|
const avg =
|
||||||
|
values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;
|
||||||
|
|
||||||
|
statsItem.max = values.length > 0 ? Math.max(...values) : 0;
|
||||||
|
statsItem.min = values.length > 0 ? Math.min(...values) : 0;
|
||||||
|
statsItem.avg = avg;
|
||||||
|
statsItem.total = total;
|
||||||
|
}
|
||||||
|
|
||||||
|
kpiStats.value.push(statsItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1414,6 +1435,10 @@ onMounted(() => {
|
|||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
ws.close();
|
ws.close();
|
||||||
|
if (kpiChart.value) {
|
||||||
|
kpiChart.value.dispose();
|
||||||
|
kpiChart.value = null;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user