You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by qi...@apache.org on 2023/02/15 05:32:38 UTC
[skywalking-booster-ui] branch main updated: refactor: optimize the attached events visualization in the trace widget (#234)
This is an automated email from the ASF dual-hosted git repository.
qiuxiafan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-booster-ui.git
The following commit(s) were added to refs/heads/main by this push:
new a1066f0 refactor: optimize the attached events visualization in the trace widget (#234)
a1066f0 is described below
commit a1066f09e40083efa72b5081d9ac63efdcaa0a22
Author: Fine0830 <fa...@gmail.com>
AuthorDate: Wed Feb 15 13:32:32 2023 +0800
refactor: optimize the attached events visualization in the trace widget (#234)
---
src/layout/components/SideBar.vue | 15 +++-
.../trace/components/D3Graph/SpanDetail.vue | 88 ++++++++++------------
.../dashboard/related/trace/utils/d3-trace-list.ts | 17 ++++-
3 files changed, 69 insertions(+), 51 deletions(-)
diff --git a/src/layout/components/SideBar.vue b/src/layout/components/SideBar.vue
index 77ebdce..f630503 100644
--- a/src/layout/components/SideBar.vue
+++ b/src/layout/components/SideBar.vue
@@ -13,7 +13,7 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
- <div class="side-bar" v-if="showMenu" @click="isCollapse = false" @mouseleave="isCollapse = true">
+ <div class="side-bar" v-if="showMenu" @click="isCollapse = false" @mouseleave="closeMenu">
<div :class="isCollapse ? 'logo-icon-collapse' : 'logo-icon'">
<Icon :size="isCollapse ? 'xl' : 'logo'" :iconName="isCollapse ? 'logo' : 'logo-sw'" />
</div>
@@ -81,6 +81,7 @@ limitations under the License. -->
const route = useRoute();
const isCollapse = ref(true);
const showMenu = ref(true);
+ const open = ref<boolean>(false);
if (/Android|webOS|iPhone|iPod|iPad|BlackBerry/i.test(navigator.userAgent)) {
appStore.setIsMobile(true);
@@ -97,7 +98,17 @@ limitations under the License. -->
return menus.filter((d) => d.meta && !d.meta.notShow);
};
function setCollapse() {
- isCollapse.value = false;
+ open.value = true;
+ setTimeout(() => {
+ if (open.value) {
+ isCollapse.value = false;
+ }
+ open.value = false;
+ }, 1000);
+ }
+ function closeMenu() {
+ isCollapse.value = true;
+ open.value = false;
}
</script>
diff --git a/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue b/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue
index 0f7ae37..ee813dd 100644
--- a/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue
+++ b/src/views/dashboard/related/trace/components/D3Graph/SpanDetail.vue
@@ -74,7 +74,7 @@ limitations under the License. -->
<h5 class="mb-10" v-if="currentSpan.attachedEvents && currentSpan.attachedEvents.length"> {{ t("events") }}. </h5>
<div
class="attach-events"
- ref="timeline"
+ ref="eventGraph"
v-if="currentSpan.attachedEvents && currentSpan.attachedEvents.length"
></div>
<el-button class="popup-btn" type="primary" @click="getTaceLogs">
@@ -131,8 +131,7 @@ limitations under the License. -->
import { useI18n } from "vue-i18n";
import type { PropType } from "vue";
import dayjs from "dayjs";
- import { DataSet, Timeline } from "vis-timeline/standalone";
- import "vis-timeline/styles/vis-timeline-graph2d.css";
+ import ListGraph from "../../utils/d3-trace-list";
import copy from "@/utils/copy";
import { ElMessage } from "element-plus";
import { dateFormat } from "@/utils/dateFormat";
@@ -146,8 +145,6 @@ limitations under the License. -->
});
const { t } = useI18n();
const traceStore = useTraceStore();
- const timeline = ref<Nullable<HTMLDivElement>>(null);
- const visGraph = ref<Nullable<any>>(null);
const pageNum = ref<number>(1);
const showRelatedLogs = ref<boolean>(false);
const showEventDetail = ref<boolean>(false);
@@ -156,6 +153,8 @@ limitations under the License. -->
const total = computed(() =>
traceStore.traceList.length === pageSize ? pageSize * pageNum.value + 1 : pageSize * pageNum.value,
);
+ const tree = ref<any>(null);
+ const eventGraph = ref<Nullable<HTMLDivElement>>(null);
const visDate = (date: number, pattern = "YYYY-MM-DD HH:mm:ss:SSS") => dayjs(date).format(pattern);
onMounted(() => {
@@ -180,52 +179,46 @@ limitations under the License. -->
}
}
function visTimeline() {
- if (!timeline.value) {
+ if (!eventGraph.value) {
return;
}
- if (visGraph.value) {
- visGraph.value.destroy();
- }
- const h = timeline.value.getBoundingClientRect().height;
const attachedEvents = props.currentSpan.attachedEvents || [];
- const events: any[] = attachedEvents.map((d: SpanAttachedEvent, index: number) => {
- let startTimeNanos = String(d.startTime.nanos).slice(-6).padStart(6, "0");
- let endTimeNanos = String(d.endTime.nanos).slice(-6).padStart(6, "0");
- endTimeNanos = toString(endTimeNanos);
- startTimeNanos = toString(startTimeNanos);
- return {
- id: index + 1,
- content: d.event,
- start: new Date(Number(d.startTime.seconds * 1000 + d.startTime.nanos / 1000000)),
- end: new Date(Number(d.endTime.seconds * 1000 + d.endTime.nanos / 1000000)),
- ...d,
- startTime: d.startTime.seconds * 1000 + d.startTime.nanos / 1000000,
- endTime: d.endTime.seconds * 1000 + d.endTime.nanos / 1000000,
- className: "Normal",
- startTimeNanos,
- endTimeNanos,
- };
- });
+ const events: any[] = attachedEvents
+ .map((d: SpanAttachedEvent) => {
+ let startTimeNanos = String(d.startTime.nanos).slice(-6).padStart(6, "0");
+ let endTimeNanos = String(d.endTime.nanos).slice(-6).padStart(6, "0");
+ endTimeNanos = toString(endTimeNanos);
+ startTimeNanos = toString(startTimeNanos);
+ const startTime = d.startTime.seconds * 1000 + d.startTime.nanos / 1000000;
+ const endTime = d.endTime.seconds * 1000 + d.endTime.nanos / 1000000;
+ return {
+ label: d.event,
+ ...d,
+ startTime,
+ endTime,
+ startTimeNanos,
+ endTimeNanos,
+ };
+ })
+ .sort((a: { startTime: number; endTime: number }, b: { startTime: number; endTime: number }) => {
+ return a.startTime - b.startTime;
+ });
- const items = new DataSet(events);
- const options: any = {
- height: h,
- width: "100%",
- locale: "en",
- groupHeightMode: "fitItems",
- zoomMin: 80,
- };
+ tree.value = new ListGraph(eventGraph.value, selectEvent);
+ tree.value.init(
+ {
+ children: events,
+ label: "",
+ },
+ events,
+ 0,
+ );
+ tree.value.draw();
+ }
- visGraph.value = new Timeline(timeline.value, items, options);
- visGraph.value.on("select", (data: { items: number[] }) => {
- const index = data.items[0];
- currentEvent.value = events[index - 1 || 0] || {};
- if (data.items.length) {
- showEventDetail.value = true;
- return;
- }
- showEventDetail.value = false;
- });
+ function selectEvent(i: any) {
+ currentEvent.value = i.data;
+ showEventDetail.value = true;
}
function toString(str: string) {
return str.replace(/\d(?=(\d{3})+$)/g, "$&,");
@@ -247,7 +240,8 @@ limitations under the License. -->
.attach-events {
width: 100%;
margin: 0 5px 5px 0;
- height: 200px;
+ height: 400px;
+ overflow: auto;
}
.popup-btn {
diff --git a/src/views/dashboard/related/trace/utils/d3-trace-list.ts b/src/views/dashboard/related/trace/utils/d3-trace-list.ts
index 7bb39a6..8c14382 100644
--- a/src/views/dashboard/related/trace/utils/d3-trace-list.ts
+++ b/src/views/dashboard/related/trace/utils/d3-trace-list.ts
@@ -18,6 +18,7 @@
import * as d3 from "d3";
import d3tip from "d3-tip";
import type { Trace } from "@/types/trace";
+import dayjs from "dayjs";
export default class ListGraph {
private barHeight = 48;
@@ -91,7 +92,6 @@ export default class ListGraph {
this.svg
.append("g")
.attr("class", "trace-xaxis")
-
.attr("transform", `translate(${this.width * 0.618 - 20},${30})`)
.call(this.xAxis);
this.sequentialScale = d3
@@ -164,6 +164,7 @@ export default class ListGraph {
.attr("x", 35)
.attr("y", -6)
.attr("fill", "#333")
+ .style("font-size", "12px")
.html((d: any) => {
if (d.data.label === "TRACE_ROOT") {
return "";
@@ -214,7 +215,16 @@ export default class ListGraph {
.attr("y", 12)
.attr("fill", "#ccc")
.style("font-size", "11px")
- .text((d: any) => `${d.data.layer || ""} ${d.data.component ? "- " + d.data.component : d.data.component || ""}`);
+ .text(
+ (d: any) =>
+ `${d.data.layer || ""} ${
+ d.data.component
+ ? "- " + d.data.component
+ : d.data.event
+ ? this.visDate(d.data.startTime) + ":" + d.data.startTimeNanos
+ : ""
+ }`,
+ );
nodeEnter
.append("rect")
.attr("rx", 2)
@@ -305,6 +315,9 @@ export default class ListGraph {
callback();
}
}
+ visDate(date: number, pattern = "YYYY-MM-DD HH:mm:ss:SSS") {
+ return dayjs(date).format(pattern);
+ }
resize() {
if (!this.el) {
return;