mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-04 17: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.calls = calls;
|
||||||
this.nodes = data.nodes;
|
this.nodes = data.nodes;
|
||||||
console.log(calls);
|
|
||||||
},
|
},
|
||||||
async createNetworkTask(param: {
|
async createNetworkTask(param: {
|
||||||
serviceId: string;
|
serviceId: string;
|
||||||
|
@ -17,64 +17,6 @@
|
|||||||
import icons from "@/assets/img/icons";
|
import icons from "@/assets/img/icons";
|
||||||
import { Call } from "@/types/topology";
|
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
|
// Control Point coordinates of quadratic Bezier curve
|
||||||
function computeControlPoint(ps: number[], pe: number[], arc = 0.5) {
|
function computeControlPoint(ps: number[], pe: number[], arc = 0.5) {
|
||||||
const deltaX = pe[0] - ps[0];
|
const deltaX = pe[0] - ps[0];
|
||||||
@ -106,13 +48,18 @@ function quadraticBezier(
|
|||||||
return [x, y];
|
return [x, y];
|
||||||
}
|
}
|
||||||
export function getMidpoint(d: Call) {
|
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(
|
const controlPos = computeControlPoint(
|
||||||
[d.source.x, d.source.y],
|
[d.source.x, d.source.y],
|
||||||
[d.target.x, d.target.y],
|
[d.target.x, d.target.y],
|
||||||
0.5
|
0.5
|
||||||
);
|
);
|
||||||
if (d.lowerArc) {
|
if (d.lowerArc) {
|
||||||
console.log(true);
|
|
||||||
controlPos[1] = -controlPos[1];
|
controlPos[1] = -controlPos[1];
|
||||||
}
|
}
|
||||||
const p = quadraticBezier(
|
const p = quadraticBezier(
|
||||||
@ -124,6 +71,12 @@ export function getMidpoint(d: Call) {
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
export function linkPath(d: Call) {
|
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(
|
const controlPos = computeControlPoint(
|
||||||
[d.source.x, d.source.y - 5],
|
[d.source.x, d.source.y - 5],
|
||||||
[d.target.x, d.target.y - 5],
|
[d.target.x, d.target.y - 5],
|
||||||
|
@ -33,7 +33,13 @@ limitations under the License. -->
|
|||||||
</text>
|
</text>
|
||||||
</g>
|
</g>
|
||||||
<g class="nodes">
|
<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
|
<image
|
||||||
:href="icons.CUBE"
|
:href="icons.CUBE"
|
||||||
style="cursor: 'move'"
|
style="cursor: 'move'"
|
||||||
@ -56,7 +62,7 @@ limitations under the License. -->
|
|||||||
v-for="(call, index) in networkProfilingStore.calls"
|
v-for="(call, index) in networkProfilingStore.calls"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="topo-call"
|
class="topo-call"
|
||||||
markerEnd="url(#arrow)"
|
marker-end="url(#arrow)"
|
||||||
stroke="#97B0F8"
|
stroke="#97B0F8"
|
||||||
:d="linkPath(call)"
|
:d="linkPath(call)"
|
||||||
/>
|
/>
|
||||||
@ -71,16 +77,13 @@ limitations under the License. -->
|
|||||||
height="15"
|
height="15"
|
||||||
:x="getMidpoint(call)[0] - 8"
|
:x="getMidpoint(call)[0] - 8"
|
||||||
:y="getMidpoint(call)[1] - 13"
|
:y="getMidpoint(call)[1] - 13"
|
||||||
|
@click="handleLinkClick($event, call)"
|
||||||
/>
|
/>
|
||||||
</g>
|
</g>
|
||||||
<g class="arrows">
|
<g class="arrows">
|
||||||
<defs
|
<defs v-for="(_, index) in networkProfilingStore.calls" :key="index">
|
||||||
v-for="(call, index) in networkProfilingStore.calls"
|
|
||||||
:key="index"
|
|
||||||
>
|
|
||||||
<marker
|
<marker
|
||||||
id="arrow"
|
id="arrow"
|
||||||
class="topo-line-arrow"
|
|
||||||
markerUnits="strokeWidth"
|
markerUnits="strokeWidth"
|
||||||
markerWidth="8"
|
markerWidth="8"
|
||||||
markerHeight="8"
|
markerHeight="8"
|
||||||
@ -95,6 +98,7 @@ limitations under the License. -->
|
|||||||
</g>
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
<div id="tooltip">test tooltip</div>
|
||||||
</div>
|
</div>
|
||||||
<el-popover placement="bottom" :width="295" trigger="click">
|
<el-popover placement="bottom" :width="295" trigger="click">
|
||||||
<template #reference>
|
<template #reference>
|
||||||
@ -145,12 +149,10 @@ const networkProfilingStore = useNetworkProfilingStore();
|
|||||||
const height = ref<number>(100);
|
const height = ref<number>(100);
|
||||||
const width = ref<number>(100);
|
const width = ref<number>(100);
|
||||||
const chart = ref<Nullable<HTMLDivElement>>(null);
|
const chart = ref<Nullable<HTMLDivElement>>(null);
|
||||||
const tip = ref<Nullable<HTMLDivElement>>(null);
|
const tooltip = ref<Nullable<any>>(null);
|
||||||
const graph = ref<any>(null);
|
const svg = ref<Nullable<any>>(null);
|
||||||
const node = ref<any>(null);
|
const graph = ref<Nullable<any>>(null);
|
||||||
const link = ref<any>(null);
|
const tip = ref<Nullable<any>>(null);
|
||||||
const anchor = ref<any>(null);
|
|
||||||
const arrow = ref<any>(null);
|
|
||||||
const oldVal = ref<{ width: number; height: number }>({ width: 0, height: 0 });
|
const oldVal = ref<{ width: number; height: number }>({ width: 0, height: 0 });
|
||||||
const config = ref<any>(props.config || {});
|
const config = ref<any>(props.config || {});
|
||||||
const diff = ref<number[]>([220, 200]);
|
const diff = ref<number[]>([220, 200]);
|
||||||
@ -167,10 +169,12 @@ onMounted(() => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
async function init() {
|
async function init() {
|
||||||
// svg.value = d3.select(chart.value).append("svg").attr("class", "process-svg");
|
|
||||||
if (!networkProfilingStore.nodes.length) {
|
if (!networkProfilingStore.nodes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
svg.value = d3.select(".process-svg");
|
||||||
|
graph.value = d3.select(".svg-graph");
|
||||||
|
tooltip.value = d3.select("#tooltip");
|
||||||
freshNodes();
|
freshNodes();
|
||||||
useThrottleFn(resize, 500)();
|
useThrottleFn(resize, 500)();
|
||||||
}
|
}
|
||||||
@ -182,6 +186,10 @@ function drawGraph() {
|
|||||||
};
|
};
|
||||||
height.value = (dom.height || 40) - 20;
|
height.value = (dom.height || 40) - 20;
|
||||||
width.value = dom.width;
|
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) {
|
function clickTopology(event: any) {
|
||||||
@ -418,7 +426,7 @@ function resize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function freshNodes() {
|
async function freshNodes() {
|
||||||
d3.select("svg-graph").remove();
|
// d3.select(".svg-graph").remove();
|
||||||
if (!networkProfilingStore.nodes.length) {
|
if (!networkProfilingStore.nodes.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -426,6 +434,18 @@ async function freshNodes() {
|
|||||||
createLayout();
|
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(
|
watch(
|
||||||
() => networkProfilingStore.nodes,
|
() => networkProfilingStore.nodes,
|
||||||
() => {
|
() => {
|
||||||
@ -495,4 +515,9 @@ watch(
|
|||||||
.query {
|
.query {
|
||||||
margin-left: 510px;
|
margin-left: 510px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#tooltip {
|
||||||
|
position: absolute;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
Loading…
Reference in New Issue
Block a user