BALKANGraph / FamilyTreeJS

Build family tree app with BALKAN FamilyTreeJS library. Family Tree also called a genealogy or a pedigree chart, is a chart representing family relationships in a conventional tree structure.
60 stars 17 forks source link

Selectively blurring nodes in the family tree #126

Closed frankbracq closed 4 months ago

frankbracq commented 5 months ago

Hi,

I'd like to display the family tree with all nodes blurred except those whose IDs are listed in an array "selectedIds," (the content of which can be dynamically modified by code in another part of my application). If selectedIds is empty, then no nodes in the family tree are blurred.

Thank you in advance for your help!

Frank

ZornitsaPesheva commented 5 months ago

Please check if this example can help you: https://code.balkan.app/family-tree-js/blur#JS In your case you don't need to iterate the parents, but only the list of your nodes.

frankbracq commented 5 months ago

Thanks for the info!

frankbracq commented 5 months ago

Works fine! Here is the code I'm using to display the family tree with the selective blur feature.

The selected nodes represent the shortest paths in the family tree between them and their common ancestor. How could I make sure that all nodes listed in the "selectedIds" array are visible upon the family tree display, thus avoiding the need to manually deploy the nodes as you can see in this video: https://www.loom.com/share/5b3e20c6e9f2464487f88622077907f0?sid=c2796f2e-8643-4576-a00e-f4a95d6b2a79.

My code

export function initializeFamilyTree() { const selectedIds = [ "@I164@", "@I148@", "@I86@", "@I94@", "@I105@", "@I111@", "@I789613205@", "@I170@" ];

const individualsCache = getIndividualsCache();
const familyTreeData = formatIndividualsData(individualsCache);

const family = new FamilyTree(document.getElementById('familyTree'), {
    mouseScrool: FamilyTree.action.none,
    scaleInitial: FamilyTree.match.height,
    roots: ['@I111@','@I164@'],
    clinks: [
        {from: '@I111@', to: '@I94@', label: 'text'}
    ],
    nodeBinding: {
        field_0: 'name',
        field_1: 'birthDate',
        field_2: 'deathDate',
        field_3: 'id'
    },
    orientation: FamilyTree.orientation.top,
    miniMap: true,
    toolbar: {
        layout: true,
        zoom: true,
        fit: true,
        expandAll: false,
        fullScreen: true
    },
});

family.on("prerender", function(sender, args) {
    var nodes = args.res.nodes;
    console.log("Nodes before processing:", nodes); // Log all nodes before processing
    for (var id in nodes) {
        if (!selectedIds.includes(nodes[id].id)) {
            // console.log("Blurring node:", nodes[id].id); // Log the node being blurred
            nodes[id].tags.push('blurred');
        } else {
            // console.log("Not blurring node:", nodes[id].id); // Log the node not being blurred
            nodes[id].tags = nodes[id].tags.filter(tag => tag !== 'blurred');
        }
    }
    console.log("Nodes after processing:", nodes); // Log all nodes after processing
});

family.load(familyTreeData);

}

// Fonction pour formater les données pour FamilyTreeJS function formatIndividualsData(individualsCache) { const familyTreeData = []; individualsCache.forEach((data, id) => { familyTreeData.push({ id: data.id, fid: data.fatherId, mid: data.motherId, pids: data.spouseIds, name: ${data.name} ${data.surname}, birthDate: data.birthDate, deathDate: data.deathYear, gender: data.gender, display: true }); }); return familyTreeData; }

ZornitsaPesheva commented 5 months ago

So you are asking how to create the selectedIds list?

frankbracq commented 5 months ago

No, I know how to create the list. I just want to know how I can make visible all the nodes in the list, so that user don't have to click (as shown in the video) to display the hidden nodes.

Frank Bracq +33 6 11 71 19 58

Le mer. 26 juin 2024 à 06:40, ZornitsaPesheva @.***> a écrit :

So you are asking how to create the selectedIds list?

— Reply to this email directly, view it on GitHub https://github.com/BALKANGraph/FamilyTreeJS/issues/126#issuecomment-2190673803, or unsubscribe https://github.com/notifications/unsubscribe-auth/AISB57XTXPWAHL4XRLHEYVTZJJA2PAVCNFSM6AAAAABJ3RGQXCVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDCOJQGY3TGOBQGM . You are receiving this because you authored the thread.Message ID: @.***>

ZornitsaPesheva commented 4 months ago

You should find the root and set it as a root. here is an example: https://code.balkan.app/family-tree-js/set-root#JS

frankbracq commented 4 months ago

I'm probably missing something but it doesn't work as expected. In this code (see hereafter), I set node with id = @I164@ as root. So, I expect that this node is visible when the family tree is displayed. It is not the case, and I have to click successively on different nodes to make the node @I164@ (name = Léon Divry) appear (see attached video https://www.loom.com/share/458ba895263246138cc7263d0670cd83?sid=7b790ff5-7fec-4017-9294-4fdca5985f7f). With the FamilyTree API, is there a way to force the display of a root node?

My code:

//... export function initializeFamilyTree() { const selectedIds = getCommonAncestryGraphData();

const individualsCache = getIndividualsCache();
const familyTreeData = formatIndividualsData(individualsCache);

const family = new FamilyTree(document.getElementById('familyTree'), {
    mouseScrool: FamilyTree.action.none,
    scaleInitial: FamilyTree.match.height,
    roots: ['@I164@'],
    clinks: [
        {from: '@I111@', to: '@I94@', label: 'text'}
    ],
    nodeBinding: {
        field_0: 'name',
        field_1: 'birthDate',
        field_2: 'deathDate',
        field_3: 'id'
    },
    orientation: FamilyTree.orientation.top,
    miniMap: true,
    toolbar: {
        layout: true,
        zoom: true,
        fit: true,
        expandAll: false,
        fullScreen: true
    },
});

//...

ZornitsaPesheva commented 4 months ago

To be able to help, we need a running example with a data that we can reproduce the issue with. Please create an example in our code app: https://code.balkan.app/org-chart-js/simple-example#JS

frankbracq commented 4 months ago

OK. I'll send you the data asap

frankbracq commented 4 months ago

I've set up an example with my data (same data set as in the video). at https://code.balkan.app/root-individual-not-displayed#JS

Root individual as defined in the js is @I164@. As you will see, root individual is not displayed :

ZornitsaPesheva commented 4 months ago

In the current implementation of Family Tree JS a root can be only a top level node. As @i164@ has parents, it cannot be a root.

frankbracq commented 4 months ago

So, as a temporary workaround, i need to trigger a reload of the family tree without the ancestors of @I164@ ?

frankbracq commented 4 months ago

Or does the familytree api provide a methd to filter out unneeded nodes?

ZornitsaPesheva commented 4 months ago

I don't understand why you are trying to set that node as a root. To highlight the parents a node, you need to show the parents to the root. You tell us that you have the list that you'd like to be shown and highlighted. IF you give us that list for the data in the example below, we could try to help: https://code.balkan.app/root-individual-not-displayed#JS

frankbracq commented 4 months ago

I wish to implement a feature allowing the user to highlight the relationship between two family members (for example @I789613205@ and @I170@). I have an algorithm that detects their common ancestor (= @I164). The algorithm also returns the list of the nodes that link the 2 nodes to their common ancestors ([ "@I164@", "@I148@", "@I86@", "@I94@", "@I105@", "@I111@", "@I789613205@", "@I170@" ]. This is why I want to set @I164@ as a root node so that user can see how @I789613205@ and @I170@ are linked.

frankbracq commented 4 months ago

Of course I could dynamically reload the family tree without any parent for @I164@

ZornitsaPesheva commented 4 months ago

You can show all the nodes above @i164@ to the root.