Skip to content

[fix] Prevent Overlapping of Clusters in netjsongraph.js #171 #349

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 160 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
160 commits
Select commit Hold shift + click to select a range
38a34d4
Refactor CSS for consistency and clarity
cestercian Mar 1, 2025
5ad2983
Merge branch 'master' into master
cestercian Mar 5, 2025
f314caa
Create netjson-cluster-overlap.html
cestercian Mar 12, 2025
09005af
Update netjsongraph.util.js
cestercian Mar 12, 2025
02682ae
Merge branch 'master' of https://github.com/cestercian/netjsongraph.js
cestercian Mar 12, 2025
c02b4ad
Revert "Create netjson-cluster-overlap.html"
cestercian Mar 12, 2025
659b2d6
Reapply "Create netjson-cluster-overlap.html"
cestercian Mar 12, 2025
61fe412
Revert "Reapply "Create netjson-cluster-overlap.html""
cestercian Mar 12, 2025
ff949d7
Reapply "Reapply "Create netjson-cluster-overlap.html""
cestercian Mar 19, 2025
d62d97b
Update index.html
cestercian Mar 19, 2025
a84b1fe
Create netjson-cluster-overlap.html
cestercian Mar 19, 2025
cc0722d
Update netjson-cluster-overlap.html
cestercian Mar 20, 2025
ffc2a0c
Update index.html
cestercian Mar 20, 2025
61a9d91
Update index.html
cestercian Mar 22, 2025
87e82af
Merge branch 'master' into master
cestercian Mar 22, 2025
d3c5c82
Update netjson-cluster-overlap.html
cestercian Mar 22, 2025
882b22c
Update netjson-cluster-overlap.html
cestercian Mar 22, 2025
4579f8b
Update netjson-cluster-overlap.html
cestercian Mar 22, 2025
fc182c7
Update netjson-cluster-overlap.html
cestercian Mar 22, 2025
3f38efd
Update netjson-cluster-overlap.html
cestercian Mar 23, 2025
09f2814
Merge branch 'master' into master
nemesifier Mar 24, 2025
3c0e099
Update netjson-cluster-overlap.html
cestercian Mar 25, 2025
4deeb11
Update netjson-cluster-overlap.html
cestercian Mar 26, 2025
9a23460
Update netjson-cluster-overlap.html
cestercian Mar 26, 2025
9477fe2
Create clusterUtils.js
cestercian Mar 26, 2025
7c2359a
Update netjson-cluster-overlap.html
cestercian Mar 26, 2025
68d9cf9
Update README.md
cestercian Mar 26, 2025
662f6f8
Update README.md
cestercian Mar 26, 2025
52592f6
Update netjson-cluster-overlap.html
cestercian Mar 27, 2025
04679a3
Update .gitignore
cestercian Mar 27, 2025
1ac4463
Update netjson-cluster-overlap.html
cestercian Mar 27, 2025
f445098
Update netjsongraph.config.js
cestercian Mar 27, 2025
20ff2fa
Update netjson-cluster-overlap.html
cestercian Mar 27, 2025
0370da1
Merge branch 'master' into master
cestercian Apr 2, 2025
2206e70
[fix] Netjsongraph.js
cestercian Apr 3, 2025
47213da
[fix] Formatting
cestercian Apr 3, 2025
baa2a04
[fix] netjson-cluster-overlap.html
cestercian Apr 10, 2025
4d70d61
[fix] Netjson cluster overlap.html
cestercian Apr 10, 2025
1b42afd
Merge branch 'master' of https://github.com/cestercian/netjsongraph.js
cestercian Apr 10, 2025
3db782c
[fix] Netjson-cluster-overlap.html
cestercian Apr 10, 2025
1bbc178
Merge branch 'master' into master
cestercian Apr 11, 2025
3b1ad94
Update netjson-clustering.html
cestercian Apr 11, 2025
a287629
[fix] Clustering.html
cestercian Apr 11, 2025
8f8a394
[fix] Index.html
cestercian Apr 11, 2025
73d96c5
[fix] Gitignore
cestercian Apr 11, 2025
ce4313d
[fix] Readme.md
cestercian Apr 11, 2025
32d052c
Merge branch 'master' of https://github.com/cestercian/netjsongraph.js
cestercian Apr 11, 2025
9986a39
[fix] Merge master into feature-branch
cestercian Apr 11, 2025
26e5f67
Merge branch 'master' of https://github.com/cestercian/netjsongraph.js
cestercian Apr 11, 2025
3077a5c
[fix] Readme
cestercian Apr 11, 2025
664e8d4
[fix] Readme
cestercian Apr 12, 2025
8106dbd
[fix] Readme
cestercian Apr 12, 2025
63aaa20
[fix] Netjson-clustering.html
cestercian Apr 12, 2025
455aeb1
Merge branch 'master' into master
cestercian Apr 15, 2025
f4451e8
[fix] Netjson-clustering.html
cestercian Apr 17, 2025
737e393
Update netjsongraph.render.js
cestercian Apr 22, 2025
1656537
Update netjsongraph.config.js
cestercian Apr 22, 2025
c60ad0a
[fix] Netjsongraph.render.js
cestercian Apr 22, 2025
f9a5441
[fix] Netjsongraph.js
cestercian Apr 22, 2025
ce05edf
[fix] Netjsongraph.js
cestercian Apr 22, 2025
81a44b5
[fix] Netjsongraph.spec.js
cestercian Apr 22, 2025
6b6a604
[fix] Netjsongraph.spec.js
cestercian Apr 22, 2025
122fc12
[fix] Netjsongraph.js
cestercian Apr 22, 2025
71e004d
[fix] Netjsongraph.render.js
cestercian Apr 23, 2025
be2e4c6
Revert "[fix] Netjsongraph.render.js"
cestercian Apr 23, 2025
572155f
[fix] Netjsongraph.render.js
cestercian Apr 23, 2025
fd5b529
[change] Netjsongraph.js
cestercian Apr 23, 2025
46390b0
[fix] Formatting
cestercian Apr 23, 2025
d8e7ec6
[fix] Netjson-clustering.html
cestercian Apr 24, 2025
6b60948
[fix] Netjson-clustering.html
cestercian Apr 24, 2025
ab8af74
[change] Removed Comments
cestercian Apr 24, 2025
3a8fd56
[fix] Prettier
cestercian Apr 24, 2025
401de7f
[fix] Netjsongraph.config.js
cestercian Apr 26, 2025
09bc435
[fix] Prettier
cestercian Apr 26, 2025
f7acfcc
[fix] Netjsongraph.render.test.js
cestercian Apr 26, 2025
273f5ac
[fix] Netjsongraph.render.test.js
cestercian Apr 26, 2025
fd0e1bb
Revert "[fix] Netjsongraph.render.test.js"
cestercian Apr 26, 2025
8369683
[fix] Netjsongraph.render.test.js
cestercian Apr 26, 2025
f37ac79
[fix] Eslint
cestercian Apr 26, 2025
08681ff
Merge branch 'master' into master
cestercian May 3, 2025
a79eeec
[fix] Cluster-utlis.js
cestercian May 5, 2025
12b3437
[fix] Netjsongraph.render.js
cestercian May 5, 2025
250a437
[fix] Netjsongraph.render.js
cestercian May 10, 2025
0faba71
Merge branch 'master' into master
nemesifier May 16, 2025
a53f590
[change] Netjsongraph.util.js
cestercian May 26, 2025
cf06552
[change] Revert changes in Netjsongraph.util.js
cestercian May 27, 2025
c76b2d8
Merge branch 'master' into master
cestercian May 30, 2025
200d9f2
[fix] Cluster Overlap
cestercian Jun 2, 2025
c3146ef
Merge branch 'master' into master
cestercian Jun 3, 2025
52ddb86
[change] Refine Changes
cestercian Jun 3, 2025
036c042
[fix] Updated Test cases
cestercian Jun 4, 2025
3a05bc2
[fix] Prettier format
cestercian Jun 4, 2025
53188d8
[fix] Updated clustering logic
cestercian Jun 5, 2025
8c2a572
[fix] Update netjson-clustering.html
cestercian Jun 12, 2025
c8d82dd
[fix] Netjsongraph.util.js
cestercian Jun 12, 2025
ed6a30c
[fix] Zoom function on clicking clusters
cestercian Jun 16, 2025
41cfb93
[fix] Prettier
cestercian Jun 16, 2025
cd8c16d
[chores] Added inline comments
cestercian Jun 18, 2025
dd0cc05
[fix] Clustering logic
cestercian Jun 24, 2025
6b2c070
[change] Updated test cases for the new clustering logic
cestercian Jun 24, 2025
88b7d95
[fix] Qa-checks
cestercian Jun 24, 2025
7df045b
[fix] Qa-checks
cestercian Jun 24, 2025
96abea3
Merge branch 'master' into master
cestercian Jul 2, 2025
d84c9c0
[fix] Created JSON file for exteranl data
cestercian Jul 4, 2025
57fa156
[fix] Updated netjson-clustering.html
cestercian Jul 4, 2025
26cff99
[change] Streamlined map rendering logic
cestercian Jul 9, 2025
0fb5372
Revert "[change] Streamlined map rendering logic"
cestercian Jul 9, 2025
a0cfae4
[fix] Updated the Echarts rendering
cestercian Jul 10, 2025
597411a
[fix] Updated the Echarts rendering
cestercian Jul 10, 2025
77c295b
Merge Conflicts
cestercian Jul 10, 2025
f3a763b
Merge pull request #394 from cestercian/Streamline-Map-Rendering
cestercian Jul 10, 2025
761e8a2
[fix] Streamlining map rendering logic
cestercian Jul 10, 2025
22097e4
[fix] Updated Test Cases
cestercian Jul 14, 2025
59bf856
[fix] Removed Marker-Cluster Dependency
cestercian Jul 14, 2025
af548a7
Merge pull request #399 from cestercian/Uniform-GeoJSON-map-rendering
cestercian Jul 14, 2025
ddfdfc3
[fix] Removed Marker-Cluster Dependency
cestercian Jul 14, 2025
292643e
[fix] Uniform GeoJSON map rendering
cestercian Jul 14, 2025
8f8215d
[fix] Prettier fix
cestercian Jul 14, 2025
cd8c137
Merge pull request #400 from cestercian/Uniform-GeoJSON-map-rendering
cestercian Jul 14, 2025
3f4d8a4
Merge branch 'stramlining-map-rendering' into Streamline-Map-Rendering
cestercian Jul 16, 2025
860f7b8
Merge pull request #401 from cestercian/Streamline-Map-Rendering
cestercian Jul 16, 2025
b9cd9f3
[fix] Removed bloating of if conditions
cestercian Jul 16, 2025
33cf5cd
[fix] QA-checks and Test cases
cestercian Jul 16, 2025
b99c37a
[fix] Qa-checks again
cestercian Jul 16, 2025
ba95437
[fix] Test Coverage
cestercian Jul 16, 2025
adedbe8
[chores] Squashed all commits into one
cestercian Jul 17, 2025
bba47c5
Merge branch 'stramlining-map-rendering' of https://github.com/openwi…
cestercian Jul 17, 2025
48b36ae
[change] Uniform geojson map rendering
cestercian Jul 17, 2025
cbdd6b0
Merge branch 'stramlining-map-rendering' of https://github.com/openwi…
cestercian Jul 17, 2025
4aaecad
feat: Add node clustering in map view
cestercian Jul 17, 2025
7b2fb66
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 17, 2025
f73f161
[fix] QA-checks + yarn.lock changes
cestercian Jul 17, 2025
7adb7a1
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 18, 2025
08361a1
[fix] Changed Config to not show Label for test cases
cestercian Jul 18, 2025
e601fc7
[change] Refactor GeoJSON handling into dedicated module
cestercian Jul 21, 2025
1f8c0bb
[fix] Prettier
cestercian Jul 21, 2025
5d63609
[change] Preserve GeoJSON type in NetJSONGraph
cestercian Jul 22, 2025
03628ca
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 22, 2025
c7c21be
Merge branch 'master' of https://github.com/cestercian/netjsongraph.js
cestercian Jul 22, 2025
7cdb431
[fix] Add GeoJSON samples and refactor geometry handling
cestercian Jul 22, 2025
1d1baa3
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 22, 2025
746143b
Merge branch 'master' of https://github.com/cestercian/netjsongraph.js
cestercian Jul 22, 2025
2cf3441
Revert "[change] Preserve GeoJSON type in NetJSONGraph"
cestercian Jul 24, 2025
2dc36b4
[fix] Improve handling of node/link identities and UI display
cestercian Jul 24, 2025
e4d9471
[chores] Add map auto-fit fix linting
cestercian Jul 24, 2025
1d9696b
[changes] Improve map auto-fit to include polygons
cestercian Jul 24, 2025
99840f1
[Fix] Polygon bounds and add GeoJSON conversion tests
cestercian Jul 24, 2025
a5d99be
[fix] Refactor NetJSON type checks to use isNetJSON utility
cestercian Jul 24, 2025
58570b4
[chores] Update netjsongraph.render.js
cestercian Jul 24, 2025
3650c2c
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 24, 2025
8011b27
[chores] Update test node IDs and labels
cestercian Jul 27, 2025
ea99cb5
[fix] QA-checks
cestercian Jul 27, 2025
db7e856
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 27, 2025
3fd41b8
[change] PrepareData() call for Geojson
cestercian Jul 27, 2025
13b8c04
Merge branch 'stramlining-map-rendering' into master
cestercian Jul 27, 2025
02c50f9
[change] Improve clustering logic for non-Point features
cestercian Jul 28, 2025
39bfdbc
Merge branch 'master' into master
cestercian Jul 29, 2025
6724a85
[fix] Node category assignment and remove polygon rendering
cestercian Jul 29, 2025
758ba41
[chores] QA-checks
cestercian Jul 29, 2025
c04b323
[fix] Preserve GeoJSON feature IDs
cestercian Jul 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 153 additions & 0 deletions examples/netjson-cluster-overlap.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>NetJSON Cluster Overlap Example</title>
<meta name="description" content="NetJSON Cluster Overlap Example" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="stylesheet" href="../src/css/netjsongraph.css" />
<link rel="stylesheet" href="../src/css/netjsongraph-theme.css" />
<style>
body {
margin: 0;
padding: 0;
}
#legend {
position: fixed;
top: 10px;
right: 10px;
background: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 4px;
}
.status-ok, .status-problem, .status-critical {
display: inline-block;
width: 15px;
height: 15px;
margin-right: 5px;
border-radius: 50%;
}
.status-ok {
background-color: #1ba619;
}
.status-problem {
background-color: #ffa500;
}
.status-critical {
background-color: #c92517;
}
</style>
</head>
<body>
<script src="../dist/netjsongraph.min.js"></script>
<script type="text/javascript">
// Create test data with overlapping nodes of different statuses
const testData = {
type: "NetworkGraph",
label: "Cluster Overlap Test",
nodes: [
// Group 1 - Overlapping nodes with different statuses
{
id: "1",
name: "Node 1",
location: { lat: 45.4642, lng: 9.1900 },
properties: { status: "ok" }
},
{
id: "2",
name: "Node 2",
location: { lat: 45.4641, lng: 9.1901 },
properties: { status: "problem" }
},
{
id: "3",
name: "Node 3",
location: { lat: 45.4643, lng: 9.1902 },
properties: { status: "critical" }
},
// Group 2 - Another set of overlapping nodes
{
id: "4",
name: "Node 4",
location: { lat: 45.4742, lng: 9.1800 },
properties: { status: "ok" }
},
{
id: "5",
name: "Node 5",
location: { lat: 45.4741, lng: 9.1801 },
properties: { status: "problem" }
},
{
id: "6",
name: "Node 6",
location: { lat: 45.4743, lng: 9.1802 },
properties: { status: "critical" }
}
],
links: []
};

const map = new NetJSONGraph(testData, {
render: "map",
clustering: true,
clusteringThreshold: 2,
clusterRadius: 40,
clusteringAttribute: "status",
// Set map initial state
mapOptions: {
center: [45.4642, 9.1900],
zoom: 15,
nodeConfig: {
label: {
offset: [0, -10],
},
}
},
nodeCategories: [
{
name: "ok",
nodeStyle: {
color: "#1ba619"
}
},
{
name: "problem",
nodeStyle: {
color: "#ffa500"
}
},
{
name: "critical",
nodeStyle: {
color: "#c92517"
}
}
],
// Convert to internal json format
prepareData: (data) => {
data.nodes.forEach((node) => {
node.label = node.name;
node.properties = {
...node.properties,
location: node.location
};
});
}
});

// Create legend
const legend = document.createElement("div");
legend.id = "legend";
legend.innerHTML = `
<h4>Node Status</h4>
<p><span class="status-ok"></span> OK</p>
<p><span class="status-problem"></span> Problem</p>
<p><span class="status-critical"></span> Critical</p>
`;
document.body.appendChild(legend);

map.render();
</script>
</body>
</html>
9 changes: 7 additions & 2 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@
</head>
<body>
<button class="theme-toggle" aria-label="Toggle Dark Mode">
🌓 Toggle Theme
Toggle Theme
</button>

<header>
Expand Down Expand Up @@ -236,6 +236,11 @@ <h1>NetJSONGraph.js Example Demos</h1>
>Clustering</a
>
</div>
<div class="cards">
<a href="./examples/netjson-cluster-overlap.html" target="_blank">
Cluster Overlap Example
</a>
</div>
</main>

<script>
Expand All @@ -252,7 +257,7 @@ <h1>NetJSONGraph.js Example Demos</h1>

themeToggle.addEventListener('click', () => {
htmlElement.classList.toggle('dark-mode');

// Save theme preference
const currentTheme = htmlElement.classList.contains('dark-mode') ? 'dark' : 'light';
localStorage.setItem('theme', currentTheme);
Expand Down
212 changes: 212 additions & 0 deletions public/example_templates/netjson-cluster-overlap.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NetJSON Cluster Overlap Example</title>
<link rel="stylesheet" href="../../src/css/netjsongraph.css" />
<link rel="stylesheet" href="../../src/css/netjsongraph-theme.css" />
<style>
body {
margin: 0;
padding: 0;
}
#legend {
position: fixed;
top: 10px;
right: 10px;
background: rgba(255, 255, 255, 0.8);
padding: 10px;
border-radius: 4px;
}
.status-ok, .status-problem, .status-critical {
display: inline-block;
width: 15px;
height: 15px;
margin-right: 5px;
border-radius: 50%;
}
.status-ok {
background-color: #1ba619;
}
.status-problem {
background-color: #ffa500;
}
.status-critical {
background-color: #c92517;
}
</style>
</head>
<body>
<script src="../../dist/netjsongraph.min.js"></script>
<script type="text/javascript">
// Create test data with overlapping nodes of different statuses
const testData = {
type: "NetworkGraph",
label: "Cluster Overlap Test",
nodes: [
// Group 1 - Overlapping nodes with different statuses
{
id: "1",
name: "Node 1",
location: { lat: 45.4642, lng: 9.1900 },
properties: { status: "ok" }
},
{
id: "2",
name: "Node 2",
location: { lat: 45.4641, lng: 9.1901 },
properties: { status: "problem" }
},
{
id: "3",
name: "Node 3",
location: { lat: 45.4643, lng: 9.1902 },
properties: { status: "critical" }
},
// Group 2 - Another set of overlapping nodes
{
id: "4",
name: "Node 4",
location: { lat: 45.4742, lng: 9.1800 },
properties: { status: "ok" }
},
{
id: "5",
name: "Node 5",
location: { lat: 45.4741, lng: 9.1801 },
properties: { status: "problem" }
},
{
id: "6",
name: "Node 6",
location: { lat: 45.4743, lng: 9.1802 },
properties: { status: "critical" }
}
],
links: []
};

// Custom function to prevent cluster overlap by category
function preventClusterOverlap(map) {
// Store clusters by location
const clustersByLocation = {};

// Get all cluster markers
const clusterMarkers = document.querySelectorAll('.leaflet-marker-icon.marker-cluster');

clusterMarkers.forEach((marker, index) => {
// Get marker position
const left = parseInt(marker.style.left.replace('px', ''));
const top = parseInt(marker.style.top.replace('px', ''));
const key = `${left},${top}`;

// Initialize array for this location if it doesn't exist
if (!clustersByLocation[key]) {
clustersByLocation[key] = [];
}

// Add marker to the location array
clustersByLocation[key].push(marker);
});

// Offset overlapping clusters
Object.values(clustersByLocation).forEach(markers => {
if (markers.length > 1) {
// Calculate offset radius based on marker size
const radius = 30;

// Position markers in a circle around the original position
markers.forEach((marker, i) => {
const angle = (2 * Math.PI * i) / markers.length;
const offsetX = radius * Math.cos(angle);
const offsetY = radius * Math.sin(angle);

// Apply offset
const originalLeft = parseInt(marker.style.left.replace('px', ''));
const originalTop = parseInt(marker.style.top.replace('px', ''));

marker.style.left = `${originalLeft + offsetX}px`;
marker.style.top = `${originalTop + offsetY}px`;
});
}
});
}

const map = new NetJSONGraph(testData, {
render: "map",
clustering: true,
clusteringThreshold: 2,
clusterRadius: 40,
clusteringAttribute: "status",
// Set map initial state
mapOptions: {
center: [45.4642, 9.1900],
zoom: 15,
nodeConfig: {
label: {
offset: [0, -10],
},
}
},
nodeCategories: [
{
name: "ok",
nodeStyle: {
color: "#1ba619"
}
},
{
name: "problem",
nodeStyle: {
color: "#ffa500"
}
},
{
name: "critical",
nodeStyle: {
color: "#c92517"
}
}
],
// Convert to internal json format
prepareData: (data) => {
data.nodes.forEach((node) => {
node.label = node.name;
node.properties = {
...node.properties,
location: node.location
};
});
}
});

// Create legend
const legend = document.createElement("div");
legend.id = "legend";
legend.innerHTML = `
<h4>Node Status</h4>
<p><span class="status-ok"></span> OK</p>
<p><span class="status-problem"></span> Problem</p>
<p><span class="status-critical"></span> Critical</p>
`;
document.body.appendChild(legend);

map.render();

// Add event listener to apply our custom function after the map is fully rendered
map.echarts.on('rendered', function() {
setTimeout(() => {
preventClusterOverlap(map);
}, 500);
});

// Also apply when zooming or panning
map.echarts._api.getZr().on('mousemove', function() {
setTimeout(() => {
preventClusterOverlap(map);
}, 100);
});
</script>
</body>
</html>
Loading
Loading