litegraph.js

repository·master·Indexed 27 days ago

https://github.com/jagenjo/litegraph.js

A JavaScript library for creating node-based graphs in the browser, similar to Unreal Engine's Blueprints or PD. It features a built-in editor using HTML5 Canvas, optimized execution for hundreds of nodes, and supports both client-side and server-side (NodeJS) environments. The library allows for the creation of custom nodes with inputs, outputs, and interactive widgets, and enables exporting graphs for use in applications.

Tokens
4.8K
Snippets
11
Records
27
Agent score
90%

What's inside litegraph.js

  1. Create a custom Node type

    master

    To create a new node, define a constructor function that uses addInput, addOutput, and sets properties. Implement the onExecute prototype method to define the node's logic. Finally, register the node using LiteGraph.registerNodeType.

    //node constructor class
    function MyAddNode()
    {
      this.addInput("A","number");
      this.addInput("B","number");
      this.addOutput("A+B","number");
      this.properties = { precision: 1 };
    }
    
    //name to show
    MyAddNode.title = "Sum";
    
    //function to call when the node is executed
    MyAddNode.prototype.onExecute = function()
    {
      var A = this.getInputData(0);
      if( A === undefined )
        A = 0;
      var B = this.getInputData(1);
      if( B === undefined )
        B = 0;
      this.setOutputData( 0, A + B );
    }
    
    //register in the system
    LiteGraph.registerNodeType("basic/sum", MyAddNode );
  2. Add and configure Node Widgets

    master

    Widgets allow users to interact with node values (text, sliders, etc.). Add them in the constructor using this.addWidget(type, label, value, callback, options).

    Supported Widget Types

    • "number": Numeric input. Options: { min, max, step, precision }.
    • "slider": Draggable numeric input. Options: { min, max, step, precision }.
    • "combo": Selection list. Options: { values: ["a", "b"] } or { values: { "label": value } }.
    • "text": String editing.
    • "toggle": Checkbox.
    • "button": Clickable button.

    Widget Integration

    • Property Binding: To link a widget to a node property, use the property key in the options object: this.addWidget("text", "Name", "", { property: "my_prop" }).
    • Serialization: Widgets are NOT serialized by default. To include them in graph saves, set this.serialize_widgets = true; in the constructor.
    function MyNodeType()
    {
      this.slider_widget = this.addWidget("slider","Slider", 0.5, function(value, widget, node){ /* do something with the value */ }, { min: 0, max: 1} );
    }
  3. Customize Link Tooltips for complex objects

    master

    When hovering over a link, LiteGraph displays a tooltip showing the data being passed. For complex objects, the tooltip defaults to [Object].

    To provide a custom description, add a toToolTip function to the object being passed through the slot. This function should return the string you wish to display.

    this.setOutputData(0, {
      complexObject: {
        yes: true,
      },
      toToolTip: () => 'A useful description',
    });
  4. Integrate LiteGraph into an HTML application

    master

    To use LiteGraph, instantiate an LGraph for the logic and an LGraphCanvas for the visual interface.

    var graph = new LiteGraph.LGraph();
    var graph_canvas = new LiteGraph.LGraphCanvas( canvas_element, graph );
    
    // To start execution:
    graph.start();
    var graph = new LiteGraph.LGraph();
    var graph_canvas = new LiteGraph.LGraphCanvas( canvas, graph );
  5. Use Events to trigger node actions

    master

    By default, graph.runStep() calls the onExecute method of every node. To perform actions only when specific triggers occur, use the LiteGraph Event system.

    1. Define Slots: Use LiteGraph.ACTION for input slots that receive triggers and LiteGraph.EVENT for output slots that dispatch triggers.
    2. Handle Actions: Implement the onAction(action, data) method on your node to define what happens when a specific input slot is triggered.
    3. Trigger Events: Use this.triggerSlot(index) to dispatch an event from an output slot (e.g., from within onExecute or a widget callback).
    function MyNode()
    {
      this.addInput("play", LiteGraph.ACTION );
      this.addOutput("onFinish", LiteGraph.EVENT );
    }
    
    MyNode.prototype.onAction = function(action, data)
    {
       if(action == "play")
       {
         //do your action...
       }
    }
    
    MyNode.prototype.onExecute = function()
    {
       if( this.button_was_clicked )
        this.triggerSlot(0); //triggers event in slot 0
    }
  6. Run LiteGraph in NodeJS

    master

    LiteGraph can be executed on the server side using NodeJS. Note that nodes requiring browser APIs (such as Audio, WebGL, or Gamepad input) will not function in a server environment.

    var LiteGraph = require("./litegraph.js").LiteGraph;
    
    var graph = new LiteGraph.LGraph();
    
    var node_time = LiteGraph.createNode("basic/time");
    graph.add(node_time);
    
    var node_console = LiteGraph.createNode("basic/console");
    node_console.mode = LiteGraph.ALWAYS;
    graph.add(node_console);
    
    node_time.connect( 0, node_console, 1 );
    
    graph.start()
  7. Run the local demo server

    master

    To run the local development environment with the demo site, clone the repository, install dependencies, and run the utility server.

    $ git clone https://github.com/jagenjo/litegraph.js.git
    $ cd litegraph.js
    $ npm install
    $ node utils/server.js
  8. Create a custom LiteGraph node

    master

    To create a new node, define a constructor function to set up inputs, outputs, and properties. You do not need to inherit from LGraphNode directly; instead, use LiteGraph.registerNodeType to register your class, which automatically copies the necessary prototype methods to your node.

    Key steps:

    1. Define the constructor: use this.addInput(name, type) and this.addOutput(name, type).
    2. Set MyNode.title for the canvas display name.
    3. Implement MyNode.prototype.onExecute to handle logic.
    4. Register the node using LiteGraph.registerNodeType("category/name", MyNode).
    //your node constructor class
    function MyAddNode()
    {
      //add some input slots
      this.addInput("A","number");
      this.addInput("B","number");
      //add some output slots
      this.addOutput("A+B","number");
      //add some properties
      this.properties = { precision: 1 };
    }
    
    //name to show on the canvas
    MyAddNode.title = "Sum";
    
    //function to call when the node is executed
    MyAddNode.prototype.onExecute = function()
    {
      //retrieve data from inputs
      var A = this.getInputData(0);
      if( A === undefined )
        A = 0;
      var B = this.getInputData(1);
      if( B === undefined )
        B = 0;
      //assing data to outputs
      this.setOutputData( 0, A + B );
    }
    
    //register in the system
    LiteGraph.registerNodeType("basic/sum", MyAddNode );
  9. Create a basic LiteGraph project

    master

    To use LiteGraph in a web application, include litegraph.css and litegraph.js. You need to initialize an LGraph instance and an LGraphCanvas attached to an HTML <canvas> element to provide an editor interface.

    <html
    <head>
    	<link rel="stylesheet" type="text/css" href="litegraph.css">
    	<script type="text/javascript" src="litegraph.js"></script>
    </head>
    <body style='width:100%; height:100%'>
    <canvas id='mycanvas' width='1024' height='720' style='border: 1px solid'></canvas>
    <script>
    var graph = new LGraph();
    
    var canvas = new LGraphCanvas("#mycanvas", graph);
    
    var node_const = LiteGraph.createNode("basic/const");
    node_const.pos = [200,200];
    graph.add(node_const);
    node_const.setValue(4.5);
    
    var node_watch = LiteGraph.createNode("basic/watch");
    node_watch.pos = [700,200];
    graph.add(node_watch);
    
    node_const.connect(0, node_watch, 0 );
    
    graph.start()
    </script>
    </body>
    </html>
  10. Execute a Graph

    master

    To run the graph logic, call graph.runStep().

    Execution follows the graph's morphology: nodes without inputs are level 0, and subsequent connected nodes are processed in increasing levels. The order is automatically recalculated when the graph structure changes (e.g., adding nodes or connections). Data is passed between nodes via this.setOutputData(index, data) and this.getInputData(index).

  11. Wrap an existing function as a Node

    master

    You can quickly turn a standard JavaScript function into a LiteGraph node using LiteGraph.wrapFunctionAsNode(type, function, inputTypes, outputType).

    function sum(a,b)
    {
       return a+b;
    }
    
    LiteGraph.wrapFunctionAsNode("math/sum",sum, ["Number","Number"],"Number");