├── editor ├── .gitignore ├── src │ ├── index.js │ ├── providers │ │ ├── index.js │ │ ├── ExampleRuleProvider.js │ │ ├── ExampleContextPadProvider.js │ │ └── ExamplePaletteProvider.js │ └── editor.js ├── docs │ └── screenshot.png ├── webpack.config.js ├── README.md ├── package.json └── public │ ├── index.js │ └── index.html ├── renovate.json └── README.md /editor/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public/vendor -------------------------------------------------------------------------------- /editor/src/index.js: -------------------------------------------------------------------------------- 1 | export { default } from './editor'; -------------------------------------------------------------------------------- /editor/docs/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bpmn-io/diagram-js-examples/HEAD/editor/docs/screenshot.png -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://docs.renovatebot.com/renovate-schema.json", 3 | "extends": [ 4 | "github>bpmn-io/renovate-config:recommended" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # diagram-js Examples 2 | 3 | This repository contains a number of examples that showcase how use and/or integrate [diagram-js](https://github.com/bpmn-io/diagram-js) into your applications. 4 | 5 | 6 | ## Advanced 7 | 8 | * [editor](./editor) - an example showcasing how to build an diagram editor powered by diagram-js 9 | 10 | 11 | ## License 12 | 13 | MIT _(unless noted otherwise)_ 14 | -------------------------------------------------------------------------------- /editor/src/providers/index.js: -------------------------------------------------------------------------------- 1 | import ExampleContextPadProvider from './ExampleContextPadProvider'; 2 | import ExamplePaletteProvider from './ExamplePaletteProvider'; 3 | import ExampleRuleProvider from './ExampleRuleProvider'; 4 | 5 | export default { 6 | __init__: [ 7 | 'exampleContextPadProvider', 8 | 'examplePaletteProvider', 9 | 'exampleRuleProvider' 10 | ], 11 | exampleContextPadProvider: [ 'type', ExampleContextPadProvider ], 12 | examplePaletteProvider: [ 'type', ExamplePaletteProvider ], 13 | exampleRuleProvider: [ 'type', ExampleRuleProvider ] 14 | }; -------------------------------------------------------------------------------- /editor/webpack.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | entry: { 3 | bundle: ['./src/index.js'] 4 | }, 5 | output: { 6 | library: 'Editor', 7 | libraryExport: 'default', 8 | libraryTarget: 'umd', 9 | path: __dirname + '/public', 10 | filename: 'vendor/editor.js' 11 | }, 12 | module: { 13 | rules: [ 14 | { 15 | test: /\.css$/i, 16 | use: [ 17 | "style-loader", 18 | "css-loader" 19 | ], 20 | }, 21 | ], 22 | }, 23 | mode: 'development', 24 | devtool: 'source-map' 25 | }; 26 | -------------------------------------------------------------------------------- /editor/src/providers/ExampleRuleProvider.js: -------------------------------------------------------------------------------- 1 | import inherits from 'inherits'; 2 | 3 | import RuleProvider from 'diagram-js/lib/features/rules/RuleProvider'; 4 | 5 | import { isFrameElement } from 'diagram-js/lib/util/Elements'; 6 | 7 | 8 | export default function ExampleRuleProvider(eventBus) { 9 | RuleProvider.call(this, eventBus); 10 | } 11 | 12 | ExampleRuleProvider.$inject = [ 'eventBus' ]; 13 | 14 | inherits(ExampleRuleProvider, RuleProvider); 15 | 16 | 17 | ExampleRuleProvider.prototype.init = function() { 18 | this.addRule('shape.create', function(context) { 19 | var target = context.target, 20 | shape = context.shape; 21 | 22 | return target.parent === shape.target; 23 | }); 24 | 25 | this.addRule('connection.create', function(context) { 26 | var source = context.source, 27 | target = context.target; 28 | 29 | return source.parent === target.parent; 30 | }); 31 | 32 | this.addRule('shape.resize', function(context) { 33 | var shape = context.shape; 34 | 35 | return isFrameElement(shape); 36 | }); 37 | }; -------------------------------------------------------------------------------- /editor/README.md: -------------------------------------------------------------------------------- 1 | # diagram-js Editor Example 2 | 3 | A simple diagram editor built with diagram-js. 4 | 5 | ![Screenshot](docs/screenshot.png) 6 | 7 | You can use this as a starting point for your own diagram-js based editor or look into [tools built on top of it](https://github.com/bpmn-io/diagram-js#built-with-diagram-js) for inspiration. 8 | 9 | 10 | ## Example Structure 11 | 12 | ```plain 13 | editor/ 14 | ├─ public/ <-- simple web page using the editor 15 | ├─ src/ <-- editor source 16 | | ├─ providers/ <-- a custom editor module 17 | | └─ index.js <-- editor entry point 18 | └─ webpack.config.js <-- configuration to bundle the editor into 19 | the public/vendor directory 20 | ``` 21 | 22 | 23 | ## Build the Example 24 | 25 | Initialize the project dependencies via 26 | 27 | ``` 28 | npm install 29 | ``` 30 | 31 | Bundle the editor contained in `src` and output it to `public/vendor`: 32 | 33 | ``` 34 | npm run all 35 | ``` 36 | 37 | Start the development setup, opening the example app and rebuild on changes: 38 | 39 | ``` 40 | npm run dev 41 | ``` 42 | 43 | 44 | ## Licence 45 | 46 | MIT -------------------------------------------------------------------------------- /editor/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "diagram-js-editor", 3 | "version": "0.0.0", 4 | "description": "A simple example how to build your own diagram-js based diagram editor", 5 | "main": "public/vendor/editor.js", 6 | "scripts": { 7 | "all": "run-s build", 8 | "build": "webpack --mode production", 9 | "dev": "webpack-dev-server --open", 10 | "start": "run-s dev" 11 | }, 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/bpmn-io/diagram-js-examples", 15 | "directory": "editor" 16 | }, 17 | "keywords": [ 18 | "diagram-js", 19 | "diagram-js-example", 20 | "diagram", 21 | "editor" 22 | ], 23 | "author": { 24 | "name": "Philipp Fromme", 25 | "url": "https://github.com/philippfromme" 26 | }, 27 | "contributors": [ 28 | { 29 | "name": "bpmn.io contributors", 30 | "url": "https://github.com/bpmn-io" 31 | } 32 | ], 33 | "license": "MIT", 34 | "devDependencies": { 35 | "css-loader": "^7.1.2", 36 | "diagram-js": "^15.2.4", 37 | "npm-run-all2": "^8.0.0", 38 | "style-loader": "^4.0.0", 39 | "webpack": "^5.98.0", 40 | "webpack-cli": "^6.0.1", 41 | "webpack-dev-server": "^5.2.1" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /editor/src/providers/ExampleContextPadProvider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A example context pad provider. 3 | */ 4 | export default function ExampleContextPadProvider(connect, contextPad, modeling) { 5 | this._connect = connect; 6 | this._modeling = modeling; 7 | 8 | contextPad.registerProvider(this); 9 | } 10 | 11 | ExampleContextPadProvider.$inject = [ 12 | 'connect', 13 | 'contextPad', 14 | 'modeling' 15 | ]; 16 | 17 | 18 | ExampleContextPadProvider.prototype.getContextPadEntries = function(element) { 19 | var connect = this._connect, 20 | modeling = this._modeling; 21 | 22 | function removeElement() { 23 | modeling.removeElements([ element ]); 24 | } 25 | 26 | function startConnect(event, element, autoActivate) { 27 | connect.start(event, element, autoActivate); 28 | } 29 | 30 | return { 31 | 'delete': { 32 | group: 'edit', 33 | className: 'context-pad-icon-remove', 34 | title: 'Remove', 35 | action: { 36 | click: removeElement, 37 | dragstart: removeElement 38 | } 39 | }, 40 | 'connect': { 41 | group: 'edit', 42 | className: 'context-pad-icon-connect', 43 | title: 'Connect', 44 | action: { 45 | click: startConnect, 46 | dragstart: startConnect 47 | } 48 | } 49 | }; 50 | }; -------------------------------------------------------------------------------- /editor/public/index.js: -------------------------------------------------------------------------------- 1 | /* global Editor */ 2 | 3 | 4 | // (1) create new editor instance 5 | 6 | const diagram = new Editor({ 7 | container: document.querySelector('#container') 8 | }); 9 | 10 | 11 | // (2) draw diagram elements (i.e. import) 12 | 13 | const canvas = diagram.get('canvas'); 14 | const elementFactory = diagram.get('elementFactory'); 15 | 16 | // add root 17 | var root = elementFactory.createRoot(); 18 | 19 | canvas.setRootElement(root); 20 | 21 | // add shapes 22 | var shape1 = elementFactory.createShape({ 23 | x: 150, 24 | y: 100, 25 | width: 100, 26 | height: 80 27 | }); 28 | 29 | canvas.addShape(shape1, root); 30 | 31 | var shape2 = elementFactory.createShape({ 32 | x: 290, 33 | y: 220, 34 | width: 100, 35 | height: 80 36 | }); 37 | 38 | canvas.addShape(shape2, root); 39 | 40 | 41 | var connection1 = elementFactory.createConnection({ 42 | waypoints: [ 43 | { x: 250, y: 180 }, 44 | { x: 290, y: 220 } 45 | ], 46 | source: shape1, 47 | target: shape2 48 | }); 49 | 50 | canvas.addConnection(connection1, root); 51 | 52 | 53 | var shape3 = elementFactory.createShape({ 54 | x: 450, 55 | y: 80, 56 | width: 100, 57 | height: 80 58 | }); 59 | 60 | canvas.addShape(shape3, root); 61 | 62 | var shape4 = elementFactory.createShape({ 63 | x: 425, 64 | y: 50, 65 | width: 300, 66 | height: 200, 67 | isFrame: true 68 | }); 69 | 70 | canvas.addShape(shape4, root); 71 | 72 | 73 | // (3) interact with the diagram via API 74 | 75 | const selection = diagram.get('selection'); 76 | 77 | selection.select(shape3); -------------------------------------------------------------------------------- /editor/src/providers/ExamplePaletteProvider.js: -------------------------------------------------------------------------------- 1 | /** 2 | * A example palette provider. 3 | */ 4 | export default function ExamplePaletteProvider(create, elementFactory, lassoTool, palette) { 5 | this._create = create; 6 | this._elementFactory = elementFactory; 7 | this._lassoTool = lassoTool; 8 | this._palette = palette; 9 | 10 | palette.registerProvider(this); 11 | } 12 | 13 | ExamplePaletteProvider.$inject = [ 14 | 'create', 15 | 'elementFactory', 16 | 'lassoTool', 17 | 'palette' 18 | ]; 19 | 20 | 21 | ExamplePaletteProvider.prototype.getPaletteEntries = function() { 22 | var create = this._create, 23 | elementFactory = this._elementFactory, 24 | lassoTool = this._lassoTool; 25 | 26 | return { 27 | 'lasso-tool': { 28 | group: 'tools', 29 | className: 'palette-icon-lasso-tool', 30 | title: 'Activate Lasso Tool', 31 | action: { 32 | click: function(event) { 33 | lassoTool.activateSelection(event); 34 | } 35 | } 36 | }, 37 | 'tool-separator': { 38 | group: 'tools', 39 | separator: true 40 | }, 41 | 'create-shape': { 42 | group: 'create', 43 | className: 'palette-icon-create-shape', 44 | title: 'Create Shape', 45 | action: { 46 | click: function() { 47 | var shape = elementFactory.createShape({ 48 | width: 100, 49 | height: 80 50 | }); 51 | 52 | create.start(event, shape); 53 | } 54 | } 55 | }, 56 | 'create-frame': { 57 | group: 'create', 58 | className: 'palette-icon-create-frame', 59 | title: 'Create Frame', 60 | action: { 61 | click: function() { 62 | var shape = elementFactory.createShape({ 63 | width: 300, 64 | height: 200, 65 | isFrame: true 66 | }); 67 | 68 | create.start(event, shape); 69 | } 70 | } 71 | } 72 | }; 73 | }; -------------------------------------------------------------------------------- /editor/src/editor.js: -------------------------------------------------------------------------------- 1 | import Diagram from 'diagram-js'; 2 | 3 | import ConnectModule from 'diagram-js/lib/features/connect'; 4 | import ContextPadModule from 'diagram-js/lib/features/context-pad'; 5 | import CreateModule from 'diagram-js/lib/features/create'; 6 | import LassoToolModule from 'diagram-js/lib/features/lasso-tool'; 7 | import ModelingModule from 'diagram-js/lib/features/modeling'; 8 | import MoveCanvasModule from 'diagram-js/lib/navigation/movecanvas'; 9 | import MoveModule from 'diagram-js/lib/features/move'; 10 | import OutlineModule from 'diagram-js/lib/features/outline'; 11 | import PaletteModule from 'diagram-js/lib/features/palette'; 12 | import ResizeModule from 'diagram-js/lib/features/resize'; 13 | import RulesModule from 'diagram-js/lib/features/rules'; 14 | import SelectionModule from 'diagram-js/lib/features/selection'; 15 | import ZoomScrollModule from 'diagram-js/lib/navigation/zoomscroll'; 16 | 17 | import 'diagram-js/assets/diagram-js.css'; 18 | 19 | import ProvidersModule from './providers'; 20 | 21 | /** 22 | * A module that changes the default diagram look. 23 | */ 24 | const ElementStyleModule = { 25 | __init__: [ 26 | [ 'defaultRenderer', function(defaultRenderer) { 27 | // override default styles 28 | defaultRenderer.CONNECTION_STYLE = { fill: 'none', strokeWidth: 5, stroke: '#000' }; 29 | defaultRenderer.SHAPE_STYLE = { fill: 'white', stroke: '#000', strokeWidth: 2 }; 30 | defaultRenderer.FRAME_STYLE = { fill: 'none', stroke: '#000', strokeDasharray: 4, strokeWidth: 2 }; 31 | } ] 32 | ] 33 | }; 34 | 35 | 36 | /** 37 | * Our editor constructor 38 | * 39 | * @param { { container: Element, additionalModules?: Array } } options 40 | * 41 | * @return {Diagram} 42 | */ 43 | export default function Editor(options) { 44 | 45 | const { 46 | container, 47 | additionalModules = [] 48 | } = options; 49 | 50 | // default modules provided by the toolbox 51 | const builtinModules = [ 52 | ConnectModule, 53 | ContextPadModule, 54 | CreateModule, 55 | LassoToolModule, 56 | ModelingModule, 57 | MoveCanvasModule, 58 | MoveModule, 59 | OutlineModule, 60 | PaletteModule, 61 | ResizeModule, 62 | RulesModule, 63 | SelectionModule, 64 | ZoomScrollModule 65 | ]; 66 | 67 | // our own modules, contributing controls, customizations, and more 68 | const customModules = [ 69 | ProvidersModule, 70 | ElementStyleModule 71 | ]; 72 | 73 | return new Diagram({ 74 | canvas: { 75 | container 76 | }, 77 | modules: [ 78 | ...builtinModules, 79 | ...customModules, 80 | ...additionalModules 81 | ] 82 | }); 83 | } -------------------------------------------------------------------------------- /editor/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 39 | --------------------------------------------------------------------------------