The minimal javascript library to create flowcharts ✨

Overview

Flowy

Demo
A javascript library to create pretty flowcharts with ease

Dribbble | Twitter | Live demo

Flowy makes creating WebApps with flowchart functionality an incredibly simple task. Build automation software, mind mapping tools, or simple programming platforms in minutes by implementing the library into your project.

You can support this project (and many others) through GitHub Sponsors! ❤️

Made by Alyssa X

Table of contents

Features

Currently, Flowy supports the following:

  • Responsive drag and drop
  • Automatic snapping
  • Automatic scrolling
  • Block rearrangement
  • Delete blocks
  • Automatic block centering
  • Conditional snapping
  • Conditional block removal
  • Import saved files
  • Mobile support
  • Vanilla javascript (no dependencies)
  • npm install

You can suggest new features here

Installation

Adding Flowy to your WebApp is incredibly simple:

  1. Link flowy.min.js and flowy.min.css to your project. Through jsDelivr:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/alyssaxuu/flowy/flowy.min.css"> 
<script src="https://cdn.jsdelivr.net/gh/alyssaxuu/flowy/flowy.min.js"></script>
  1. Create a canvas element that will contain the flowchart (for example, <div id="canvas"></div>)
  2. Create the draggable blocks with the .create-flowy class (for example, <div class="create-flowy">Grab me</div>)

Running Flowy

Initialization

flowy(canvas, ongrab, onrelease, onsnap, onrearrange, spacing_x, spacing_y);
Parameter Type Description
canvas javascript DOM element The element that will contain the blocks
ongrab function (optional) Function that gets triggered when a block is dragged
onrelease function (optional) Function that gets triggered when a block is released
onsnap function (optional) Function that gets triggered when a block snaps with another one
onrearrange function (optional) Function that gets triggered when blocks are rearranged
spacing_x integer (optional) Horizontal spacing between blocks (default 20px)
spacing_y integer (optional) Vertical spacing between blocks (default 80px)

To define the blocks that can be dragged, you need to add the class .create-flowy

Example

HTML

<div class="create-flowy">The block to be dragged</div>
<div id="canvas"></div>

Javascript

var spacing_x = 40;
var spacing_y = 100;
// Initialize Flowy
flowy(document.getElementById("canvas"), onGrab, onRelease, onSnap, onRearrange, spacing_x, spacing_y);
function onGrab(block){
	// When the user grabs a block
}
function onRelease(){
	// When the user releases a block
}
function onSnap(block, first, parent){
	// When a block snaps with another one
}
function onRearrange(block, parent){
	// When a block is rearranged
}

Callbacks

In order to use callbacks, you need to add the functions when initializing Flowy, as explained before.

On grab

function onGrab(block){
	// When the user grabs a block
}

Gets triggered when a user grabs a block with the class create-flowy

Parameter Type Description
block javascript DOM element The block that has been grabbed

On release

function onRelease(){
	// When the user lets go of a block
}

Gets triggered when a user lets go of a block, regardless of whether it attaches or even gets released in the canvas.

On snap

function onSnap(block, first, parent){
	// When a block can attach to a parent
	return true;
}

Gets triggered when a block can attach to another parent block. You can either prevent the attachment, or allow it by using return true;

Parameter Type Description
block javascript DOM element The block that has been grabbed
first boolean If true, the block that has been dragged is the first one in the canvas
parent javascript DOM element The parent the block can attach to

On rearrange

function onRearrange(block, parent){
	// When a block is rearranged
	return true;
}

Gets triggered when blocks are rearranged and are dropped anywhere in the canvas, without a parent to attach to. You can either allow the blocks to be deleted, or prevent it and thus have them re-attach to their previous parent using return true;

Parameter Type Description
block javascript DOM element The block that has been grabbed
parent javascript DOM element The parent the block can attach to

Methods

Get the flowchart data

// As an object
flowy.output();
// As a JSON string
JSON.stringify(flowy.output());

The JSON object that gets outputted looks like this:

{
	"html": "",
	"blockarr": [],
	"blocks": [
		{
			"id": 1,
			"parent": 0,
			"data": [
				{
				"name": "blockid",
				"value": "1"
				}
			],
			"attr": [
				{
				"id": "block-id",
				"class": "block-class"
				}
			]
		}
	]
}

Here's what each property means:

Key Value type Description
html string Contains the canvas data
blockarr array Contains the block array generated by the library (for import purposes)
blocks array Contains the readable block array
id integer Unique value that identifies a block
parent integer The id of the parent a block is attached to (-1 means the block has no parent)
data array of objects An array of all the inputs within a certain block
name string The name attribute of the input
value string The value attribute of the input
attr array of objects Contains all the data attributes of a certain block

Import the flowchart data

flowy.import(output)

Allows you to import entire flowcharts initially exported using the previous method, flowy.output()

Parameter Type Description
output javascript DOM element The data from flowy.output()

Warning

This method accepts raw HTML and does not sanitize it, therefore this method is vulnerable to XSS. The only safe use for this method is when the input is absolutely trusted, if the input is not to be trusted the use this method can introduce a vulnerability in your system.

Delete all blocks

To remove all blocks at once use:

flowy.deleteBlocks()

Currently there is no method to individually remove blocks. The only way to go about it is by splitting branches manually.

Feel free to reach out to me through email at [email protected] or on Twitter if you have any questions or feedback! Hope you find this useful 💜

Comments
  • Convert to NPM package

    Convert to NPM package

    • [x] Add build script to compile to ES5 modules and UMD for web
    • [x] Add publish script to build and publish NPM module
    • [x] Add script to build demo or run demo in browser

    @alyssaxuu note that you will need to choose a package name because "flowy" is already taken

    Credit goes to #12 for the UMD build process.

    question 
    opened by joelvh 50
  • ES6 over jQuery

    ES6 over jQuery

    One of the beauties of this project is to have minimum dependency, if we can use ES6 APIs to replace jQuery, it would be even more slim.

    Like Element.querySelector over 1 element $('selector'), or Element.querySelectorAll() for multiple element $('selector').

    enhancement 
    opened by unruledboy 17
  • React version of demo

    React version of demo

    This is a port to React.

    • [x] Render HTML layout in React
    • [x] Port all blocks to React components
    • [x] Port event listeners to React lifecycle
    • [x] Create adapter from React to Flowy engine
    • [x] Implement minimizing left card
    • [x] Improve highlighting blocks and toggle right card

    This builds on the work in #37 and #38

    question 
    opened by joelvh 16
  • Multiple parent blocks

    Multiple parent blocks

    In some cases, components may have two or more parents, which potentially could lead to these scenarios (not currently supported by flowy):

        +-------+ +-------+
        |       | |       |
        +-+---+-+ +---+---+
          |   |       |
          |   |       |
       +--+   +--+ +--+
       v         v v
    +--+--+    +-+-+-+
    |     |    |     |
    +-----+    +-----+
    
        +-------+      +-------+
        |       |      |       |
        +-+---+-+      +---+---+
          |   |            |
          |   |            |
       +--+   +--+         |
       v         v         v
    +--+--+   +--+--+   +--+--+
    |     |   |     |   |     |
    +-----+   +--+--+   +--+--+
                 |         |
                 |         |
                 +--+   +--+
                    v   v
                  +-+---+-+
                  |       |
                  +-------+
    
    question 
    opened by benhid 14
  • Help With Alignment

    Help With Alignment

    Hi @alyssaxuu . I am trying to integrate the demo inside a modal. Sometimes I run into an alignment issue. Not sure exactly what is causing it because it seems to occur intermittently. When it happens it looks like this. Any idea what would be causing this ?

    Thanks for the help.

    Screen Shot 2020-08-04 at 9 51 25 PM question 
    opened by Kannndev 12
  • Dragging problem after importing data

    Dragging problem after importing data

    Hello Alyssa: Congrat and thanks!!!! for your great plugin, I think best of this kind. I´m checking it and I got a problem with the drag performing after flowy. importing data: Data is displayed well but drag stopped working, I mean, when you click on an object this remains stocked in the mouse cursor and never is released. This issue happens under only one condition: on importing after start the page. I recycle output->import and works fine, I publish to database and read it rightaway and works fine, only happens when I restart and import the data from database. it is not a parsing problem, I tryed with a flowy.output string constant as data and when it is imported after page start the fails come out. Message in console is: TypeError: tempblock2 is undefined. You use two functions in main.js drag(block) and release() I "consoled" them inside with some text, and the problem is drag(block) never runs. I reclarify: this issue only happens after reloading the page and flowy.import data. Thanks in advance Alyssa for your help.

    bug 
    opened by emoreno108 12
  • how to add node programmatically

    how to add node programmatically

    Hello, I have a Json , I want to Generate node Programmatically by using below JSON.

    //---------------------DEMO JSON ---------------------------//
    {
    	"blockarr": [
    		{
    			"parent": -1,
    			"id": 0
    		},
    		{
    			"parent": 0,
    			"id": 1
    		}
    	],
    	"blocks": [
    		{
    			"id": 0,
    			"parent": -1,
    			"data": [
    				{
    					"name": "id",
    					"value": ""
    				},
    				{
    					"name": "name",
    					"value": "RootNode"
    				},
    				{
    					"name": "type",
    					"value": "Base"
    				},
    				{
    					"name": "blockid",
    					"value": "0"
    				}
    			],
    		},
    		{
    			"id": 1,
    			"parent": 0,
    			"data": [
    				{
    					"name": "id",
    					"value": ""
    				},
    				{
    					"name": "name",
    					"value": "Childnode"
    				},
    				{
    					"name": "type",
    					"value": "Option"
    				},
    				{
    					"name": "blockid",
    					"value": "1"
    				}
    			],
    		}
    	]
    }
    

    //--------------- Its should appear like that-------------// image

    is it possible to it programmatically .

    opened by Rohitgta77 10
  • Enhancement - Allow snapping of blocks by type

    Enhancement - Allow snapping of blocks by type

    This is not an issue but more of a feature request, could there be a way to only allow certain types of blocks to attach to others, like in your demo only allow Actions and Loggers to be attached to a Trigger block. Thank you!

    question 
    opened by imeneses 8
  • Browser resolution and object placement

    Browser resolution and object placement

    Having an error that if a Flowy configuration is saved at one browser resolution and imported at smaller resolution the arrows are not placed correctly on the virtual axis and blocks collide on snapping.

    For instance I saved at a large resolution and imported at a smaller and all the arrows were placed above the blocks. When I click drag and snap a block and the rearrange occurs the blocks and arrows may overlap and or collide rendering the diagram unreadable.

    question 
    opened by fcnyp 7
  • Conditionals and finalising the process in one node are not allowed

    Conditionals and finalising the process in one node are not allowed

    Hello Alyssa,

    First of all congratulations for this excellent work. It is very helpful.

    I would like to know if you can confirm that the current code is not possible to do the actions as below:

    • Conditional node
    • That the process finalizes in one node.

    As an example, I have added a picture with the nodes/actions that I think is not allowed currently. I have marked them in red.

    Diagram

    Could you update the code with these actions?

    I'm looking forward to hearing from you,

    all my best,

    José

    question 
    opened by jlmrobles 7
  • Refactor to leverage ES6 language features and a more modular object model

    Refactor to leverage ES6 language features and a more modular object model

    This refactor maintains the same public API, while updating the internals.

    • [x] Refactor string concatenation to string interpolation
    • [x] Remove global variables and instead manage state on a simple object for clarity and flexibility
    • [x] Add helper methods to consolidate common tasks
    • [x] Simplify some logic for clarity

    @alyssaxuu this is a subsequent update following #37

    opened by joelvh 6
  • Unable to add text box in the flowchart

    Unable to add text box in the flowchart

    it would be super useful if there was an option to add text boxes in each blocks. i tried making one. tried to input some text into the text-box and whenever i drag and drop another block into the canvas, i just completely lose the existing text which was inserted. i am also attaching the image for your reference.

    Screenshot from 2022-11-14 14-20-05

    opened by Santoshgokulc 0
  • Drag block item when scrolled

    Drag block item when scrolled

    When dragging a block item to the canvas, everything works perfect.

    However after you scroll the dragging does not follow your cursor, and when you drop the block item on the canvas it doesn't drop it near where your mouse is, it's like the block items drag on the window's default position rather than what you see after scroll

    opened by benjamin-Keller 0
  • Conditional Snapping Issue

    Conditional Snapping Issue

    There has to be some provision for conditional snapping like If Else condition

    I want one drag option of If Else condition which will already have two child blocks called Yes and No attached to one conditional Parent If block.

    Can someone help me achieve this goal with the existing flowy code.

    What i want is when i drag a single Block from the left on the Canvas it should attach two child blocks to it like "Yes" and "No"

    opened by codiastic 1
Owner
Alyssa X
Designer, developer, & entrepreneur. Founder of Sonuum + other ventures. Best woman maker of 2018 (Maker Mag) & nominated as Maker of The Year (Product Hunt)
Alyssa X
Gatsby-starter-minimal-blog - Typography driven, feature-rich blogging theme with minimal aesthetics.

Gatsby-starter-minimal-blog - Typography driven, feature-rich blogging theme with minimal aesthetics. Includes tags/categories support and extensive features for code blocks such as live preview, line numbers, and line highlighting.

Priya Chakraborty 0 Jan 29, 2022
Quickly create an interactive HTML mock-up by auto sourcing lorem ipsum/images generators, with minimal html markup, and no server side code

RoughDraft.js v0.1.5 Quickly mockup / prototype HTML pages with auto-generated content, without additional JavaScript or server side code. <section>

Nick Dreckshage 464 Dec 21, 2022
Minimal Phaser3 + Create React App template

Phaser 3 + Create React App template This project was bootstrapped with Create React App. What's included? - Check the preview Phaser 3 - overlaid can

Kuan-Hsuan (Kevin) Shen 53 Dec 26, 2022
Minimal Typescript / NextJS dApp template bootstrapped with wagmi Ethereum react hooks library.

Welcome to the NextJS wagmi starter template ?? Looking to get up and running with a Typescript / NextJS dApp as quickly as possible? You're in the ri

Seth 78 Jan 4, 2023
A minimal routing library designed to sit on top of Bun's fast HTTP server.

siopao A minimal routing library designed to sit on top of Bun's fast HTTP server. Based on Radix Tree. Sio=Hot Pao=Bun Installation bun add siopao Us

Robert Soriano 69 Nov 8, 2022
Super minimal selector and event library

min.js A super tiny JavaScript library to execute simple DOM querying and hooking event listeners. Aims to return the raw DOM node for you to manipula

Remy Sharp 1.1k Dec 13, 2022
Minimal template engine with compiled output for JavaScript.

@fnando/seagull Minimal template engine with compiled output for JavaScript. Installation This package is available as a NPM package. To install it, u

Nando Vieira 5 Mar 1, 2022
This the minimal to do list done using JavaScript, HTML and CSS.

To_DO_List This the minimal to do list done using JavaScript, html and CSS In this project, we built a basic to do list website: plain JavaScript with

Michael Tamirie 12 Mar 9, 2022
Essential Audio Player JS is a simple, clean and minimal JavaScript / HTML5 / CSS web audio player.

Essential Audio Player JS is a simple, clean and minimal JavaScript / HTML5 / CSS web audio player. No unnecessary controls, just a button and a track

null 32 Dec 14, 2022
This project is written in JavaScript with minimal npm scripts and commands

This is an Educational repository, for learning how to install and implement the Webpack, Webpack-CLI and the Webpack-dev-server for a project. This project is written in Javascript with minimal npm scripts and commands. It is a minimal implementation of a To Do list application.

John Omachi 7 Sep 23, 2022
LiveTabs is a Javascript library that allows you to create and manage tabs on the fly. This library gives the ability to your application to act like browser tabs, making dynamic tabs.

LiveTabs Table of content Description Goals Technologies Setup Description LiveTabs is a Javascript library that allows you to create and manage tabs

Hossein Khalili 3 May 3, 2022
Fast & minimal implementation of bech32, base64, base32, base16 & base58

micro-base Fast and minimal implementation of bech32, base64, base58, base32 & base16. Matches following specs: Bech32, Bech32m: BIP173, BIP350 Base16

Paul Miller 45 Jan 4, 2023
A minimal norui portfolio example built with NextJS and powered by Notion 🚀.

Minimal Norui A minimal norui portfolio example built with NextJS and powered by Notion ?? . Links Demo Site Documentation Minimal Norui Notion Databa

Joeylene Rivera 4 Nov 13, 2022
Absolutely minimal view layer for building web interfaces.

Superfine Superfine is a minimal view layer for building web interfaces. Think Hyperapp without the framework—no state machines, effects, or subscript

Jorge Bucaran 1.6k Dec 29, 2022
Audited & minimal implementation of BIP39 mnemonic phrases

scure-bip39 Secure, audited & minimal implementation of BIP39 mnemonic phrases. Developed for js-ethereum-cryptography. Check out scure-bip32 if you n

Paul Miller 47 Dec 25, 2022
Verbosely Documented, Minimal Starknet Contract Examples.

cairo-by-example • Verbosely Documented, Minimal Starknet Contract Examples. Cairo By Example deployed to https://cairo-by-example.xyz Developing Clon

andreas 63 Dec 6, 2022
A minimal, modern, generic, hot-reloading local web server to help web developers

eleventy-dev-server ?? ⚡️ ?? ?? A minimal, modern, generic, hot-reloading local web server to help web developers. ➡ Documentation Please star Elevent

Eleventy 52 Dec 31, 2022
A minimal Node.js restarter.

minimon A minimal Node.js restarter based on zx. A modest nodemon replacement. Check out the blog post covering how it was written. Install npm i mini

Jonas Galvez 9 Aug 9, 2022
Chronos is an ML Scheduler Tool, helping students to block and manage time with minimal manual intervention.

Chronos (Currently in progress) Chronos is an ML Scheduler Tool, helping students to block and manage time with minimal manual intervention. It adapts

Shromann Majumder 3 Aug 17, 2022