Menus

NodeTreeMenu

You can add nodeTreeMenu using this option:
    var family = new FamilyTree(document.getElementById("tree"), {
      nodeTreeMenu: true,
      ...
    });

Example:

Family Tree JS has these menus

  1. menu - top right corner
  2. nodeMenu - a button in the node
  3. nodeContextMenu - context menu for none
The demo bellow demonstrates how to define, menu, nodeMenu and nodeContextMenu in one chart:

Predefined menus items

  • edit - calls editUI.show method
  • details - calls editUI.show method
  • svg - calls exportSVG method
  • pdf - calls exportPDF method
  • png - calls exportPNG method
  • csv - calls exportCSV method
For the predefined menu items you can specify the text and/or the icon
 
    var family = new FamilyTree (document.getElementById("tree"), {
      nodeContextMenu: {
        edit: { text: "Edit", icon: FamilyTree.icon.edit(18, 18, '#039BE5')  },
      },
      ...
    });
    

Add your own menu item to the node menu with Icon, Click event and Text

 
    var family = new family(document.getElementById("tree"), {
         nodeMenu: {
                call: {
                    icon: webcallMeIcon,
                    text: "Call now",
                    onClick: callHandler
                }
            },
            ...
    });
    

Icon can be image html element (img) or svg element.

 
    var webcallMeIcon = <svg width="24" height="24" viewBox="0 0 300 400"><g transform="matrix...
    // the svg code is in the example below

callHandler function has one parameter nodeId.

 
    function callHandler(nodeId) {
        var nodeData = chart.get(nodeId);
        var employeeName = nodeData["name"];
        window.open('https://webcall.me/' + employeeName, employeeName, 'width=340px, height=670px, top=50px, left=50px');
    }
    

Here is an example:


Override node menu items for specific node using tags

You can override node menu items by tagging a node

 
    var family = new family(document.getElementById("tree"), {
        nodeMenu: {
            pdf: {
                text: "Export To Pdf",
            }
        },
        tags:{
            overrideMenu:{
                nodeMenu:{
                    edit: {text: "Edit" }
                }
            }
        },
        ...
    });
    

In the example below the node menu items for father and mother nodes will be different form node menus on children nodes:


Override node menu items for specific node using on show event

 
    var family = new family(document.getElementById("tree"), {
        nodeMenu: {},
        nodeContextMenu: {},
        menu: {}
        ...
    });

   
     family.nodeMenuUI.on('show', function(sender, args){
          args.menu = { myMenuItem: { text: "My Text", icon: family.icon.add(16,16,"#ccc"), onClick: function(id) {alert(id)} } }
    });
    
     family.menuUI.on('show', function(sender, args){
          args.menu = { myMenuItem: { text: "My Text", icon: family.icon.add(16,16,"#ccc"), onClick: function(id) {alert(id)} } }
    });
    
     family.nodeContextMenuUI.on('show', function(sender, args){
          args.menu = { myMenuItem: { text: "My Text", icon: family.icon.add(16,16,"#ccc"), onClick: function(id) {alert(id)} } }
    });

     family.load(...);       
    

Node Circle Menu

To add a Node Circle Menu:

  • First you need to define nodeCircleMenu for your template:
    
            FamilyTree.templates.tommy.nodeCircleMenuButton = 
                FamilyTree.templates.tommy_female.nodeCircleMenuButton = FamilyTree.templates.tommy_male.nodeCircleMenuButton = {
                    radius: 25,
                    x: 230,
                    y: 60,
                    color: '#fff',
                    stroke: '#aeaeae'
                };
            
  • Then you need to add nodeCircleMenu in the chart configuration:
    
                var chart = new OrgChart(document.getElementById("tree"), {
                    nodeCircleMenu: {
                        PDFProfile: {
                            icon: FamilyTree.icon.pdf(30, 30, '#aeaeae'),
                            text: "PDF Profile",
                            color: "white"
                            },
    
                            editNode: {
                                icon: FamilyTree.icon.edit(30, 30, '#aeaeae'),
                                text: "Edit node",
                                color: "white"
                            },
                            addClink: {
                                icon: FamilyTree.icon.link(30, 30, '#aeaeae'),
                                text: "Add C link",
                                color: '#fff',
                                draggable: true
                            },
                            pet: {
                                icon: FamilyTree.icon.teddy(30, 30, '#aeaeae'),
                                text: "Add pet",
                                color: "white"
                            }
                    }
                });
            
  • You can use the show event to add menu item conditionaly:
    
            family.nodeCircleMenuUI.on('show', function (sender, args) {
                var node = family.getNode(args.nodeId);
                delete args.menu.father;
                delete args.menu.mother;
                delete args.menu.wife;
                delete args.menu.husband;
                if (FamilyTree.isNEU(node.mid)) {
                    args.menu.mother = {
                        icon: FamilyTree.icon.mother(30, 30, '#F57C00'),
                        text: "Add mother",
                        color: "white"
                    };
                }
                if (FamilyTree.isNEU(node.fid)) {
                    args.menu.father = {
                        icon: FamilyTree.icon.father(30, 30, '#039BE5'),
                        text: "Add father",
                        color: "white"
                    };
                }
                if (node.gender == 'male') {
                    args.menu.wife = {
                        icon: FamilyTree.icon.wife(30, 30, '#F57C00'),
                        text: "Add wife",
                        color: "white"
                    };
                }
                else if (node.gender == 'female') {
                    args.menu.husband = {
                        icon: FamilyTree.icon.husband(30, 30, '#F57C00'),
                        text: "Add husband",
                        color: "white"
                    };
                }
                else {
                    args.menu.wife = {
                        icon: FamilyTree.icon.wife(30, 30, '#F57C00'),
                        text: "Add wife",
                        color: "white"
                    };
                    args.menu.husband = {
                        icon: FamilyTree.icon.husband(30, 30, '#039BE5'),
                        text: "Add husband",
                        color: "white"
                    };
                }
    
            });
            
  • Use the click, drop, mouseenter or mouseout nodeCircleMenuUI events to create the node menu items functionality. Example:
    
                family.nodeCircleMenuUI.on('click', function (sender, args) {
                    var node = family.getNode(args.nodeId);
    
                    switch (args.menuItemName) {
                        case "husband":
                            family.addPartnerNode({ gender: 'male', pids: [args.nodeId] });
                            break;
                        case "wife":
                            family.addPartnerNode({ gender: 'female', pids: [args.nodeId] });
                            break;
                        case "pet":
                            family.addPartnerNode({ gender: 'pet', pids: [args.nodeId] });
                            break;
                        case "mother":
                            var data = { gender: 'female' };
                            if (!FamilyTree.isNEU(node.fid)) {
                                data.pids = [node.fid];
                            }
                            family.addParentNode(args.nodeId, 'mid', data);
                            break;
                        case "father":
                            var data = { gender: 'male' };
                            if (!FamilyTree.isNEU(node.mid)) {
                                data.pids = [node.mid];
                            }
                            family.addParentNode(args.nodeId, 'fid', data);
                            break;
                        case "PDFProfile":
                            family.exportPDFProfile({
                                id: args.nodeId
                            });
                            break;
                        case "editNode": family.editUI.show(args.nodeId);
                            break;
                        default:
                    };
                });
    
                family.nodeCircleMenuUI.on('drop', function (sender, args) {
                    family.addClink(args.from, args.to).draw(FamilyTree.action.update);
                });
    
                family.nodeCircleMenuUI.on('mouseenter', function (sender, args) {
                    if (args.menuItem.text == "Remove node") {
                        var node = document.querySelector('[data-n-id="' + args.from + '"]');
                        node.style.opacity = 0.5;
                    }
                });
    
                family.nodeCircleMenuUI.on('mouseout', function (sender, args) {
                    var node = document.querySelector('[data-n-id="' + args.from + '"]');
                    node.style.opacity = 1;
                });