Graph Editor
The graph editor is part of the SocialStack administration panel and can be used to create data or control flows without code. It is most commonly seen as a part of the Canvas Editor as a way to connect a component with dynamic input values. For example, you might have a component which renders a grid of images. Rather than hardcoding a specific location that the array of images comes from, you can use a graph to pipe a generic array of images to the component instead. This results in much more reusable components because the props are no longer being hardcoded in the javascript and it also works particularly well with Dynamic Content Types.
Above is a graph which loads the primary content object on the page, which in the example is a User object, and then displays the username in a component called Header on the page.
Nodes[edit | edit source]
The individual units of a graph are called nodes. In the image above for example, there are 2 nodes connected together. On any graph, one of the nodes is special as it is the root node. The root node is the one which is the ultimate output of your graph, and you can change it using the set root button in the top right corner of the node you want to change:
Above: The button which changes the root node. Pressing it changes the output of the graph to the node you pressed it on.
The current root node can be identified because it doesn't have this button visible and can't be deleted either. By convention, it is usually also the most rightward node because left to right is the flow direction that makes the connection lines most visible.
Constant Node[edit | edit source]
The Constant node simply outputs a specific value of a specific common type, such as a number or piece of text. Note that it's not used that often as constant values can also be directly added to fields of common types. The constant node primarily exists to reuse the same value in multiple places.
Content Node[edit | edit source]
Most commonly set to "Primary type", this node loads some content from the API - either the primary object from the page or a piece of content with a specified type and ID.
Content List Node[edit | edit source]
Much like the content node except it requests a set of things from the API based on a filter. Using ? arguments in the filter string will cause input fields to automatically appear.
Above: "Get me a list of all users with a role of 4". As with all API calls, this will only return results the user is permitted to see.
Component Node[edit | edit source]
Usually this is the main output of a typical graph, but doesn't have to be. Component nodes can appear anywhere in your graph too. If you'd like to have a prop on a component which accepts a component node as an input, use a propType of "jsx", then the value given is simply treated as if it was any other JSX object.
From List and To List Nodes[edit | edit source]
Simple nodes which can be used to construct a list from singular objects or extract an object at a specific index in a list. Usually quite rarely needed.
Fields Node[edit | edit source]
The Fields node displays the available fields on a given object. This is most often used together with the Loop node, where it can show you what fields are available on the current list entry.
Loop Node[edit | edit source]
The Loop node is used to convert a list of things into a list of other things, usually a list of content into a list of components. First connect the list you want to loop over to its main input. From there, in a nutshell, turn "loop item" into "iteration result". So for example, if you connect a list of Users to the input, "loop item" will be a single User in the list. You'll then usually use a Fields node to expand all the available fields on the User object. Let's say we're outputting a list of Components - you'd then add a Component node of the component you want, and connect the user's fields to it as required. Then, connect the component to "iteration result", forming an actual loop of connections with the Loop component. Assuming everything has been connected, a new field - "Output" - will appear which will then be a list of components.
Above: A list of tags is given to a loop node. For each tag, a Fields node displays the available fields exposing the tag name and description to us. The tag is then converted into a component, which is connected back to the iteration result field. That ultimately means this loop node takes in a list of tags and outputs a list of components.
Connecting Nodes[edit | edit source]
Each node has field values which define the inputs and outputs of a node. A nodes inputs are on the left side, and its outputs are on the right. Many nodes have outputs which depend on the inputs or their configuration, so the outputs are often not visible until the inputs have been configured. To connect nodes together, click and drag a fields connection point to another connection point (or click on one, then click the other):
You'll know the connection was successful because a line will then be drawn between the two connection points.
You can't connect incompatible field types together however. You can identify what the value type is that you're working with based on the colour of the connection point. If colours are quite similar, then hovering the mouse over a connection point will also display what the value type is. A type denoted with two cubes instead of one is a list of things (an array).
Custom Graphs[edit | edit source]
You can use a custom graph editor on any part of the admin panel with Input, like so:
<Input type='graph' />
As with all Input types, it can therefore also be used on C# fields as well:
[Data("type", "graph")]
public string GraphStructureJson;
By default when a parent form is submitted, the value is collected and outputted as a JSON string. You can skip the to JSON part and instead obtain an object tree with the objectOutput prop like so:
<Input type='graph' objectOutput />
Rendering a custom graph[edit | edit source]
Use the Graph object from the UI/Functions/GraphRuntime/Graph file to execute the nodes of your graph. Because graphs are always context sensitive, you'll need to specify which namespace your graph nodes are using if it is not the default canvas one.
import Graph from 'UI/Functions/GraphRuntime/Graph';
..
var graphToRun = new Graph(graphJsonHere);
graphToRun.setContext({ .. }); // Additional context to pass to the graph nodes. Shows up as this.context on all nodes.
graphToRun.run().then(result => {
// Do something with the provided result.
});
If you're using a custom set of nodes (see below for more on that), that is specified in the config like so:
var graphToRun = new Graph(graphJsonHere, {ns: 'UI/DialogueTree/NodeSet/'});
Custom graph nodes[edit | edit source]
By default a graph will use the canvas graph node set. However you can specify a custom set of nodes by specifying a namespace:
<Input type='graph' namespace={'Admin/DialogueTree/NodeSet/'} />
/* or 'ns' */
<Input type='graph' ns={'Admin/DialogueTree/NodeSet/'} />
Note that a node set exists in two different namespaces - one which provides the admin functionality, and another which provides the actual executors which run the graph when it's on the frontend (or also in the admin panel). The Input namespace prop is always specifically for the Admin node set.
The namespace to locate the executors on the frontend is specified with the namespace or ns config option on Graph:
new Graph(graphJsonStructure, {namespace: 'UI/DialogueTree/NodeSet/'})
/* or 'ns' */
new Graph(graphJsonStructure, {ns: 'UI/DialogueTree/NodeSet/'})
The canvas node executors can be found in UI/Canvas/Graph/ - this is the default Graph namespace if none is specified.