diff --git a/src/store/modules/topology.ts b/src/store/modules/topology.ts
new file mode 100644
index 00000000..201311f4
--- /dev/null
+++ b/src/store/modules/topology.ts
@@ -0,0 +1,52 @@
+/**
+ * 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.
+ */
+import { defineStore } from "pinia";
+import { store } from "@/store";
+import { Node, Call } from "@/types/topology";
+
+interface TopologyState {
+ node: Node | null;
+ call: Call | null;
+ calls: Call[];
+ nodes: Node[];
+}
+
+export const topologyStore = defineStore({
+ id: "topology",
+ state: (): TopologyState => ({
+ calls: [],
+ nodes: [],
+ node: null,
+ call: null,
+ }),
+ actions: {
+ setNode(node: Node) {
+ this.node = node;
+ },
+ setLink(link: Call) {
+ this.call = link;
+ },
+ setTopology(nodes: Node[], links: Call[]) {
+ this.nodes = nodes;
+ this.calls = links;
+ },
+ },
+});
+
+export function useTopologyStore(): any {
+ return topologyStore(store);
+}
diff --git a/src/types/topology.d.ts b/src/types/topology.d.ts
new file mode 100644
index 00000000..eb419746
--- /dev/null
+++ b/src/types/topology.d.ts
@@ -0,0 +1,41 @@
+/**
+ * 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 interface Call {
+ avgResponseTime: number;
+ cpm: number;
+ isAlert: boolean;
+ source: string | any;
+ target: string | any;
+ id: string;
+ detectPoints: string[];
+ type?: string;
+ sourceObj?: any;
+}
+export interface Node {
+ apdex: number;
+ avgResponseTime: number;
+ cpm: number;
+ id: string;
+ isAlarm: boolean;
+ name: string;
+ numOfServer: number;
+ numOfServerAlarm: number;
+ numOfServiceAlarm: number;
+ sla: number;
+ type: string;
+ isReal: boolean;
+}
diff --git a/src/views/dashboard/Edit.vue b/src/views/dashboard/Edit.vue
index 10cb8759..a3c23d9a 100644
--- a/src/views/dashboard/Edit.vue
+++ b/src/views/dashboard/Edit.vue
@@ -31,7 +31,7 @@ limitations under the License. -->
:destroy-on-close="true"
@closed="dashboardStore.setTopology(false)"
>
- topology
+
@@ -41,6 +41,7 @@ import GridLayout from "./panel/Layout.vue";
// import { LayoutConfig } from "@/types/dashboard";
import Tool from "./panel/Tool.vue";
import ConfigEdit from "./configuration/ConfigEdit.vue";
+import Graph from "./related/topology/Graph.vue";
import { useDashboardStore } from "@/store/modules/dashboard";
import { useAppStoreWithOut } from "@/store/modules/app";
diff --git a/src/views/dashboard/related/topology/Graph.vue b/src/views/dashboard/related/topology/Graph.vue
index 380b6a36..20b896c5 100644
--- a/src/views/dashboard/related/topology/Graph.vue
+++ b/src/views/dashboard/related/topology/Graph.vue
@@ -13,9 +13,252 @@ 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. -->
-
+
+
diff --git a/src/views/dashboard/related/topology/utils/icons.js b/src/views/dashboard/related/topology/utils/icons.ts
similarity index 72%
rename from src/views/dashboard/related/topology/utils/icons.js
rename to src/views/dashboard/related/topology/utils/icons.ts
index 8c669f60..bfd40353 100755
--- a/src/views/dashboard/related/topology/utils/icons.js
+++ b/src/views/dashboard/related/topology/utils/icons.ts
@@ -16,19 +16,22 @@
*/
const requireComponent = require.context("../../assets", false, /\.png$/);
-const result = {};
-function capitalizeFirstLetter(str) {
+const result: { [key: string]: string } = {};
+function capitalizeFirstLetter(str: string) {
return str.toUpperCase();
}
-function validateFileName(str) {
- return (
- /^\S+\.png$/.test(str) &&
- str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) => capitalizeFirstLetter($1))
- );
+function validateFileName(str: string): string | undefined {
+ if (/^\S+\.png$/.test(str)) {
+ return str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) =>
+ capitalizeFirstLetter($1)
+ );
+ }
}
-requireComponent.keys().forEach((filePath) => {
+requireComponent.keys().forEach((filePath: string) => {
const componentConfig = requireComponent(filePath);
const fileName = validateFileName(filePath);
- result[fileName] = componentConfig;
+ if (fileName) {
+ result[fileName] = componentConfig;
+ }
});
export default result;
diff --git a/src/views/dashboard/related/topology/utils/legend.js b/src/views/dashboard/related/topology/utils/legend.ts
similarity index 93%
rename from src/views/dashboard/related/topology/utils/legend.js
rename to src/views/dashboard/related/topology/utils/legend.ts
index 7c075674..be34a06b 100644
--- a/src/views/dashboard/related/topology/utils/legend.js
+++ b/src/views/dashboard/related/topology/utils/legend.ts
@@ -16,7 +16,11 @@
*/
import icons from "./icons";
-export default function topoLegend(graph, clientHeight, clientWidth) {
+export default function topoLegend(
+ graph: any,
+ clientHeight: number,
+ clientWidth: number
+) {
for (const item of ["CUBE", "CUBEERROR"]) {
graph
.append("image")
diff --git a/src/views/dashboard/related/topology/utils/linkElement.js b/src/views/dashboard/related/topology/utils/linkElement.ts
similarity index 76%
rename from src/views/dashboard/related/topology/utils/linkElement.js
rename to src/views/dashboard/related/topology/utils/linkElement.ts
index c56c14d7..13bd3514 100644
--- a/src/views/dashboard/related/topology/utils/linkElement.js
+++ b/src/views/dashboard/related/topology/utils/linkElement.ts
@@ -14,26 +14,28 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export const linkElement = (graph) => {
+export const linkElement = (graph: any) => {
const linkEnter = graph
.append("path")
.attr("class", "topo-line")
- .attr("stroke", (d) => (d.cpm ? "#217EF25f" : "#6a6d7777"));
+ .attr("stroke", (d: { cpm: number }) =>
+ d.cpm ? "#217EF25f" : "#6a6d7777"
+ );
return linkEnter;
};
-export const anchorElement = (graph, funcs, tip) => {
+export const anchorElement = (graph: any, funcs: any, tip: any) => {
const linkEnter = graph
.append("circle")
.attr("class", "topo-line-anchor")
.attr("r", 5)
- .attr("fill", (d) => (d.cpm ? "#217EF25f" : "#6a6d7777"))
- .on("mouseover", function (d) {
+ .attr("fill", (d: { cpm: number }) => (d.cpm ? "#217EF25f" : "#6a6d7777"))
+ .on("mouseover", function (d: unknown) {
tip.html(funcs.$tip).show(d, this);
})
.on("mouseout", function () {
tip.hide(this);
})
- .on("click", (d) => {
+ .on("click", (d: unknown) => {
funcs.handleLinkClick(d);
});
return linkEnter;
diff --git a/src/views/dashboard/related/topology/utils/nodeElement.js b/src/views/dashboard/related/topology/utils/nodeElement.ts
similarity index 76%
rename from src/views/dashboard/related/topology/utils/nodeElement.js
rename to src/views/dashboard/related/topology/utils/nodeElement.ts
index c81136f8..30412892 100644
--- a/src/views/dashboard/related/topology/utils/nodeElement.js
+++ b/src/views/dashboard/related/topology/utils/nodeElement.ts
@@ -17,7 +17,7 @@
import icons from "./icons";
icons["KAFKA-CONSUMER"] = icons.KAFKA;
-export default (d3, graph, tool, funcs, tip) => {
+export default (d3: any, graph: any, tool: any, funcs: any, tip: any) => {
const nodeEnter = graph
.append("g")
.call(
@@ -27,22 +27,22 @@ export default (d3, graph, tool, funcs, tip) => {
.on("drag", funcs.dragged)
.on("end", funcs.dragended)
)
- .on("mouseover", function (d) {
- tip.html((data) => `
${data.name}
`).show(d, this);
+ .on("mouseover", function (d: any) {
+ tip.html((data: any) => `${data.name}
`).show(d, this);
})
.on("mouseout", function () {
tip.hide(this);
})
- .on("click", (d) => {
+ .on("click", (event: any, d: any) => {
event.stopPropagation();
- event.preventDefault();
- tool.attr("style", "display: none");
+ // event.preventDefault();
+ // tool.attr("style", "display: none");
funcs.handleNodeClick(d);
- if (d.isReal) {
- tool
- .attr("transform", `translate(${d.x},${d.y - 20})`)
- .attr("style", "display: block");
- }
+ // if (d.isReal) {
+ // tool
+ // .attr("transform", `translate(${d.x},${d.y - 20})`)
+ // .attr("style", "display: block");
+ // }
});
nodeEnter
.append("image")
@@ -51,7 +51,7 @@ export default (d3, graph, tool, funcs, tip) => {
.attr("x", 2)
.attr("y", 10)
.attr("style", "cursor: move;")
- .attr("xlink:href", (d) =>
+ .attr("xlink:href", (d: { isReal: number; sla: number; cpm: number }) =>
d.sla < 95 && d.isReal && d.cpm > 1 ? icons.CUBEERROR : icons.CUBE
);
nodeEnter
@@ -68,7 +68,7 @@ export default (d3, graph, tool, funcs, tip) => {
.attr("height", 18)
.attr("x", 13)
.attr("y", -7)
- .attr("xlink:href", (d) =>
+ .attr("xlink:href", (d: { type: string }) =>
!d.type || d.type === "N/A"
? icons.UNDEFINED
: icons[d.type.toUpperCase().replace("-", "")]
@@ -79,7 +79,7 @@ export default (d3, graph, tool, funcs, tip) => {
.attr("text-anchor", "middle")
.attr("x", 22)
.attr("y", 70)
- .text((d) =>
+ .text((d: { name: string }) =>
d.name.length > 20 ? `${d.name.substring(0, 20)}...` : d.name
);
return nodeEnter;
diff --git a/src/views/dashboard/related/topology/utils/simulation.js b/src/views/dashboard/related/topology/utils/simulation.ts
similarity index 86%
rename from src/views/dashboard/related/topology/utils/simulation.js
rename to src/views/dashboard/related/topology/utils/simulation.ts
index 58f37b4d..e05fbad1 100644
--- a/src/views/dashboard/related/topology/utils/simulation.js
+++ b/src/views/dashboard/related/topology/utils/simulation.ts
@@ -14,7 +14,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export const simulationInit = (d3, data_nodes, data_links, ticked) => {
+export const simulationInit = (
+ d3: any,
+ data_nodes: any,
+ dataLinks: any,
+ ticked: any
+) => {
const simulation = d3
.forceSimulation(data_nodes)
.force(
@@ -26,7 +31,7 @@ export const simulationInit = (d3, data_nodes, data_links, ticked) => {
.force("charge", d3.forceManyBody().strength(-520))
.force(
"link",
- d3.forceLink(data_links).id((d) => d.id)
+ d3.forceLink(dataLinks).id((d: { id: string }) => d.id)
)
.force(
"center",
@@ -38,7 +43,7 @@ export const simulationInit = (d3, data_nodes, data_links, ticked) => {
return simulation;
};
-export const simulationSkip = (d3, simulation, ticked) => {
+export const simulationSkip = (d3: any, simulation: any, ticked: any) => {
d3.timeout(() => {
const n = Math.ceil(
Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())
diff --git a/src/views/dashboard/related/topology/utils/tool.js b/src/views/dashboard/related/topology/utils/tool.ts
similarity index 69%
rename from src/views/dashboard/related/topology/utils/tool.js
rename to src/views/dashboard/related/topology/utils/tool.ts
index 98a9f81c..89ddd0a8 100644
--- a/src/views/dashboard/related/topology/utils/tool.js
+++ b/src/views/dashboard/related/topology/utils/tool.ts
@@ -15,40 +15,43 @@
* limitations under the License.
*/
const requireComponent = require.context("./tool", false, /\.png$/);
+const icons: { [key: string]: string } = {};
-const icons = {};
-function capitalizeFirstLetter(str) {
+function capitalizeFirstLetter(str: string) {
return str.toUpperCase();
}
-function validateFileName(str) {
- return (
- /^\S+\.png$/.test(str) &&
- str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) => capitalizeFirstLetter($1))
- );
+function validateFileName(str: string): string | undefined {
+ if (/^\S+\.png$/.test(str)) {
+ return str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) =>
+ capitalizeFirstLetter($1)
+ );
+ }
}
-requireComponent.keys().forEach((filePath) => {
+requireComponent.keys().forEach((filePath: string) => {
const componentConfig = requireComponent(filePath);
const fileName = validateFileName(filePath);
- icons[fileName] = componentConfig;
+ if (fileName) {
+ icons[fileName] = componentConfig;
+ }
});
-const Hexagon = (side, r, cx, cy) => {
+const Hexagon = (side: number, r: number, cx: number, cy: number) => {
let path = "";
for (let i = 0; i < side; i += 1) {
- let x = Math.cos(((2 / side) * i + 1 / side) * Math.PI) * r + cx;
- let y = -Math.sin(((2 / side) * i + 1 / side) * Math.PI) * r + cy;
+ const x = Math.cos(((2 / side) * i + 1 / side) * Math.PI) * r + cx;
+ const y = -Math.sin(((2 / side) * i + 1 / side) * Math.PI) * r + cy;
path += !i ? `M${x},${y} ` : `L${x},${y} `;
if (i == side - 1) path += "Z";
}
return path;
};
-export default (graph, data) => {
+export default (graph: any, data: any) => {
const tool = graph.append("g").attr("class", "topo-tool");
const side = 6;
for (let i = 0; i < data.length; i += 1) {
- let x = Math.cos((2 / side) * i * Math.PI) * 34;
- let y = -Math.sin((2 / side) * i * Math.PI) * 34;
+ const x = Math.cos((2 / side) * i * Math.PI) * 34;
+ const y = -Math.sin((2 / side) * i * Math.PI) * 34;
const tool_g = tool
.append("g")
.attr("class", "topo-tool-i")
diff --git a/src/views/dashboard/related/topology/utils/zoom.js b/src/views/dashboard/related/topology/utils/zoom.ts
similarity index 96%
rename from src/views/dashboard/related/topology/utils/zoom.js
rename to src/views/dashboard/related/topology/utils/zoom.ts
index f7046881..8a41d294 100644
--- a/src/views/dashboard/related/topology/utils/zoom.js
+++ b/src/views/dashboard/related/topology/utils/zoom.ts
@@ -14,7 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-export default (d3, graph) =>
+export default (d3: any, graph: any) =>
d3
.zoom()
.scaleExtent([0.3, 10])