This commit is contained in:
Fine 2025-03-27 15:53:25 +08:00
parent 9f9bf8b20a
commit 63b2ee2b6f
3 changed files with 31 additions and 36 deletions

View File

@ -17,7 +17,7 @@ limitations under the License. -->
<div ref="traceGraph" class="d3-graph"></div> <div ref="traceGraph" class="d3-graph"></div>
<div id="action-box"> <div id="action-box">
<div @click="showDetail = true">Span Details</div> <div @click="showDetail = true">Span Details</div>
<div v-for="span in parentSpans" :key="span.parentSegmentId" @click="viewParentSpan">{{ <div v-for="span in parentSpans" :key="span.parentSegmentId" @click="viewParentSpan(span)">{{
`Parent Span: ${span.parentSegmentId}` `Parent Span: ${span.parentSegmentId}`
}}</div> }}</div>
</div> </div>
@ -116,8 +116,8 @@ limitations under the License. -->
}); });
} }
} }
function viewParentSpan() { function viewParentSpan(span: Recordable) {
tree.value.highlightParents(); tree.value.highlightParents(span);
} }
function traverseTree(node: Recordable, spanId: string, segmentId: string, data: Recordable) { function traverseTree(node: Recordable, spanId: string, segmentId: string, data: Recordable) {
if (!node || node.isBroken) { if (!node || node.isBroken) {

View File

@ -55,12 +55,12 @@ limitations under the License. -->
function downloadTrace() { function downloadTrace() {
const serializer = new XMLSerializer(); const serializer = new XMLSerializer();
const svgNode: any = d3.select(".trace-list-dowanload").node(); const svgNode: any = d3.select(".trace-list").node();
const source = `<?xml version="1.0" standalone="no"?>\r\n${serializer.serializeToString(svgNode)}`; const source = `<?xml version="1.0" standalone="no"?>\r\n${serializer.serializeToString(svgNode)}`;
const canvas = document.createElement("canvas"); const canvas = document.createElement("canvas");
const context: any = canvas.getContext("2d"); const context: any = canvas.getContext("2d");
canvas.width = (d3.select(".trace-list-dowanload") as Recordable)._groups[0][0].clientWidth; canvas.width = (d3.select(".trace-list") as Recordable)._groups[0][0].clientWidth;
canvas.height = (d3.select(".trace-list-dowanload") as Recordable)._groups[0][0].clientHeight; canvas.height = (d3.select(".trace-list") as Recordable)._groups[0][0].clientHeight;
context.fillStyle = appStore.theme === Themes.Dark ? "#212224" : `#fff`; context.fillStyle = appStore.theme === Themes.Dark ? "#212224" : `#fff`;
context.fillRect(0, 0, canvas.width, canvas.height); context.fillRect(0, 0, canvas.width, canvas.height);
const image = new Image(); const image = new Image();

View File

@ -48,11 +48,11 @@ export default class ListGraph {
this.el = el; this.el = el;
this.width = el.getBoundingClientRect().width - 10; this.width = el.getBoundingClientRect().width - 10;
this.height = el.getBoundingClientRect().height - 10; this.height = el.getBoundingClientRect().height - 10;
d3.select(`.${this.el?.className} .trace-list-dowanload`).remove(); d3.select(`.${this.el?.className} .trace-list`).remove();
this.svg = d3 this.svg = d3
.select(this.el) .select(this.el)
.append("svg") .append("svg")
.attr("class", "trace-list-dowanload") .attr("class", "trace-list")
.attr("width", this.width > 0 ? this.width : 10) .attr("width", this.width > 0 ? this.width : 10)
.attr("height", this.height > 0 ? this.height : 10) .attr("height", this.height > 0 ? this.height : 10)
.attr("transform", `translate(-5, 0)`); .attr("transform", `translate(-5, 0)`);
@ -118,10 +118,6 @@ export default class ListGraph {
} }
draw(callback: Function) { draw(callback: Function) {
this.update(this.root, callback); 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");
// });
} }
click(d: Recordable, scope: Recordable) { click(d: Recordable, scope: Recordable) {
if (!d.data.type) return; if (!d.data.type) return;
@ -172,7 +168,7 @@ export default class ListGraph {
d3.select("#action-box") d3.select("#action-box")
.style("display", "block") .style("display", "block")
.style("left", `${event.pageX - 70}px`) .style("left", `${event.pageX - 70}px`)
.style("top", `${event.pageY - 100}px`); .style("top", `${event.pageY + 30}px`);
t.selectedNode = d3.select(this); t.selectedNode = d3.select(this);
if (t.handleSelectSpan) { if (t.handleSelectSpan) {
t.handleSelectSpan(d); t.handleSelectSpan(d);
@ -407,38 +403,37 @@ export default class ListGraph {
callback(); callback();
} }
} }
highlightParents() { highlightParents(span: Recordable) {
if (!this.selectedNode) { if (!span) {
return; return;
} }
const nodes = this.root.descendants().map((node: { id: number }) => { const nodes = this.root.descendants().map((node: { id: number }) => {
d3.select(`#list-node-${node.id}`).classed("highlightedParent", false); d3.select(`#list-node-${node.id}`).classed("highlightedParent", false);
return node; return node;
}); });
const selectedNode = this.selectedNode.datum(); const parentSpan = nodes.find(
const parentSpans = selectedNode.data.refs.map((d: Recordable) => d); (node: Recordable) =>
if (selectedNode.data?.parentSpanId !== -1) { span.parentSpanId === node.data.spanId &&
parentSpans.push({ span.parentSegmentId === node.data.segmentId &&
parentSegmentId: selectedNode.data.segmentId, span.traceId === node.data.traceId,
parentSpanId: selectedNode.data.parentSpanId, );
traceId: selectedNode.data.traceId, if (parentSpan) {
}); d3.select(`#list-node-${parentSpan.id}`).classed("highlightedParent", true);
}
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"); d3.select("#action-box").style("display", "none");
this.selectedNode.classed("highlighted", false); this.selectedNode.classed("highlighted", false);
if (!parentSpan) return;
const container = document.querySelector(".trace-chart .charts");
const containerRect = container?.getBoundingClientRect();
if (!containerRect) return;
const targetElement = document.querySelector(`#list-node-${parentSpan.id}`);
if (!targetElement) return;
const targetRect = targetElement.getBoundingClientRect();
container?.scrollTo({
left: targetRect.left - containerRect.left + container?.scrollLeft,
top: targetRect.top - containerRect.top + container?.scrollTop - 100,
behavior: "smooth",
});
} }
visDate(date: number, pattern = "YYYY-MM-DD HH:mm:ss:SSS") { visDate(date: number, pattern = "YYYY-MM-DD HH:mm:ss:SSS") {
return dayjs(date).format(pattern); return dayjs(date).format(pattern);