Search code examples
workflowbpmnmxgraph

How to customize mxgraph toolbar and properties panel


I'm writing an web application. I have workflow in my application, means that we should create our workflow and extract data from it and save in database.

I chose mxgraph for designing workflow. For now I need to customize it for my project: 1. custom toolbar that just contain some tools for bpmn and workflow. 2. ability for double click on elements and open modal for creating element attributes.

How can I do this? I read documents but was not clear for me.


Solution

  • I will assume that you're using the GraphEditorExample

    1. You can create a new sidebar using this code below:

    On your Sidebar.js

    
    Sidebar.prototype.init = function()
    {
        var dir = STENCIL_PATH;
    
        this.addYourPalette(true); // HERE YOU CAN ADD A NEW PALLETE
        this.addSearchPalette(true);
        this.addGeneralPalette(true); 
        this.addMiscPalette(false); 
        this.addAdvancedPalette(false); 
        this.addBasicPalette(dir);   
        this.addStencilPalette('arrows', mxResources.get('arrows'), dir + '/arrows.xml',
            ';whiteSpace=wrap;html=1;fillColor=#ffffff;strokeColor=#000000;strokeWidth=2');
        this.addUmlPalette(false);
        this.addBpmnPalette(dir, false);
        this.addImagePalette('clipart', mxResources.get('clipart'), dir + '/clipart/', '_128x128.png',
            ['Earth_globe', 'Empty_Folder', 'Full_Folder', 'Gear', 'Lock', 'Software', 'Virus', 'Email',
             'Database', 'Router_Icon', 'iPad', 'iMac', 'Laptop', 'MacBook', 'Monitor_Tower', 'Printer',
             'Server_Tower', 'Workstation', 'Firewall_02', 'Wireless_Router_N', 'Credit_Card',
             'Piggy_Bank', 'Graph', 'Safe', 'Shopping_Cart', 'Suit1', 'Suit2', 'Suit3', 'Pilot1',
             'Worker1', 'Soldier1', 'Doctor1', 'Tech1', 'Security1', 'Telesales1'], null,
             {'Wireless_Router_N': 'wireless router switch wap wifi access point wlan',
              'Router_Icon': 'router switch'});
    };
    
    

    You can define which elements you want in this new palette creating a function:

    
    Sidebar.prototype.addYourPalette = function(expand)
    {
        var lineTags = 'line lines connector connectors connection connections arrow arrows ';
    
        var fns = [
            this.createVertexTemplateEntry('rounded=0;whiteSpace=wrap;html=1;', 120, 60, '', 'Rectangle', null, null, 'rect rectangle box'),
            this.createVertexTemplateEntry('rounded=1;whiteSpace=wrap;html=1;', 120, 60, '', 'Rounded Rectangle', null, null, 'rounded rect rectangle box'),
    
        ];
    
        this.addPaletteFunctions('New', 'New', (expand != null) ? expand : true, fns);
    };
    

    The example above will have 2 elements: a Rectangle and a Rounded Rectangle, but you can put wherever element you like.

    1. You can add new properties to the cell using the example below:

    In your Dialogs.js use the function

    
        function addProps(name) {
            // Avoid ':' in attribute names which seems to be valid in Chrome
            if (name.length > 0 && name != 'label' && name != 'placeholders' && name.indexOf(':') < 0) {
                try {
                    var idx = mxUtils.indexOf(names, name);
    
                    if (idx >= 0 && texts[idx] != null) {
                        texts[idx].focus();
                    } else {
                        // Checks if the name is valid
                        var clone = value.cloneNode(false);
                        clone.setAttribute(name, '');
    
                        if (idx >= 0) {
                            names.splice(idx, 1);
                            texts.splice(idx, 1);
                        }
    
                        names.push(name);
                        var text = form.addTextarea(name + ':', '', 2);
                        text.style.width = '100%';
                        texts.push(text);
                        addRemoveButton(text, name);
    
                        text.focus();
                    }
    
                    nameInput.value = '';
                } catch (e) {
                    mxUtils.alert(e);
                }
            } else {
                mxUtils.alert(mxResources.get('invalidName'));
            }
        }
    

    And then call the function passing in your parameter the name of the new property

        addProps('yourPropName');