mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-04 10:05:24 +00:00
refactor process topology
This commit is contained in:
parent
22f3a4cd5f
commit
df42b263f4
@ -109,7 +109,6 @@ export const networkProfilingStore = defineStore({
|
||||
}, []);
|
||||
this.calls = calls;
|
||||
this.nodes = data.nodes;
|
||||
console.log(calls);
|
||||
},
|
||||
async createNetworkTask(param: {
|
||||
serviceId: string;
|
||||
|
@ -17,64 +17,6 @@
|
||||
import icons from "@/assets/img/icons";
|
||||
import { Call } from "@/types/topology";
|
||||
|
||||
export const linkElement = (graph: any) => {
|
||||
const linkEnter = graph
|
||||
.append("path")
|
||||
.attr("class", "topo-call")
|
||||
.attr("marker-end", "url(#arrow)")
|
||||
.attr("stroke", "#97B0F8")
|
||||
.attr("d", (d: Call) => linkPath(d));
|
||||
return linkEnter;
|
||||
};
|
||||
export const anchorElement = (graph: any, funcs: any, tip: any) => {
|
||||
const linkEnter = graph
|
||||
.append("g")
|
||||
.attr("class", "topo-line-anchor")
|
||||
.on("mouseover", function (event: unknown, d: unknown) {
|
||||
tip.html(funcs.tipHtml).show(d, this);
|
||||
})
|
||||
.on("mouseout", function () {
|
||||
tip.hide(this);
|
||||
})
|
||||
.on("click", (event: unknown, d: unknown) => {
|
||||
funcs.handleLinkClick(event, d);
|
||||
});
|
||||
|
||||
linkEnter
|
||||
.append("image")
|
||||
.attr("width", 15)
|
||||
.attr("height", 15)
|
||||
.attr("x", (d: Call) => {
|
||||
const p = getMidpoint(d);
|
||||
return p[0] - 8;
|
||||
})
|
||||
.attr("y", (d: Call) => {
|
||||
const p = getMidpoint(d);
|
||||
return p[1] - 13;
|
||||
})
|
||||
.attr("xlink:href", (d: Call) => {
|
||||
return getAnchor(d);
|
||||
});
|
||||
return linkEnter;
|
||||
};
|
||||
export const arrowMarker = (graph: any) => {
|
||||
const defs = graph.append("defs");
|
||||
const arrow = defs
|
||||
.append("marker")
|
||||
.attr("id", "arrow")
|
||||
.attr("class", "topo-line-arrow")
|
||||
.attr("markerUnits", "strokeWidth")
|
||||
.attr("markerWidth", "8")
|
||||
.attr("markerHeight", "8")
|
||||
.attr("viewBox", "0 0 12 12")
|
||||
.attr("refX", "10")
|
||||
.attr("refY", "6")
|
||||
.attr("orient", "auto");
|
||||
const arrowPath = "M2,2 L10,6 L2,10 L6,6 L2,2";
|
||||
|
||||
arrow.append("path").attr("d", arrowPath).attr("fill", "#97B0F8");
|
||||
return arrow;
|
||||
};
|
||||
// Control Point coordinates of quadratic Bezier curve
|
||||
function computeControlPoint(ps: number[], pe: number[], arc = 0.5) {
|
||||
const deltaX = pe[0] - ps[0];
|
||||
@ -106,13 +48,18 @@ function quadraticBezier(
|
||||
return [x, y];
|
||||
}
|
||||
export function getMidpoint(d: Call) {
|
||||
if (isNaN(d.source.x) || isNaN(d.source.y)) {
|
||||
return [0, 0];
|
||||
}
|
||||
if (isNaN(d.target.x) || isNaN(d.target.y)) {
|
||||
return [0, 0];
|
||||
}
|
||||
const controlPos = computeControlPoint(
|
||||
[d.source.x, d.source.y],
|
||||
[d.target.x, d.target.y],
|
||||
0.5
|
||||
);
|
||||
if (d.lowerArc) {
|
||||
console.log(true);
|
||||
controlPos[1] = -controlPos[1];
|
||||
}
|
||||
const p = quadraticBezier(
|
||||
@ -124,6 +71,12 @@ export function getMidpoint(d: Call) {
|
||||
return p;
|
||||
}
|
||||
export function linkPath(d: Call) {
|
||||
if (isNaN(d.source.x) || isNaN(d.source.y)) {
|
||||
return;
|
||||
}
|
||||
if (isNaN(d.target.x) || isNaN(d.target.y)) {
|
||||
return;
|
||||
}
|
||||
const controlPos = computeControlPoint(
|
||||
[d.source.x, d.source.y - 5],
|
||||
[d.target.x, d.target.y - 5],
|
||||
|
@ -33,7 +33,13 @@ limitations under the License. -->
|
||||
</text>
|
||||
</g>
|
||||
<g class="nodes">
|
||||
<g v-for="(node, index) in nodeList" :key="index">
|
||||
<g
|
||||
v-for="(node, index) in nodeList"
|
||||
:key="index"
|
||||
class="topo-node"
|
||||
@mouseover="showNodeTip(node)"
|
||||
@mouseout="hideNodeTip"
|
||||
>
|
||||
<image
|
||||
:href="icons.CUBE"
|
||||
style="cursor: 'move'"
|
||||
@ -56,7 +62,7 @@ limitations under the License. -->
|
||||
v-for="(call, index) in networkProfilingStore.calls"
|
||||
:key="index"
|
||||
class="topo-call"
|
||||
markerEnd="url(#arrow)"
|
||||
marker-end="url(#arrow)"
|
||||
stroke="#97B0F8"
|
||||
:d="linkPath(call)"
|
||||
/>
|
||||
@ -71,16 +77,13 @@ limitations under the License. -->
|
||||
height="15"
|
||||
:x="getMidpoint(call)[0] - 8"
|
||||
:y="getMidpoint(call)[1] - 13"
|
||||
@click="handleLinkClick($event, call)"
|
||||
/>
|
||||
</g>
|
||||
<g class="arrows">
|
||||
<defs
|
||||
v-for="(call, index) in networkProfilingStore.calls"
|
||||
:key="index"
|
||||
>
|
||||
<defs v-for="(_, index) in networkProfilingStore.calls" :key="index">
|
||||
<marker
|
||||
id="arrow"
|
||||
class="topo-line-arrow"
|
||||
markerUnits="strokeWidth"
|
||||
markerWidth="8"
|
||||
markerHeight="8"
|
||||
@ -95,6 +98,7 @@ limitations under the License. -->
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
<div id="tooltip">test tooltip</div>
|
||||
</div>
|
||||
<el-popover placement="bottom" :width="295" trigger="click">
|
||||
<template #reference>
|
||||
@ -145,12 +149,10 @@ const networkProfilingStore = useNetworkProfilingStore();
|
||||
const height = ref<number>(100);
|
||||
const width = ref<number>(100);
|
||||
const chart = ref<Nullable<HTMLDivElement>>(null);
|
||||
const tip = ref<Nullable<HTMLDivElement>>(null);
|
||||
const graph = ref<any>(null);
|
||||
const node = ref<any>(null);
|
||||
const link = ref<any>(null);
|
||||
const anchor = ref<any>(null);
|
||||
const arrow = ref<any>(null);
|
||||
const tooltip = ref<Nullable<any>>(null);
|
||||
const svg = ref<Nullable<any>>(null);
|
||||
const graph = ref<Nullable<any>>(null);
|
||||
const tip = ref<Nullable<any>>(null);
|
||||
const oldVal = ref<{ width: number; height: number }>({ width: 0, height: 0 });
|
||||
const config = ref<any>(props.config || {});
|
||||
const diff = ref<number[]>([220, 200]);
|
||||
@ -167,10 +169,12 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
async function init() {
|
||||
// svg.value = d3.select(chart.value).append("svg").attr("class", "process-svg");
|
||||
if (!networkProfilingStore.nodes.length) {
|
||||
return;
|
||||
}
|
||||
svg.value = d3.select(".process-svg");
|
||||
graph.value = d3.select(".svg-graph");
|
||||
tooltip.value = d3.select("#tooltip");
|
||||
freshNodes();
|
||||
useThrottleFn(resize, 500)();
|
||||
}
|
||||
@ -182,6 +186,10 @@ function drawGraph() {
|
||||
};
|
||||
height.value = (dom.height || 40) - 20;
|
||||
width.value = dom.width;
|
||||
diff.value[0] = (dom.width - radius * 2) / 2 + radius;
|
||||
tip.value = (d3tip as any)().attr("class", "d3-tip").offset([-8, 0]);
|
||||
graph.value.call(tip.value);
|
||||
svg.value.call(zoom(d3, graph.value, diff.value));
|
||||
}
|
||||
|
||||
function clickTopology(event: any) {
|
||||
@ -418,7 +426,7 @@ function resize() {
|
||||
}
|
||||
|
||||
async function freshNodes() {
|
||||
d3.select("svg-graph").remove();
|
||||
// d3.select(".svg-graph").remove();
|
||||
if (!networkProfilingStore.nodes.length) {
|
||||
return;
|
||||
}
|
||||
@ -426,6 +434,18 @@ async function freshNodes() {
|
||||
createLayout();
|
||||
}
|
||||
|
||||
function showNodeTip(d: any) {
|
||||
const tipHtml = ` <div class="mb-5"><span class="grey">name: </span>${d.name}</div>`;
|
||||
tooltip.value
|
||||
.style("top", d.y + diff.value[1] - 30 + "px")
|
||||
.style("left", d.x + diff.value[0] - 20 + "px");
|
||||
tooltip.value.style("visibility", "visible");
|
||||
}
|
||||
|
||||
function hideNodeTip() {
|
||||
tooltip.value.style("visibility", "hidden");
|
||||
}
|
||||
|
||||
watch(
|
||||
() => networkProfilingStore.nodes,
|
||||
() => {
|
||||
@ -495,4 +515,9 @@ watch(
|
||||
.query {
|
||||
margin-left: 510px;
|
||||
}
|
||||
|
||||
#tooltip {
|
||||
position: absolute;
|
||||
visibility: hidden;
|
||||
}
|
||||
</style>
|
||||
|
Loading…
Reference in New Issue
Block a user