I'm trying to visualize the data coming through the API with Sigma.JS, but I can't always get results. When I tried to visualize the dynamic incoming data without mock data by writing a simple API with Flask, it worked, but this data is slightly different from the real JSON data of the project, I can't integrate the new incoming data, although I took custom rendering as an example, I couldn't solve it. I will be leaving the JSON data I will be using below. In the nodes section, the JSON data is divided into two groups according to the y index in the form of attacker and destination, think of them as SIEM logs. ip is available in the id section, attackType in the label section
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Sigma.js Example</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/sigma.js/2.4.0/sigma.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/graphology/0.25.4/graphology.umd.min.js"></script>
<style>
#container {
width: 100%;
height: 100vh;
background: white;
}
</style>
</head>
<body>
<div id="container"></div>
<script>
const graph = new graphology.Graph();
function shuffleArray(array) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
}
async function fetchAttackTypes() {
try {
const response = await fetch('http://127.0.0.1:5000/data');
const data = await response.json();
return data.attackTypes;
} catch (error) {
console.error('Error:', error);
return [];
}
}
async function renderGraph() {
const attackTypes = await fetchAttackTypes();
shuffleArray(attackTypes);
attackTypes.forEach((type, index) => {
const angle = index * (2 * Math.PI / attackTypes.length);
const x = 200 * Math.cos(angle);
const y = 200 * Math.sin(angle);
graph.addNode(type, { label: type, x, y, size: 10, color: '#00f' });
});
attackTypes.forEach(type => {
const otherNodes = attackTypes.filter(otherType => otherType !== type);
const hasConnections = graph.neighbors(type).length > 0;
if (!hasConnections) {
const randomIndex = Math.floor(Math.random() * otherNodes.length);
const randomType = otherNodes[randomIndex];
graph.addEdge(type, randomType, { color: '#f00' });
}
});
const sigmaInstance = new Sigma(graph, document.getElementById("container"));
sigmaInstance.on('overNode', function(e) {
e.data.node.color = '#f00';
e.data.node.size *= 2;
sigmaInstance.refresh();
});
sigmaInstance.on('outNode', function(e) {
e.data.node.color = '#00f';
e.data.node.size /= 2;
sigmaInstance.refresh();
});
}
renderGraph();
</script>
</body>
</html>
nodes.json
"nodes": [
{
"color": "blue",
"id": "59.166.0.9",
"label": Exploit,
"size": 10,
"x": 0,
"y": 0
},
{
"color": "blue",
"id": "149.171.126.1",
"label": Fuzzing,
"size": 10,
"x": 0,
"y": 0
},
{
"color": "blue",
"id": "59.166.0.2",
"label": NaN,
"size": 10,
"x": 0,
"y": 1
},
{
"color": "blue",
"id": "149.171.126.7",
"label": NaN,
"size": 10,
"x": 0,
"y": 1
},
{
"color": "blue",
"id": "59.166.0.9",
"label": NaN,
"size": 10,
"x": 0,
"y": 2
},
{
"color": "blue",
"id": "149.171.126.4",
"label": NaN,
"size": 10,
"x": 0,
"y": 2
},
{
"color": "blue",
"id": "59.166.0.0",
"label": NaN,
"size": 10,
"x": 0,
"y": 3
},
{
"color": "blue",
"id": "149.171.126.3",
"label": NaN,
"size": 10,
"x": 0,
"y": 3
}
]
edges.json
"edges": [
{
"color": "purple",
"id": "e1_1000",
"size": 5,
"source": "175.45.176.1",
"target": "149.171.126.10"
},
{
"color": "purple",
"id": "e1_1001",
"size": 5,
"source": "175.45.176.1",
"target": "149.171.126.10"
},
{
"color": "purple",
"id": "e1_1002",
"size": 5,
"source": "175.45.176.0",
"target": "149.171.126.14"
},
{
"color": "purple",
"id": "e1_1003",
"size": 5,
"source": "149.171.126.18",
"target": "175.45.176.3"
},
{
"color": "purple",
"id": "e1_1004",
"size": 5,
"source": "149.171.126.18",
"target": "175.45.176.3"
},
]
Image of the code I wrote while it is running:

I need to show the incoming data:

Processing the data sent as JSON in the backend
graph_data = {"nodes": [], "edges": []}
def update_graph_data():
global graph_data
data_iterator = load_data()
for i, data in enumerate(data_iterator):
for index, row in data.iterrows():
if row['attack_cat'] != "nan":
graph_data["nodes"].append({"id": row['srcip'], "label": row['attack_cat'], "x": i, "y": index, "size": 10, "color": "blue"})
graph_data["nodes"].append({"id": row['dstip'], "label": row['attack_cat'], "x": i, "y": index, "size": 10, "color": "blue"})
if i > 0:
graph_data["edges"].append({"id": f"e{i}_{index}", "source": row['srcip'], "target": row['dstip'], "size": 5, "color": "purple"})
time.sleep(1)