From 8b54498236297ab55aca12d22171c96c416535cb Mon Sep 17 00:00:00 2001 From: Qiuxia Fan Date: Thu, 10 Feb 2022 13:58:26 +0800 Subject: [PATCH] feat: add arrow marker --- src/store/modules/topology.ts | 1 - .../dashboard/related/topology/Graph.vue | 19 +++++++++------ .../related/topology/utils/linkElement.ts | 24 +++++++++++++++++++ 3 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts index ad057041..40a950ae 100644 --- a/src/store/modules/topology.ts +++ b/src/store/modules/topology.ts @@ -45,7 +45,6 @@ export const topologyStore = defineStore({ this.call = link; }, setTopology(data: { nodes: Node[]; calls: Call[] }) { - console.log(data); this.nodes = data.nodes; this.calls = data.calls; }, diff --git a/src/views/dashboard/related/topology/Graph.vue b/src/views/dashboard/related/topology/Graph.vue index 25c05c9e..b38568cc 100644 --- a/src/views/dashboard/related/topology/Graph.vue +++ b/src/views/dashboard/related/topology/Graph.vue @@ -23,7 +23,7 @@ import d3tip from "d3-tip"; import zoom from "./utils/zoom"; import { simulationInit, simulationSkip } from "./utils/simulation"; import nodeElement from "./utils/nodeElement"; -import { linkElement, anchorElement } from "./utils/linkElement"; +import { linkElement, anchorElement, arrowMarker } from "./utils/linkElement"; // import tool from "./utils/tool"; // import topoLegend from "./utils/legend"; import { Node, Call } from "@/types/topology"; @@ -53,6 +53,7 @@ const graph = ref(null); const node = ref(null); const link = ref(null); const anchor = ref(null); +const arrow = ref(null); const tools = ref(null); onMounted(async () => { @@ -76,6 +77,7 @@ onMounted(async () => { node.value = graph.value.append("g").selectAll(".topo-node"); link.value = graph.value.append("g").selectAll(".topo-line"); anchor.value = graph.value.append("g").selectAll(".topo-line-anchor"); + arrow.value = graph.value.append("g").selectAll(".topo-line-arrow"); svg.value.call(zoom(d3, graph.value)); // tools.value = tool(graph.value, [ // { icon: "API", click: handleGoEndpoint }, @@ -118,7 +120,7 @@ function ticked() { ); anchor.value.attr( "transform", - (d: any) => + (d: Call | any) => `translate(${(d.source.x + d.target.x) / 2}, ${ (d.target.y + d.source.y) / 2 - d.loopFactor * 45 })` @@ -150,8 +152,7 @@ function dragended(d: any) { } } function handleNodeClick(d: any) { - const { x, y, vx, vy, fx, fy, index, ...rest } = d; - topologyStore.setNode(rest); + topologyStore.setNode(d); topologyStore.setLink({}); } function handleLinkClick(event: any, d: any) { @@ -176,11 +177,11 @@ function update() { tip.value ).merge(node.value); // line element - link.value = link.value.data(topologyStore.calls, (d: any) => d.id); + link.value = link.value.data(topologyStore.calls, (d: Call) => d.id); link.value.exit().remove(); link.value = linkElement(link.value.enter()).merge(link.value); // anchorElement - anchor.value = anchor.value.data(topologyStore.calls, (d: any) => d.id); + anchor.value = anchor.value.data(topologyStore.calls, (d: Call) => d.id); anchor.value.exit().remove(); anchor.value = anchorElement( anchor.value.enter(), @@ -201,12 +202,16 @@ function update() { }, tip.value ).merge(anchor.value); + // arrow marker + arrow.value = arrow.value.data(topologyStore.calls, (d: Call) => d.id); + arrow.value.exit().remove(); + arrow.value = arrowMarker(arrow.value.enter()).merge(arrow.value); // force element simulation.value.nodes(topologyStore.nodes); simulation.value .force("link") .links(topologyStore.calls) - .id((d: any) => d.id); + .id((d: Call) => d.id); simulationSkip(d3, simulation.value, ticked); const loopMap: any = {}; for (let i = 0; i < topologyStore.calls.length; i++) { diff --git a/src/views/dashboard/related/topology/utils/linkElement.ts b/src/views/dashboard/related/topology/utils/linkElement.ts index 13bd3514..8f27d368 100644 --- a/src/views/dashboard/related/topology/utils/linkElement.ts +++ b/src/views/dashboard/related/topology/utils/linkElement.ts @@ -14,10 +14,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + export const linkElement = (graph: any) => { const linkEnter = graph .append("path") .attr("class", "topo-line") + // .attr("stroke-width", (d: { cpm: number }) => (d.cpm ? 8 : 2)) + .attr("marker-end", "url(#arrow)") .attr("stroke", (d: { cpm: number }) => d.cpm ? "#217EF25f" : "#6a6d7777" ); @@ -40,3 +43,24 @@ export const anchorElement = (graph: any, funcs: any, tip: any) => { }); 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", "6") + .attr("markerHeight", "6") + .attr("viewBox", "0 0 12 12") + .attr("refX", "5") + .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", (d: { cpm: number }) => (d.cpm ? "#217EF25f" : "#6a6d7777")); + return arrow; +};