primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.21k stars 4.55k forks source link

preserveSpace property to OrganizationChart #7313

Closed Angeleye01 closed 4 years ago

Angeleye01 commented 5 years ago

I'm submitting a ...

[ ] bug report
[ x ] feature request
[ ] support request 

Current behavior Org Chart child nodes become hidden on collapse making the org chart unnecessarily huge when all/some nodes are collapsed. untitled

Expected behavior The child nodes on have display:none. Something like horizontal tree onCollapse event. untitled2

What is the motivation / use case for changing the behavior? The org chart look weirdly unorganized when few nodes are collapsed.

Angeleye01 commented 5 years ago

Any work around this will also do for me.

kasonjimLD commented 5 years ago

@Angeleye01 The only work around I was able to do for this was to edit the node_modules/primeng/components/organizationchart/organizationchart.js (also organizationchart.metadata.json if doing a production build) component file directly and change [style.visibility] to [style.display], and change the respective ternary values

[style.display]=\"!leaf&&node.expanded ? '' : 'none'\"

Since this does get overwritten whenever you update PrimeNG, this is only a temporary solution to develop with. I will make a PR with some organizationchart items when I can (if it isn't made already)

Angeleye01 commented 5 years ago

Yes that i what I'm currently doing locally. But as you mention it gets overwritten on update. So I was hoping if was possible to get the update from end.

csongebalazs commented 4 years ago

The OrgChart uses TreeNode IF, which has an expanded, a type and a parent attribute. If I set them, I can check is the parent node expanded or not, and if not, I can put a class onto leafs.

HTML:

<ng-template let-node pTemplate="leaf">
    <div class="org-leaf" [ngClass]="{'closed' : !isNodeParentExpanded(node)}">
        <div>{{node.label}}</div>
    </div>
</ng-template>

JS:

isNodeParentExpanded(node: TreeNode): boolean {
    return node && node.parent && node.parent.expanded;
}

SCSS:

.closed {
    display: none;
}

Sadly if the tree contains more level then root-parent-leaf, the OrgChart component puts a tonns of none visible table elements into the DOM, and using this class adding trick on none-root+none-leaf nodes does not help :(

Maybe if someone store the full tree in a variable, and manage a "shorted" copy of it using onNodeExpand and onNodeCollapse events, which contains only the expanded nodes, and the OrgChart value binded to the shorted copy, then this problem can be avoided. But I did not test it.

csongebalazs commented 4 years ago

I made a workaround solution. OrgChart value has been set via a cloned menu tree (at start it fully exapnded).

In onNodeCollapse I clear all children of the given (cloned) node.

    onNodeCollapse(event) {
        console.log('KomponensDemoComponent - onNodeCollapse', event);
        if (event && event.node) {
            event.node.children = [];
        }
    }

In onNodeExpand I getting the node object back from the original menu tree, and setting child list of the expanded node back, but clearing the children attribute of every restored child.

    onNodeExpand(event) {
        const node = this.menuService.getMenuMapItemByNodeName(event.node.label);
        if (node && node.node && node.node.children && node.node.children.length > 0) {
            const children: TreeNode[] = cloneDeep(node.node.children);
            children.forEach(child => {
                child.expanded = false;
                child.children = [];
            });
            event.node.children = children;
        }
    }

In the example getMenuMapItemByNodeName method return with an object with 2 attribites.

cagataycivici commented 4 years ago

Will be an option like preserveSpace="true or false"

thetucko commented 1 week ago

if you still have this issue (maybe using old version like i do :)) i did it this way

add these variables private collapsedNodeChildrenMap: Map<TreeNode, TreeNode[]> = new Map(); // Store the original children private readonly PLACEHOLDER_NODE: TreeNode = { label: '', data: {}, children: [] }; // Placeholder node

than hook to these onNodeCollapse(event) { const node = event.node;

// Store the original children if not already stored
if (!this.collapsedNodeChildrenMap.has(node)) {
  this.collapsedNodeChildrenMap.set(node, node.children || []);
}

// Add a placeholder node to keep the expand button visible
node.children = [this.PLACEHOLDER_NODE];
this.cdr.detectChanges();  // Trigger change detection to update view

}

onNodeExpand(event) { const node = event.node;

// Restore the children if previously stored
if (this.collapsedNodeChildrenMap.has(node)) {
  node.children = this.collapsedNodeChildrenMap.get(node) || [];
  this.collapsedNodeChildrenMap.delete(node); // Clean up the stored children
}

// Remove the placeholder node if it exists
if (node.children.length === 1 && node.children[0] === this.PLACEHOLDER_NODE) {
  node.children = [];
}

this.cdr.detectChanges();  // Trigger change detection to update view

}

where private cdr: ChangeDetectorRef,