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

Implement GraphWidget #6

Open
GenericConfluent opened this issue Mar 1, 2024 · 0 comments
Open

Implement GraphWidget #6

GenericConfluent opened this issue Mar 1, 2024 · 0 comments
Labels
Priority: Medium This could block progess later Type: Enhancement New feature or request

Comments

@GenericConfluent
Copy link
Owner

GenericConfluent commented Mar 1, 2024

Task

Build an iced widget that can render course graphs. The goal is to build something similar to the obsidian graph view:

  • Pan and Zoom with the mouse to navigate.
  • Arrange class nodes based on the course level, 400-level classes should be placed above the 300 level, which should be placed above the 200 level. (Maybe)
  • Coreqs should be rendered as a single node that counts as two classes. (I may need to revisit this thought if there exist classes A, B, and C s.t. A is a coreq of B && B is a coreq of C && A is not a coreq of C).
  • Dependencies between courses should be drawn as arrows where the end of the arrow points to the dependency (if I can't implement the above point due to the reason listed I'm planning on using double-ended arrows for coreqs)
  • Distinguish between user-selected classes and classes auto-filled by the course selection algorithm by node shape.
  • Click on a node to bring up the course description, information, and dependency list.
  • BONUS: Add in some nice colours. There are a couple of things they could be used for and I don't know which I want yet.

Motivation

Ideally, users can see and interact with the courses they are selecting with minimal lag as they exist. It's possible to just have the user type up the course they want into a text input, and then run the course selection to fill in the requirements and coreqs. But a dedicated widget better shows how stuff is structured.

Implementation

Option 1

A lot of the requirements could be filled by using petgraph to serialize the final course graph to DOT, modifying the style as required and running dot as a subprocess, grabbing the SVG commands from stdout and then piping that to the SVG widget. Which once placed in a scrollable would allow users to scroll.

Pros:

  • Doesn't require writing a layout engine.
  • Leverages existing iced widgets.

Cons:

  • Updates may be laggy or slow depending on the course graph size.
  • Would need to implement a custom container type for the SVG to handle zoom with the mouse wheel and a proper pan with a left mouse button click.
  • Handling click events on nodes would probably be a nightmare.
  • How app performance would be affected by a large SVG in a scrollable sitting in the UI is unknown.
  • Requires either that dot is present on the user's system or that we can bootstrap graphviz and compile it with the app binary (which may or may not require writing bindings which would be tedious).

Option 2 (Preferred method)

Use Cache and the various methods implemented on the various Renderer traits in the crate.

Pros:

  • Would be reasonably performant. (No invoking subprocesses, and waiting for it to complete)
  • Does not require adding any additional dependencies like Graphviz to the project.
  • All event handling would be equally difficult to add, but the widget could handle stuff in the way specified in the requirements since it is yet to be implemented.
  • There is much more flexibility for making implementation changes. It would be possible to fine tune how the graph is generated.
  • Users could interact and modify graph in real time.

Cons:

  • The code required for this would be more complex than that for Option 1 because it would require handling all the layout (nevermind, there is a layout engine in the layout-rs crate topo module) and rendering Graphviz would do for us.

Option 3

Use wgpu directly and write a shader. This would be verbose and is very likely overkill. If neither of the first two work out though this is what remains. Though this could provide the absolute best performance.

@GenericConfluent GenericConfluent added Priority: Low Improves user experience Type: Enhancement New feature or request Priority: Medium This could block progess later and removed Priority: Low Improves user experience labels Mar 1, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Priority: Medium This could block progess later Type: Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant