Options
All
  • Public
  • Public/Protected
  • All
Menu

A Graph is is a simple undirected graph. On it's own it isn't too useful but it forms the basic functionality for the DirectedGraph and DirectedAcyclicGraph.

Creating a Graph

You can create a graph to contain any type of node, for example:

type NodeType = { a: Number, b: string }
const graph = new Graph<NodeType>()

// Add a node of the defined type
const node: string = graph.insert({ a: 10, b: 'string' })

// Get the node back
const nodeValue: NodeType | undefined = graph.getNode(node);

Defining a custom node identity

When you create a graph you likely want to create include a custom nodeIdentity function. This function tells the graph how to uniquely identify nodes in a graph, default is to simply use an hash which means that functionality like replace will not work.

type NodeType = { count: number, name: string }
const graph = new Graph<NodeType>((n) => n.name)

// Add a node
graph.insert({ count: 5, name: 'node1' })
// This will throw an error even though `count` is different because they share a name.
graph.insert({ count: 20, name: 'node1' })

Adding an edge

Graphs without edges aren't very useful. Inserting edges is done using the node identity string returned by the node identity function.

const node1: string = graph.insert({ count: 5, name: 'node1' })
const node2: string = graph.insert({ count: 20, name: 'node2' })

graph.addEdge(node1, node2)

// This will throw an error since there is no node with the later name.
graph.addEdge(node1, 'not a real node')

In an undirected graph the order in which you input the node names doesn't matter, but in directed graphs the "from node" comes first and the "to node" will come second.

Replacing a node

If a node already exists you can update it using replace. nodeIdentity(newNode) must be equal to nodeIdentity(oldNode).

const node1: string = graph.insert({ count: 5, name: 'node1' })
const node2: string = graph.insert({ count: 20, name: 'node2' })

// This will work because the name has not changed.
graph.replace({ count: 15, name: 'node1' })

// This will not work because the name has changed.
graph.replace({ count: 20, name: 'node3' })

replace will throw a NodeDoesntExistError exception if you are trying to replace a node that is missing from the graph.

Upsert

Often you will want to create a node node if it doesn't exist and update it does. This can be achieved using upsert.

const node1: string = graph.insert({ count: 5, name: 'node1' })

// Both of these will work, the first updating node1 and the second creating a node.
const node2: string = graph.upsert({ count: 15, name: 'node1' })
const node3: string = graph.upsert({ count: 25, name: 'node3' })

upsert always return the node identity string of the inserted or updated node. At presented there is no way to tell if the node was created or updated.

Type parameters

  • T

    T is the node type of the graph. Nodes can be anything in all the included examples they are simple objects.

Hierarchy

Index

Constructors

constructor

  • new Graph(nodeIdentity?: (node: T) => string): Graph
  • Parameters

    • Default value nodeIdentity: (node: T) => string = node => hash(node)
        • (node: T): string
        • Parameters

          • node: T

          Returns string

    Returns Graph

Properties

Protected adjacency

adjacency: Array<Array<Edge>>

Protected nodeIdentity

nodeIdentity: (t: T) => string

Type declaration

    • (t: T): string
    • Parameters

      • t: T

      Returns string

Protected nodes

nodes: Map<string, T>

Methods

addEdge

  • addEdge(node1Identity: string, node2Identity: string): void
  • Create an edge between two nodes in the graph. Throws a [[NodeDoesNotExistsError]] if no either of the nodes you are attempting to connect do not exist.

    Parameters

    Returns void

getNode

  • getNode(nodeIdentity: string): T | undefined
  • Returns a specific node given the node identity returned from the insert function

    Parameters

    • nodeIdentity: string

    Returns T | undefined

getNodes

  • getNodes(compareFunc?: undefined | ((a: T, b: T) => number)): T[]
  • This simply returns all the nodes stored in the graph

    Parameters

    • Optional compareFunc: undefined | ((a: T, b: T) => number)

      An optional function that indicates the sort order of the returned array

    Returns T[]

insert

  • insert(node: T): string
  • Add a node to the graph if it doesn't already exist. If it does, throw a NodeAlreadyExistsError.

    Parameters

    • node: T

      The node to be added

    Returns string

    A string that is the identity of the newly inserted node. This is created by applying the nodeIdentity.

replace

  • replace(node: T): void
  • This replaces an existing node in the graph with an updated version. Throws a [[NodeDoesNotExistsError]] if no node with the same identity already exists.

    __Caveat_:_ The default identity function means that this will never work since if the node changes it will have a different hash.

    Parameters

    • node: T

      The new node that is replacing the old one.

    Returns void

upsert

  • upsert(node: T): string
  • This essentially combines the behavior of insert and replace. If the node doesn't exist, create it. If the node already exists, replace it with the updated version.

    Parameters

    • node: T

      The node to insert or update

    Returns string

    The identity string of the node inserted or updated.

Legend

  • Constructor
  • Property
  • Method
  • Inherited constructor
  • Inherited property
  • Inherited method
  • Private property
  • Private method
  • Protected property
  • Static property

Generated using TypeDoc