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
- menu - top right corner
- nodeMenu - a button in the node
- nodeContextMenu - context menu for none
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
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; });