{"id":20081253,"url":"https://github.com/depuits/ned","last_synced_at":"2025-05-06T00:31:07.441Z","repository":{"id":86549600,"uuid":"75306352","full_name":"depuits/ned","owner":"depuits","description":"Javascript node editor ui","archived":false,"fork":false,"pushed_at":"2024-01-19T13:39:54.000Z","size":44,"stargazers_count":30,"open_issues_count":0,"forks_count":8,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-09T06:06:14.060Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://depuits.github.io/ned/index.html","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/depuits.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-12-01T15:34:23.000Z","updated_at":"2024-07-01T17:25:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"f3c9ed07-4756-44b4-9436-bcd2e2da9425","html_url":"https://github.com/depuits/ned","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depuits%2Fned","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depuits%2Fned/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depuits%2Fned/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/depuits%2Fned/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/depuits","download_url":"https://codeload.github.com/depuits/ned/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252598230,"owners_count":21774224,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-13T15:34:05.149Z","updated_at":"2025-05-06T00:31:07.170Z","avatar_url":"https://github.com/depuits.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ned\nSimple javascript node editor using svg graphics. A working example can be found [here](https://depuits.github.io/ned).\n\n Some **SVG2** features are required. Currently working and tested in **Chrome**. \n\nThe panning and zooming in the example uses [svg-pan-zoom](https://github.com/bumbu/svg-pan-zoom) but any pan and/or zoom could be used.\n\n## Examples\n* [Pan and zoom](https://depuits.github.io/ned/index.html)\n* [Dual pannels](https://depuits.github.io/ned/examples/dual.html)\n* [Html content](https://depuits.github.io/ned/examples/content.html)\n\n## How To Use\nFor a complete look on how everything works you can take a look at the [index.html](./index.html).\n\n### Editor\nCreate and init an editor using `Ned.Create(arg)`. The argument to function should be a CSS selector or a DOM Element.\n```javascript\nvar editor = Ned.create(\"#svg\");\n// or\nvar svgElement = document.querySelector(\"#svg\");\nvar editor = Ned.create(svgElement);\n```\n\nAfter creating an editor you can setup the options and create nodes.\n\n#### Options\n+ `snapping`: value to snap nodes to (`0` or `false` is disabled). Default is `0`.\n+ `singleInputs`: when `true` input connectors only allow a single connection. Default is `false`.\n+ `singleOutputs`: when `true` output connectors only allow a single connection. Default is `false`.\n+ `screenToWorld`: function to translate screen coördinates to world coördinates. This is used to corectly position nodes and paths when you enable a pan and/or zoom on the svg. Default is `(pos) =\u003e { return pos; }`.\n\nThe `screenToWorld` function should be correctly set before any connections are made. Any paths added before this will be drawn incorrectly. The caliing context of this method is the editor trying to translate the position.\n\nScreenToWorld example with svg position offset.\n```javascript\neditor.screenToWorld = function(pos) {\n\tvar rect = this.svg.getBoundingClientRect();\n\n\treturn { \n\t\tx: (pos.x - rect.left), \n\t\ty: (pos.y - rect.top)\n\t};\n};\n```\n\nScreenToWorld example with svg position offset and pan and zoom using [ariutta svg-pan-zoom](https://github.com/ariutta/svg-pan-zoom).\n```javascript\nvar panZoom = svgPanZoom(editor.svg);\n\neditor.screenToWorld = function(pos) {\n\tvar rect = this.svg.getBoundingClientRect();\n\tvar pan = this.panZoom.getPan();\n\tvar zoom = this.panZoom.getZoom();\n\n\treturn { \n\t\tx: (((pos.x - rect.left) - pan.x) / zoom), \n\t\ty: (((pos.y - rect.top) - pan.y) / zoom)\n\t};\n};\n```\n\n### Nodes\nNodes can simple be created by calling \n```javascript\n// create a new node\nvar n1 = editor.createNode(\"Node title\");\n\n// position and size the node\nn1.position = { x: 100, y: 180};\nn1.size = { width: 100, height: 60 };\n```\n\n#### Connectors\nConnectors are the link points of the nodes. Any node can have as many or little connectors as needed. Connectors are split in two groups: input and output. To add connectors you call\n```javascript\n// a node n1 was already created\nvar n1i1 = n1.addInput(\"Input name\");\nvar n1o1 = n1.addOutput(\"Output name\");\n```\n\nConnections can be made by simply calling the `connectTo` function on a connector and passing in the target connector. If a connection can not be made the function will return `false`.\n```javascript\nn1o1.connectTo(n2i1);\n```\n\nDepending on the editor settings for `singleInputs` and `singleOutputs` the number of possible connections is limited.\n\n## Customization\nMost of the visual customization can be done inside the [css](./ned.css).\n\nCustom content can be added to the `eForeign` object. A working example can be found [here](https://depuits.github.io/ned/examples/content.html).\n```javascript\nvar n1 = editor.createNode(\"Test node\");\nn1.position = { x: 100, y: 180};\nn1.size = { width: 400, height: 200 };\n\nn1.eForeign.insertAdjacentHTML(\"afterbegin\", \n  `\u003cdiv class=\"nodeContent\"\u003e\n  \u003cselect\u003e\n    \u003coption\u003etest 1\u003c/option\u003e\n    \u003coption\u003etest 2\u003c/option\u003e\n    \u003coption\u003etest 3\u003c/option\u003e\n  \u003c/select\u003e\n  \u003ctextarea\u003eText must come here\u003c/textarea\u003e\n  \u003c/div\u003e\n  `);\n```\n\n\n## SVG structure\nThis is the default svg structure without any other libraries or other things in the svg. Except for the first ROOT svg element the structure is \"`DOM object` ClassName\".\n\n```\n`svg` ROOT  \n  │  \n  ├─ `g` Nodegroup  \n  │   ├─ `svg` NodeContainer  \n  │   │   ├─ `rect` Background  \n  │   │   ├─ `g` Header  \n  │   │   │   ├─ `rect`  \n  │   │   │   └─ `text`  \n  │   │   ├─ `svg` Inputs  \n  │   │   │   ├─ `svg` Input  \n  │   │   │   │   ├─ `text`  \n  │   │   │   │   └─ `circle`  \n  │   │   │   └─ ...  \n  │   │   ├─ `svg` Outputs  \n  │   │   │   ├─ `svg` Output  \n  │   │   │   │   ├─ `text`  \n  │   │   │   │   └─ `circle`  \n  │   │   │   └─ ...  \n  │   │   └─ `foreignObject`  \n  │   └─ ...  \n  └─ `g` PathGroup  \n      ├─ `path` Path  \n      └─ ...  \n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdepuits%2Fned","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdepuits%2Fned","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdepuits%2Fned/lists"}