mirror of
https://github.com/apache/skywalking-booster-ui.git
synced 2025-07-18 20:44:08 +00:00
feat: add graph tools
This commit is contained in:
parent
eb7426c3fe
commit
4b194a18f8
34
src/views/dashboard/related/topology/utils/icons.js
Executable file
34
src/views/dashboard/related/topology/utils/icons.js
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
const requireComponent = require.context("../../assets", false, /\.png$/);
|
||||||
|
|
||||||
|
const result = {};
|
||||||
|
function capitalizeFirstLetter(str) {
|
||||||
|
return str.toUpperCase();
|
||||||
|
}
|
||||||
|
function validateFileName(str) {
|
||||||
|
return (
|
||||||
|
/^\S+\.png$/.test(str) &&
|
||||||
|
str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) => capitalizeFirstLetter($1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
requireComponent.keys().forEach((filePath) => {
|
||||||
|
const componentConfig = requireComponent(filePath);
|
||||||
|
const fileName = validateFileName(filePath);
|
||||||
|
result[fileName] = componentConfig;
|
||||||
|
});
|
||||||
|
export default result;
|
42
src/views/dashboard/related/topology/utils/legend.js
Normal file
42
src/views/dashboard/related/topology/utils/legend.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/**
|
||||||
|
* 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 icons from "./icons";
|
||||||
|
|
||||||
|
export default function topoLegend(graph, clientHeight, clientWidth) {
|
||||||
|
for (const item of ["CUBE", "CUBEERROR"]) {
|
||||||
|
graph
|
||||||
|
.append("image")
|
||||||
|
.attr("width", 30)
|
||||||
|
.attr("height", 30)
|
||||||
|
.attr("x", clientWidth - (item === "CUBEERROR" ? 340 : 440))
|
||||||
|
.attr("y", clientHeight - 50)
|
||||||
|
.attr("xlink:href", () =>
|
||||||
|
item === "CUBEERROR" ? icons.CUBEERROR : icons.CUBE
|
||||||
|
);
|
||||||
|
graph
|
||||||
|
.append("text")
|
||||||
|
.attr("x", clientWidth - (item === "CUBEERROR" ? 310 : 410))
|
||||||
|
.attr("y", clientHeight - 30)
|
||||||
|
.text(() => {
|
||||||
|
return item === "CUBEERROR"
|
||||||
|
? "Unhealthy (Successful Rate < 95% and Traffic > 1 call/min)"
|
||||||
|
: "Healthy";
|
||||||
|
})
|
||||||
|
.style("fill", "#efeff1")
|
||||||
|
.style("font-size", "11px");
|
||||||
|
}
|
||||||
|
}
|
40
src/views/dashboard/related/topology/utils/linkElement.js
Normal file
40
src/views/dashboard/related/topology/utils/linkElement.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* 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 const linkElement = (graph) => {
|
||||||
|
const linkEnter = graph
|
||||||
|
.append("path")
|
||||||
|
.attr("class", "topo-line")
|
||||||
|
.attr("stroke", (d) => (d.cpm ? "#217EF25f" : "#6a6d7777"));
|
||||||
|
return linkEnter;
|
||||||
|
};
|
||||||
|
export const anchorElement = (graph, funcs, tip) => {
|
||||||
|
const linkEnter = graph
|
||||||
|
.append("circle")
|
||||||
|
.attr("class", "topo-line-anchor")
|
||||||
|
.attr("r", 5)
|
||||||
|
.attr("fill", (d) => (d.cpm ? "#217EF25f" : "#6a6d7777"))
|
||||||
|
.on("mouseover", function (d) {
|
||||||
|
tip.html(funcs.$tip).show(d, this);
|
||||||
|
})
|
||||||
|
.on("mouseout", function () {
|
||||||
|
tip.hide(this);
|
||||||
|
})
|
||||||
|
.on("click", (d) => {
|
||||||
|
funcs.handleLinkClick(d);
|
||||||
|
});
|
||||||
|
return linkEnter;
|
||||||
|
};
|
86
src/views/dashboard/related/topology/utils/nodeElement.js
Normal file
86
src/views/dashboard/related/topology/utils/nodeElement.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/**
|
||||||
|
* 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 icons from "./icons";
|
||||||
|
|
||||||
|
icons["KAFKA-CONSUMER"] = icons.KAFKA;
|
||||||
|
export default (d3, graph, tool, funcs, tip) => {
|
||||||
|
const nodeEnter = graph
|
||||||
|
.append("g")
|
||||||
|
.call(
|
||||||
|
d3
|
||||||
|
.drag()
|
||||||
|
.on("start", funcs.dragstart)
|
||||||
|
.on("drag", funcs.dragged)
|
||||||
|
.on("end", funcs.dragended)
|
||||||
|
)
|
||||||
|
.on("mouseover", function (d) {
|
||||||
|
tip.html((data) => `<div>${data.name}</div>`).show(d, this);
|
||||||
|
})
|
||||||
|
.on("mouseout", function () {
|
||||||
|
tip.hide(this);
|
||||||
|
})
|
||||||
|
.on("click", (d) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
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");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
nodeEnter
|
||||||
|
.append("image")
|
||||||
|
.attr("width", 49)
|
||||||
|
.attr("height", 49)
|
||||||
|
.attr("x", 2)
|
||||||
|
.attr("y", 10)
|
||||||
|
.attr("style", "cursor: move;")
|
||||||
|
.attr("xlink:href", (d) =>
|
||||||
|
d.sla < 95 && d.isReal && d.cpm > 1 ? icons.CUBEERROR : icons.CUBE
|
||||||
|
);
|
||||||
|
nodeEnter
|
||||||
|
.append("image")
|
||||||
|
.attr("width", 32)
|
||||||
|
.attr("height", 32)
|
||||||
|
.attr("x", 6)
|
||||||
|
.attr("y", -10)
|
||||||
|
.attr("style", "opacity: 0.5;")
|
||||||
|
.attr("xlink:href", icons.LOCAL);
|
||||||
|
nodeEnter
|
||||||
|
.append("image")
|
||||||
|
.attr("width", 18)
|
||||||
|
.attr("height", 18)
|
||||||
|
.attr("x", 13)
|
||||||
|
.attr("y", -7)
|
||||||
|
.attr("xlink:href", (d) =>
|
||||||
|
!d.type || d.type === "N/A"
|
||||||
|
? icons.UNDEFINED
|
||||||
|
: icons[d.type.toUpperCase().replace("-", "")]
|
||||||
|
);
|
||||||
|
nodeEnter
|
||||||
|
.append("text")
|
||||||
|
.attr("class", "topo-text")
|
||||||
|
.attr("text-anchor", "middle")
|
||||||
|
.attr("x", 22)
|
||||||
|
.attr("y", 70)
|
||||||
|
.text((d) =>
|
||||||
|
d.name.length > 20 ? `${d.name.substring(0, 20)}...` : d.name
|
||||||
|
);
|
||||||
|
return nodeEnter;
|
||||||
|
};
|
51
src/views/dashboard/related/topology/utils/simulation.js
Normal file
51
src/views/dashboard/related/topology/utils/simulation.js
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/**
|
||||||
|
* 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 const simulationInit = (d3, data_nodes, data_links, ticked) => {
|
||||||
|
const simulation = d3
|
||||||
|
.forceSimulation(data_nodes)
|
||||||
|
.force(
|
||||||
|
"collide",
|
||||||
|
d3.forceCollide().radius(() => 60)
|
||||||
|
)
|
||||||
|
.force("yPos", d3.forceY().strength(1))
|
||||||
|
.force("xPos", d3.forceX().strength(1))
|
||||||
|
.force("charge", d3.forceManyBody().strength(-520))
|
||||||
|
.force(
|
||||||
|
"link",
|
||||||
|
d3.forceLink(data_links).id((d) => d.id)
|
||||||
|
)
|
||||||
|
.force(
|
||||||
|
"center",
|
||||||
|
d3.forceCenter(window.innerWidth / 2, window.innerHeight / 2 - 20)
|
||||||
|
)
|
||||||
|
.on("tick", ticked)
|
||||||
|
.stop();
|
||||||
|
simulationSkip(d3, simulation, ticked);
|
||||||
|
return simulation;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const simulationSkip = (d3, simulation, ticked) => {
|
||||||
|
d3.timeout(() => {
|
||||||
|
const n = Math.ceil(
|
||||||
|
Math.log(simulation.alphaMin()) / Math.log(1 - simulation.alphaDecay())
|
||||||
|
);
|
||||||
|
for (let i = 0; i < n; i += 1) {
|
||||||
|
simulation.tick();
|
||||||
|
ticked();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
70
src/views/dashboard/related/topology/utils/tool.js
Normal file
70
src/views/dashboard/related/topology/utils/tool.js
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
const requireComponent = require.context("./tool", false, /\.png$/);
|
||||||
|
|
||||||
|
const icons = {};
|
||||||
|
function capitalizeFirstLetter(str) {
|
||||||
|
return str.toUpperCase();
|
||||||
|
}
|
||||||
|
function validateFileName(str) {
|
||||||
|
return (
|
||||||
|
/^\S+\.png$/.test(str) &&
|
||||||
|
str.replace(/^\S+\/(\w+)\.png$/, (rs, $1) => capitalizeFirstLetter($1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
requireComponent.keys().forEach((filePath) => {
|
||||||
|
const componentConfig = requireComponent(filePath);
|
||||||
|
const fileName = validateFileName(filePath);
|
||||||
|
icons[fileName] = componentConfig;
|
||||||
|
});
|
||||||
|
|
||||||
|
const Hexagon = (side, r, cx, cy) => {
|
||||||
|
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;
|
||||||
|
path += !i ? `M${x},${y} ` : `L${x},${y} `;
|
||||||
|
if (i == side - 1) path += "Z";
|
||||||
|
}
|
||||||
|
return path;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (graph, data) => {
|
||||||
|
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 tool_g = tool
|
||||||
|
.append("g")
|
||||||
|
.attr("class", "topo-tool-i")
|
||||||
|
.on("click", data[i].click);
|
||||||
|
tool_g
|
||||||
|
.append("path")
|
||||||
|
.attr("class", "tool-hexagon")
|
||||||
|
.attr("d", Hexagon(6, 17, x, y));
|
||||||
|
tool_g
|
||||||
|
.append("svg:image")
|
||||||
|
.attr("width", 14)
|
||||||
|
.attr("height", 14)
|
||||||
|
.attr("x", x - 7)
|
||||||
|
.attr("y", y - 7)
|
||||||
|
.attr("style", "opacity: 0.8")
|
||||||
|
.attr("xlink:href", icons[data[i].icon]);
|
||||||
|
}
|
||||||
|
return tool;
|
||||||
|
};
|
BIN
src/views/dashboard/related/topology/utils/tool/ALARM.png
Normal file
BIN
src/views/dashboard/related/topology/utils/tool/ALARM.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.8 KiB |
BIN
src/views/dashboard/related/topology/utils/tool/API.png
Normal file
BIN
src/views/dashboard/related/topology/utils/tool/API.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
BIN
src/views/dashboard/related/topology/utils/tool/ENDPOINT.png
Normal file
BIN
src/views/dashboard/related/topology/utils/tool/ENDPOINT.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
BIN
src/views/dashboard/related/topology/utils/tool/INSTANCE.png
Normal file
BIN
src/views/dashboard/related/topology/utils/tool/INSTANCE.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.7 KiB |
BIN
src/views/dashboard/related/topology/utils/tool/TRACE.png
Normal file
BIN
src/views/dashboard/related/topology/utils/tool/TRACE.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
26
src/views/dashboard/related/topology/utils/zoom.js
Normal file
26
src/views/dashboard/related/topology/utils/zoom.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/**
|
||||||
|
* 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 default (d3, graph) =>
|
||||||
|
d3
|
||||||
|
.zoom()
|
||||||
|
.scaleExtent([0.3, 10])
|
||||||
|
.on("zoom", () => {
|
||||||
|
graph.attr(
|
||||||
|
"transform",
|
||||||
|
`translate(${d3.event.transform.x},${d3.event.transform.y})scale(${d3.event.transform.k})`
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user