Skip to content

Feature: Edge Weights #285

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

Merged
merged 13 commits into from
Jun 12, 2023
Merged

Feature: Edge Weights #285

merged 13 commits into from
Jun 12, 2023

Conversation

benloh
Copy link
Collaborator

@benloh benloh commented Jun 9, 2023

Addresses #245

This adds a new parameter weight to edges.

  • By default weight is 1
  • Weight can be turned on and off via the template. Older versions of projects will open with weight defaulting to 1 if there were no values set.
  • Maximum edge size is set via the edgeSizeMax parameter.
  • edgeSizeMax only affects how edges are rendered in d3. So an edge can have a weight of 100, but if edgeSizeMax is 20, it will display only as a 20-pixel wide link.
  • Set edgeSizeMax to 0 to turn off the max limit. WARNING: You can potentially end up with lines far wider than the nodes they point to.
  • We used to use edge sizes^2 to make the differences between edge sizes more visible. We removed that for now so that the edgeSize template settings and weight settings are all treated essentially as pixel measurements. e.g. an edge weight of "2" will have a stroke width of 2 pixels.
  • Weight can be viewed in Edge Tables.
  • Weight can be filtered.

DEV NOTES:

  • We changed the architecture for how d3 renders, adding an edge synthesis module that reduces duplicate edges to a single edge AND at the same time calculates the weight of that edge. This is a necessary precursor to arrow support as well.
  • If you open an older version project, weight will be hidden by default. You'll have to edit the template to unhide weight before you'll see when you edit edges.

See also user input data flow whimsical diagram for system architecture.

Migrating Data

server-database.js will now "migrate" graph data as it opens the project file. It uses parameters defined in the template to determine if migration is necessary and can automatically define missing fields and set default values. It currently does not do more sophisticated migration (e.g. change a property from one name to another), but these can be easily added.

Currently this is primarily being used to add the "Weight" to any project that has "Weight" defined as set as "isRequired" and has a defaultValue defined.

The basic check is this:
1. If the TEMPLATE property `isRequired`
2. ...and the TEMPLATE propert has `defaultValue` defined
2. ...and the node/edge property is currently undefined or ``
3. ...then we set the property to the defaultValue

The key parameters:
  `property.isRequired`
  `property.defaultValue`

If `isRequired` or `defaultValue` is not defined on the property, we skip migration..

You can use this technique to auto-populate data on a project. Just add isRequired and defaultValue to the projects' *.template.toml file. e.g. this will set all node types to Person if the node type was not previously set when the project is opened:

[nodeDefs.type]
...
isRequired = true
defaultValue = "Person"

[[nodeDefs.type.options]]
color = "#eeeeee"
label = ""
[[nodeDefs.type.options]]
color = "#ff0000"
label = "Person"

NOTE the migration does NOT save the changes until you do something to modify the database and trigger an autosave.

dsriseah and others added 4 commits June 9, 2023 13:32
When a property doesn't exist in the data (due to old version of project),
the key (e.g. 'weight') can be undefined leading to unsortable NaN value
@benloh benloh added this to the Spring 2024 milestone Jun 9, 2023
@benloh benloh requested a review from jdanish June 9, 2023 22:43
@jdanish
Copy link
Collaborator

jdanish commented Jun 10, 2023

Can we change the default display name and export name for Weight to be Weight?

@jdanish
Copy link
Collaborator

jdanish commented Jun 10, 2023

Maybe in the Edge table make Weight slightly smaller and Comments slightly wider?

@jdanish
Copy link
Collaborator

jdanish commented Jun 10, 2023

To avoid confusion, when creating a new edge, if weights are visible can we add the weight number to it? It displays the edge correctly as 1 but having the field blank feels potentially confusion.

@jdanish
Copy link
Collaborator

jdanish commented Jun 10, 2023

I created two edges in opposite directions between the same set of nodes and it seems to have done some weird things - making the edge suddenly REALLY thick and also coloring it red in the table. I tried switching direction and that did not fix it. Deleting the second edge it looks fine.

Note upon further experimenting the issue with size always happens with 2 edges: 2 edges of weight 1 each are much thicker than one edge of weight 2.

I'm guessing the red is because you picked an edge color? I like the idea, but 2 things there: 1) I think choosing the color of the thickest edge makes sense if possible, and 2) turning it red is confusing. I'm inclined to suggest either fading it, or just leaving it normally displayed. Or maybe indicating it is hidden with some symbol in the table? Leaning towards normal display but will ponder and am open to suggestions.

Screenshot 2023-06-10 at 6 44 41 AM

@jdanish
Copy link
Collaborator

jdanish commented Jun 10, 2023

By the way I tested adding a letter to the edge weight and it was fine - it just left the prior number it seemed. However, given the long-term goal of using more validation it'd be nice if this required an integer like the focus field does (assuming its easy to use the same code - if not, this can wait since I imagine that if we are validating numbers we'll eventually want a range to be something we can identify in the template? though this can have a range similar to focus of 1-infinity so long as it is a positive integer?).

@benloh
Copy link
Collaborator Author

benloh commented Jun 10, 2023

Can we change the default display name and export name for Weight to be Weight?

Ooops. Sorry, victim of copy and paste.

Maybe in the Edge table make Weight slightly smaller and Comments slightly wider?

Done

To avoid confusion, when creating a new edge, if weights are visible can we add the weight number to it? It displays the edge correctly as 1 but having the field blank feels potentially confusion.

How do you want to handle the case where an old project is converted to add weight? Do we respect the fact that the old project did not define weight and leave it blank? Or do we always insert 1 if it wasn't defined? And should we do that when the project is opened (applies to all edges), or when an EdgeEditor is opened (applies only to opened+edited edges)?

By the way I tested adding a letter to the edge weight and it was fine - it just left the prior number it seemed. However, given the long-term goal of using more validation it'd be nice if this required an integer like the focus field does (assuming its easy to use the same code - if not, this can wait since I imagine that if we are validating numbers we'll eventually want a range to be something we can identify in the template? though this can have a range similar to focus of 1-infinity so long as it is a positive integer?).

We can spec a number input field for now and force a min of 1. If the value is outside of the range, we show a red border for the input field, but otherwise we allow the value. Adding customizable min/max values and more sophisticated validation will be something we'll add in the future when we go to the completely flexible data architecture.

weight calculation

Hmm...checking my algorithms...

@jdanish
Copy link
Collaborator

jdanish commented Jun 10, 2023 via email

benloh added 6 commits June 10, 2023 11:26
…e sizes were ridiculously large because "2" + "2" became "22".
…Required` and `defaultValue`. If both are set, and the node/edge property is undefined or '', then the property is set to the `defaultValue`

You can actually use this to auto-insert values simply by editing a project's template without affecting the template schema.
@benloh
Copy link
Collaborator Author

benloh commented Jun 10, 2023

Fixes

  • Edges Table column widths are now adjusted, with "Weight" smaller and "Comments" bigger.
  • Edge sizes now properly render (was a string vs number problem when adding weights)
  • The default "Weight" labels and help text now properly reference "Weight" (and not "Number")
  • The Edge Editor now properly uses the Template displayLabel instead of a temporary override
  • The "Weight" input field now only allows numbers.
  • Trying to input a "Weight" less than 1 will now cause the Input field to show a red border (but we do not otherwise do any validation)
  • Added a rudimentary method for migrating data across template/data versions.

Migrating Data

server-database.js will now "migrate" graph data as it opens the project file. It uses parameters defined in the template to determine if migration is necessary and can automatically define missing fields and set default values. It currently does not do more sophisticated migration (e.g. change a property from one name to another), but these can be easily added.

Currently this is primarily being used to add the "Weight" to any project that has "Weight" defined as set as "isRequired" and has a defaultValue defined.

The basic check is this:
1. If the TEMPLATE property `isRequired`
2. ...and the TEMPLATE propert has `defaultValue` defined
2. ...and the node/edge property is currently undefined or ``
3. ...then we set the property to the defaultValue

The key parameters:
  `property.isRequired`
  `property.defaultValue`

If `isRequired` or `defaultValue` is not defined on the property, we skip migration..

You can use this technique to auto-populate data on a project. Just add isRequired and defaultValue to the projects' *.template.toml file. e.g. this will set all node types to Person if the node type was not previously set when the project is opened:

[nodeDefs.type]
...
isRequired = true
defaultValue = "Person"

[[nodeDefs.type.options]]
color = "#eeeeee"
label = ""
[[nodeDefs.type.options]]
color = "#ff0000"
label = "Person"

NOTE the migration does NOT save the changes until you do something to modify the database and trigger an autosave.
(copied to main PR description for reference)

@jdanish
Copy link
Collaborator

jdanish commented Jun 11, 2023

Two minor issues, but I'll accept and then add those. They are: 1) If you delete the number in weight field it now makes a 0 and you cannot delete that. Which is weird. Also 2) It'd be nice to show the color on an edge of the edge with the highest weight (e.g., if I have a->b (green) and a->d (blue) but c-d is weight 2 and a-b is weight 1, it should be displayed green.

@jdanish
Copy link
Collaborator

jdanish commented Jun 11, 2023

Note: issues #288 and #289 have been created.

@jdanish
Copy link
Collaborator

jdanish commented Jun 12, 2023

Looks good!

@jdanish jdanish merged commit b2dd6e5 into dev Jun 12, 2023
@benloh
Copy link
Collaborator Author

benloh commented Jun 12, 2023

#288 and #289 should be addressed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants