Giter VIP home page Giter VIP logo

rete's Introduction

Rete.js

Made in Ukraine Discord

JavaScript framework for visual programming

rete logo

#StandWithUkraine πŸ’™πŸ’›

#RussiaInvadedUkraine on 24 of February 2022, at 5.00 AM the armed forces of the Russian Federation attacked Ukraine. Please, Stand with Ukraine, stay tuned for updates on Ukraine’s official sources and channels in English and support Ukraine in its fight for freedom and democracy in Europe.

Help to defend Ukraine β€” donate to Ukraine’s main charity fund

Help to defend Ukraine β€” donate to the fund of the National Bank of Ukraine

Introduction πŸŽ₯

Rete.js is a framework for creating visual interfaces and workflows. It provides out-of-the-box solutions for visualization using various libraries and frameworks, as well as solutions for processing graphs based on dataflow and control flow approaches.

Getting started

Use Rete Kit to quickly set up a Rete.js application. It lets you select a stack (React.js, Vue.js or Angular, Svelte) and the set of features

npx rete-kit app

Alternatively, you can follow the complete guide

Documentation

Sponsors

Thank you to all our sponsors! Become a sponsor

Backers

Thank you to all our backers! Become a backer

Contributors

This project exists thanks to all the people who contribute. Contribute.

License

MIT

rete's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rete's Issues

Multi depth menu

Issue being when there renders on the second tab going into third it just displays label and no further popout

new D3NE.ContextMenu({
  'top': {
    'first': onFirstEvent,
   'Second parent':{
          'three deep': something //this wont show
  }
}
})

Styling docs are not clear

Hi,I am sorry, but what is ".node.title-of-node" .I mean what is "title-of-node"? Where do I set/find it?

Thanks.

Compatible sockets

Adding a connection between different sockets for which this is allowed
2017-06-22_165419

EventListener's handler has no parameters

This code example from wiki page is not working, gives compile error on Angular 5 for me.

`editor.eventListener.on('nodecreate', (node, persistent) => {
// trigger after each of the first six events

/// check if there is already a node with that name
var haveSomeNode = editor.nodes.some(item => item.name === node.name);
return !haveSomeNode; // prevent the addition of a new node
});`

Handler's declaration not allows parameters but it will be very useful if we could do something with the newly created, selected, etc. node.

How can I know the index of the current node?

Let's say I have got 5 nodes connected linearly in chain. How can I know from within each node its index in the chain?
Sorry for asking it here,I didn't find anything related to it in the docs.

Get component by name

When getting the builders of the components, in the demo you get them by position, like this:

var menu = new D3NE.ContextMenu({ 'Actions':{ 'Action': function(){alert('Subitem selected');} }, 'Nodes':{ 'Number': components[0].builder, 'Add': components[1].builder } });

In my opinion it would be much more useful to get the builders by their name, something like components.getComponent('number').builder, mainly because if the components are loaded dynamically, you probably won't know the order in which they are added into the collection (this is my case).

Thanks!

Problem trying to use this lib in TypeScript

The line

import * as D3NE from 'd3-node-editor';

gives me the following error

Could not find a declaration file for module 'd3-node-editor'. '/node_modules/d3-node-editor/build/d3-node-editor.js' implicitly has an 'any' type.
Try npm install @types/d3-node-editor if it exists or add a new declaration (.d.ts) file containing declare module 'd3-node-editor';

Allow non-selected Control Click event

I am trying to find how this library suppresses the users click event on controls when the node is not selected I would like to be able to turn that feature off for some nodes so that the user can change inputs without needing to click the control 2 times

First-class support for groups

Thanks for working on this. I've been thinking about something along those lines for a while. It's great to see it materialized.

Do you plan to support some sort of first-class group concept, similar to what Blender offers, so one might just select a few nodes, mark them as a group, and make them expand and collapse as needed?

How to retrieve the accumulated data from the last node?

Hi. I am sorry for nudging ,but the examples for this lib are really basic.It is hard figure out a lot of real world functionality. For example, I have the following case.I have a a sequence of nodes. All the nodes are of the same component type.Each one connection only with one node at the right. Chain like composition,all right.Each node holds a string.When a node gets connected with another node from the left,it concatenates left's node string with its own string and puts it into outputs[0] ,which is string. So I expect,somehow ,to be able to get the long string of all the string from all the nodes at the last node.But it doesn't work. Worker of the node component does this:

 ```

worker(node, inputs, outputs)
{
outputs[0] = inputs[0] +"," + node.data.fname;
}



And I am trying to get the final string at the last node like this:

editor.eventListener.on("change", async function()

{
await engine.abort();
await engine.process(editor.toJSON());
console.log("Num connected nodes:" + editor.nodes.length);
console.log("Files:" + editor.nodes[editor.nodes.length -1].outputs[0]);
});


But it shows some [Object] thing,That's it.I have been also trying to debug the editor object in the chrome debugger and when inspecting every node object stored in the editor,I don't see any reference to the values from the previous nodes.Also,the worker function does spit the accumulated value,but it does so even if the nodes are not connected,but just are thrown at the scene.So either I am missing something bug,or something wrong with the lib. The docs are very poor. I mean,I am completely fine with supporting this project at patreon or something,but it's hard to understand even how to use this lib at the very basic level.





Cannot use an id below 100

The regex of the isValidId function:/^[\w-]{3,}@[0-9]+\.[0-9]+\.[0-9]+$/ is too restrictive. When I create a new "document" I would like its id to be 0 but unfortunately we need to have at least 3 chars for the id part. I cannot use the fromJson without having the error:

Uncaught Error: ID should be valid to [email protected] format

We also need to provide a version number (and an int is not ok, we need to use x.y.z)
I am not working with versioning right now so I am juste adding @0.0.1 to the end of my id.
Is there any way to bypass theses errors ?

The id regex could be a minimum of 1 char instead of 3, why not use 1,2,3...10 as id instead of beginning at 100 ?
And the version parameter could be optional as well

Node types

allow to create nodes of different kinds
For example: event, value, function

How to add node without using the context menu ?

I need to have buttons that create node(s) in order to automate some process. After looking at the functions I found the editor.addNode() one that take a node in argument, and I have my component "myComponent" defined as the folowing:

    var myComponent = new D3NE.Component('My Component', {
        builder: function builder(node) {
            var input = new D3NE.Input('Dialog', dialogSocket, true);
            var output = new D3NE.Output('Dialog', dialogSocket, false);
            var questionControl = new D3NE.Control('<textarea rows="5"></textarea>', function (element, control) {
                element.value = control.getData('question') || '';
                control.putData('question', element.value);
                element.addEventListener('change', ()=> {
                    control.putData('question', element.value);
                });
            });

            node.addControl(questionControl);

            node.addOutput(output);
            node.addInput(input);

            return node;
        },
        worker: function worker(node, inputs, outputs) {
        }
    });

I want a button to add a node of myComponent. I've tried:

  d3.select('#addMyComponent').on('click', function () {
       editor.addNode(myComponent.newNode());
       editor.addNode(myComponent.builder());
   });

myComponent.newNode() add a node but without any output and without my textarea.

myComponent.builder() throw an error because it expect an input node...

How can I accomplish that ?


Edit: It seems to work (very slowly) with:

    d3.select('#addMyComponent').on('click', function () {
        editor.addNode(myComponent.builder(myComponent.newNode()));
    });

Is it the right way of doing it ?

The demo does not appear to work

Im on chrome Version 59.0.3071.115 (Official Build) (64-bit) and cant see anything in the demo for the editor.

i get this error in the console

pen.js:73 Uncaught TypeError: D3NE.NodeBuilder is not a constructor
    at pen.js:73:20

[Angular] Draggable problems

Hello,

I tried to implement node editor in Angular 5 as it is provided in example and wiki. However, the drag functionality seems to be malfunctioning - if I click on a component, it somehow triggers the canvas (div) drag event and it is impossible to move the components or connect them.

Is this something on my side or it might be a problem with outdated example/wiki article?

How can I limit outputs to only one connection ?

In the wiki you write:

All outputs can have an unlimited number of connections. By default inputs can only have one connection. You can change this passing the third parameter as true

But in my case, I need to restrict an output to only one connection, can I do this ? Why does the output constructor does not have the multiConns param ?

fromJSON() doesn't load values

The method fromJSON() of the editor class doesn't load the value of the nodes, nodes take always the default values or "null".

Example based on the sample of the wiki:
The exported data using "editor.toJSON()":

{"id":"[email protected]","nodes":{"1":{"id":1,"data":{"num":10},"group":null,"inputs":[],"outputs":[{"connections":[{"node":3,"input":0}]}],"position":[80,200],"title":"Number"},"2":{"id":2,"data":{"num":10},"group":null,"inputs":[],"outputs":[{"connections":[{"node":3,"input":1}]}],"position":[80,400],"title":"Number"},"3":{"id":3,"data":{},"group":null,"inputs":[{"connections":[{"node":1,"output":0}]},{"connections":[{"node":2,"output":0}]}],"outputs":[{"connections":[]}],"position":[500,240],"title":"Add"}},"groups":{}}

but after calling "editor.fromJSON(data)", the 10 value is getting ignored and became 1, the default value:

{"id":"[email protected]","nodes":{"1":{"id":1,"data":{"num":1},"group":null,"inputs":[],"outputs":[{"connections":[{"node":3,"input":0}]}],"position":[80,200],"title":"Number"},"2":{"id":2,"data":{"num":1},"group":null,"inputs":[],"outputs":[{"connections":[{"node":3,"input":1}]}],"position":[80,400],"title":"Number"},"3":{"id":3,"data":{},"group":null,"inputs":[{"connections":[{"node":1,"output":0}]},{"connections":[{"node":2,"output":0}]}],"outputs":[{"connections":[]}],"position":[500,240],"title":"Add"}},"groups":{}}

Selection of suitable nodes

Show suitable nodes when you hold down a Ctrl and click on an empty location after selecting an output connection

Async Tasks Not working

Making an async task appears to make the resolving part not fire or react even though promise resolves correctly

var componentDelayEvent = new D3NE.Component("Delay Event", {
  builder(node) {
    let act = new D3NE.Output("Action", actSocket),
        inp1 = new D3NE.Input("Action", actSocket)
    return node.addOutput(act).addInput(inp1);
  },
  worker(node, inputs, outputs) {
    var task = new D3NE.Task(inputs, async(inps) => {
      console.log("Resolve");
      await resolveAfter2Seconds()
      console.log("Should Pass");
      return [new D3NE.Task(inputs,(inps)=>{}).option(0)] //As need to return the option part as if return task.output below will fire on make
    })
    
    outputs[0] = task.output(0);
  }
});

function resolveAfter2Seconds() {
  return new Promise(resolve => {
    setTimeout(() => {
      console.log("Resolved");
      resolve('resolved');
    }, 2000);
  });
}

Multiple browser support

I've found that the library is not working properly on Edge and Firefox. The nodes are cropped (but functional), and in Edge the dragging is odd.
Is there any chance of making it work fully in Edge and Firefox?

Thanks!

is it possible to modify node from worker?

Hi!
First of all d3-node-editor is awesome! I've spent some time to find a tool like this. I'm trying to use it to draw/describe testing scenarios for our app (hypermedia siren api). I looked at node-red as a possible candidate but it's too heavy and not very easy to use for non-developers. And your library looks like a perfect fit for our use case. Thanks!

Small question:
I looked at "Customisation" page in wiki but if I'm fine with the built-in template is it possible to update node data used in the template through the worker? I was trying to do something like this:

 // doesn't work for me
 async worker(node, inputs, outputs) {
    await something();
    node.title += ' - done!';
 }

 // somewhere later, on "start" button click
 await engine.process(editor.toJSON());
 // doesn't help either
 editor.view.update();

If the whole approach is bad - please point me in the right direction.

Best way to do socket verification?

For example I have created a ObjectId socket which should only allow values of /^[a-fA-F0-9]{24}$/.

I mean I could verify it at every worker, but that seems burdensome...

Any hints?

PS: Great work on this thing btw!

alight is not defined

I'm trying to use this library in an Electron editor, for editing a configuration file.

I downloaded the examples and included them:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Editor</title>
    <link href="d3-node-editor/d3-node-editor.css" rel="stylesheet"></link>
    <link href="editor.css" rel="stylesheet"></link>
  </head>
  <body>
   <div id="nodeEditor" class="node-editor"></div>
    <script type="text/javascript" src="d3-node-editor/alight.min.js"></script>
    <script type="text/javascript" src="d3-node-editor/d3.min.js"></script>
    <script type="text/javascript" src="d3-node-editor/d3-node-editor.js"></script>
    <script type="text/javascript" src="editor.js"></script>
  </body>
</html>

In the editor, I just copy-pasted the codepen example:

document.onreadystatechange = () => {
  if (document.readyState === 'complete') {
    dostuff();
  }
};

function dostuff() {
    var numSocket = new D3NE.Socket("number", "Number value", "hint");

    var componentNum = new D3NE.Component("Number", {
       builder(node) {
          var out1 = new D3NE.Output("Number", numSocket);
          var numControl = new D3NE.Control('<input type="number">',
             (el, c) => {
                el.value = c.getData('num') || 1;

                function upd() {
                   c.putData("num", parseFloat(el.value));
                }

                el.addEventListener("input", ()=>{
                   upd();
                   editor.eventListener.trigger("change");
                });
                // prevent node movement when selecting text in the input field
                el.addEventListener("mousedown", function(e){e.stopPropagation()});
               upd();
             }
          );

          return node.addControl(numControl).addOutput(out1);
       },
       worker(node, inputs, outputs) {
          outputs[0] = node.data.num;
       }
    });

    var componentAdd = new D3NE.Component("Add", {
       builder(node) {
          var inp1 = new D3NE.Input("Number", numSocket);
          var inp2 = new D3NE.Input("Number", numSocket);
          var out = new D3NE.Output("Number", numSocket);

          var numControl = new D3NE.Control(
             '<input readonly type="number">',
             (el, control) => {
                control.setValue = val => {
                   el.value = val;
                };
             }
          );

          return node
             .addInput(inp1)
             .addInput(inp2)
             .addControl(numControl)
             .addOutput(out);
       },
       worker(node, inputs, outputs) {
          var sum = inputs[0][0] + inputs[1][0];
          editor.nodes.find(n => n.id == node.id).controls[0].setValue(sum);
          outputs[0] = sum;
       }
    });

    var menu = new D3NE.ContextMenu({
       Values: {
          Value: componentNum,
          Action: function() {
             alert("ok");
          }
       },
       Add: componentAdd
    });

    var container = document.getElementById("nodeEditor");
    var components = [componentNum, componentAdd];
    var editor = new D3NE.NodeEditor("[email protected]", container, components, null);

    var nn = componentNum.newNode();
    nn.data.num = 2;
    var n1 = componentNum.builder(nn);
    var n2 = componentNum.builder(componentNum.newNode());
    var add = componentAdd.builder(componentAdd.newNode());

    n1.position = [80, 200];
    n2.position = [80, 400];
    add.position = [500, 240];

    editor.connect(n1.outputs[0], add.inputs[0]);
    editor.connect(n2.outputs[0], add.inputs[1]);

    editor.addNode(n1);
    editor.addNode(n2);
    editor.addNode(add);
    //  editor.selectNode(tnode);

    var engine = new D3NE.Engine("[email protected]", components);

    editor.eventListener.on("change", async function() {
       await engine.abort();
       await engine.process(editor.toJSON());
    });

    editor.view.zoomAt(editor.nodes);
    editor.eventListener.trigger("change");
    editor.view.resize();
}

I just get this error and I don't know why:

d3-node-editor.js:1840 Uncaught ReferenceError: alight is not defined
    at ContextMenu.bindTemplate (d3-node-editor.js:1840)
    at new ContextMenu (d3-node-editor.js:1830)
    at dostuff (editor.js:66)
    at HTMLDocument.document.onreadystatechange (editor.js:3)

The call stack:

(editor.js:66)                   var menu = new D3NE.ContextMenu({
(d3-node-editor.js:1830)         this.bindTemplate(template$1());
(d3-node-editor.js:1840)         declareMenuDirectives(this, alight); // <- alight is not defined

I mean, I did include the alight library before the editor. I don't quite understand why this doesn't work. I also tried using require() (in electrons index.js), but that doesn't work either because the document is not defined. So I included the scripts in the html. I am not sure why it works in the codepen, but not locally.

JSON Format for Editor

Nodes is not an array. As a result, when trying to programatically generate JSON, manual editing of the produced JSON is required:

{ "id":"[email protected]", "nodes":[ { "id":1, "data":{"num":1}, "group":null, "inputs":[], "outputs":[ {"connections":[ {"node":3, "input":0 } ]} ], "position":[ 80, 200 ], "title":"Number" } ], "groups":{ } }

Needs changing to:
{ "id":"[email protected]", "nodes":{ "1":{ "id":1, "data":{"num":1}, "group":null, "inputs":[], "outputs":[ {"connections":[ {"node":3, "input":0 } ]} ], "position":[ 80, 200 ], "title":"Number" } }, "groups":{ } }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.