mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-05-13 08:17:33 +00:00
feat: drag nodes
This commit is contained in:
parent
01feb349be
commit
1fdfdd5e0d
@ -23,14 +23,16 @@ limitations under the License. -->
|
|||||||
<svg ref="svg" :width="width - 100" :height="height" style="background-color: #fff" @click="svgEvent">
|
<svg ref="svg" :width="width - 100" :height="height" style="background-color: #fff" @click="svgEvent">
|
||||||
<g :style="`transform: translate(${(width - graphWidth - 100) / 2}px, 100px)`">
|
<g :style="`transform: translate(${(width - graphWidth - 100) / 2}px, 100px)`">
|
||||||
<g
|
<g
|
||||||
|
class="topo-node"
|
||||||
v-for="(n, index) in topologyLayout.nodes"
|
v-for="(n, index) in topologyLayout.nodes"
|
||||||
:key="index"
|
:key="index"
|
||||||
@mouseout="hideTip"
|
@mouseout="hideTip"
|
||||||
@mouseover="showNodeTip($event, n)"
|
@mouseover="showNodeTip($event, n)"
|
||||||
@click="handleNodeClick($event, n)"
|
@click="handleNodeClick($event, n)"
|
||||||
class="topo-node"
|
@mousedown="startMoveNode($event, n)"
|
||||||
|
@mouseup="stopMoveNode($event)"
|
||||||
>
|
>
|
||||||
<circle class="node" r="18" stroke-width="6" :stroke="getNodeStatus(n)" fill="none" :cx="n.x" :cy="n.y" />
|
<circle class="node" fill="#fff" r="18" stroke-width="6" :stroke="getNodeStatus(n)" :cx="n.x" :cy="n.y" />
|
||||||
<image
|
<image
|
||||||
width="18"
|
width="18"
|
||||||
height="18"
|
height="18"
|
||||||
@ -145,7 +147,7 @@ limitations under the License. -->
|
|||||||
import { aggregation } from "@/hooks/useMetricsProcessor";
|
import { aggregation } from "@/hooks/useMetricsProcessor";
|
||||||
import icons from "@/assets/img/icons";
|
import icons from "@/assets/img/icons";
|
||||||
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
|
import { useQueryTopologyMetrics } from "@/hooks/useMetricsProcessor";
|
||||||
import { layout } from "./utils/layout";
|
import { layout, circleIntersection } from "./utils/layout";
|
||||||
|
|
||||||
/*global Nullable, defineProps */
|
/*global Nullable, defineProps */
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@ -173,6 +175,7 @@ limitations under the License. -->
|
|||||||
const topologyLayout = ref<any>({});
|
const topologyLayout = ref<any>({});
|
||||||
const tooltip = ref<Nullable<any>>(null);
|
const tooltip = ref<Nullable<any>>(null);
|
||||||
const graphWidth = ref<number>(100);
|
const graphWidth = ref<number>(100);
|
||||||
|
const currentNode = ref<Nullable<Node>>();
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
await nextTick();
|
await nextTick();
|
||||||
@ -254,6 +257,57 @@ limitations under the License. -->
|
|||||||
}
|
}
|
||||||
topologyLayout.value = layout(levels, topologyStore.calls);
|
topologyLayout.value = layout(levels, topologyStore.calls);
|
||||||
graphWidth.value = topologyLayout.value.layout.width;
|
graphWidth.value = topologyLayout.value.layout.width;
|
||||||
|
const drag: any = d3.drag().on("drag", (d: { x: number; y: number }) => {
|
||||||
|
moveNode(d);
|
||||||
|
});
|
||||||
|
setTimeout(() => {
|
||||||
|
d3.selectAll(".node").call(drag);
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
function moveNode(d: { x: number; y: number }) {
|
||||||
|
if (!currentNode.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (const node of topologyLayout.value.nodes) {
|
||||||
|
if (node.id === currentNode.value.id) {
|
||||||
|
node.x = d.x;
|
||||||
|
node.y = d.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const call of topologyLayout.value.calls) {
|
||||||
|
if (call.sourceObj.id === currentNode.value.id) {
|
||||||
|
call.sourceObj.x = d.x;
|
||||||
|
call.sourceObj.y = d.y;
|
||||||
|
}
|
||||||
|
if (call.targetObj.id === currentNode.value.id) {
|
||||||
|
call.targetObj.x = d.x;
|
||||||
|
call.targetObj.y = d.y;
|
||||||
|
}
|
||||||
|
if (call.targetObj.id === currentNode.value.id || call.sourceObj.id === currentNode.value.id) {
|
||||||
|
const pos: any = circleIntersection(
|
||||||
|
call.sourceObj.x,
|
||||||
|
call.sourceObj.y,
|
||||||
|
18,
|
||||||
|
call.targetObj.x,
|
||||||
|
call.targetObj.y,
|
||||||
|
18,
|
||||||
|
);
|
||||||
|
call.sourceX = pos[0].x;
|
||||||
|
call.sourceY = pos[0].y;
|
||||||
|
call.targetX = pos[1].x;
|
||||||
|
call.targetY = pos[1].y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function startMoveNode(event: MouseEvent, d: Node) {
|
||||||
|
event.stopPropagation();
|
||||||
|
currentNode.value = d;
|
||||||
|
}
|
||||||
|
function stopMoveNode(event: MouseEvent) {
|
||||||
|
event.stopPropagation();
|
||||||
|
currentNode.value = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function findMostFrequent(arr: Call[]) {
|
function findMostFrequent(arr: Call[]) {
|
||||||
|
@ -59,6 +59,19 @@ export function layout(levels: Node[][], calls: any[]) {
|
|||||||
call.targetX = pos[1].x;
|
call.targetX = pos[1].x;
|
||||||
call.targetY = pos[1].y;
|
call.targetY = pos[1].y;
|
||||||
}
|
}
|
||||||
|
// for (const call of calls) {
|
||||||
|
// for (const link of calls) {
|
||||||
|
// if (
|
||||||
|
// (call.id !== link.id && call.sourceX === link.targetX && call.sourceY === link.targetY) ||
|
||||||
|
// (call.id !== link.id && call.targetX === link.sourceX && call.targetY === link.sourceY)
|
||||||
|
// ) {
|
||||||
|
// call.sourceX += 10;
|
||||||
|
// link.targetX -= 10;
|
||||||
|
// call.sourceY += 10;
|
||||||
|
// link.targetY -= 10;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
const layout = {
|
const layout = {
|
||||||
width: d3.max(nodes, (n: { x: number }) => n.x) || 0 + node_width + 2 * padding,
|
width: d3.max(nodes, (n: { x: number }) => n.x) || 0 + node_width + 2 * padding,
|
||||||
height: d3.max(nodes, (n: { y: number }) => n.y) || 0 + node_height / 2 + 2 * padding,
|
height: d3.max(nodes, (n: { y: number }) => n.y) || 0 + node_height / 2 + 2 * padding,
|
||||||
@ -67,7 +80,7 @@ export function layout(levels: Node[][], calls: any[]) {
|
|||||||
return { nodes, layout, calls };
|
return { nodes, layout, calls };
|
||||||
}
|
}
|
||||||
|
|
||||||
function circleIntersection(ax: number, ay: number, ar: number, bx: number, by: number, br: number) {
|
export function circleIntersection(ax: number, ay: number, ar: number, bx: number, by: number, br: number) {
|
||||||
const dab = Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));
|
const dab = Math.sqrt(Math.pow(ax - bx, 2) + Math.pow(ay - by, 2));
|
||||||
|
|
||||||
const dfx = (ar * Math.abs(ax - bx)) / dab;
|
const dfx = (ar * Math.abs(ax - bx)) / dab;
|
||||||
|
Loading…
Reference in New Issue
Block a user