diff --git a/src/i18n/locales/en-US.ts b/src/i18n/locales/en-US.ts index 842a2687..44d14ebb 100644 --- a/src/i18n/locales/en-US.ts +++ b/src/i18n/locales/en-US.ts @@ -719,6 +719,7 @@ export default { exportSure:'Confirm whether to export all statistical data', exportEmpty: "Export data is empty", showChartSelected: "Show All", + realTimeData: "Real Time 5s Data", } }, traceManage: { diff --git a/src/i18n/locales/zh-CN.ts b/src/i18n/locales/zh-CN.ts index 2a27a2a2..e3851625 100644 --- a/src/i18n/locales/zh-CN.ts +++ b/src/i18n/locales/zh-CN.ts @@ -719,6 +719,7 @@ export default { exportSure:'确认是否导出全部统计数据', exportEmpty: "导出数据为空", showChartSelected: "显示全部", + realTimeData: "实时5s数据", } }, traceManage: { diff --git a/src/views/perfManage/goldTarget/index.vue b/src/views/perfManage/goldTarget/index.vue index c35a4dea..a7df4ddf 100644 --- a/src/views/perfManage/goldTarget/index.vue +++ b/src/views/perfManage/goldTarget/index.vue @@ -14,14 +14,25 @@ import { LineChart, LineSeriesOption } from 'echarts/charts'; import { UniversalTransition } from 'echarts/features'; import { CanvasRenderer } from 'echarts/renderers'; -import { reactive, ref, onMounted, toRaw, markRaw, nextTick } from 'vue'; +import { + reactive, + ref, + onMounted, + toRaw, + markRaw, + nextTick, + onBeforeUnmount, +} from 'vue'; import { PageContainer } from 'antdv-pro-layout'; import { message, Modal } from 'ant-design-vue/lib'; import { ColumnsType } from 'ant-design-vue/lib/table'; import { SizeType } from 'ant-design-vue/lib/config-provider'; import { MenuInfo } from 'ant-design-vue/lib/menu/src/interface'; import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue'; -import { RESULT_CODE_SUCCESS } from '@/constants/result-constants'; +import { + RESULT_CODE_ERROR, + RESULT_CODE_SUCCESS, +} from '@/constants/result-constants'; import useNeInfoStore from '@/store/modules/neinfo'; import useI18n from '@/hooks/useI18n'; import { getKPITitle, listKPIData } from '@/api/perfManage/goldTarget'; @@ -29,8 +40,10 @@ import { parseDateToStr } from '@/utils/date-utils'; import { writeSheet } from '@/utils/execl-utils'; import saveAs from 'file-saver'; import { generateColorRGBA } from '@/utils/generate-utils'; +import { OptionsType, WS } from '@/plugins/ws-websocket'; const neInfoStore = useNeInfoStore(); const { t, currentLocale } = useI18n(); +const ws = new WS(); echarts.use([ TooltipComponent, @@ -160,66 +173,17 @@ function fnTableChange(pagination: any, filters: any, sorter: any, extra: any) { type StateType = { /**网元类型 */ neType: string[]; + /**图表实时统计 */ + chartRealTime: boolean; /**图表标签选择 */ chartLegendSelectedFlag: boolean; - /**图表标签选择 */ - chartLegendSelected: Record; - /**图表配置数据 */ - chartOption: EChartsOption; }; /**对象信息状态 */ let state: StateType = reactive({ neType: [], + chartRealTime: false, chartLegendSelectedFlag: false, - chartLegendSelected: {}, - chartOption: { - tooltip: { - trigger: 'axis', - position: function (pt: any) { - return [pt[0], '10%']; - }, - }, - xAxis: { - type: 'category', - boundaryGap: false, - data: [], - }, - yAxis: { - type: 'value', - boundaryGap: [0, '100%'], - }, - legend: { - type: 'scroll', - orient: 'vertical', - top: 40, - right: 20, - itemWidth: 20, - itemGap: 25, - textStyle: { - color: '#646A73', - }, - icon: 'circle', - selected: {}, - }, - grid: { - left: '10%', - right: '30%', - bottom: '20%', - }, - dataZoom: [ - { - type: 'inside', - start: 90, - end: 100, - }, - { - start: 90, - end: 100, - }, - ], - series: [], - }, }); /** @@ -373,7 +337,54 @@ function fnRanderChart() { if (!container) return; kpiChart.value = markRaw(echarts.init(container, 'light')); - kpiChart.value.setOption(state.chartOption); + const option: EChartsOption = { + tooltip: { + trigger: 'axis', + position: function (pt: any) { + return [pt[0], '10%']; + }, + }, + xAxis: { + type: 'category', + boundaryGap: false, + data: [], // 数据x轴 + }, + yAxis: { + type: 'value', + boundaryGap: [0, '100%'], + }, + legend: { + type: 'scroll', + orient: 'vertical', + top: 40, + right: 20, + itemWidth: 20, + itemGap: 25, + textStyle: { + color: '#646A73', + }, + icon: 'circle', + selected: {}, + }, + grid: { + left: '10%', + right: '30%', + bottom: '20%', + }, + dataZoom: [ + { + type: 'inside', + start: 90, + end: 100, + }, + { + start: 90, + end: 100, + }, + ], + series: [], // 数据y轴 + }; + kpiChart.value.setOption(option); // 创建 ResizeObserver 实例 var observer = new ResizeObserver(entries => { @@ -385,17 +396,24 @@ function fnRanderChart() { observer.observe(container); } +/**图表标签选择 */ +let chartLegendSelected: Record = {}; +/**图表配置数据x轴 */ +let chartDataXAxisData: string[] = []; +/**图表配置数据y轴 */ +let chartDataYSeriesData: Record[] = []; + /**图表数据渲染 */ function fnRanderChartData() { if (kpiChart.value == null && tableState.data.length <= 0) { return; } - const xDatas: string[] = []; - const yDatas: Record[] = []; + // 重置 + chartLegendSelected = {}; + chartDataXAxisData = []; + chartDataYSeriesData = []; - const tableColumnsKeyArr: string[] = []; - const chartLegendSelected: Record = {}; for (const columns of tableColumns.value) { if ( columns.key === 'neName' || @@ -405,8 +423,9 @@ function fnRanderChartData() { continue; } const color = generateColorRGBA(); - yDatas.push({ + chartDataYSeriesData.push({ name: `${columns.title}`, + key: `${columns.key}`, type: 'line', symbol: 'none', sampling: 'lttb', @@ -427,7 +446,6 @@ function fnRanderChartData() { }, data: [], }); - tableColumnsKeyArr.push(`${columns.key}`); chartLegendSelected[`${columns.title}`] = state.chartLegendSelectedFlag; } @@ -436,40 +454,38 @@ function fnRanderChartData() { if (queryParams.sortOrder === 'desc') { orgData = orgData.toReversed(); } + for (const item of orgData) { - xDatas.push(item['timeGroup']); + chartDataXAxisData.push(item['timeGroup']); const keys = Object.keys(item); - for (let i = 0; i < tableColumnsKeyArr.length; i++) { + for (const y of chartDataYSeriesData) { for (const key of keys) { - if (tableColumnsKeyArr[i] === key) { - yDatas[i].data.push(+item[key]); + if (y.key === key) { + y.data.push(+item[key]); } } } } - // console.log(queryParams.sortOrder, xDatas, yDatas); + // console.log(queryParams.sortOrder, chartLegendSelected); + // console.log(chartDataXAxisData, chartDataYSeriesData) - // 图标签选择状态标记 - state.chartLegendSelected = chartLegendSelected; + // 绘制图数据 kpiChart.value.setOption({ legend: { selected: chartLegendSelected, }, xAxis: { - data: xDatas, + data: chartDataXAxisData, }, - series: yDatas, + series: chartDataYSeriesData, }); } /**图表折线显示全部 */ function fnLegendSelected(bool: any) { - const chartLegendSelected: Record = {}; - for (const key of Object.keys(state.chartLegendSelected)) { + for (const key of Object.keys(chartLegendSelected)) { chartLegendSelected[key] = bool; } - // 图标签选择状态标记 - state.chartLegendSelected = chartLegendSelected; kpiChart.value.setOption({ legend: { selected: chartLegendSelected, @@ -477,6 +493,75 @@ function fnLegendSelected(bool: any) { }); } +/**图表实时统计 */ +function fnRealTimeSwitch(bool: any) { + if (bool) { + // 建立链接 + const options: OptionsType = { + url: '/ws', + params: { + /**订阅通道组 + * + * 指标(GroupID:10) + */ + subGroupID: '10', + }, + onmessage: wsMessage, + onerror: wsError, + }; + ws.connect(options); + } else { + ws.close(); + } +} + +/**接收数据后回调 */ +function wsError(ev: any) { + // 接收数据后回调 + console.error(ev); +} + +/**接收数据后回调 */ +function wsMessage(res: Record) { + const { code, requestId, data } = res; + if (code === RESULT_CODE_ERROR) { + console.warn(res.msg); + return; + } + + // 订阅组信息 + if (!data?.groupId) { + return; + } + // kpiEvent 黄金指标指标事件 + if (data.groupId === '10') { + const kpiEvent = data.data; + for (const key of Object.keys(data.data)) { + const v = kpiEvent[key]; + // x轴 + if (key === 'timeGroup') { + // chartDataXAxisData.shift(); + chartDataXAxisData.push(v); + continue; + } + // y轴 + const yItem = chartDataYSeriesData.find(item => item.key === key); + if (yItem) { + // yItem.data.shift(); + yItem.data.push(v); + } + } + + // 绘制图数据 + kpiChart.value.setOption({ + xAxis: { + data: chartDataXAxisData, + }, + series: chartDataYSeriesData, + }); + } +} + onMounted(() => { // 获取网元网元列表 neInfoStore.fnNelist().then(res => { @@ -512,8 +597,8 @@ onMounted(() => { // 查询当前小时 const nowDate: Date = new Date(); nowDate.setMinutes(0, 0, 0); - queryRangePicker.value[0] = parseDateToStr(nowDate); - // queryRangePicker.value[0] = '2024-01-30 00:00:00'; + // queryRangePicker.value[0] = parseDateToStr(nowDate); + queryRangePicker.value[0] = '2024-01-30 00:00:00'; nowDate.setMinutes(59, 59, 59); queryRangePicker.value[1] = parseDateToStr(nowDate); fnGetListTitle(); @@ -528,6 +613,10 @@ onMounted(() => { } }); }); + +onBeforeUnmount(() => { + ws.close(); +});