documentationfor yFiles for HTML 2.6

GraphBuilder

Populates a graph from custom data.

Inheritance Hierarchy
GraphBuilder

Remarks

This class can be used when the data consists of one or more collections of nodes, edges, and optionally, groups. The methods createNodesSource, createGroupNodesSource, and createEdgesSource bind the data to source objects from which nodes, groups, and edges will be created.

Generally, using the GraphBuilder class consists of a few basic steps:

  1. Create a GraphBuilder and optionally, provide an IGraph on which it should operate.
    const graphBuilder = new GraphBuilder(graph)
  2. Create one or more sources from which the GraphBuilder should create the graph structure (createNodesSource, createGroupNodesSource, createEdgesSource).

    To create edges from the data, provide sourceIdProvider and targetIdProvider with createEdgesSource and a respective idProvider for the NodesSource<TDataItem> to tell the GraphBuilder how the data is structured.

    const nodesData = getNodesData()
    const nodesSource = graphBuilder.createNodesSource(
      nodesData, // nodes data
      (nodeDataItem) => nodeDataItem.nodeId // node id provider
    )
    const edgesData = getEdgesData()
    const edgesSource = graphBuilder.createEdgesSource(
      edgesData,
      (edgeDataItem) => edgeDataItem.sourceNodeId,
      (edgeDataItem) => edgeDataItem.targetNodeId
    )
  3. Each NodesSource<TDataItem> provides a NodeCreator<TDataItem> that allows for further specification of how the items from this source should be created. You can provide defaults for the default styling but also bind more specific styling based on the actual data item with the styleProvider and styleBindings.
    nodesSource.nodeCreator.defaults.shareStyleInstance = false
    nodesSource.nodeCreator.defaults.style = new ShapeNodeStyle({
      stroke: 'darkOrange',
      fill: 'lightYellow',
      shape: 'round-rectangle'
    })
    nodesSource.nodeCreator.styleBindings.addBinding('stroke', (employee) =>
      employee.position.includes('Chief') ? 'darkRed' : 'darkOrange'
    )
    nodesSource.nodeCreator.styleBindings.addBinding('shape', (employee) =>
      employee.freelancer ? 'hexagon' : 'roundRectangle'
    )

    It also allows for applying layout information from the data item (layoutProvider), as well as further specification of the created node's tag (tagProvider).

  4. Similarly, each EdgesSource<TDataItem> provides an EdgeCreator<TDataItem> that allows for specifying the styling of the created items (defaults, styleProvider, and styleBindings).
    edgesSource.edgeCreator.defaults.style = new PolylineEdgeStyle({
      smoothingLength: 20
    })

    Furthermore, it allows for obtaining bend locations from the data item (bendsProvider), as well as further specification of the created edge's tag (tagProvider).

    edgesSource.edgeCreator.bendsProvider = (edgeDataItem) =>
      edgeDataItem.bendPoints
  5. Optionally, labels can be added by providing one or multiple label bindings. If there is a varying number of labels per node, createLabelsSource can be used, instead. Similar methods are also available on the EdgeCreator<TDataItem>.

    The LabelsSource<TDataItem> provides a LabelCreator<TDataItem> that allows for adjusting all aspects of the label creation, like style, text, size, and tag.

    const edgeLabelCreator = edgesSource.edgeCreator.createLabelBinding(
      (edgeDataItem) => edgeDataItem.name
    )
    edgeLabelCreator.defaults.style = new DefaultLabelStyle({
      backgroundFill: 'rgb(225,242,253)',
      backgroundStroke: 'lightskyblue',
      textSize: 8
    })
  6. Call buildGraph to populate the graph. You can apply a layout algorithm afterward to make the graph look nice.
    // Build a graph initially
    graphBuilder.buildGraph()
    // Apply a layout in a subsequent step
    graph.applyLayout(new OrganicLayout())
  7. If your items or collections change later, call updateGraph to make the changes visible in the graph. If the data item instances have changed, you can call setData or setData.
    // Set the new data collections:
    graphBuilder.setData(nodesSource, getNodesData())
    graphBuilder.setData(edgesSource, getEdgesData())
    // Update a graph after the business data has changed
    graphBuilder.updateGraph()
    // Apply a layout in a subsequent step
    graph.applyLayout(new OrganicLayout())

Group nodes can be defined in three ways depending on the data:

  • As a separate list, with each entry in the list defining a group node and an id. The child nodes belonging to a group node define the id of their the group node as the parent id.
    graphBuilder.createGroupNodesSource(
      groupNodesData,
      (groupNodeData) => groupNodeData.nodeId
    )
    
    const nodesSource = graphBuilder.createNodesSource(
      nodesData,
      (nodeData) => nodeData.nodeId
    )
    nodesSource.parentIdProvider = (nodeData) => nodeData.parentId
  • As a recursive hierarchical structure. That is, a group's data also includes a list of its children's data which is defined as createChildNodesSource. Note that a child can have children on its own.
    const topLevelNodesSource = graphBuilder.createNodesSource(
      topLevelNodesData,
      (data) => data.nodeId
    )
    const childNodeSource = topLevelNodesSource.createChildNodesSource(
      (data) => data.children
    )
    childNodeSource.addChildNodesSource(
      (child) => child.children,
      childNodeSource
    )
  • As a group node which is implicitly defined on one or more of its children. Parent nodes can be defined as createParentNodesSource.
    const leafNodesSource = graphBuilder.createNodesSource(
      leafNodesData,
      (data) => data.nodeId
    )
    const parentSource = leafNodesSource.createParentNodesSource(
      (data) => data.parent
    )

You can further customize how nodes, groups, and edges are created by adding event handlers to the various events and modifying the items there. This can be used to modify items in ways that are not directly supported by the available bindings or defaults. There are creation and update events for all items, which allow for separate customization when nodes, groups, and edges are created or updated. For completely static graphs, where updateGraph is not needed, the update events can be safely ignored.

Related Reading in the Developer's Guide

The different graph builders are discussed in the section Creating a Graph from Business Data. Class GraphBuilder, in particular, is topic of section GraphBuilder.

Type Details

yfiles module
view-component
yfiles-umd modules
All view modules
Legacy UMD name
yfiles.binding.GraphBuilder

See Also

This class serves as a convenient way to create general graphs. Some aspects to look out for:

  • buildGraph does not clear the graph. If needed, call clear to empty the graph before building it anew.
  • The GraphBuilder ignores and preserves items manually created on the graph in between calls to updateGraph.

If you need to extensively modify your data in order to fit the requirements of the GraphBuilder, it is often better to write the code interfacing with the graph by hand instead of relying on GraphBuilder.

updateGraph merely updates the graph structure. Any other bound data must be updated explicitly if necessary. Calling the respective update methods on the creators (e.g. updateStyle), resolves the provider (e.g. styleProvider) and applies the bindings (e.g. applyStyleBindings). The latter can also be applied solely.

For example, to update any aspect of node creation:
// configure the NodeCreator to update non-structural aspects
nodesSource.nodeCreator.addNodeUpdatedListener((sender, evt) => {
  nodesSource.nodeCreator.updateLayout(evt.graph, evt.item, evt.dataItem)
  nodesSource.nodeCreator.updateStyle(evt.graph, evt.item, evt.dataItem)
  nodesSource.nodeCreator.updateTag(evt.graph, evt.item, evt.dataItem)
  nodesSource.nodeCreator.updateLabels(evt.graph, evt.item, evt.dataItem)
})

builder.updateGraph()

Constructors

Properties

Methods

Events