CINXE.COM
<!doctype html> <html lang="en" dir="ltr" class="blog-wrapper blog-tags-post-list-page plugin-blog plugin-id-default" data-has-hydrated="false"> <head> <meta charset="UTF-8"> <meta name="generator" content="Docusaurus v2.4.3"> <title data-rh="true">55 posts tagged with "svg" | Diagram and visual applications builder - JsPlumb Toolkit</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://jsplumbtoolkit.com/blog/tags/svg"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="keywords" content="kanban, erd, entity relationship diagram, flowchart, decision tree, entity relationship diagram, diagram, chatbot, chart, graph, gantt charts, network topology diagrams, visualization, javascript, diagramming library, typescript, charts, orgchart"><meta data-rh="true" property="og:image" content="https://jsplumbtoolkit.com/img/rendering-ports/reskinned-chatbot.png"><meta data-rh="true" property="og:site_name" content="JsPlumb Toolkit, leading diagramming and visual connectivity Javascript and Typescript library"><meta data-rh="true" property="og:title" content="55 posts tagged with "svg" | Diagram and visual applications builder - JsPlumb Toolkit"><meta data-rh="true" name="docusaurus_tag" content="blog_tags_posts"><meta data-rh="true" name="docsearch:docusaurus_tag" content="blog_tags_posts"><link data-rh="true" rel="icon" href="/img/favicon.ico"><link data-rh="true" rel="canonical" href="https://jsplumbtoolkit.com/blog/tags/svg"><link data-rh="true" rel="alternate" href="https://jsplumbtoolkit.com/blog/tags/svg" hreflang="en"><link data-rh="true" rel="alternate" href="https://jsplumbtoolkit.com/blog/tags/svg" hreflang="x-default"><link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Diagram and visual applications builder - JsPlumb Toolkit RSS Feed"> <link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Diagram and visual applications builder - JsPlumb Toolkit Atom Feed"> <link rel="preconnect" href="https://www.googletagmanager.com"> <script>window.dataLayer=window.dataLayer||[]</script> <script>!function(e,t,a,n,g){e[n]=e[n]||[],e[n].push({"gtm.start":(new Date).getTime(),event:"gtm.js"});var m=t.getElementsByTagName(a)[0],r=t.createElement(a);r.async=!0,r.src="https://www.googletagmanager.com/gtm.js?id=GTM-PNVM4WJV",m.parentNode.insertBefore(r,m)}(window,document,"script","dataLayer")</script> <script>var sc_project="12334448",sc_invisible=1,sc_security="71953373"</script> <script src="https://www.statcounter.com/counter/counter.js"></script> <link rel="alternate" type="application/rss+xml" href="/talking-tech/rss.xml" title="Diagram and visual applications builder - JsPlumb Toolkit RSS Feed"> <link rel="alternate" type="application/atom+xml" href="/talking-tech/atom.xml" title="Diagram and visual applications builder - JsPlumb Toolkit Atom Feed"> <script src="https://js.stripe.com/v3/"></script><link rel="stylesheet" href="/assets/css/styles.1542c693.css"> <link rel="preload" href="/assets/js/runtime~main.d7194b24.js" as="script"> <link rel="preload" href="/assets/js/main.58243ff6.js" as="script"> </head> <body class="navigation-with-keyboard"> <noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-PNVM4WJV" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <script>!function(){function t(t){document.documentElement.setAttribute("data-theme",t)}var e=function(){var t=null;try{t=new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}return t}()||function(){var t=null;try{t=localStorage.getItem("theme")}catch(t){}return t}();t(null!==e?e:"light")}()</script><div id="__docusaurus"> <div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.svg" alt="JsPlumb Toolkit" class="themedImage_ToTc themedImage--light_HNdA"><img src="/img/logo.svg" alt="JsPlumb Toolkit" class="themedImage_ToTc themedImage--dark_i4oU"></div><b class="navbar__title text--truncate"></b></a></div><div class="navbar__items navbar__items--right"><a aria-current="page" class="navbar__item navbar__link btn btn-link navbar__link--active" href="/blog">News</a><a class="navbar__item navbar__link btn btn-link" href="/features">Features</a><a class="navbar__item navbar__link btn btn-link" href="/demonstrations">Demonstrations</a><a href="https://docs.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link btn btn-link">Documentation</a><a class="navbar__item navbar__link btn btn-link" href="/contact">Contact</a><a href="https://licensing.jsplumbtoolkit.com/download/toolkit" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link btn btn-link">Download</a><a class="navbar__item navbar__link btn btn-secondary mx-2" href="/trial">Free trial</a><a href="https://licensing.jsplumbtoolkit.com/purchase/toolkit" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link btn btn-primary">Buy</a><div class="searchBox_ZlJk"></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0"><div class="container margin-vert--lg"><div class="row"><aside class="col col--3"><nav class="sidebar_re4s thin-scrollbar" aria-label="Blog recent posts navigation"><div class="sidebarItemTitle_pO2u margin-bottom--md">Recent posts</div><ul class="sidebarItemList_Yudw clean-list"><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/10/14/release-6.81.0">Release 6.81.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/10/04/release-6.80.0">Release 6.80.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/09/24/release-6.72.0">Release 6.72.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/09/16/release-6.71.0">Release 6.71.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/09/06/release-6.70.0">Release 6.70.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/08/26/release-6.60.0">Release 6.60.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/08/23/release-6.50.0">Release 6.50.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/08/16/release-6.40">Release 6.40.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/07/18/wrapping-data-in-web-components">Wrapping JsPlumb in Web Components</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/07/03/building-a-tile-game-with-drag-constrain-functions">Building a tile game using JsPlumb's advanced drag handling</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/26/release-6.30">Release 6.30.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/25/release-6.29.0">Release 6.29.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/23/unit-testing">Unit Testing with JsPlumb</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/23/release-6.28.0">Release 6.28.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/20/release-6.27.0">Release 6.27.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/18/release-6.26.0">Release 6.26.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/11/release-6.25.0">Release 6.25.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/06/06/release-6.24.0">Release 6.24.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/05/17/jsplumb-and-html2canvas">Generating output with html2canvas and JsPlumb</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/05/12/release-6.23.0">Release 6.23.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/04/19/release-6.22.0">Release 6.22.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/04/18/release-6.21.0">Release 6.21.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/04/08/release-6.20.0">Release 6.20.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/04/05/release-6.19.0">Release 6.19.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/04/04/release-6.18.0">Release 6.18.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/03/28/angular-signals-integration">Angular signals integration</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/03/26/release-6.17.0">Release 6.17.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/03/25/release-6.16.0">Release 6.16.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/02/18/release-6.15.0">Release 6.15.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/02/16/release-6.14.0">Release 6.14.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/02/02/release-2.50.0">Release 2.50.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2024/01/31/release-6.13.0">Release 6.13.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/12/28/release-6.12.0">Release 6.12.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/12/20/release-6.11.0">Release 6.11.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/12/11/animated-edges">Animating edges in SVG</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/12/10/release-6.10.0">Release 6.10.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/27/release-6.9.1">Release 6.9.1</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/22/release-6.9.0">Release 6.9.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/19/image-processing-with-canvas">Image processing with HTML canvas</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/17/rendering-ports">Rendering ports in the Toolkit</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/09/release-6.8.2">Release 6.8.2</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/08/release-6.8.1">Release 6.8.1</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/07/release-6.8.0">Release 6.8.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/11/03/magnetizing-diagram-elements">Magnetizing diagram elements</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/30/fixed-and-floating-elements">Fixed and floating elements (also, how the snaplines plugin works)</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/30/release-6.7.2">Release 6.7.2</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/25/release-6.7.1">Release 6.7.1</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/24/jsplumb-jointjs-comparison">JointJS - JsPlumb Comparison</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/19/release-6.7.0">Release 6.7.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/13/release-6.6.5">Release 6.6.5</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/10/release-6.6.4">Release 6.6.4</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/04/release-6.6.3">Release 6.6.3</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/04/angular-chatbot">Angular chatbot</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/10/03/how-to-build-a-chatbot-designer">Building a chatbot app in 3 hours and 37 minutes</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/09/26/release-6.6.2">Release 6.6.2 - Rotating custom overlays</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/09/24/jsplumb-element-rendering">The case for rendering to separate elements</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/09/20/release-6.6.0">Release 6.6.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/09/03/release-6.5.0">Release 6.5.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/06/21/release-6.2.5">Release 6.2.5</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2023/04/04/release-6.0.0">Release 6.0.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2022/11/28/release-5.13.1">Release 5.13.1</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2022/08/16/toolkit-release-5.10.8">Release 5.10.8</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2022/07/26/docusaurus-env-loader-json-plugin">Docusaurus JSON environment loader</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2022/05/21/angular-inputs-and-outputs">Angular Inputs and Outputs</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2022/05/20/custom-connectors">Custom connectors</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2022/02/10/anchor-position-finder-toolkit-edition">Anchor position finders</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2021/11/09/version-5.0.0">Version 5.0.0</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2021/09/06/docusaurus-and-statcounter">Statcounter plugin for Docusaurus</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2018/06/26/world-cup-visualisation-part-2">World Cup 2018, part 2</a></li><li class="sidebarItem__DBe"><a class="sidebarItemLink_mo7H" href="/blog/2018/06/25/world-cup-visualisation-part-1">World Cup 2018, part 1</a></li></ul></nav></aside><main class="col col--7" itemscope="" itemtype="http://schema.org/Blog"><header class="margin-bottom--xl"><h1>55 posts tagged with "svg"</h1><a href="/blog/tags">View All Tags</a></header><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="Release 6.81.0 contains a few nice ergonomic improvements to the Inspector, and to undo/redo functionality."><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/10/14/release-6.81.0">Release 6.81.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-10-14T06:00:00.000Z" itemprop="datePublished">October 14, 2024</time> · <!-- -->2 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>Release 6.81.0 contains a few nice ergonomic improvements to the Inspector, and to undo/redo functionality.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="inspector">Inspector<a href="#inspector" class="hash-link" aria-label="Direct link to Inspector" title="Direct link to Inspector"></a></h3><p>By default, the inspector will not write an empty string for a value where that value does not already have a value in some object's backing data. For example, consider our <a href="https://jsplumbtoolkit.com/demonstrations/flowchart-builder" target="_blank" rel="noopener noreferrer">Flowchart Builder</a> starter app - when you drag a new item onto the canvas, the inspector opens, and the focus is on the <code>Text</code> field:</p><p><img src="/img/release_6_81_0/inspector-blank-values.png" alt="Writing blank values with the inspector - JsPlumb, leading alternative to GoJS, JointJS and ReactFlow"></p><p>Since this inspector is set to <code>autoCommit</code>, a blur event (ie.the mouse is clicked somewhere else on the screen) will cause the inspector to write the current textfield contents into the object's backing data. This also has the effect of pushing an event onto the undo/redo stack. But in this case there is no effective change, from the user's point of view. Prior to 6.81.0, if the user subsequently presses 'undo', the first event that was undone was this update, which makes no discernible change from the user's perspective.</p><p> From 6.81.0 onwards, the inspector will not write out blank values to a data object if there was no previous value for that field in the object. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="edge-undoredo">Edge undo/redo<a href="#edge-undoredo" class="hash-link" aria-label="Direct link to Edge undo/redo" title="Direct link to Edge undo/redo"></a></h3><p> We've also made a change to the way edges are handled by undo/redo when your edge paths are editable. Prior to 6.81.0 when you dragged a new edge with the mouse, an edge add event was pushed onto the undo stack, and then a separate path edit event was pushed afterwards. This again was counterintuitive for a user, since from their perspective the new edge and its starting geometry form the entire event. In 6.81.0 we've remedied this situation: now when you drag a new edge and you have a path editor attached, only one event is pushed to the undo stack.</p><p>These couple of changes, whilst minor, make a big difference to the ergonomics of your app for your users.</p><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li><p>Read about JsPlumb's inspector component here: <a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/inspectors" target="_blank" rel="noopener noreferrer">https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/inspectors</a></p></li><li><p>Browse our docs on edge path editing: <a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/edges/edge-path-editing" target="_blank" rel="noopener noreferrer">https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/edges/edge-path-editing</a></p></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="Release 6.80.0 is a major update to our Svelte integration, with the introduction of a host of new components, plus a surface provider, making it easier than ever before to rapidly build visual connectivity apps."><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/10/04/release-6.80.0">Release 6.80.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-10-04T06:00:00.000Z" itemprop="datePublished">October 4, 2024</time> · <!-- -->4 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>Release 6.80.0 is a major update to our Svelte integration, with the introduction of a host of new components, plus a surface provider, making it easier than ever before to rapidly build visual connectivity apps.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="svelte-updates">Svelte Updates<a href="#svelte-updates" class="hash-link" aria-label="Direct link to Svelte Updates" title="Direct link to Svelte Updates"></a></h3><p>Where previously you'd have to manually instantiate a <code>ControlsComponent</code> or add a <code>MiniviewPlugin</code>, from 6.80.0 onwards these are supplied as Svelte components which can be declared as children of a <code>SurfaceComponent</code>:</p><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">{</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">MiniviewComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">SurfaceComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">ControlsComponent</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">'@jsplumbtoolkit/browser-ui-svelte'</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">const</span><span class="token script language-javascript"> data </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">nodes</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">id</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">label</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">left</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">50</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">top</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">50</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">id</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"2"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">label</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"TWO"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">left</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">250</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">top</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">250</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">edges</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">source</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">target</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"2"</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{data}</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ControlsComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">MiniviewComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="surfaceprovider">SurfaceProvider<a href="#surfaceprovider" class="hash-link" aria-label="Direct link to SurfaceProvider" title="Direct link to SurfaceProvider"></a></h3><p>In the above code, <code>ControlsComponent</code> and <code>MiniviewComponent</code> are able to locate the Surface to attach to because under the hood the <code>SurfaceComponent</code> has populated a Svelte context. We've also included a dedicated <code>SurfaceProvider</code> component which populates the context, and which you can use when you need to supply a surface reference to some other component, such as a <code>PaletteComponent</code> or <code>InspectorComponent</code>. You'll see this in a couple of the examples below.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="palettecomponent">PaletteComponent<a href="#palettecomponent" class="hash-link" aria-label="Direct link to PaletteComponent" title="Direct link to PaletteComponent"></a></h3><p>We've included a <code>PaletteComponent</code>, from which your users can drag new nodes/groups onto the canvas:</p><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">{</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">MiniviewComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">SurfaceComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">ControlsComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">PaletteComponent</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">'@jsplumbtoolkit/browser-ui-svelte'</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">const</span><span class="token script language-javascript"> </span><span class="token script language-javascript function-variable function" style="color:#d73a49">dataGenerator</span><span class="token script language-javascript"> </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">function</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript parameter">el</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword control-flow" style="color:#00009f">return</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">w</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">120</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">h</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">80</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">type</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript">el</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript method function property-access" style="color:#d73a49">getAttribute</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript string" style="color:#e3116c">"data-node-type"</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">const</span><span class="token script language-javascript"> data </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">nodes</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">id</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">label</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">left</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">50</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">top</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">50</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">id</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"2"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">label</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"TWO"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">left</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">250</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">top</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">250</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">edges</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">source</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">target</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"2"</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">row</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{data}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-9</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ControlsComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">MiniviewComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">PaletteComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">selector</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">li</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">dataGenerator</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{dataGenerator}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-3</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ul</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">li</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data-node-type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">foo</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">jtk-is-group</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">true</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain">FOO</span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">li</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">li</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data-node-type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">bar</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain">BAR</span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">li</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">ul</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">PaletteComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="shapelibrarypalettecomponent">ShapeLibraryPaletteComponent<a href="#shapelibrarypalettecomponent" class="hash-link" aria-label="Direct link to ShapeLibraryPaletteComponent" title="Direct link to ShapeLibraryPaletteComponent"></a></h3><p>We've included a <code>ShapeLibraryPaletteComponent</code>, a specialised instance of <code>PaletteComponent</code> that renders the contents of some <code>ShapeLibrary</code> and allows your uses to drag new SVG shapes onto the canvas.</p><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">{</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">MiniviewComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">SurfaceComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">ControlsComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">ShapeLibraryPaletteComponent</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">'@jsplumbtoolkit/browser-ui-svelte'</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript maybe-class-name">ShapeLibraryImpl</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript constant" style="color:#36acaa">FLOWCHART_SHAPES</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">"@jsplumbtoolkit/browser-ui"</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">const</span><span class="token script language-javascript"> shapeLibrary </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">new</span><span class="token script language-javascript"> </span><span class="token script language-javascript class-name">ShapeLibraryImpl</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript constant" style="color:#36acaa">FLOWCHART_SHAPES</span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">row</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{data}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-9</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">shapeLibrary</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{shapeLibrary}</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ControlsComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">MiniviewComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ShapeLibraryPaletteComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-3</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="inspectorcomponent">InspectorComponent<a href="#inspectorcomponent" class="hash-link" aria-label="Direct link to InspectorComponent" title="Direct link to InspectorComponent"></a></h3><p>We've included an <code>InspectorComponent</code>, which wraps the vanilla JS <code>Inspector</code> with a nice component-based API:</p><div class="tabs-container tabList__CuJ"><ul role="tablist" aria-orientation="horizontal" class="tabs"><li role="tab" tabindex="0" aria-selected="true" class="tabs__item tabItem_LNqP tabs__item--active">App</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">NodeInspector</li><li role="tab" tabindex="-1" aria-selected="false" class="tabs__item tabItem_LNqP">EdgeInspector</li></ul><div class="margin-top--md"><div role="tabpanel" class="tabItem_Ymn6"><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">{</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">SurfaceComponent</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">InspectorComponent</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">'@jsplumbtoolkit/browser-ui-svelte'</span><span class="token script language-javascript punctuation" style="color:#393A34">;</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">{</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">Node</span><span class="token script language-javascript imports punctuation" style="color:#393A34">,</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports maybe-class-name">Edge</span><span class="token script language-javascript imports"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> '@jsplumbtoolkit</span><span class="token script language-javascript operator" style="color:#393A34">/</span><span class="token script language-javascript">browser</span><span class="token script language-javascript operator" style="color:#393A34">-</span><span class="token script language-javascript">ui"</span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports maybe-class-name">NodeInspector</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">"./NodeInspector.svelte"</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports maybe-class-name">EdgeInspector</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">"./EdgeInspector.svelte"</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">const</span><span class="token script language-javascript"> inspectors </span><span class="token script language-javascript operator" style="color:#393A34">=</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript maybe-class-name">Node</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript property-access">objectType</span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript maybe-class-name">NodeInspector</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript maybe-class-name">Edge</span><span class="token script language-javascript punctuation" style="color:#393A34">.</span><span class="token script language-javascript property-access">objectType</span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript maybe-class-name">EdgeInspector</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">row</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{data}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-9</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">shapeLibrary</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{shapeLibrary}</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ControlsComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">MiniviewComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">InspectorComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-3</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">inspectors</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value" style="color:#e3116c">{inspectors}/</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">export</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">let</span><span class="token script language-javascript"> inspector </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">d-flex flex-column</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">input</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">text</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">jtk-att</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">label</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">enter node label</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">input</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">color</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">jtk-att</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">color</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div><div role="tabpanel" class="tabItem_Ymn6" hidden=""><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">export</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword" style="color:#00009f">let</span><span class="token script language-javascript"> inspector </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">class</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">d-flex flex-column</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">input</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">text</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">jtk-att</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">label</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">placeholder</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">enter edge label</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div></div></div></div><p>Those are a few of the key items, but there's a lot in this Svelte upgrade. The full changelog is:</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-functionality">New functionality<a href="#new-functionality" class="hash-link" aria-label="Direct link to New functionality" title="Direct link to New functionality"></a></h3><ul><li><p>Added <code>SurfaceProvider</code>, an element that provides context for various other elements, allowing things like the miniview or controls components to find the surface to attach to.</p></li><li><p>Added <code>MiniviewComponent</code>, which provides a miniview attached to some surface.</p></li><li><p>Added <code>ControlsComponent</code>, which provides a set of controls with basic operations such as zoom to extents, undo/redo, etc.</p></li><li><p>Added <code>ExportControlsComponent</code>, which provides a set of buttons from which users can export a diagram to SVG, PNG or JPG.</p></li><li><p>Added <code>PaletteComponent</code>, a component from which users can drag new nodes/groups onto the canvas.</p></li><li><p>Added <code>ShapeLibraryPaletteComponent</code>, a specialized version of <code>PaletteComponent</code> that renders the contents of a shape library, from which users can drag shapes onto the canvas.</p></li><li><p>Added <code>ShapeComponent</code>, an SVG shape renderer.</p></li><li><p>Added <code>InspectorComponent</code>, a Svelte wrapper around JsPlumb's <code>Inspector</code>. </p></li><li><p>Added <code>EdgeTypePickerComponent</code>, a component that renders samples of a list of edge types, and allows a user to select one.</p></li><li><p>The Svelte <code>SurfaceComponent</code> will now render a default component for nodes/groups if no explicit mapping is found in the view. This is great for rapid prototyping.</p></li><li><p>Added full JS docs for all interfaces in the Svelte integration.</p></li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-changes">Breaking changes<a href="#breaking-changes" class="hash-link" aria-label="Direct link to Breaking changes" title="Direct link to Breaking changes"></a></h3><ul><li><p>The props for the Svelte <code>SurfaceComponent</code> have changed:</p><ul><li><code>renderParams</code> is now <code>renderOptions</code></li><li><code>viewParams</code> is now <code>viewOptions</code></li><li><code>toolkitParams</code> is now <code>modelOptions</code></li></ul></li><li><p>You'll now need to use, at a minimum, Svelte 3.55. But we recommend using Svelte 4.</p></li></ul><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li><p>Checkout our new and improved API documentation here: <a href="https://apidocs.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">https://apidocs.jsplumbtoolkit.com</a></p></li><li><p>Read about JsPlumb's comprehensive Svelte integration here: <a href="https://angular.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://svelte.jsplumbtoolkit.com/</a></p></li><li><p>Browse our Svelte API docs here: <a href="https://apidocs.jsplumbtoolkit.com/6.x/current/browser-ui-svelte/" target="_blank" rel="noopener noreferrer">https://apidocs.jsplumbtoolkit.com/6.x/current/browser-ui-svelte/</a></p></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="This is a minor release, with the focus being on improving the JS docs, in conjunction with a major upgrade to https://docs.jsplumbtoolkit.com"><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/09/24/release-6.72.0">Release 6.72.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-09-24T06:00:00.000Z" itemprop="datePublished">September 24, 2024</time> · <!-- -->One min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>This is a minor release, with the focus being on improving the JS docs, in conjunction with a major upgrade to <a href="https://docs.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">https://docs.jsplumbtoolkit.com</a></p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="new-functionality">New functionality<a href="#new-functionality" class="hash-link" aria-label="Direct link to New functionality" title="Direct link to New functionality"></a></h3><ul><li>Added <code>onVertexAdded</code> input to Angular <code>ShapeLibraryPalette</code> component. </li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking">Breaking<a href="#breaking" class="hash-link" aria-label="Direct link to Breaking" title="Direct link to Breaking"></a></h3><ul><li>The <code>AnimationEvents</code> enum was removed and its members (<code>EVENT_END_OVERLAY_ANIMATION</code> etc) are now just exposed as constants. </li></ul><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li><p>Checkout our new and improved API documentation here: <a href="https://apidocs.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">https://apidocs.jsplumbtoolkit.com</a></p></li><li><p>Read about JsPlumb's comprehensive Angular integration here: <a href="https://angular.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://angular.jsplumbtoolkit.com/</a></p></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="In this release:"><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/09/16/release-6.71.0">Release 6.71.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-09-16T06:00:00.000Z" itemprop="datePublished">September 16, 2024</time> · <!-- -->2 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>In this release:</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="connectors">Connectors<a href="#connectors" class="hash-link" aria-label="Direct link to Connectors" title="Direct link to Connectors"></a></h3><ul><li>We've "undeprecated" the usage of static connector type names, such as <code>OrthogonalConnector.type</code>. Where previously we'd deprecated these in favour of string constants (such as <code>CONNECTOR_TYPE_ORTHOGONAL</code>), we - and some licensees - have found that in some situations using the string constant causes a tree shaker to leave the connector code out. This was particularly prevalent in Angular apps. We recommend now using the static type names, even if you're not using Angular.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="adhoc-layouts">Adhoc Layouts<a href="#adhoc-layouts" class="hash-link" aria-label="Direct link to Adhoc Layouts" title="Direct link to Adhoc Layouts"></a></h3><ul><li>The <code>adHocLayout</code> method of the Surface now clears the geometry of all the edges in the canvas, because edited edge paths are intrinsically linked to the position of their source and target vertices, and the <code>adHocLayout</code> method can arbitrarily move any vertex.</li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="angular-integration">Angular integration<a href="#angular-integration" class="hash-link" aria-label="Direct link to Angular integration" title="Direct link to Angular integration"></a></h3><ul><li>We added optional <code>data</code> and <code>url</code> inputs to the <code>jsplumb-surface</code> component in the Angular integration. You can now do things like this in your templates:</li></ul><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">jsplumb-surface</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[toolkitParams]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">toolkitParams</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[renderParams]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">renderParams</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[view]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">view</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">url</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">/assets/dataset.json</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">jsplumb-surface</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>or</p><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">jsplumb-surface</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[toolkitParams]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">toolkitParams</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[renderParams]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">renderParams</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[view]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">view</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"></span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">[data]</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">data</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">jsplumb-surface</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>instead of having to declare a <code>@ViewChild</code> and load the data afterwards.</p><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li>Read about JsPlumb's comprehensive Angular integration here: <a href="https://angular.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://angular.jsplumbtoolkit.com/</a></li><li>Read about JsPlumb's connector types here: <a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/connectors" target="_blank" rel="noopener noreferrer">https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/connectors</a></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="In release 6.70.0 we've updated our Vue 3 integration to make it more modern and easier to use, with reduced boilerplate and better documentation."><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/09/06/release-6.70.0">Release 6.70.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-09-06T06:00:00.000Z" itemprop="datePublished">September 6, 2024</time> · <!-- -->3 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>In release 6.70.0 we've updated our Vue 3 integration to make it more modern and easier to use, with reduced boilerplate and better documentation. </p><p>It is now optional to set <code>surfaceId</code> on the <code>SurfaceComponent</code>, <code>MiniviewComponent</code>, <code>ControlsComponent</code>, <code>ExportControlsComponent</code> and <code>ShapePaletteComponent</code> - the components will use a default value if not provided.</p><p>With these changes you can now get up and running with JsPlumb Vue quicker than ever:</p><div class="language-html codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-html codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">template</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag special-attr attr-name" style="color:#00a4db">style</span><span class="token tag special-attr attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag special-attr attr-value punctuation" style="color:#393A34">"</span><span class="token tag special-attr attr-value value css language-css property" style="color:#36acaa">width</span><span class="token tag special-attr attr-value value css language-css punctuation" style="color:#393A34">:</span><span class="token tag special-attr attr-value value css language-css number" style="color:#36acaa">100</span><span class="token tag special-attr attr-value value css language-css unit" style="color:#e3116c">%</span><span class="token tag special-attr attr-value value css language-css punctuation" style="color:#393A34">;</span><span class="token tag special-attr attr-value value css language-css property" style="color:#36acaa">height</span><span class="token tag special-attr attr-value value css language-css punctuation" style="color:#393A34">:</span><span class="token tag special-attr attr-value value css language-css number" style="color:#36acaa">100</span><span class="token tag special-attr attr-value value css language-css unit" style="color:#e3116c">%</span><span class="token tag special-attr attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">:data</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">this.getData()</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ControlsComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">MiniviewComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">template</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">import</span><span class="token script language-javascript"> </span><span class="token script language-javascript imports punctuation" style="color:#393A34">{</span><span class="token script language-javascript imports"> defineComponent </span><span class="token script language-javascript imports punctuation" style="color:#393A34">}</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">from</span><span class="token script language-javascript"> </span><span class="token script language-javascript string" style="color:#e3116c">"vue"</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">export</span><span class="token script language-javascript"> </span><span class="token script language-javascript keyword module" style="color:#00009f">default</span><span class="token script language-javascript"> </span><span class="token script language-javascript function" style="color:#d73a49">defineComponent</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">methods</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript function-variable function" style="color:#d73a49">getData</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript keyword" style="color:#00009f">function</span><span class="token script language-javascript punctuation" style="color:#393A34">(</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript keyword control-flow" style="color:#00009f">return</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">data</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">nodes</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">id</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">label</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">left</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">50</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">top</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">50</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">id</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"2"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">label</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"TWO"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">left</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">250</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">top</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript number" style="color:#36acaa">250</span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">edges</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript punctuation" style="color:#393A34">[</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">{</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">source</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"1"</span><span class="token script language-javascript punctuation" style="color:#393A34">,</span><span class="token script language-javascript"> </span><span class="token script language-javascript literal-property property" style="color:#36acaa">target</span><span class="token script language-javascript operator" style="color:#393A34">:</span><span class="token script language-javascript string" style="color:#e3116c">"2"</span><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">]</span><span class="token script language-javascript"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"> </span><span class="token script language-javascript punctuation" style="color:#393A34">}</span><span class="token script language-javascript punctuation" style="color:#393A34">)</span><span class="token script language-javascript"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token script language-javascript"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">script</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We've also made a bunch of other nice changes in this release. The full changelog is:</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="updates">Updates<a href="#updates" class="hash-link" aria-label="Direct link to Updates" title="Direct link to Updates"></a></h3><ul><li><p>None of the Vue 3 components require a <code>surface-id</code> prop anymore. For the vast majority of apps, having a single surface, that means you can rely on the defaults and remove a bunch of boilerplate from your templates.</p></li><li><p>If you do not provide a component to map a node or a group, the Vue 3 integration will now use a default component.</p></li><li><p>Vue 3's <code>loadSurface</code> method now makes surfaceId optional: if you omit it, JsPlumb will use the default surface id.</p></li><li><p>We've added a <code>ControlsComponent</code> to our Vue 3 integration</p></li><li><p>We've added an <code>ExportControlsComponent</code> to our Vue 3 integration</p></li><li><p>We've added an <code>ExportControlsComponent</code> to our React integration</p></li><li><p>Our Vue 3 docs have been updated to be easier to follow and to find the things you need.</p></li><li><p>The <code>ControlsComponent</code> in the React integration was updated to honour an orientation prop set on it.</p></li><li><p>You can pass an optional <code>typeParameter</code> and/or <code>categoryParameter</code> to the constructor of ShapeLibraryImpl. This allows you to override the parameters the shape library will use from each vertex's data to resolve the shape to use.</p></li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-changes">Breaking changes<a href="#breaking-changes" class="hash-link" aria-label="Direct link to Breaking changes" title="Direct link to Breaking changes"></a></h3><p>A few components were renamed in the Vue 3 integration:</p><ul><li><code>jsplumb-toolkit</code> is now <code>SurfaceComponent</code></li><li><code>jsplumb-miniview</code> is now <code>MiniviewComponent</code></li><li><code>jsplumb-shape</code> is now <code>ShapeComponent</code></li><li><code>jsplumb-shape-palette</code> is now <code>ShapePaletteComponent</code></li><li><code>jsplumb-edge-type-picker</code> is now <code>EdgeTypePicker</code></li></ul><p>In the Vue 3 SurfaceComponent:</p><ul><li><code>renderParams</code> was renamed to <code>renderOptions</code></li><li><code>view</code> was renamed to <code>viewOptions</code></li><li><code>toolkitParams</code> was renamed to <code>toolkitOptions</code></li></ul><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li>Read about JsPlumb's comprehensive Vue 3 integration here: <a href="https://vue.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://vue.jsplumbtoolkit.com/</a></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="In release 6.60.0 we've updated our Angular integration to make it more modern and easier to use, with support for signals, reduced boilerplate, and better documentation. The @jsplumbtoolkit/browser-ui-angular package now requires Angular 16 or later. Don't worry, though, if you're on a version of Angular older than 16: we've renamed our existing Angular integration to @jsplumbtoolkit/browser-ui-angular-legacy, and you can still use it."><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/08/26/release-6.60.0">Release 6.60.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-08-26T06:00:00.000Z" itemprop="datePublished">August 26, 2024</time> · <!-- -->3 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>In release 6.60.0 we've updated our Angular integration to make it more modern and easier to use, with support for signals, reduced boilerplate, and better documentation. The <code>@jsplumbtoolkit/browser-ui-angular</code> package now requires Angular 16 or later. Don't worry, though, if you're on a version of Angular older than 16: we've renamed our existing Angular integration to <code>@jsplumbtoolkit/browser-ui-angular-legacy</code>, and you can still use it. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="signals">Signals<a href="#signals" class="hash-link" aria-label="Direct link to Signals" title="Direct link to Signals"></a></h3><p>You may recall a post we wrote a few months ago, detailing how <a href="https://jsplumbtoolkit.com/blog/2024/03/28/angular-signals-integration" target="_blank" rel="noopener noreferrer">signals could be integrated with JsPlumb Angular</a>. We've taken the code we sketched out in that post and integrated it into a brand new <code>BaseNodeComponent</code>, which exposes the underlying vertex data as a signal - <code>objSignal</code> - and ensures that the signal is kept up to date to changes in the node's data.</p><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> Component</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> computed </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@angular/core"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> BaseNodeComponent </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@jsplumbtoolkit/browser-ui-angular"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">Component</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> template</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c"><div>{{myComputedValue()}}</div></span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">NodeComponent</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">extends</span><span class="token plain"> </span><span class="token class-name">BaseNodeComponent</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">readonly</span><span class="token plain"> myComputedValue </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">computed</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">this</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">objSignal</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token plain">values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token function" style="color:#d73a49">join</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">","</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We've also created <code>BaseGroupComponent</code>, for the sake of completeness. Prior to 6.60.0 users had to extend <code>BaseNodeComponent</code> when creating a component to render a group. </p><p><code>BasePortComponent</code> has also been updated to expose its underlying data object as a signal. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="reduced-boilerplate">Reduced boilerplate<a href="#reduced-boilerplate" class="hash-link" aria-label="Direct link to Reduced boilerplate" title="Direct link to Reduced boilerplate"></a></h3><ul><li><p>It is now optional to set <code>toolkitId</code> on a <code>SurfaceComponent</code>; the component will use a default value if not provided. Given that most apps have only one Toolkit model having to always provide a <code>toolkitId</code> was largely redundant.</p></li><li><p>It is now optional to set <code>surfaceId</code> on the <code>SurfaceComponent</code>, <code>MiniviewComponent</code>, <code>ControlsComponent</code> and <code>ShapeLibraryPaletteComponent</code>; the components will use a default value if not provided.</p></li></ul><p>With these changes you can now get up and running with JsPlumb Angular quicker than ever:</p><div class="language-typescript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-typescript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> Component </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@angular/core"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> NodeComponent </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./node.component"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token decorator at operator" style="color:#393A34">@</span><span class="token decorator function" style="color:#d73a49">Component</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> selector</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'app-component'</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> template</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string string" style="color:#e3116c"><div></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> <jsplumb-surface [view]="view" </span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> [renderParams]="renderParams"></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> </jsplumb-surface></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> <jsplumb-miniview></jsplumb-miniview></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> <jsplumb-controls></jsplumb-controls></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> </div></span><br></span><span class="token-line" style="color:#393A34"><span class="token template-string string" style="color:#e3116c"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">class</span><span class="token plain"> </span><span class="token class-name">AppComponent</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> view </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">default</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">NodeComponent</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> renderParams </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token operator" style="color:#393A34">...</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-changes">Breaking changes<a href="#breaking-changes" class="hash-link" aria-label="Direct link to Breaking changes" title="Direct link to Breaking changes"></a></h3><ul><li>The <code>@jsplumbtoolkit/browser-ui-angular</code> package now requires Angular 16 or later. If you are using a version of Angular older than 16, you will need to use our <code>@jsplumbtoolkit/browser-ui-angular-legacy</code> package.</li></ul><p>A few classes were renamed in the Angular integration (although note their selectors were unchanged):</p><ul><li><code>jsPlumbSurfaceComponent</code> is now <code>SurfaceComponent</code></li><li><code>jsPlumbMiniviewComponent</code> is now <code>MiniviewComponent</code></li><li><code>jsPlumbSurfaceDropComponent</code> is now <code>SurfaceDropComponent</code></li><li><code>jsPlumbDragDropComponent</code> is now <code>DragDropComponent</code></li><li>The original <code>BaseNodeComponent</code> is now <code>LegacyBaseNodeComponent</code></li><li>The original <code>BasePortComponent</code> is now <code>LegacyBasePortComponent</code></li></ul><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li><p>Read about JsPlumb's comprehensive Angular integration here: <a href="https://angular.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://angular.jsplumbtoolkit.com/</a></p></li><li><p>Read about JsPlumb's legacy Angular integration here: <a href="https://docs.jsplumbtoolkit.com/toolkit/lib/angular-integration-legacy" target="_blank" rel="noopener noreferrer">https://docs.jsplumbtoolkit.com/toolkit/lib/angular-integration-legacy</a></p></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="This release sees a few more updates to our React integration to make it easier than ever to use:"><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/08/23/release-6.50.0">Release 6.50.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-08-23T06:00:00.000Z" itemprop="datePublished">August 23, 2024</time> · <!-- -->3 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>This release sees a few more updates to our React integration to make it easier than ever to use:</p><ul><li><p>The <code>ShapeLibraryPaletteComponent</code> in the React integration no longer needs to be provided with a <code>shapeLibrary</code> as a prop - it retrieves the shape library from the Surface it is attached to.</p></li><li><p>A new <code>ShapeComponent</code> was added to the React integration. This component is functional and takes as a prop the <code>ctx</code> that the Surface passes to the mapping your view.</p></li><li><p>We've introduced a <code>JsxWrapperProps</code> interface to define the <code>ctx</code> member that the surface passes in to JSX mapped in your viewOptions.</p></li></ul><p>We've used these updates in our React Flowchart Builder starter app - they've really simplified the JSX in a couple of places. For example, our palette can now locate the shape library to use from the context given by the <code>SurfaceProvider</code>:</p><div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">shapeLibrary</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">shapeLibrary</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">....</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> ...</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag class-name" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">jtk-demo-rhs</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">ShapeLibraryPaletteComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">node-palette</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">dataGenerator</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">dataGenerator</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">initialSet</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript constant" style="color:#36acaa">FLOWCHART_SHAPES</span><span class="token tag script language-javascript punctuation" style="color:#393A34">.</span><span class="token tag script language-javascript property-access" style="color:#00009f">id</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">Inspector</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">edgeMappings</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript function" style="color:#d73a49">edgeMappings</span><span class="token tag script language-javascript punctuation" style="color:#393A34">(</span><span class="token tag script language-javascript punctuation" style="color:#393A34">)</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"></span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag class-name" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>And when using a shape component to render some SVG we now only need to pass in the <code>ctx</code> :</p><div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">NodeComponent</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">{</span><span class="token parameter">ctx</span><span class="token parameter punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">flowchart-object</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data-jtk-target</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">true</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">ShapeComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">ctx</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">ctx</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">showLabels</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript boolean" style="color:#36acaa">true</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">labelProperty</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">text</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain-text"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><code>ShapeComponent</code> gets the surface it is attached to from the context, and then it gets the shape library to use from the surface.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="changelog">Changelog<a href="#changelog" class="hash-link" aria-label="Direct link to Changelog" title="Direct link to Changelog"></a></h3><p>The full changelog is:</p><h4 class="anchor anchorWithStickyNavbar_LWe7" id="updates">Updates<a href="#updates" class="hash-link" aria-label="Direct link to Updates" title="Direct link to Updates"></a></h4><ul><li><p>The algorithm used to select a Dynamic anchor was adjusted to not add the delta between some anchor and the element's center to its calculations.</p></li><li><p>A new <code>ShapeComponent</code> was added to the React integration. This component is functional and takes as a prop the <code>ctx</code> that the Surface passes to the mapping your view. </p></li><li><p>The <code>ShapeLibraryPaletteComponent</code> in the React integration no longer needs to be provided with a <code>shapeLibrary</code> as a prop - it retrieves the shape library from the Surface it is attached to.</p></li><li><p>We've introduced a <code>JsxWrapperProps</code> interface to define the <code>ctx</code> member that the surface passes in to JSX mapped in your viewOptions.</p></li></ul><h4 class="anchor anchorWithStickyNavbar_LWe7" id="breaking">Breaking<a href="#breaking" class="hash-link" aria-label="Direct link to Breaking" title="Direct link to Breaking"></a></h4><ul><li><p>In the React integration, the original <code>ShapeComponent</code> has been renamed to <code>LegacyShapeComponent</code>.</p></li><li><p>In <code>jsplumbtoolkit.css</code>, the <code>.jtk-miniview</code> class is now specified <code>position:absolute</code> instead of <code>position:relative</code>. This better reflects how a miniview is typically used in the majority of UIs.</p></li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li>Read about JsPlumb's comprehensive React integration here: <a href="https://react.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://react.jsplumbtoolkit.com/</a></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="Release 6.40.0 is a fairly big release, containing:"><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/08/16/release-6.40">Release 6.40.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-08-16T06:00:00.000Z" itemprop="datePublished">August 16, 2024</time> · <!-- -->5 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>Release 6.40.0 is a fairly big release, containing:</p><ul><li><p><a href="#react-updates">A major update to our React integration</a>, with the introduction of contexts and providers, making it easier than ever before to rapidly build visual connectivity apps.</p></li><li><p>A vastly improved algorithm for repainting orthogonal connectors when the source or target node is dragged</p></li><li><p>Default node components in the Angular and React integration, allowing you to quickly prototype something without needing to focus on too many details upfront</p></li><li><p>Improvements to our documentation to make it easier to see how to achieve specific tasks with different integrations. This is an ongoing process but we've hit upon a basic structure now that we think works nicely.</p></li><li><p>A couple of bugfixes</p></li><li><p>An <a href="#hierarchy-layout">update to the Hierarchy layout</a> to support ports.</p></li></ul><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="react-updates">React Updates<a href="#react-updates" class="hash-link" aria-label="Direct link to React Updates" title="Direct link to React Updates"></a></h3><p>In 6.40.0 we have introduced <code>Contexts</code> and <code>Providers</code>, and we've rewritten our components so that they are all context aware. You no longer need to mount components inside a <code>useEffect</code> as they can find the surface they should attach to via a context:</p><div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">React</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"react"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">MiniviewComponent</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">SurfaceComponent</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">ControlsComponent</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@jsplumbtoolkit/browser-ui-react'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">DemoComponent</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">{</span><span class="token parameter">someProps</span><span class="token parameter punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> data </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">nodes</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">label</span><span class="token operator" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">left</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">top</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"2"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">label</span><span class="token operator" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"TWO"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">left</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">250</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">top</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">250</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">edges</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">source</span><span class="token operator" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"1"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">target</span><span class="token operator" style="color:#393A34">:</span><span class="token string" style="color:#e3116c">"2"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">SurfaceComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">data</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">ControlsComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">MiniviewComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag class-name" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>These changes also apply to our new <code>PaletteComponent</code>, which is a replacement for the previous <code>JsPlumbToolkitDragDropComponent</code>. Here we see how to use one inside a <code>SurfaceProvider</code>:</p><div class="language-jsx codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-jsx codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">PaletteComponent</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">SurfaceComponent</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> </span><span class="token imports maybe-class-name">SurfaceProvder</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'@jsplumbtoolkit/browser-ui-react'</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">MyApp</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">dataGenerator</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">function</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">el</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">w</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">120</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">h</span><span class="token operator" style="color:#393A34">:</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">type</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">el</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">getAttribute</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"data-node-type"</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">row</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-9</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">SurfaceComponent</span><span class="token tag punctuation" style="color:#393A34">/></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">col-3</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag class-name" style="color:#00009f">PaletteComponent</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">selector</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">li</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">dataGenerator</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">dataGenerator</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">ul</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">li</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data-node-type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">foo</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">jtk-is-group</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">true</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text">FOO</span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">li</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"><</span><span class="token tag" style="color:#00009f">li</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">data-node-type</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">bar</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text">BAR</span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">li</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">ul</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag class-name" style="color:#00009f">PaletteComponent</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag class-name" style="color:#00009f">SurfaceProvider</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain-text"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain-text"> </span><span class="token tag punctuation" style="color:#393A34"></</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">></span><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We think these changes will make a big difference to how easy it is to build apps using JsPlumb React.</p><p>The full list of updates to React is:</p><ul><li><p><code>SurfaceContext</code> added to project. This is a Context that provides a Surface for other components to access.</p></li><li><p><code>SurfaceProvider</code> added to project. This provides a SurfaceContext.</p></li><li><p><code>SurfaceComponent</code> added. This is a new version of <code>JsPlumbToolkitSurfaceComponent</code> which is context aware, and which itself can act as a surface provider for other components.</p></li><li><p><code>MiniviewComponent</code> and <code>ControlsComponent</code> have been updated to be functional components, and to be context aware. For the most part these components can now simply be declared in your JSX with no configuration or mounting necessary.</p></li><li><p><code>JsPlumbProvider</code> added to project. This provides an instance of <code>JsPlumbToolkit</code> to any descendant components. Although not such a common use case, this provider can be used to render one instance of the Toolkit in multiple surfaces.</p></li><li><p><code>PaletteComponent</code> added. This is a new, functional, version of the original <code>SurfaceDropComponent</code>. It is context aware and can discover a Surface provided either from a <code>SurfaceComponent</code> or a <code>SurfaceProvider</code>. </p></li><li><p><code>ShapeLibraryPaletteComponent</code> is now a functional component that is context aware and can function within any context that provides a surface.</p></li><li><p><code>InspectorComponent</code> added. This is a context aware React wrapper around JsPlumb's <code>Inspector</code>. </p></li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="orthogonal-connector-redraw">Orthogonal connector redraw<a href="#orthogonal-connector-redraw" class="hash-link" aria-label="Direct link to Orthogonal connector redraw" title="Direct link to Orthogonal connector redraw"></a></h3><p>We've made several improvements to the algorithm that repaints an orthogonal connector when its source or target is moved. These updates are particularly noticeable when the edge is using Continuous anchors. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="hierarchy-layout">Hierarchy layout<a href="#hierarchy-layout" class="hash-link" aria-label="Direct link to Hierarchy layout" title="Direct link to Hierarchy layout"></a></h3><p>The Hierarchy layout has been updated to support edges that are from ports on nodes/groups, not just edges from nodes/groups themselves.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="inspectors">Inspectors<a href="#inspectors" class="hash-link" aria-label="Direct link to Inspectors" title="Direct link to Inspectors"></a></h3><ul><li><p>Added optional <code>filter</code> to <code>Inspector</code>, allowing you to control which elements the inspector will edit</p></li><li><p>Fixed an issue in the <code>Inspector</code> where in some cases the "active" css class was being added to its container even though there was no object to edit.</p></li></ul><h3 class="anchor anchorWithStickyNavbar_LWe7" id="default-component-mappings-for-react-and-angular">Default component mappings for React and Angular<a href="#default-component-mappings-for-react-and-angular" class="hash-link" aria-label="Direct link to Default component mappings for React and Angular" title="Direct link to Default component mappings for React and Angular"></a></h3><p>The Angular and React integrations now use a default node/group mapping if you do not provide one in your view. This lets you prototype things more quickly without having to get bogged down in details. </p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="breaking-changes">Breaking changes<a href="#breaking-changes" class="hash-link" aria-label="Direct link to Breaking changes" title="Direct link to Breaking changes"></a></h3><ul><li><p>The default layout for a Surface is now the <code>AbsoluteLayout</code>, where previously it was <code>EmptyLayout</code>.</p></li><li><p>The default endpoint is now <code>BlankEndpoint</code>, where previously it was <code>DotEndpoint</code>.</p></li><li><p>The default anchor is now <code>Continuous</code>, where previously it was <code>AnchorLocations.Bottom</code>.</p></li><li><p>When a user relocates the anchor point in an orthogonal connector with the mouse, the connector's geometry is now reset. We've never been too happy with the way the connector tries to reconstruct the user's intent and in 6.40.0 we decided that changing the anchor point was a decisive enough gesture that it signalled the user wanted to re-route the entire connector.</p></li></ul><p>In the React integration a few components have been renamed and several marked deprecated, due to the new components discussed below. Specifically, the changes are:</p><ul><li>The original <code>ShapeLibraryPaletteComponent</code> is now <code>JsPlumbToolkitShapeLibraryPaletteComponent</code></li><li>The original <code>ControlsComponent</code> is now <code>JsPlumbToolkitControlsComponent</code></li><li>The original <code>MiniviewComponent</code> is now <code>JsPlumbToolkitMiniviewComponent</code></li></ul><p>It may not be evident that these changes have occurred since for each of the classes renamed we have created new versions with the original names, as functional components that are able to operate inside the <code>SurfaceProvider</code> which was introduced in 6.40.0.</p><p>Props and state for each of these components were also renamed - where you see something prefixed with <code>JsPlumbToolkit</code>, you know it's now legacy code and will be removed in a future release.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li><p>Read about JsPlumb's comprehensive React integration here: <a href="https://react.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://react.jsplumbtoolkit.com/</a></p></li><li><p>Check out the smooth connector redraw in our <a href="https://jsplumbtoolkit.com/demonstrations/flowchart-builder" target="_blank" rel="noopener noreferrer">Flowchart starter app</a> </p></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="Many libraries offer the ability to drag elements around, but JsPlumb's drag handler is a little more advanced than most: there are a number of options you can set on JsPlumb to get very fine-grained control of how your users drag elements around. One of these - the constrainFunction - is the focus of our post today, and we'll show you how it can be used to make a simple tile game with the minimum of effort."><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/07/03/building-a-tile-game-with-drag-constrain-functions">Building a tile game using JsPlumb's advanced drag handling</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-07-03T06:00:00.000Z" itemprop="datePublished">July 3, 2024</time> · <!-- -->8 min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>Many libraries offer the ability to drag elements around, but JsPlumb's drag handler is a little more advanced than most: there are a number of options you can set on JsPlumb to get very fine-grained control of how your users drag elements around. One of these - the <code>constrainFunction</code> - is the focus of our post today, and we'll show you how it can be used to make a simple tile game with the minimum of effort.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="constrain-functions">Constrain functions<a href="#constrain-functions" class="hash-link" aria-label="Direct link to Constrain functions" title="Direct link to Constrain functions"></a></h3><p>In this first canvas, you can drag around each of the nodes as you please: </p><div class="tdemo tile-game-demo"></div><p>This is the default setup for JsPlumb. But let's say in this case want to impose the following constraints:</p><ul><li>Blue nodes can only be dragged horizontally</li><li>Red nodes can only be dragged vertically</li></ul><p>How can we do that? That's right! With a <code>constrainFunction</code>. We pass this to the <code>dragOptions</code> for our Surface:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token literal-property property" style="color:#36acaa">dragOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">constrainFunction</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">desiredLoc</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> el</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> parentBounds</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> size</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> currentLoc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> modelObject </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">jtk</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">modelObject</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">type</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"blue"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">y</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">modelObject</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">type</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"blue"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Try dragging the elements here - you'll see they conform to the rules given above:</p><div class="tdemo tile-game-demo"></div><p>Our <code>constrainFunction</code> is given 5 pieces of information:</p><ul><li><strong>desiredLoc</strong> This is an object containing <code>x</code> and <code>y</code> values for where, in canvas coordinates, JsPlumb would like to drag the element to.</li><li><strong>el</strong> This is the DOM element that is being dragged. We can retrieve the associated model object via <code>el.jtk.node</code>.</li><li><strong>parentBounds</strong> This provides the size of the viewport; in some constrain scenarios this information is useful.</li><li><strong>size</strong> The size of the element being dragged.</li><li><strong>currentLoc</strong> An object containing <code>x</code> and <code>y</code> values for the element's current position.</li></ul><p>In our implementation, we test the <code>type</code> of the element. For <code>blue</code> elements we allow the desired X location but keep the current Y; for <code>red</code> elements we keep the current X but allow the desired Y:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> modelObject </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">jtk</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">modelObject</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">type</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"blue"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">y</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">modelObject</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">type</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"blue"</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="mixer-console">Mixer Console<a href="#mixer-console" class="hash-link" aria-label="Direct link to Mixer Console" title="Direct link to Mixer Console"></a></h3><p>One real world application that occurred to me as I was writing this is for the faders in a mixer:</p><div class="tile-game-demo tile-game-mixer-demo"></div><p>For this one we have a little helper function that computes the bounds based on the type of fader:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> travel </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">crossfade</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">desired</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> current</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">x</span><span class="token operator" style="color:#393A34">:</span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">190</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">max</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">50</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> desired</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">y</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">current</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">channel</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">desired</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> current</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">current</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">y</span><span class="token operator" style="color:#393A34">:</span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">240</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">max</span><span class="token punctuation" style="color:#393A34">(</span><span class="token number" style="color:#36acaa">80</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> desired</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>and the <code>constrainFunction</code> is:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function-variable function" style="color:#d73a49">constrainFunction</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">desiredLoc</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> el</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> parent</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> size</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> currentLoc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> modelObject </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> el</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">jtk</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">node</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> travel</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">modelObject</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">type</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">desiredLoc</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h3 class="anchor anchorWithStickyNavbar_LWe7" id="traversing-a-path">Traversing a path<a href="#traversing-a-path" class="hash-link" aria-label="Direct link to Traversing a path" title="Direct link to Traversing a path"></a></h3><p>Another very useful application for the ability to constrain dragging is traversing a path. In the canvas below you can drag the red marker horizontally and the vertical position will be calculated from the equation that defines the path (in this case, <code>y=x^2</code>):</p><div class="tile-game-demo tile-game-curve-demo"><button class="tile-game-curve-reset btn btn-secondary">reset</button><div class="tile-game-curve-coords"><div>0</div><div>0</div></div></div><p>In this example, our <code>constrainFunction</code> uses the function that defines the path to determine the Y value that corresponds to the current value of X:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function-variable function" style="color:#d73a49">constrainFunction</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">desiredLoc</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> el</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> parent</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> size</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> currentLoc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// pixels values</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> start </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> end </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">300</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// values in the coord system we're using</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> min </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> max </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">5</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> xRange </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> max </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> min</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// map the canvas pixel location to our chart's coordinate system </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mappedX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> min </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> start</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> end </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> xRange</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// compute the Y value in our chart's coordinate system. Note: we negate the value here, because in a browser, Y increases as you go down the screen. </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> mappedY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token function" style="color:#d73a49">fn</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mappedX</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// map the Y value back to canvas pixel coordinates</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">start </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">end </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">mappedY </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> min</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> xRange</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">x</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> y</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This approach works for any curve - here's <code>y=x^3</code>:</p><div class="tile-game-demo tile-game-curve-demo"><button class="tile-game-curve-reset btn btn-secondary">reset</button><div class="tile-game-curve-coords"><div>0</div><div>0</div></div></div><p>How about <code>y=sin(x)</code> ?</p><div class="tile-game-demo tile-game-curve-demo"><button class="tile-game-curve-reset btn btn-secondary">reset</button><div class="tile-game-curve-coords"><div>0</div><div>0</div></div></div><p>I like the look of these; I could go on for ages. But I promised a tile game, so let's talk about that.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="tiled-image-game">Tiled image game<a href="#tiled-image-game" class="hash-link" aria-label="Direct link to Tiled image game" title="Direct link to Tiled image game"></a></h3><p>It's likely you've seen one of these before - an image cut up into tiles and rearranged, with one blank space. Your task is to move the tiles around and reconstruct the original image.</p><p>So, here's an image of a cow. You may recall this cow from some of our other posts. We've loaded up this cow and, using <a href="/blog/2023/11/19/image-processing-with-canvas">the canvas processing library we wrote for our ImageProcessor demo</a>, we've cut it up into a 5x5 grid and drawn it out. You can drag the individual tiles around - go ahead and try:</p><div class="tile-game-demo tile-game-game-demo"></div><p>This is the first step - an image broken up into a grid, and dragging is constrained to the grid. We loaded up the image and then determined how big our tiles should be based on our required grid:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> tileCount </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">3</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> image </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Image</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method-variable function-variable method function property-access" style="color:#d73a49">onload</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> minAxis </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">min</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">width</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">height</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> tileSize </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">floor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">minAxis </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">image</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">src</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"/path/to/cow.jpg"</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We now split the image into a set of tiles, and each one of those tiles will be a node in our JsPlumb instance:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> promises </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34"><</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> x</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34"><</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> promises</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">cropImage</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">image</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tileSize </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> x</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tileSize </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tileSize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> tileSize</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token known-class-name class-name">Promise</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">all</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">promises</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">then</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">values</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> dataUrls </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> values</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">map</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">imageToDataURL</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34"><</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> x</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34"><</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> url </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> dataUrls</span><span class="token punctuation" style="color:#393A34">[</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> y</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">push</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">id</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">x</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string string" style="color:#e3116c">_</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">${</span><span class="token template-string interpolation">y</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#393A34">}</span><span class="token template-string template-punctuation string" style="color:#e3116c">`</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> url</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">width</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> tileSize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">height</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> tileSize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">left</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileSize</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">top</span><span class="token operator" style="color:#393A34">:</span><span class="token plain">y </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> toolkit</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">load</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">data</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>That second section of code also runs inside the <code>onload</code> for the image. At that point we have the result shown above - an image, split into tiles, and rendered as individual nodes.</p><p>The next steps are:</p><ul><li>Pick a random tile to leave blank</li><li>Randomly arrange the tiles</li></ul><p>We're going to introduce two variables - <code>emptyTileX</code> and <code>emptyTileY</code> - to track the grid location of the empty tile.</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// a random sort of the nodes.</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain">nodes</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">sort</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">a</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> b</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">random</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">></span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0.5</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">?</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">-</span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// random grid position for the x/y of the empty tile</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> emptyTileX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">floor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">random</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> emptyTileY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">floor</span><span class="token punctuation" style="color:#393A34">(</span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">random</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// nodes are stored in a linear array; this gives us the array index </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// for the empty tile</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> tileToOmitIndex </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">emptyTileX </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> emptyTileY</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Lastly, we now need to update the nodes array to set new positions after they've been randomly ordered, and we also set <code>blank</code> value on our blank node:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34"><</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> x</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">for</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token keyword" style="color:#00009f">let</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">0</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34"><</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"> y</span><span class="token operator" style="color:#393A34">++</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> idx </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileCount</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">+</span><span class="token plain"> y</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">idx</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">left</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> x </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">idx</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">top</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> y </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> nodes</span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">idx</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">blank</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> idx </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> tileToOmitIndex</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>This gives us:</p><div class="tile-game-demo tile-game-game-demo"></div><p>Almost there. But we still need to constrain dragging. Our <code>constrainFunction</code> looks like this:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token function-variable function" style="color:#d73a49">constrainFunction</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">desiredLoc</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> el</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> parent</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> size</span><span class="token parameter punctuation" style="color:#393A34">,</span><span class="token parameter"> currentLoc</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// get the grid position for the target location and for the current location</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> targetGridX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> targetGridY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> desiredLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> currentGridX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> currentGridY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> currentLoc</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// only tiles rthat are adjacent in one direction are candidates for being</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// dragged into the empty slot </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> dx </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">abs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">targetGridX </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> currentGridX</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> dy </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token known-class-name class-name">Math</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">abs</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">targetGridY </span><span class="token operator" style="color:#393A34">-</span><span class="token plain"> currentGridY</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> isAdjacent </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> dx </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&&</span><span class="token plain"> dy </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> dx </span><span class="token operator" style="color:#393A34">!==</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&&</span><span class="token plain"> dy </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">isAdjacent</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> currentLoc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic">// finally, if the target is the empty slot, allow the tile to be dragged there. </span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">targetGridX </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> emptyTileX </span><span class="token operator" style="color:#393A34">&&</span><span class="token plain"> targetGridY </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> emptyTileY </span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> desiredLoc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">else</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> currentLoc</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>We also want to ensure we keep track of the empty slot, so we have this event listener:</p><div class="language-javascript codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-javascript codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#393A34"><span class="token literal-property property" style="color:#36acaa">events</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token constant" style="color:#36acaa">EVENT_NODE_MOVE_END</span><span class="token punctuation" style="color:#393A34">]</span><span class="token operator" style="color:#393A34">:</span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">p</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token keyword control-flow" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">pos</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> emptyTileY </span><span class="token operator" style="color:#393A34">&&</span><span class="token plain"> p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">pos</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize </span><span class="token operator" style="color:#393A34">===</span><span class="token plain"> emptyTileX</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> emptyTileY </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">originalPosition</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">y</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> emptyTileX </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> p</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">originalPosition</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">x</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">/</span><span class="token plain"> tileSize</span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg viewBox="0 0 24 24" class="copyButtonIcon_y97N"><path fill="currentColor" d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg viewBox="0 0 24 24" class="copyButtonSuccessIcon_LjdS"><path fill="currentColor" d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>And here's the final result:</p><div class="tile-game-demo tile-game-game-demo"></div><p>Too easy? How about this then:</p><div class="tile-game-demo tile-game-game-demo"></div><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li><p>Read about dragging elements with JsPlumb here: <a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/element-dragging" target="_blank" rel="noopener noreferrer">https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/element-dragging</a></p></li><li><p>Checkout our Image Processing example: <a href="https://jsplumbtoolkit.com/blog/2023/11/19/image-processing-with-canvas" target="_blank" rel="noopener noreferrer">https://jsplumbtoolkit.com/blog/2023/11/19/image-processing-with-canvas</a></p></li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jointjs">jointjs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/reactflow">reactflow</a></li></ul></div></footer></article><article class="margin-bottom--xl" itemprop="blogPost" itemscope="" itemtype="http://schema.org/BlogPosting"><meta itemprop="description" content="Release 6.30.0 contains a small update to the Angular integration that fixes an issue that can arise when updating ports inside an Angular component that were not rendered via the BasePortComponent. An example of that can be seen in our Angular Chatbot demo."><header><h2 class="title_f1Hy" itemprop="headline"><a itemprop="url" href="/blog/2024/06/26/release-6.30">Release 6.30.0</a></h2><div class="container_mt6G margin-vert--md"><time datetime="2024-06-26T06:00:00.000Z" itemprop="datePublished">June 26, 2024</time> · <!-- -->One min read</div><div class="margin-top--md margin-bottom--sm row"><div class="col col--6 authorCol_Hf19"><div class="avatar margin-bottom--sm"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" class="avatar__photo-link"><img class="avatar__photo" src="https://avatars.githubusercontent.com/u/262720?s=60&v=4" alt="Simon Porritt" itemprop="image"></a><div class="avatar__intro" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><div class="avatar__name"><a href="https://github.com/sporritt" target="_blank" rel="noopener noreferrer" itemprop="url"><span itemprop="name">Simon Porritt</span></a></div><small class="avatar__subtitle" itemprop="description">JsPlumb core team</small></div></div></div></div></header><div class="markdown" itemprop="articleBody"><p>Release 6.30.0 contains a small update to the Angular integration that fixes an issue that can arise when updating ports inside an Angular component that were not rendered via the <code>BasePortComponent</code>. An example of that can be seen in our Angular Chatbot demo.</p><hr><h3 class="anchor anchorWithStickyNavbar_LWe7" id="further-reading">Further reading<a href="#further-reading" class="hash-link" aria-label="Direct link to Further reading" title="Direct link to Further reading"></a></h3><ul><li>Read about JsPlumb's comprehensive Angular integration here: <a href="https://angular.jsplumbtoolkit.com/" target="_blank" rel="noopener noreferrer">https://angular.jsplumbtoolkit.com/</a> </li></ul><hr><h2 class="blog-trial-embed">Start a free trial</h2><p>Not a user of JsPlumb but thinking of checking it out? There's a whole lot more to discover and it's a great time to get started!</p><a href="/trial"><button class="btn btn-primary">Start a free trial</button></a><hr><h2 class="anchor anchorWithStickyNavbar_LWe7" id="get-in-touch">Get in touch!<a href="#get-in-touch" class="hash-link" aria-label="Direct link to Get in touch!" title="Direct link to Get in touch!"></a></h2><p>If you'd like to discuss any of the ideas/concepts in this article we'd love to hear from you - drop us a line at <a href="mailto:hello@jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer">hello@jsplumbtoolkit.com</a>.</p></div><footer class="row docusaurus-mt-lg"><div class="col"><b>Tags:</b><ul class="tags_jXut padding--none margin-left--sm"><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/toolkit">toolkit</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg">svg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/flowchart">flowchart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/inspector">inspector</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/erd">erd</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/svg-export">svg export</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/png">png</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpeg">jpeg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/jpg">jpg</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/apidocs">apidocs</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt">gantt</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/gantt-chart">gantt chart</a></li><li class="tag_QGVx"><a class="tag_zVej tagRegular_sFm0" href="/blog/tags/network-topology">network topology</a></li></ul></div></footer></article><nav class="pagination-nav" aria-label="Blog list page navigation"><a class="pagination-nav__link pagination-nav__link--next" href="/blog/tags/svg/page/2"><div class="pagination-nav__label">Older Entries</div></a></nav></main></div></div></div><footer class="footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">DISCOVER</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/demonstrations">Demonstrations</a></li><li class="footer__item"><a class="footer__link-item" href="/contact">Contact Us</a></li><li class="footer__item"><a class="footer__link-item" href="/faq">FAQ</a></li><li class="footer__item"><a href="/JSPLUMB-TOOLKIT-LICENSE-10-NOV-2023.pdf" target="_blank">License Agreement</a></li><li class="footer__item"><a class="footer__link-item" position="right" href="/privacy">Privacy Policy</a></li><li class="footer__item"><a class="footer__link-item" position="right" href="/talking-tech">Talking Tech</a></li></ul></div><div class="col footer__col"><div class="footer__title">DEVELOP</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://docs.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer" class="footer__link-item">Documentation</a></li><li class="footer__item"><a href="https://licensing.jsplumbtoolkit.com/download/toolkit" target="_blank" rel="noopener noreferrer" class="footer__link-item">Licensee Portal</a></li><li class="footer__item"><a href="https://licensing.jsplumbtoolkit.com/download/toolkit" target="_blank" rel="noopener noreferrer" class="footer__link-item">Download</a></li><li class="footer__item"><a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/npm-repository" target="_blank" rel="noopener noreferrer" class="footer__link-item">NPM Repository</a></li><li class="footer__item"><a class="footer__link-item" href="/trial">Try jsPlumb Toolkit for free</a></li></ul></div><div class="col footer__col"><div class="footer__title">LINKS</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/blog">News</a></li><li class="footer__item"><a href="https://licensing.jsplumbtoolkit.com/purchase/toolkit" target="_blank" rel="noopener noreferrer" class="footer__link-item">Pricing</a></li><li class="footer__item"> <div class="d-flex align-items-center mt-5"> <a href="https://github.com/jsplumb"><img class="me-2" src="/img/social-logos/github.svg" alt="github logo"></a> <a href="https://www.facebook.com/jsPlumbToolkit"><img class="mx-2" src="/img/social-logos/facebook.svg" alt="facebook logo"></a> <a href="https://www.linkedin.com/company/jsplumb/"><img class="mx-2" src="/img/social-logos/linkedin.svg" alt="linked in logo"></a> <a href="https://twitter.com/jsplumbtoolkit"><img class="mx-2" src="/img/social-logos/twitter.svg" alt="twitter logo"></a> </div></li></ul></div><div class="col footer__col"><div class="footer__title">INTEGRATIONS</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://angular.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer" class="footer__link-item">Angular</a></li><li class="footer__item"><a href="https://react.jsplumbtoolkit.com" target="_blank" rel="noopener noreferrer" class="footer__link-item">React</a></li><li class="footer__item"><a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/vue2-integration" target="_blank" rel="noopener noreferrer" class="footer__link-item">Vue 2</a></li><li class="footer__item"><a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/vue3-integration" target="_blank" rel="noopener noreferrer" class="footer__link-item">Vue 3</a></li><li class="footer__item"><a href="https://docs.jsplumbtoolkit.com/toolkit/6.x/lib/svelte-integration" target="_blank" rel="noopener noreferrer" class="footer__link-item">Svelte</a></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><a href="https://jsplumbtoolkit.com" rel="noopener noreferrer" class="footerLogoLink_BH7S"><img src="/img/logo-white.svg" alt="jsPlumb Toolkit" class="themedImage_ToTc themedImage--light_HNdA footer__logo" width="160" height="51"><img src="/img/logo-white.svg" alt="jsPlumb Toolkit" class="themedImage_ToTc themedImage--dark_i4oU footer__logo" width="160" height="51"></a></div><div class="footer__copyright">Copyright © 2024 JSPLUMB PTY LTD.</div></div></div></footer></div> <script src="/assets/js/runtime~main.d7194b24.js"></script> <script src="/assets/js/main.58243ff6.js"></script> </body> </html>