diff --git a/src/views/dashboard/related/trace/components/D3Graph/Index.vue b/src/views/dashboard/related/trace/components/D3Graph/Index.vue index 66770f09..11d9d6b0 100644 --- a/src/views/dashboard/related/trace/components/D3Graph/Index.vue +++ b/src/views/dashboard/related/trace/components/D3Graph/Index.vue @@ -17,7 +17,9 @@ limitations under the License. -->
Span Details
-
{{ `Parent Span: ${span.parentSegmentId}` }}
+
{{ + `Parent Span: ${span.parentSegmentId}` + }}
@@ -97,16 +99,26 @@ limitations under the License. --> } } function handleSelectSpan(i: Recordable) { + parentSpans.value = []; currentSpan.value = i.data; - parentSpans.value = currentSpan.value?.refs?.filter((d) => d) || []; - if (currentSpan.value?.parentSpanId !== -1) { + parentSpans.value = []; + if (!currentSpan.value) { + return; + } + for (const ref of currentSpan.value.refs || []) { + parentSpans.value.push(ref); + } + if ((currentSpan.value.parentSpanId ?? -1) > -1) { parentSpans.value.push({ - parentSegmentId: currentSpan.value?.segmentId || "", - parentSpanId: currentSpan.value?.parentSpanId || NaN, - traceId: currentSpan.value?.traceId || "", + parentSegmentId: currentSpan.value.segmentId, + parentSpanId: currentSpan.value.parentSpanId, + traceId: currentSpan.value.traceId, }); } } + function viewParentSpan() { + tree.value.highlightParents(); + } function traverseTree(node: Recordable, spanId: string, segmentId: string, data: Recordable) { if (!node || node.isBroken) { return; @@ -409,6 +421,11 @@ limitations under the License. --> fill: #409eff; } + .trace-node.highlightedParent .node-text { + font-weight: bold; + fill: #4caf50; + } + #action-box { position: absolute; color: $font-color; 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 1e13f735..f266c866 100644 --- a/src/views/dashboard/related/trace/utils/d3-trace-list.ts +++ b/src/views/dashboard/related/trace/utils/d3-trace-list.ts @@ -87,6 +87,7 @@ export default class ListGraph { } init(data: Recordable, row: Recordable[], fixSpansSize: number) { d3.select(`.${this.el?.className} .trace-xaxis`).remove(); + d3.select("#action-box").style("display", "none"); this.row = row; this.data = data; this.min = d3.min(this.row.map((i) => i.startTime)); @@ -117,10 +118,10 @@ export default class ListGraph { } draw(callback: Function) { this.update(this.root, callback); - d3.select("body").on("click", function (event) { - if (event.target.closest("#action-box")) return; - d3.select("#action-box").style("display", "none"); - }); + // d3.select("body").on("click", function (event) { + // if (event.target.closest("#action-box")) return; + // d3.select("#action-box").style("display", "none"); + // }); } click(d: Recordable, scope: Recordable) { if (!d.data.type) return; @@ -147,6 +148,7 @@ export default class ListGraph { .enter() .append("g") .attr("transform", `translate(${source.y0},${source.x0})`) + .attr("id", (d: Recordable) => `list-node-${d.id}`) .attr("class", "trace-node") .attr("style", "cursor: pointer") .on("mouseover", function (event: MouseEvent, d: Trace) { @@ -175,6 +177,10 @@ export default class ListGraph { if (t.handleSelectSpan) { t.handleSelectSpan(d); } + t.root.descendants().map((node: { id: number }) => { + d3.select(`#list-node-${node.id}`).classed("highlightedParent", false); + return node; + }); }); nodeEnter .append("rect") @@ -401,6 +407,39 @@ export default class ListGraph { callback(); } } + highlightParents() { + if (!this.selectedNode) { + return; + } + const nodes = this.root.descendants().map((node: { id: number }) => { + d3.select(`#list-node-${node.id}`).classed("highlightedParent", false); + return node; + }); + const selectedNode = this.selectedNode.datum(); + const parentSpans = selectedNode.data.refs.map((d: Recordable) => d); + if (selectedNode.data?.parentSpanId !== -1) { + parentSpans.push({ + parentSegmentId: selectedNode.data.segmentId, + parentSpanId: selectedNode.data.parentSpanId, + traceId: selectedNode.data.traceId, + }); + } + const parents = parentSpans.map((d: Recordable) => { + return nodes.find( + (node: Recordable) => + d.parentSpanId === node.data.spanId && + d.parentSegmentId === node.data.segmentId && + d.traceId === node.data.traceId, + ); + }); + for (const node of parents) { + if (node) { + d3.select(`#list-node-${node.id}`).classed("highlightedParent", true); + } + } + d3.select("#action-box").style("display", "none"); + this.selectedNode.classed("highlighted", false); + } visDate(date: number, pattern = "YYYY-MM-DD HH:mm:ss:SSS") { return dayjs(date).format(pattern); }