From c58adf798910b50767e103a5ca30fb1482a6bd8e Mon Sep 17 00:00:00 2001 From: yzygyin <1446680116@qq.com> Date: Mon, 9 Dec 2024 15:29:13 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=80=90trace=E3=80=91trace=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E9=A1=B5=E2=80=9C=E6=9C=8D=E5=8A=A1=E6=95=B0=E9=87=8F?= =?UTF-8?q?=E2=80=9D=E5=88=97=E5=B1=95=E7=A4=BA=E4=BC=98=E5=8C=96=20#=20Re?= =?UTF-8?q?viewed,=20transaction=20id:=2026190?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../webpack/src/monitor-pc/lang/title.ts | 1 + .../main/inquire-content/trace-list.scss | 102 +++++++++++++++--- .../pages/main/inquire-content/trace-list.tsx | 82 +++++++++++++- 3 files changed, 168 insertions(+), 17 deletions(-) diff --git a/bkmonitor/webpack/src/monitor-pc/lang/title.ts b/bkmonitor/webpack/src/monitor-pc/lang/title.ts index 5549c9d26f..3bc33eda9d 100644 --- a/bkmonitor/webpack/src/monitor-pc/lang/title.ts +++ b/bkmonitor/webpack/src/monitor-pc/lang/title.ts @@ -153,4 +153,5 @@ export default { 默认继承应用的类型设置: 'Default inheritance application type settings', URI信息: 'URI Info', URI配置: 'URI Configuration', + '共有 {0} 个服务': 'There are {0} services', }; diff --git a/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.scss b/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.scss index d69065ae69..8dd8db1273 100644 --- a/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.scss +++ b/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.scss @@ -7,7 +7,7 @@ .query-time { font-size: 12px; - + .query-count { margin: 0 2px; color: #ea3636; @@ -90,7 +90,7 @@ .list-item { box-sizing: border-box; } - } + } } .sort-dropdown-menu { @@ -527,7 +527,7 @@ bottom: 0; left: 0; } - + .toggle-full-screen { position: fixed; top: 0; @@ -537,7 +537,7 @@ height: 48px; color: #fff; cursor: pointer; - + .circle { position: absolute; top: -48px; @@ -548,14 +548,14 @@ background: #979ba5; border-radius: 50%; } - + .icon-monitor { position: relative; top: -2px; left: 8px; font-size: 30px; } - + &:hover { color: #3a84ff; } @@ -565,11 +565,11 @@ font-size: 116px; color: #fff; cursor: pointer; - + &:hover { color: #3a84ff; } - + &.fullscreen-close { top: 0; right: 28px; @@ -631,7 +631,7 @@ bottom: 0; left: 0; } - + .toggle-full-screen { position: fixed; top: 0; @@ -641,7 +641,7 @@ height: 48px; color: #fff; cursor: pointer; - + .circle { position: absolute; top: -48px; @@ -652,14 +652,14 @@ background: #979ba5; border-radius: 50%; } - + .icon-monitor { position: relative; top: -2px; left: 8px; font-size: 30px; } - + &:hover { color: #3a84ff; } @@ -669,11 +669,11 @@ font-size: 116px; color: #fff; cursor: pointer; - + &:hover { color: #3a84ff; } - + &.fullscreen-close { top: 0; right: 28px; @@ -710,7 +710,7 @@ display: none; } } - + &.fadeout { z-index: 9999; display: inline-block; @@ -768,4 +768,74 @@ .bk-popover.bk-pop2-content.bk-table-head-filter .content-footer span.disabled { color: #979ba5; cursor: not-allowed; -} \ No newline at end of file +} + +.stacked-bar { + display: inline-flex; + align-items: center; + justify-content: center; + width: 67px; + height: 12px; + line-height: 12px; + text-align: center; + + &:hover { + cursor: pointer; + } + + .bar { + height: 100%; + } +} + +.serve-content { + padding: 8px 12px 4px 12px; + color: #fff; + background-color: #000000cc; + border-radius: 2px; + + & > * { + margin-bottom: 8px; + } + + .serve-title { + height: 16px; + font-size: 12px; + } + + .status-wrap { + display: flex; + align-items: center; + justify-content: space-between; + height: 16px; + line-height: 16px; + + .status-color { + flex-shrink: 0; + width: 8px; + height: 8px; + margin-right: 4px; + } + + .status-text { + flex-grow: 1; + margin-right: auto; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + + } + + .status-percent { + flex-shrink: 0; + width: 25px; + margin-left: auto; + } + + } +} + +.popover-trace.bk-popover.bk-pop2-content { + padding: 0; + border-radius: 2px; +} diff --git a/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.tsx b/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.tsx index 95af67a880..b73e9acfe2 100644 --- a/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.tsx +++ b/bkmonitor/webpack/src/trace/pages/main/inquire-content/trace-list.tsx @@ -46,6 +46,7 @@ import { Checkbox, Loading, Popover, Radio, Table, Sideslider } from 'bkui-vue'; import { CancelToken } from 'monitor-api/index'; import { listOptionValues, spanDetail, traceDetail } from 'monitor-api/modules/apm_trace'; import { random } from 'monitor-common/utils/utils'; +import { COLOR_LIST_BAR } from 'monitor-ui/chart-plugins/constants'; import { echartsDisconnect } from 'monitor-ui/monitor-echarts/utils'; import EmptyStatus from '../../../components/empty-status/empty-status'; @@ -175,6 +176,7 @@ export default defineComponent({ const columnFilters = ref>({}); const selectedTraceType = ref([]); const selectedSpanType = ref([]); + const serviceColorMap = ref([]); const timeRange = useTimeRanceInject(); provide('isFullscreen', isFullscreen); @@ -697,12 +699,13 @@ export default defineComponent({ ), width: 120, settingsLabel: `${t('服务数量')}`, - field: 'service_count', + field: 'service_distribution', sort: isPreCalculationMode.value ? { sortFn: () => false, } : false, + render: ({ data }: { data: ITraceListItem }) => renderServiceDistributionPopover(data), }, ]); const chartList = computed(() => searchStore.chartPanelList); @@ -728,6 +731,83 @@ export default defineComponent({ }, { immediate: true } ); + + // 渲染堆叠图 + const renderServiceDistributionPopover = (data: ITraceListItem) => { + const serviceData = data?.service_distribution; + + if (!serviceData || Object.keys(serviceData).length === 0) { + return data?.service_count; + } + + const getColorForService = (serviceName: string) => { + if (!serviceColorMap.value[serviceName]) { + const index = Object.keys(serviceColorMap.value).length % COLOR_LIST_BAR.length; + serviceColorMap.value[serviceName] = COLOR_LIST_BAR[index]; + } + return serviceColorMap.value[serviceName]; + }; + + // 计算颜色和百分比 + const services = Object.keys(serviceData).map(key => ({ + name: key, + color: getColorForService(key), + percentage: serviceData[key]?.percentage || 0, + })); + + const serviceContent = ( +
+
{t('共有 {0} 个服务', [services.length])}
+ {services.map(service => { + return ( +
+
+
+ {service.name} +
+ +
{`${service.percentage}%`}
+
+ ); + })} +
+ ); + + const stackedBar = () => ( +
+ {services.map(service => ( +
+ ))} +
+ ); + return ( + + {stackedBar()} + + ); + }; + // 当在 table header 上选择筛选并确定后执行的回调方法。 const handleSpanFilter = (options: any) => { const {