Show / Hide Table of Contents

Predefined Templates

Modes

Family Tree JS can be displayed in "dark" or "light" modes by settong the mode option:

light mode
dark mode

Templates

Family Tree JS arrives with 2 predefined templates. You can change the template by setting the template option. Here is an example:

 
    var family = new FamilyTree(document.getElementById("tree"), {
        template: "hugo",
        ...
    }); 

You can get the source code of any of the templates and change it.

tommy

 
    FamilyTree.templates.tommy = Object.assign({}, FamilyTree.templates.base);
    FamilyTree.templates.tommy.defs = `<style>
                                        .{randId} .bft-edit-form-header, .{randId} .bft-img-button{
                                            background-color: #aeaeae;
                                        }
                                        .{randId}.male .bft-edit-form-header, .{randId}.male .bft-img-button{
                                            background-color: #039BE5;
                                        }        
                                        .{randId}.male div.bft-img-button:hover{
                                            background-color: #F57C00;
                                        }
                                        .{randId}.female .bft-edit-form-header, .{randId}.female .bft-img-button{
                                            background-color: #F57C00;
                                        }        
                                        .{randId}.female div.bft-img-button:hover{
                                            background-color: #039BE5;
                                        }
    </style>`;
    FamilyTree.templates.tommy.field_0 = 
        '<text ' + FamilyTree.attr.width + ' ="230" style="font-size: 18px;font-weight:bold;" fill="#ffffff" x="10" y="90" text-anchor="start">{val}</text>';
    FamilyTree.templates.tommy.field_1 = 
        '<text ' + FamilyTree.attr.width + ' ="150" style="font-size: 14px;" fill="#ffffff" x="10" y="65" text-anchor="start">{val}</text>';
    FamilyTree.templates.tommy.node = '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" fill="#aeaeae" stroke="#aeaeae" rx="7" ry="7"></rect>';
    FamilyTree.templates.tommy_male = Object.assign({}, FamilyTree.templates.tommy);
    FamilyTree.templates.tommy_male.node = '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" fill="#039BE5" stroke="#aeaeae" rx="7" ry="7"></rect>';
    FamilyTree.templates.tommy_female = Object.assign({}, FamilyTree.templates.tommy);
    FamilyTree.templates.tommy_female.node = '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" fill="#F57C00" stroke="#aeaeae" rx="7" ry="7"></rect>';
    


hugo

 
    FamilyTree.templates.hugo = Object.assign({}, FamilyTree.templates.base);
    FamilyTree.templates.hugo.defs = 
        `<clipPath id="hugo_img_0"><rect id="hugo_img_0_stroke" stroke-width="2" stroke="#fff" x="90" y="-5" rx="25" ry="25" width="70" height="70"></rect></clipPath>
        <linearGradient id="hugo_grad_female" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" style="stop-color:#FF8024;stop-opacity:1" />
            <stop offset="100%" style="stop-color:#FF46A3;stop-opacity:1" />
        </linearGradient>
        <linearGradient id="hugo_grad_male" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" style="stop-color:#00D3A5;stop-opacity:1" />
            <stop offset="100%" style="stop-color:#00A7D4;stop-opacity:1" />
        </linearGradient>
        <linearGradient id="hugo_grad" x1="0%" y1="0%" x2="100%" y2="0%">
            <stop offset="0%" style="stop-color:#D0D0D0;stop-opacity:1" />
            <stop offset="100%" style="stop-color:#909090;stop-opacity:1" />
        </linearGradient>
        <g id="hugo_up">
        <circle cx="12" cy="12" r="15" fill="transparent"></circle>
            ${FamilyTree.icon.ft(24,24,'#fff', 0, 0)}
        </g>
        <g id="hugo_node_menu" style="cursor:pointer;">
            <rect x="0" y="0" fill="transparent" width="22" height="22"></rect>
            <circle cx="11" cy="4" r="2" fill="#ffffff"></circle><circle cx="11" cy="11" r="2" fill="#ffffff"></circle>
            <circle cx="11" cy="18" r="2" fill="#ffffff"></circle>
        </g>
            <style>
               .{randId} .bft-edit-form-header{
                    background: linear-gradient(90deg, #D0D0D0 0%, #909090 100%);
                }
                .{randId}.male .bft-edit-form-header{
                    background: linear-gradient(90deg, #00D3A5 0%, #00A7D4 100%);
                }
                .{randId}.female .bft-edit-form-header{
                    background: linear-gradient(90deg, #FF8024 0%, #FF46A3 100%);
                }  
                .{randId} .bft-img-button{
                    background-color: #909090;
                }      
                .{randId} .bft-img-button:hover{
                    background-color: #D0D0D0;
                }
                .{randId}.male .bft-img-button{
                    background-color: #00A7D4;
                }      
                .{randId}.male .bft-img-button:hover{
                    background-color: #00D3A5;
                }
                .{randId}.female .bft-img-button{
                    background-color: #FF46A3;
                }      
                .{randId}.female .bft-img-button:hover{
                    background-color: #FF8024;
                }
        </style>`;
    FamilyTree.templates.hugo.img_0 = 
        '<use xlink:href="#hugo_img_0_stroke" />
        <image preserveAspectRatio="xMidYMid slice" clip-path="url(#hugo_img_0)" xlink:href="{val}" x="90" y="-5" width="70" height="70"></image>';
    FamilyTree.templates.hugo.field_0 = 
        '<text ' + FamilyTree.attr.width + ' ="230" style="font-size: 18px;font-weight:bold;" fill="#ffffff" x="125" y="85" text-anchor="middle">{val}</text>';
    FamilyTree.templates.hugo.field_1 = 
        '<text ' + FamilyTree.attr.width + ' ="230" style="font-size: 14px;" fill="#ffffff" x="125" y="105" text-anchor="middle">{val}</text>';
    FamilyTree.templates.hugo.node = '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" fill=url(#hugo_grad) stroke="#aeaeae" rx="7" ry="7"></rect>';
    FamilyTree.templates.hugo_male = Object.assign({}, FamilyTree.templates.hugo);
    FamilyTree.templates.hugo_male.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" fill=url(#hugo_grad_male) stroke="#aeaeae" rx="7" ry="7"></rect>';
    FamilyTree.templates.hugo_female = Object.assign({}, FamilyTree.templates.hugo);
    FamilyTree.templates.hugo_female.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" fill=url(#hugo_grad_female) stroke="#aeaeae" rx="7" ry="7"></rect>';

    FamilyTree.templates.hugo.up = '<use x="200" y="10" xlink:href="#hugo_up" />';
    FamilyTree.templates.hugo.nodeMenuButton = `<use x="225" y="10" ${FamilyTree.attr.control_node_menu_id}="{id}" xlink:href="#hugo_node_menu" />`;  


john

 
    FamilyTree.templates.john = Object.assign({}, FamilyTree.templates.base);
    FamilyTree.templates.john.defs = `<style>
                                        .{randId} .bft-edit-form-header, .{randId} .bft-img-button{
                                            background-color: #aeaeae;
                                        }
                                        .{randId}.male .bft-edit-form-header, .{randId}.male .bft-img-button{
                                            background-color: #039BE5;
                                        }        
                                        .{randId}.male div.bft-img-button:hover{
                                            background-color: #F57C00;
                                        }
                                        .{randId}.female .bft-edit-form-header, .{randId}.female .bft-img-button{
                                            background-color: #F57C00;
                                        }        
                                        .{randId}.female div.bft-img-button:hover{
                                            background-color: #039BE5;
                                        }
                                    </style>
                                    <clipPath id="john_img_0"><rect x="6" y="6" rx="54" ry="54" width="108" height="108"></rect></clipPath>
                                    ${FamilyTree.gradientCircleForDefs('circle', '#aeaeae', 60, 5)}
                                    ${FamilyTree.gradientCircleForDefs('male_circle', '#039BE5', 60, 5)}
                                    ${FamilyTree.gradientCircleForDefs('female_circle', '#F57C00', 60, 5)}`;
    FamilyTree.templates.john.field_0 = 
        '<text ' + FamilyTree.attr.width + ' ="230" style="font-size: 16px;font-weight:bold;" fill="#aeaeae" x="60" y="135" text-anchor="middle">{val}</text>';
    FamilyTree.templates.john.field_1 = 
        '<text ' + FamilyTree.attr.width + ' ="150" style="font-size: 13px;" fill="#aeaeae" x="60" y="150" text-anchor="middle">{val}</text>';
    FamilyTree.templates.john.node = '<use x="0" y="0" xlink:href="#circle" />';
    FamilyTree.templates.john.img_0 = 
        '<image preserveAspectRatio="xMidYMid slice" clip-path="url(#john_img_0)" xlink:href="{val}" x="6" y="6" width="108" height="108"></image>';
    FamilyTree.templates.john.ripple = {
        radius: 60,
        color: "#e6e6e6",
        rect: null
    };

    FamilyTree.templates.john.size = [120, 120]
    FamilyTree.templates.john_male = Object.assign({}, FamilyTree.templates.john);
    FamilyTree.templates.john_male.node += '<use x="0" y="0" xlink:href="#male_circle" />';
    FamilyTree.templates.john_male.ripple = {
        radius: 60,
        color: "#039BE5",
        rect: null
    };
    FamilyTree.templates.john_female = Object.assign({}, FamilyTree.templates.john);
    FamilyTree.templates.john_female.node += '<use x="0" y="0" xlink:href="#female_circle" />';
    FamilyTree.templates.john_female.ripple = {
        radius: 60,
        color: "#F57C00",
        rect: null
    };
    FamilyTree.templates.john.nodeMenuButton = `<use ${FamilyTree.attr.control_node_menu_id}="{id}" x="90" y="50" xlink:href="#base_node_menu" />`;


All templates are inherited form the base template. Here are defined all the other properties.
 
   FamilyTree.templates.base = {
    defs: 
        `<g transform="matrix(1,0,0,1,0,0)" id="dot"><circle class="ba-fill" cx="0" cy="0" r="5" stroke="#aeaeae" stroke-width="1"></circle></g>
        <g id="base_node_menu" style="cursor:pointer;">
            <rect x="0" y="0" fill="transparent" width="22" height="22"></rect>
            <circle cx="4" cy="11" r="2" fill="#aeaeae"></circle>
            <circle cx="11" cy="11" r="2" fill="#aeaeae"></circle>
            <circle cx="18" cy="11" r="2" fill="#aeaeae"></circle>
        </g>
        <g style="cursor: pointer;" id="base_tree_menu">
            <rect x="0" y="0" width="25" height="25" fill="transparent"></rect>
            ${FamilyTree.icon.addUser(25, 25, '#fff', 0, 0)}
        </g>
        <g style="cursor: pointer;" id="base_tree_menu_close">
            <circle cx="12.5" cy="12.5" r="12" fill="#F57C00"></circle>
            ${FamilyTree.icon.close(25, 25, '#fff', 0, 0)}
        </g>            
        <g id="base_up">
            <circle cx="15" cy="15" r="15" fill="#fff" stroke="#aeaeae" stroke-width="1"></circle>
            ${FamilyTree.icon.ft(20,20,'#aeaeae', 5, 5)}
        </g>
        <clipPath id="base_img_0">
            <rect id="base_img_0_stroke" stroke-width="3" stroke="#fff" x="170" y="-5" rx="25" ry="25" width="70" height="70"></rect>
        </clipPath>`,
    size: [250, 120],
    linkAdjuster: {
        fromX: 0,
        fromY: 0,
        toX: 0,
        toY: 0
    },
    ripple: {
        radius: 0,
        color: "#e6e6e6",
        rect: null
    },
    expandCollapseSize: 0,
    svg: 
        '<svg class="{randId} {template} {mode}" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" 
        style="display:block;" width="{w}" height="{h}" viewBox="{viewBox}">{content}</svg>',
    link: '<path stroke-linejoin="round" stroke="#aeaeae" stroke-width="1px" fill="none" d="{rounded}" />',
    assistanseLink: '<path stroke-linejoin="round" stroke="#aeaeae" stroke-width="2px" fill="none" d="M{xa},{ya} {xb},{yb} {xc},{yc} {xd},{yd} L{xe},{ye}" />',
    pointer: 
        '<g data-pointer="pointer" transform="matrix(0,0,0,0,100,100)">
            <radialGradient id="pointerGradient"><stop stop-color="#ffffff" offset="0" /><stop stop-color="#C1C1C1" offset="1" /></radialGradient>
            <circle cx="16" cy="16" r="16" stroke-width="1" stroke="#acacac" fill="url(#pointerGradient)"></circle>
        </g>',
    node: '<rect x="0" y="0" height="{h}" width="{w}" stroke-width="1" stroke="#aeaeae" rx="7" ry="7"></rect>',
    menuButton: 
        '<div style="position:absolute;right:{p}px;top:{p}px; width:40px;height:50px;cursor:pointer;" ' + FamilyTree.attr.control_export_menu + ' ="">
            <hr style="background-color: #7A7A7A; height: 3px; border: none;">
            <hr style="background-color: #7A7A7A; height: 3px; border: none;">
            <hr style="background-color: #7A7A7A; height: 3px; border: none;">
        </div>',
    padding: [50, 20, 35, 20],
    nodeMenuButton: `<use ${FamilyTree.attr.control_node_menu_id}="{id}" x="220" y="95" xlink:href="#base_node_menu" />`,    
    nodeTreeMenuButton: `<use ${'data-ctrl-n-t-menu-id'}="{id}" x="10" y="10" xlink:href="#base_tree_menu" />`,
    nodeTreeMenuCloseButton:  `<use ${'data-ctrl-n-t-menu-c'}="" x="10" y="10" xlink:href="#base_tree_menu_close" />`,
    up: '<use x="110" y="-10" xlink:href="#base_up" />',
    img_0: 
        '<use xlink:href="#base_img_0_stroke" />
        <image preserveAspectRatio="xMidYMid slice" clip-path="url(#base_img_0)" xlink:href="{val}" x="170" y="-5" width="70" height="70"></image>',
    link_field_0: '<text text-anchor="middle" fill="#aeaeae" ' + FamilyTree.attr.width + ' ="290" x="0" y="0" style="font-size:10px;">{val}</text>'

We have also predefined templates for adding nodes using the NodeTreeMenu:


mother

 
    FamilyTree.templates.mother = Object.assign({}, FamilyTree.templates.base);
    FamilyTree.templates.mother.up = '';
    FamilyTree.templates.mother.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;" stroke-width="1" stroke="#F57C00" rx="5" ry="5"></rect>'
        + '<text style="font-size: 18px;" fill="#F57C00" x="240" y="30" text-anchor="end">Add mother</text>'  + FamilyTree.icon.mother(70, 70, '#F57C00', 10, 40);


father
 
    FamilyTree.templates.father = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.father.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#039BE5;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#039BE5" x="240" y="30" text-anchor="end">Add father</text>' + FamilyTree.icon.father(70, 70, '#039BE5', 10, 40);


partner
 
    FamilyTree.templates.partner = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.partner.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#aeaeae;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#aeaeae" x="240" y="30" text-anchor="end">Add partner</text>';


son
 
    FamilyTree.templates.son = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.son.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#039BE5;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#039BE5" x="240" y="30" text-anchor="end">Add son</text>'  + FamilyTree.icon.son(70, 70, '#039BE5', 10, 40);


daughter
 
    FamilyTree.templates.daughter = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.daughter.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#F57C00;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#F57C00" x="240" y="30" text-anchor="end">Add daughter</text>' + FamilyTree.icon.daughter(70, 70, '#F57C00', 10, 40);


husband
 
    FamilyTree.templates.husband = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.husband.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#039BE5;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#039BE5" x="240" y="30" text-anchor="end">Add husband</text>'  + FamilyTree.icon.husband(70, 70, '#039BE5', 10, 40);


wife
 
    FamilyTree.templates.wife = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.wife.node = 
        '<rect x="0" y="0" height="{h}" width="{w}" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#F57C00;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#F57C00" x="240" y="30" text-anchor="end">Add wife</text>'  + FamilyTree.icon.wife(70, 70, '#F57C00', 10, 40);


pet
 
    FamilyTree.templates.pet = Object.assign({}, FamilyTree.templates.mother);
    FamilyTree.templates.pet.node = 
        '<rect x="0" y="0" style="fill:transparent;height:{h}; width:{w};stroke-width:1;stroke:#F57C00;rx:5;ry:5;"></rect>'
        + '<text style="font-size: 18px;" fill="#F57C00" x="240" y="30" text-anchor="end">Add pet</text>'  + FamilyTree.icon.teddy(70, 70, '#F57C00', 10, 40);