mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-14 08:45:23 +00:00
view ref children
This commit is contained in:
parent
883cec9264
commit
c4504b7423
BIN
src/assets/img/tools/REFER.png
Normal file
BIN
src/assets/img/tools/REFER.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 499 B |
1
src/types/trace.d.ts
vendored
1
src/types/trace.d.ts
vendored
@ -48,6 +48,7 @@ export interface Span {
|
|||||||
logs?: log[];
|
logs?: log[];
|
||||||
parentSegmentId?: string;
|
parentSegmentId?: string;
|
||||||
refs?: Ref[];
|
refs?: Ref[];
|
||||||
|
refChildren?: Recordable;
|
||||||
}
|
}
|
||||||
export type Ref = {
|
export type Ref = {
|
||||||
type: string;
|
type: string;
|
||||||
|
@ -18,6 +18,9 @@ limitations under the License. -->
|
|||||||
<el-dialog v-model="showDetail" :destroy-on-close="true" @closed="showDetail = false">
|
<el-dialog v-model="showDetail" :destroy-on-close="true" @closed="showDetail = false">
|
||||||
<SpanDetail :currentSpan="currentSpan" />
|
<SpanDetail :currentSpan="currentSpan" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
|
<el-dialog v-model="showRefsChildren" :destroy-on-close="true" @closed="showRefsChildren = false" width="850">
|
||||||
|
<div ref="refsChildrenTree" class="refs-children-tree"></div>
|
||||||
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch, onBeforeUnmount, onMounted } from "vue";
|
import { ref, watch, onBeforeUnmount, onMounted } from "vue";
|
||||||
@ -30,6 +33,7 @@ limitations under the License. -->
|
|||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { debounce } from "@/utils/debounce";
|
import { debounce } from "@/utils/debounce";
|
||||||
import { mutationObserver } from "@/utils/mutation";
|
import { mutationObserver } from "@/utils/mutation";
|
||||||
|
import { ViewSpanType } from "../data";
|
||||||
|
|
||||||
/* global defineProps, Nullable, defineExpose, Recordable */
|
/* global defineProps, Nullable, defineExpose, Recordable */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -42,10 +46,12 @@ limitations under the License. -->
|
|||||||
const showDetail = ref<boolean>(false);
|
const showDetail = ref<boolean>(false);
|
||||||
const fixSpansSize = ref<number>(0);
|
const fixSpansSize = ref<number>(0);
|
||||||
const segmentId = ref<Recordable[]>([]);
|
const segmentId = ref<Recordable[]>([]);
|
||||||
const currentSpan = ref<Array<Span>>([]);
|
const currentSpan = ref<Span | Recordable>({});
|
||||||
const refSpans = ref<Array<Ref>>([]);
|
const refSpans = ref<Array<Ref>>([]);
|
||||||
const tree = ref<Nullable<any>>(null);
|
const tree = ref<Nullable<any>>(null);
|
||||||
|
const showRefsChildren = ref<boolean>(false);
|
||||||
const traceGraph = ref<Nullable<HTMLDivElement>>(null);
|
const traceGraph = ref<Nullable<HTMLDivElement>>(null);
|
||||||
|
const refsChildrenTree = ref<Nullable<HTMLDivElement>>(null);
|
||||||
const debounceFunc = debounce(draw, 500);
|
const debounceFunc = debounce(draw, 500);
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
@ -84,20 +90,30 @@ limitations under the License. -->
|
|||||||
tree.value.init({ label: `${props.traceId}`, children: segmentId.value }, props.data);
|
tree.value.init({ label: `${props.traceId}`, children: segmentId.value }, props.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function handleSelectSpan(i: Recordable) {
|
|
||||||
currentSpan.value = i.data;
|
function drawRefsChildren() {
|
||||||
showDetail.value = true;
|
if (!refsChildrenTree.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
d3.selectAll(".d3-tip").remove();
|
||||||
|
if (props.type === "List") {
|
||||||
|
tree.value = new ListGraph(refsChildrenTree.value, handleSelectSpan);
|
||||||
|
tree.value.init({ label: "", children: currentSpan.value.refChildren }, props.data, fixSpansSize.value);
|
||||||
|
tree.value.draw();
|
||||||
|
} else {
|
||||||
|
tree.value = new TreeGraph(refsChildrenTree.value, handleSelectSpan);
|
||||||
|
tree.value.init({ label: `${props.traceId}`, children: currentSpan.value.refChildren }, props.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
function traverseTree(node: Recordable, spanId: string, segmentId: string, data: Recordable) {
|
function handleSelectSpan(i: Recordable, type?: ViewSpanType) {
|
||||||
if (!node || node.isBroken) {
|
currentSpan.value = i.data;
|
||||||
return;
|
if (type === ViewSpanType.REFS) {
|
||||||
}
|
showRefsChildren.value = true;
|
||||||
if (node.spanId === spanId && node.segmentId === segmentId) {
|
setTimeout(() => {
|
||||||
node.refChildren.push(data);
|
drawRefsChildren();
|
||||||
return;
|
}, 300);
|
||||||
}
|
} else {
|
||||||
for (const nodeItem of node.children || []) {
|
showDetail.value = true;
|
||||||
traverseTree(nodeItem, spanId, segmentId, data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
function changeTree() {
|
function changeTree() {
|
||||||
@ -317,6 +333,18 @@ limitations under the License. -->
|
|||||||
return a - b;
|
return a - b;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
function traverseTree(node: Recordable, spanId: string, segmentId: string, data: Recordable) {
|
||||||
|
if (!node || node.isBroken) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (node.spanId === spanId && node.segmentId === segmentId) {
|
||||||
|
node.refChildren.push(data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const nodeItem of node.children || []) {
|
||||||
|
traverseTree(nodeItem, spanId, segmentId, data);
|
||||||
|
}
|
||||||
|
}
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
d3.selectAll(".d3-tip").remove();
|
d3.selectAll(".d3-tip").remove();
|
||||||
window.removeEventListener("resize", debounceFunc);
|
window.removeEventListener("resize", debounceFunc);
|
||||||
@ -388,4 +416,9 @@ limitations under the License. -->
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.refs-children-tree {
|
||||||
|
height: 500px;
|
||||||
|
width: 800px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -27,7 +27,7 @@ limitations under the License. -->
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import type { PropType } from "vue";
|
import type { PropType } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import * as d3 from "d3";
|
import * as d3 from "d3";
|
||||||
|
20
src/views/dashboard/related/trace/components/data.ts
Normal file
20
src/views/dashboard/related/trace/components/data.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
export enum ViewSpanType {
|
||||||
|
REFS = "refs",
|
||||||
|
DETAILS = "details",
|
||||||
|
}
|
@ -22,10 +22,11 @@ import dayjs from "dayjs";
|
|||||||
import icons from "@/assets/img/icons";
|
import icons from "@/assets/img/icons";
|
||||||
import { useAppStoreWithOut } from "@/store/modules/app";
|
import { useAppStoreWithOut } from "@/store/modules/app";
|
||||||
import { Themes } from "@/constants/data";
|
import { Themes } from "@/constants/data";
|
||||||
|
import { ViewSpanType } from "../components/data";
|
||||||
|
|
||||||
export default class ListGraph {
|
export default class ListGraph {
|
||||||
private barHeight = 48;
|
private barHeight = 48;
|
||||||
private handleSelectSpan: Nullable<(i: Trace) => void> = null;
|
private handleSelectSpan: Nullable<(i: Trace, type?: ViewSpanType) => void> = null;
|
||||||
private el: Nullable<HTMLDivElement> = null;
|
private el: Nullable<HTMLDivElement> = null;
|
||||||
private i = 0;
|
private i = 0;
|
||||||
private width = 0;
|
private width = 0;
|
||||||
@ -223,7 +224,7 @@ export default class ListGraph {
|
|||||||
nodeEnter
|
nodeEnter
|
||||||
.append("text")
|
.append("text")
|
||||||
.attr("class", "node-text")
|
.attr("class", "node-text")
|
||||||
.attr("x", 35)
|
.attr("x", 48)
|
||||||
.attr("y", -6)
|
.attr("y", -6)
|
||||||
.attr("fill", (d: Recordable) => (d.data.isError ? `#e54c17` : appStore.theme === Themes.Dark ? "#eee" : "#333"))
|
.attr("fill", (d: Recordable) => (d.data.isError ? `#e54c17` : appStore.theme === Themes.Dark ? "#eee" : "#333"))
|
||||||
.html((d: Recordable) => {
|
.html((d: Recordable) => {
|
||||||
@ -233,6 +234,17 @@ export default class ListGraph {
|
|||||||
const label = d.data.label.length > 30 ? `${d.data.label.slice(0, 30)}...` : `${d.data.label}`;
|
const label = d.data.label.length > 30 ? `${d.data.label.slice(0, 30)}...` : `${d.data.label}`;
|
||||||
return label;
|
return label;
|
||||||
});
|
});
|
||||||
|
nodeEnter
|
||||||
|
.append("image")
|
||||||
|
.attr("width", 16)
|
||||||
|
.attr("height", 16)
|
||||||
|
.attr("x", 23)
|
||||||
|
.attr("y", -8)
|
||||||
|
.attr("xlink:href", (d: any) => (d.data.refChildren?.length ? icons.REFER : ``))
|
||||||
|
.on("click", (event: any, d: Trace) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.handleSelectSpan && this.handleSelectSpan(d, ViewSpanType.REFS);
|
||||||
|
});
|
||||||
nodeEnter
|
nodeEnter
|
||||||
.append("circle")
|
.append("circle")
|
||||||
.attr("r", 10)
|
.attr("r", 10)
|
||||||
@ -272,7 +284,7 @@ export default class ListGraph {
|
|||||||
nodeEnter
|
nodeEnter
|
||||||
.append("text")
|
.append("text")
|
||||||
.attr("class", "node-text")
|
.attr("class", "node-text")
|
||||||
.attr("x", 35)
|
.attr("x", 48)
|
||||||
.attr("y", 12)
|
.attr("y", 12)
|
||||||
.attr("fill", appStore.theme === Themes.Dark ? "#777" : "#ccc")
|
.attr("fill", appStore.theme === Themes.Dark ? "#777" : "#ccc")
|
||||||
.style("font-size", "11px")
|
.style("font-size", "11px")
|
||||||
|
Loading…
Reference in New Issue
Block a user