Skip to content
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

Option to disable Physics #489

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from

Conversation

dremerb
Copy link
Contributor

@dremerb dremerb commented May 2, 2024

I wanted the option to disable physics, because with a bigger network it takes quite some time before things settle. Also organizing is not optimal, when devices do not have coordinates yet and start flying around when another is moved.
Unfortunately, simply disabling physics puts everything at (0, 0) by default.

So I got just overengineered some static clustering.
The idea is to find a random coordinate as a center point for each rack (using the rack name as a seed yields the same "random" coordinates for every rack) and adding a small random offset by using the (unique) device name as seed.
Currently there is two magic numbers (12 in line 218 and 2 in line 225/226). They scale the resulting graph.

image

I recognize the idea is a bit unorthodox, but I also think that having physics enabled by default is not great for larger networks.

Note: If you consider merging this, I think the commit should be squashed, as I initially had #488 as a single branch and split it into two PRs. This makes the history pretty ugly.

Copy link
Collaborator

@dreng dreng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have overlooked the saved filters.

api/views.py, line 112 and below
views.py, line 713 and below.

class Migration(migrations.Migration):

dependencies = [
('netbox_topology_views', '0007_individualoptions_group_locations_and_more'),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is problematic, because another PR lists this 0007 as a dependency. This one is no. 0009 and should depend on 0008.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, this happened because I was working on this PR and #488 in parallel. #488 contains a migration with index 0008, therefore this got 0009 and cannot depend on 0008, since it is on another branch.

I propose leaving this comment open until either #488 or this PR gets accepted and change it accordingly as a last step.

netbox_topology_views/utils.py Show resolved Hide resolved
@@ -177,7 +177,7 @@ def get_query_settings(request):
if "show_neighbors" in request.GET:
if request.GET["show_neighbors"] == "on" :
show_neighbors = True

return filter_id, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, show_neighbors
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_query_settings() has to be expanded with the new option(s).

required=False,
initial=False,
help_text=_('When enables, no forces will act on nodes in the topology and they will only move '
'when dragged by hand. Devices without coordinates will be places at (0, 0) by default.')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo: 'placed' instead of 'places'

@@ -109,7 +109,7 @@ def list(self, request):

if request.GET:

filter_id, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks,show_neighbors = get_query_settings(request)
filter_id, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, show_neighbors = get_query_settings(request)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You did actually nothing here except housekeeping. Please do not touch anything that does not belong to the PR. Otherwise there is more to review than necessary.

@@ -109,7 +109,7 @@ def list(self, request):

if request.GET:

filter_id, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks,show_neighbors = get_query_settings(request)
filter_id, save_coords, show_unconnected, show_power, show_circuit, show_logical_connections, show_single_cable_logical_conns, show_cables, show_wireless, group_sites, group_locations, group_racks, show_neighbors = get_query_settings(request)

# Read options from saved filters as NetBox does not handle custom plugin filters
if "filter_id" in request.GET and request.GET["filter_id"] != '':
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

get_query_settings() has to be expanded with the new option(s).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed, Github cannot figure it out because reasons.

# make seed unique for devices for spread
if hasattr(device, "rack"):
random.seed(device.name)
# spread devices around the rack center coordinates
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Randomization will probably lead to a different layout when exporting to XML. Have you tested that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, where previously all coordinates were (0, 0), they now are set to some values.
The diff between the export of "physics enabled" and "physics disabled" consists of all mxGeometry tags. When save_coordinates is enabled, the diff before and after moving a single node (and the same enabled/disabled setting for physics) is only one mxGeometry tag.

Re-rendering with disabled physics (hence with "random coordinates") yields the same file every time.

@dreng
Copy link
Collaborator

dreng commented May 3, 2024

Hi,

first of all, thank you for your contribution.

Which accepted FR do you close with this PR actually? If it's #436, that one is under review for a good reason. It is absolutely not clear how to implement the FR. You've made a solution that only fits your personals needs. We should always find solutions that fits everyones needs or discuss until we get to a good compromise.

else:
# draw devices clustered by their rack neighbours
# for center coordinates of a rack, use the rack name as seed (if available)
random.seed(device.rack.name if hasattr(device, "rack") else device.name)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
random.seed(device.rack.name if hasattr(device, "rack") else device.name)
random.seed(device.rack.name if hasattr(device, "rack") else device.site)

site is a mandatory field when creating a new Device. Also would remove the if in line 222, simply setting the new seed to device-name for all Devices.

@dremerb
Copy link
Contributor Author

dremerb commented May 6, 2024

This PR does not have a FR, I just wanted the option to disable physics, since in my graph it was a chore to organize the nodes when things were moving constantly. Of course that changes once you turn on "save coordinates", but that still requires every node to be selected/moved once.

#436 and #122 both touch the idea of disabling physics, but it is not their main focus as far as I understand.

You've made a solution that only fits your personals needs. We should always find solutions that fits everyones needs or discuss until we get to a good compromise.

Agree with the second part. I built this as a simple fix to everything being located at (0, 0) when I disables physics in the module by setting the key to False for all nodes and edges. Also it fits my personal needs, but since I am working with a decently large setup, I hope it holds some value that can be applied generally.
The proposed code is a "best effort" clustering, instead of running a full ground state simulation on the server. While it does not look as pretty as the result of vis.js' physics simulation, it is obtained a lot faster and does not have a round shape (which is unusual for topology graphs).
A (in my opinion sane) assumption I made was, that users will re-organize the graph manually anyway, therefore I prioritized clustering racks over it looking pretty.

I maybe should have made it clearer, but this more or less is a Feature Request that offers an idea how to solve the issue of not having coordinates when simply disabling physics in vis.js.
If it is easier to discuss first, I am open to close this, create an Issue to discuss the option to disable physics.

@mr1716
Copy link

mr1716 commented May 13, 2024

This would be a great change to do!

@dremerb dremerb force-pushed the disable_physics branch from 8c95afb to 5a0d8e3 Compare May 21, 2024 08:46
@dremerb
Copy link
Contributor Author

dremerb commented May 21, 2024

Messed up managing my branches and pushed a merge that does not belong here. Removed those commits with a force push.

@dremerb dremerb force-pushed the disable_physics branch from 5a0d8e3 to f3b9985 Compare June 6, 2024 08:20
@mattieserver
Copy link
Collaborator

I tried this out but i am not convinced the seeding works very well (at least for my own testing).
I am not sure this is the way we want to implement it, however it gave me and idea on what to try.

I will not merge this for now.

@mattieserver mattieserver added the status: under review Further discussion is needed to determine this issue's scope and/or implementation label Jul 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: under review Further discussion is needed to determine this issue's scope and/or implementation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants