# Node View

# NodeView

# Description

The NodeView component is a powerful utility for rendering interactive node-based flows. It is used to define and display nodes with customizable inputs and outputs, allowing you to build complex flow-based interfaces. Use NodeView when you need to visually represent and interact with configurable node graphs.

# Usage

Instantiate a NodeView using the static helper method from the Tesserae.UI class. Once instantiated, you can define nodes using methods like DefineNode for static nodes or DefineDynamicNode for nodes that update their outputs based on inputs. Additionally, you can monitor changes in the node graph through the OnChange method.

Below is a simple example that creates a node with a text input and a text output:

using System;
using Tesserae;
using static Tesserae.UI;
using static Tesserae.UI.NodeView.Interfaces;

public class SimpleNodeViewExample
{
    public void Run()
    {
        // Create a NodeView instance
        var nodeView = NodeView().S();
        
        // Define a simple node with one input and one output
        nodeView.DefineNode("SimpleNode", ib =>
        {
            ib.AddInput("inp", () => TextInputInterface("Input", "Initial value"));
            ib.AddOutput("out", () => TextInterface("Output", "Result"));
        });
        
        // Listen to any changes on the NodeView
        nodeView.OnChange(nv =>
        {
            Console.WriteLine("NodeView changed:");
            Console.WriteLine(nv.GetJsonState(true));
        });
        
        // Render the NodeView
        var element = nodeView.Render();
        
        // (Additional code to add the element to the DOM is required in a full application)
    }
}

# Methods

  • OnChange(Action onChange)
    Registers a callback that is invoked whenever the node view's state changes.
    • Parameters:
    - onChange: An Action delegate that receives the current NodeView instance.

  • DefineNode(string nodeTypeName, Action buildNode)
    Defines a new static node type with the specified name and configuration.
    • Parameters:
    - nodeTypeName: The display name of the node type.
    - buildNode: A callback that receives an InterfaceBuilder instance to define inputs and outputs for the node.

  • DefineDynamicNode(string nodeTypeName, Action buildBaseNode, Action<InputsState, OutputsState, InterfaceBuilder> onUpdate)
    Defines a dynamic node whose outputs can change based on its input state.
    • Parameters:
    - nodeTypeName: The name of the dynamic node type.
    - buildBaseNode: A callback to define the base inputs for the node.
    - onUpdate: A callback that is triggered to update outputs based on the current inputs.

  • Render() : HTMLElement
    Renders the NodeView and returns its root HTML element.

  • GetState() : NodeViewGraphState
    Retrieves the current state of the node graph as a NodeViewGraphState object.

  • GetJsonState(bool formated = false) : string
    Returns the JSON representation of the node graph state.
    • Parameters:
    - formated: If true, the JSON is returned in a formatted (indented) style.

  • SetState(string stateJson)
    Sets the node graph state using a JSON string.
    • Parameters:
    - stateJson: A JSON string representing the new state.

  • SetState(NodeViewGraphState state)
    Sets the node graph state directly using a NodeViewGraphState object.
    • Parameters:
    - state: The new state to load into the NodeView.

# Properties

The NodeView component does not expose additional public properties apart from its fluent API methods. All configuration and updates are managed through its methods.

# Samples

# NodeView Sample Usage

The sample below demonstrates how to create a NodeView with multiple nodes, including a dynamic node whose outputs are generated based on an input value. It also shows how to attach a change listener that updates a text area with the current state in JSON format.

using System;
using Tesserae;
using static Tesserae.UI;
using static Tesserae.UI.NodeView.Interfaces;

public class NodeViewSample : IComponent
{
    public HTMLElement Render()
    {
        var nodeView = NodeView().S();

        // Define a simple node with a text input and text output
        nodeView.DefineNode("Hello World", ib => 
            ib.AddInput("inp", () => TextInputInterface("Input", "Hi Input"))
              .AddOutput("out", () => TextInputInterface("Output", "Hi Output"))
        );

        // Define a complex node with various input types and one output
        nodeView.DefineNode("Complex", ib =>
            ib.AddInput("text", () => TextInterface("Input", "Hi Input"))
              .AddInput("int", () => IntegerInterface("Input", 123))
              .AddInput("num", () => NumberInterface("Input", 3.14))
              .AddInput("btn", () => ButtonInterface("Input", () => Toast().Information("Hi!")))
              .AddInput("chk", () => CheckboxInterface("Input", false))
              .AddInput("sel", () => SelectInterface("Input", "A", new ReadOnlyArray<string>(new[] { "A", "B", "C" })))
              .AddInput("sld", () => SliderInterface("Input", 0.5, 0, 1))
              .AddOutput("out", () => TextInterface("Output", "Hi Output"))
        );

        // Define a dynamic node that updates its outputs based on an input value
        nodeView.DefineDynamicNode("Dynamic", ib => 
            ib.AddInput("inp", () => IntegerInterface("Output Count", 1)),
            (inputState, outputState, ib) =>
            {
                var inputCount = inputState["inp"].As<int>();
                for (int i = 0; i < inputCount; i++)
                {
                    ib.AddOutput($"out-{i}", () => TextInterface($"out-{i}", i.ToString()));
                }
            }
        );

        // Create a text area to view and update the NodeView state in JSON format
        var textArea = TextArea().WS().H(10).Grow();

        // Update textArea when the NodeView state changes
        nodeView.OnChange(v => textArea.Text = v.GetJsonState(true));

        // Allow updating NodeView's state from the text area upon blur event
        textArea.OnBlur((ta, ev) => nodeView.SetState(ta.Text));

        // Render the final layout in a split view
        return SplitView().SplitInMiddle().Resizable().H(600).WS()
                          .Left(nodeView)
                          .Right(textArea)
                          .Render();
    }
}

# See also

  • Toast – For displaying information messages triggered by node actions.
  • TextArea – Used in conjunction with NodeView for state editing and display.