Skip to content
This repository has been archived by the owner on Aug 27, 2019. It is now read-only.

Graph Visualizer #2

Open
teamdandelion opened this issue Apr 5, 2019 · 2 comments
Open

Graph Visualizer #2

teamdandelion opened this issue Apr 5, 2019 · 2 comments

Comments

@teamdandelion
Copy link
Contributor

teamdandelion commented Apr 5, 2019

We need a graph visualizer for our Odyssey Hackathon project (see #1 for overview). Let's use this thread to spec it out.

I imagine the graph visualizer displaying a subset of nodes in a SourceCred graph using force-directed layout. For each node, there are a few pieces of salient information we want to display:

  • the node's type
  • the node's description
  • the node's weight
  • the node's score

Most of this data will come from a PagerankGraph (using PagerankGraph rather than regular Graph so that we have scores and weights). To get node types and node descriptions, we'll also need to have the relevant plugin adapter available.

I'm not exactly sure how this information should be rendered. It would seem natural to communicate both a node's weight and a node's score via the size; score is more important than weight, so we should prioritize that, but I'm not sure how the weight should get communicated. (In the current implementation, node weight weight only matters insofar as it modifies the edge weights so maybe we don't need to worry about this.) For edges, we need to be able to render that the weight may be asymmetric, i.e. high weight in one direction but not another. Maybe we can put arrowheads on both ends of the edge, where the size of each arrowhead indicates the respective weight?

In the initial "hack" case where the "manual-mode" plugin stands alone, we can not worry about the plugin integration so much and just make it work for the manual-mode plugin, but we'll definitely want to integrate with the Git and GitHub plugin before long. Also, in the longer-term future we'll want to give plugins an opportunity to integrate custom rendering logic for their nodes and edges (and maybe custom logic for aggregating groups of nodes together), but this is not a v0 consideration.

From an implementation perspective, I imagine us using d3 with force-directed-layout, and to render the graph via SVG. I'm not sure if we'll let the user manually re-layout the graph, I think we should try to avoid this unless it proves really important.

Then, for consistency with the rest of our codebase, we should wrap the d3 visualization into a React component. I imagine the React component having a surface area kind of like this one:

export type Props = {|
  // The underlying graph. it should be a PagerankGraph and not just a 
  // regular Graph so that we have node/edge weights 
  +graph: PagerankGraph,

  // Which node or edge is selected (if anything is)
  +selected: NodeAddressT | EdgeAddressT | null,

  // Handler so the controlling component can update the selection
  +onSelectedChange: (NodeAddressT | EdgeAddressT | null) => void;

  // Which nodes in the graph are visible
  +visible: Set<NodeAddressT>,

  +adapters: $ReadOnlyArray<DynamicExplorerAdapter>,
|}

export type ZoomPosition = {|
  // Facilitate drag, zoom in, zoom out
  +zoom: number,
  +x: number,
  +y: number,
|}

export type State = {|
  +zoomPosition: ZoomPosition,
|}

export class GraphVisualizer extends React.Component<Props, State> {
  render() {
    // TODO...
  }
}
@mortonanalytics
Copy link

mortonanalytics commented Apr 6, 2019

I have a start here: https://jsfiddle.net/bjkvndL3/. (edited to abstract node and edge definition...just added edge source and target mapping demoed using the JSON data from the project: https://jsfiddle.net/39dbn4ao/. Also added an edge color function. Both the edge and node color functions use indexing rather than categorical names, but that can be changed if needed.)

The chart updates on an interval and the node name appears when you hover over a node. The first section is the chart class. I then demo the class with toy data at line 188. The opts argument takes several items that includes a mapping of the data to node and edge elements.

Anyhow, this is a start, and we can further define what we may want from the chart in the as needed for the hack.

teamdandelion pushed a commit that referenced this issue Apr 8, 2019
Summary:
The regular expressions used to detect GitHub references were of the
form `/(?:\W|^)(things)(?:\W|$)/gm`, where the outer non-capturing
groups were intended to enforce a word boundary constraint. However,
this caused reference detection in strings like `"#1 #2"` to fail,
because the putative matches would be `"#1 "` and `" #2"`, but these
matches overlap, and the JavaScript RegExp API (like most such APIs)
finds only non-overlapping matches. Therefore, in a string of
space-separated references of the same kind, only every other reference
would be detected.

A solution is to use a positive lookahead instead of the second
non-capturing group: i.e., `/(?:\W|$)/` becomes `/(?=\W|$)/`. (Ideally,
the first non-capturing group would just be a lookbehind, but JavaScript
doesn’t support those.)

In some cases, using `\b` is a simpler solution. But this does not work
in all cases: for instance, it works for repo-numeric references, but
does not work for numeric references, because the presence of the hash
means that there cannot be an immediately preceding word boundary. For
consistency, I opted to use the lookahead solution in all cases, but any
solution that passes tests is okay with me.

Test Plan:
Regression tests added. They fail before this patch and pass with it.

wchargin-branch: fix-space-separated-github-references
@mortonanalytics
Copy link

Keeping the code (and commits) here unless there's a better home.

Updated the research JSON data example with most recent code here. It's still a big fuzz ball, but some nodes pull out into orbit.

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

No branches or pull requests

2 participants