{"id":20118488,"url":"https://github.com/flowfuse/flow-renderer","last_synced_at":"2025-10-12T21:50:31.585Z","repository":{"id":235867219,"uuid":"788337265","full_name":"FlowFuse/flow-renderer","owner":"FlowFuse","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-14T16:36:26.000Z","size":478,"stargazers_count":6,"open_issues_count":7,"forks_count":2,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-06T07:51:36.639Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/FlowFuse.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,"zenodo":null}},"created_at":"2024-04-18T08:12:39.000Z","updated_at":"2025-04-14T16:36:28.000Z","dependencies_parsed_at":"2024-05-16T16:46:46.696Z","dependency_job_id":"d0093af7-a26e-44bd-b7b3-6e9bf173eb57","html_url":"https://github.com/FlowFuse/flow-renderer","commit_stats":{"total_commits":39,"total_committers":6,"mean_commits":6.5,"dds":0.2564102564102564,"last_synced_commit":"0824f6d11872dd29723025727f0d52c82d498fe1"},"previous_names":["flowfuse/flow-renderer"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlowFuse%2Fflow-renderer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlowFuse%2Fflow-renderer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlowFuse%2Fflow-renderer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FlowFuse%2Fflow-renderer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FlowFuse","download_url":"https://codeload.github.com/FlowFuse/flow-renderer/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252703341,"owners_count":21790871,"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-13T19:11:05.316Z","updated_at":"2025-10-12T21:50:26.533Z","avatar_url":"https://github.com/FlowFuse.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FlowFuse Flow Renderer\n\nA library to render Node-RED flows in a web page.\n\n\n## Installation\n\n```bash\nnpm install @flowfuse/flow-renderer\n```\n\n## development\n\nAll client-side code is in the `index.js` file for easy inclusion in a web page.\n\nRun `npm run demo` to test the flow renderer in a browser.\n\nRun `npm run build` to build a minimised version of the flow renderer. This will output the file `index.min.js`.\n\nIMPORTANT: The minified version of the flow renderer should be built before committing changes to the repository.\n\n## Usage\n\nAdd the following script tag to your HTML file:\n\n```html\n\u003cscript type=\"module\" src=\"public/flow-renderer/index.min.js\"\u003e\u003c/script\u003e\n```\n_or wherever the script is located in your project_\n\nNext, add a container element to your HTML file and instantiate a `flowRenderer`.\nNOTE: flow-renderer is an ES Module and requires a modern browser to run. Script tags must have the `type=\"module\"` attribute.\n\nBy default, the flow renderer will render the flow with `gridLines`, `images`, `labels`, `zoom`, `autoZoom`, and `autoScroll` enabled.\n`linkLines` are disabled by default.\n\nTo operate the zoom, use the mouse wheel + \u003ckbd\u003eCtrl\u003c/kbd\u003e or \u003ckbd\u003e⌘\u003c/kbd\u003e key.\nTo scroll the container vertically, use the mouse wheel without the \u003ckbd\u003eShift\u003c/kbd\u003e key.\nTo scroll the container horizontally, use the mouse wheel + \u003ckbd\u003eShift\u003c/kbd\u003e key.\n\n\n\n### Basic example\n\n```html\n\u003cdiv id=\"nr-flow-1\" class=\"flow-renderer\" style=\"height: 300px\"\u003e\u003c/div\u003e\n```\n\n```html\n\u003cscript type=\"module\"\u003e\n  const renderer = new FlowRenderer()\n  const container1 = document.getElementById('nr-flow-1');\n  const flow = [{\"id\": \"1001\", \"type\": \"inject\", \"x\": 100, \"y\": 40, \"wires\": [[\"1002\"]]}, {\"id\": \"1002\", \"type\": \"debug\", \"x\":300, \"y\": 40}]\n  renderer.renderFlows(flow, { container: container1 })\n\u003c/script\u003e\n```\n\n### Inline Options example\n\nOptions can be set by data attributes `scope`, `grid-lines`, `zoom`, `images`, `link-lines`, `labels`, `auto-zoom`, `auto-scroll`.\n\nNOTE: To SET and option, the data attribute can simply be present on the container element. To UNSET an option, the data attribute must be set to `false`.\n\n```html\n\u003cdiv id=\"nr-flow-2\" style=\"height: 300px\" \n    data-scope=\"custom-css-scope\"\n    data-grid-lines\n    data-zoom\n    data-images\n    data-link-lines=\"false\"\n    data-labels\n    data-auto-zoom\n    data-auto-scroll\n\u003e\u003c/div\u003e\n```\n\n```html\n\u003cscript type=\"module\"\u003e\n  const renderer = new FlowRenderer()\n  const container2 = document.getElementById('nr-flow-2');\n  const flow = [{\"id\": \"1001\", \"type\": \"inject\", \"x\": 100, \"y\": 40, \"wires\": [[\"1002\"]]}, {\"id\": \"1002\", \"type\": \"debug\", \"x\":300, \"y\": 40}]\n  renderer.renderFlows(flow, { container: container2 })\n\u003c/script\u003e\n```\n\n\n### Full Options example\n\n```html\n\u003cdiv id=\"nr-flow-3\" class=\"my-scope\" style=\"height: 300px\"\u003e\u003c/div\u003e\n```\n\n```javascript\nconst renderer = new FlowRenderer()\nconst container3 = document.getElementById('nr-flow-3');\nconst flow = [{\"id\": \"1001\", \"type\": \"inject\", \"x\": 100, \"y\": 40, \"wires\": [[\"1002\"]]}, {\"id\": \"1002\", \"type\": \"debug\", \"x\":300, \"y\": 40}]\nrenderer.renderFlows(flow, {\n    container: container3,\n    scope: 'custom-css-scope', // scope for CSS\n    gridLines: true, // show gridLines\n    images: true, // show images\n    linkLines: false, // show link lines\n    labels: true, // show labels\n    zoom: true, // enable zoom within the container\n    autoZoom: true, // auto zoom to fit the flow within the container upon rendering (best fit, limited to 20% min, 100% max zoom)\n    autoScroll: true, // auto scroll the leftmost node to the left of the container and the topmost node to the top of the container upon rendering\n    flowId: undefined // Id of flow to display\n})\n```\n\n### Vue example\n\n```html\n    \u003cdiv id=\"app\"\u003e\n        \u003cdiv ref=\"f1\" class=\"flow-renderer\"\u003e\u003c/div\u003e\n    \u003c/div\u003e\n\n    \u003cscript type=\"module\"\u003e\n        import { createApp } from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'\n        import FlowRenderer from './index.js'\n        createApp({\n            mounted() {\n                const flow = [{\"id\": \"1001\", \"type\": \"inject\", \"x\": 100, \"y\": 40, \"wires\": [[\"1002\"]]}, {\"id\": \"1002\", \"type\": \"debug\", \"x\":300, \"y\": 40}]\n                const renderer = new FlowRenderer()\n                renderer.renderFlows(flow, { container: this.$refs.f1 })\n            }\n        }).mount('#app')\n    \u003c/script\u003e\n```\n\n\n### Basic example comparing to flows\n\n```html\n\u003cdiv id=\"nr-flow-1\" class=\"flow-renderer\" style=\"height: 300px\"\u003e\u003c/div\u003e\n```\n\n```html\n\u003cscript type=\"module\"\u003e\n  const renderer = new FlowRenderer()\n  const container1 = document.getElementById('nr-flow-1');\n  const flow1 = [{\"id\": \"1001\", \"type\": \"inject\", \"x\": 100, \"y\": 40, \"z\": \"9999\", \"wires\": [[\"1002\"]]}, {\"id\": \"1002\", \"type\": \"debug\", \"x\":300, \"y\": 40, \"z\": \"9999\"}]\n  const flow2 = [{\"id\": \"1001\", \"type\": \"inject\", \"x\": 120, \"y\": 40, \"z\": \"9999\", \"wires\": [[\"1002\"]]}, {\"id\": \"1002\", \"type\": \"debug\", \"x\":120, \"y\": 80, \"z\": \"9999\"}]\n  renderer.compare([flow1, flow2], { container: container1 })\n\u003c/script\u003e\n```\n\n\n## Acknowledgements\n\nThis project owes a huge thanks to Gerrit Riessen for his original works on [node-red-flowviewer](https://github.com/gorenje/node-red-flowviewer-js). It was this great contribution that started the ball rolling. Gerrit kindly allowed us relicense the parts we needed to use in this project.\n\n## Limitations\n\n* Only client-side rendering is currently supported\n* Mobile pinch zoom is not yet implemented\n* The flow renderer does not support the full range of contributed Node-RED nodes however they will render as a generic node type complete with the node's label.\n* The flow renderer does not always render the flows and nodes exactly as they appear in the Node-RED editor. This is due in part to being a client-side render with no server-side component to provide full context and partly due to the current limitations of the renderer itself.\n* The flow compare functionality is still in very early development and may not work as expected if the flows are too dissimilar or are not well formed exports from Node-RED.\n\n## Versioning\n\nWhile the API is in development, the version number of this package will remain at `0.x.y`.\n`x` will be incremented for breaking changes, `y` for new features and patches.\nOnce the API is stable, the version number will be updated to 1.0.0 and full SemVer rules will be applied.\n\n## License\n\nApache-2.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowfuse%2Fflow-renderer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fflowfuse%2Fflow-renderer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fflowfuse%2Fflow-renderer/lists"}