2

Angular version 16; D3 version 7.9.0; D3-org-chart version 3.1.1... I created a chart of organization. But I would want to provide the organizational chart a zoom-in and zoom-out function.

I added the code for zoom-in and zoom-out feature but when zoom-in or out the chart disappeared.

I don't know how to set the zoom-in ,zoom-out limitations for organizational chart.

HTML code

<div id="orgchart" class="chart-container"></div>


SCSS code

#orgchart {

    .node .label {
        fill: green !important;
    }

    .node .title {
        fill: red !important;
    }

    .node rect {
        fill: lightblue !important;
    }

    svg {
        background-color: rgb(213, 219, 220);
    }

    ::ng-deep.node-button-div {
        width: 134% !important;
    }


    // ::ng-deep svg.svg-chart-container {
    //     height: 200vh !important;
    // }

    ::ng-deep svg.svg-chart-container {
        height: auto !important;
        width: auto !important;

    }

}




TS code

import {
    OnChanges,
    Component,
    OnInit,
    Input,
    ViewChild,
    ElementRef,
} from '@angular/core';
import * as d3 from 'd3';
import { HierarchyNode } from 'd3';
import { OrgChart, State } from 'd3-org-chart';



@Component({
    selector: 'app-org-chart',
    templateUrl: './org-chart.component.html',
    styleUrls: ['./org-chart.component.scss']
})
export class OrgChartComponent implements OnInit, OnChanges {
    @ViewChild("chartContainer") chartContainer: ElementRef | undefined;
    @Input() data: any[] | undefined;
    chart: any;
    datas: any[] = [];
    constructor() { }

    ngOnInit() {





        const res = {
            data: [
                {
                    id: 1,
                    pos_name: 'KITTING PROCESS',
                    size: '',
                    parentId: 0,
                    member: 'Mani.N  (027)',
                    imgname: null,
                    desig_id: 1,
                    desig_name: 'Managing Director',
                    file_path: null,
                    // status: 'inprogress',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },
                {
                    id: 2,
                    pos_name: 'ASSEMBLY PROCESS',
                    size: '',
                    parentId: 0,
                    // member: 'Soumen Deb  (142)',
                    imgname: null,
                    desig_id: 2,
                    // desig_name: 'Test27_desig',
                    file_path: null,
                    // status: 'pending',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },
                {
                    id: 3,
                    pos_name: 'TESTING PROCESS',
                    size: '',
                    parentId: 0,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 3,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'completed',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },
                {
                    id: 4,
                    pos_name: 'Dry Process',
                    size: '',
                    parentId: 1,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 4,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'completed',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },
                {
                    id: 5,
                    pos_name: 'Wet Process',
                    size: '',
                    parentId: 1,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 4,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'pending',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },

                {
                    id: 6,
                    pos_name: 'Radix Lab to Fab Products',
                    size: '',
                    parentId: 1,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 6,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'inprogress',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },

                {
                    id: 7,
                    pos_name: "Strategic Technology Platforms",
                    size: "",
                    parentId: 1,
                    member: "Sanjay.G  (476)",
                    imgname: null,
                    desig_id: 73,
                    desig_name: "Senior Officer - Costing",
                    file_path: null,
                    // status: 'completed',
                    imageUrl: "http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png"
                },
                {
                    id: 8,
                    pos_name: 'Dry Process',
                    size: '',
                    parentId: 2,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 4,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'completed',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },
                {
                    id: 9,
                    pos_name: 'Wet Process',
                    size: '',
                    parentId: 2,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 4,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'pending',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },

                {
                    id: 10,
                    pos_name: 'Radix Lab to Fab Products',
                    size: '',
                    parentId: 2,
                    // member: 'Tanmoy Ghosh  (341)',
                    imgname: null,
                    desig_id: 6,
                    // desig_name: 'Manager-Laser Customer Relations',
                    file_path: null,
                    // status: 'inprogress',
                    imageUrl:
                        'http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png',
                },

                {
                    id: 11,
                    pos_name: "Strategic Technology Platforms",
                    size: "",
                    parentId: 2,
                    member: "Sanjay.G  (476)",
                    imgname: null,
                    desig_id: 73,
                    desig_name: "Senior Officer - Costing",
                    file_path: null,
                    // status: 'completed',
                    imageUrl: "http://103.154.184.122:8080/kpi_api_dev/authenticate/profileimage/user.png"
                },
             
                {
                    id: 0,
                    pos_name: "YES",
                    size: "",
                    parentId: "",
                    member: "Organizational Chart",

                    desig_id: 73,
                    desig_name: "",

                }
            ]
        }



        console.log('Org Chart Data:', res.data);
        console.log('ID type:', typeof res.data[0].id, 'ParentID type:', typeof res.data[0].parentId);
        console.log('IDs:', res.data.map(item => item.id));
        res.data.forEach(item => {
            if (item.id === null || item.id === undefined || item.parentId === null || item.parentId === undefined) {
                console.log('Null or undefined found:', item);
            }
        });

        if (res) {
            const chartContainer = d3.select('.chart-container');
            chartContainer.append('defs')
                .append('clipPath')
                .attr('id', 'clip')
                .append('rect')
                .attr('width', '100%')
                .attr('height', '100%');
            this.chart = new OrgChart()
                .container('.chart-container')
                .layout('left')
                .data(res.data)
                .nodeWidth((d: any) => 300)
                .initialZoom(0.8)
                .nodeHeight((d: any) => 175)


                .buttonContent(
                    ({
                        node,
                        state,
                    }: {
                        node: HierarchyNode<any>;
                        state: State<any>;
                    }) => {
                        return `<div style="color:#fff;    border-radius: 5px;
    padding: 3px 9px 3px 8px;font-size:10px;margin:auto auto;background-color:#007672;border: 1px solid #007672">
    <span style="font-size:14px">
    ${node.data._directSubordinates}
        ${node.children
                                ? `<i class="fa fa-angle-up"></i>`
                                : `<i class="fa fa-angle-down"></i>`
                            }
    </span>

    </div>`;
                    }
                )
                .linkUpdate((d: any, i: any, arr: any) => {
                    const selection = d3.select('.chart-container');
                    const strokeColor = '#007672';
                    const strokeWidth = d.data._upToTheRootHighlighted ? 15 : 1;
                    selection.style('stroke', strokeColor);
                    selection.attr('stroke-width', strokeWidth);


                    if (d.data._upToTheRootHighlighted) {
                        selection.raise();
                    }
                })
                .childrenMargin((d: any) => 50)
                .compactMarginBetween((d: any) => 35)
                .compactMarginPair((d: any) => 90)
                .nodeContent(function (
                    d: HierarchyNode<any>,
                    i: number,
                    arr: HierarchyNode<any>[],
                    state: State<any>
                ) {
                    const nodeWithWidth = d as HierarchyNode<any> & { width: number };
                    const imageUrl = d.data.imageUrl ? d.data.imageUrl : 'assets/masters/user.jpg';

                    let borderColor = 'lightgray'; // Default border color

                    if (d.data.status === 'pending') {
                        borderColor = 'orange';
                    } else if (d.data.status === 'inprogress') {
                        borderColor = 'blue';
                    } else if (d.data.status === 'completed') {
                        borderColor = 'green';
                    }
                    return `

    

    <div style="padding-top:0px;background-color:none;    border-radius: 20px; margin-left:1px;height:${d.height}px;border-radius:2px;overflow:visible">
    <div style="height:inherit;padding-top:0px;background-color:white;border:5px solid ${borderColor};    border-radius: 20px;">
    <div
    class="col-xs-12 col-sm-12 col-md-12 col-lg-12 row m-0 p-0"
    style="
      background: #ffffff 0% 0% no-repeat padding-box;
      box-shadow: 0px 3px 6px #00000029;
      height: inherit;
      width: inherit;
  border-radius: 20px;
    "
    >
    
    <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 row m-0 p-3">
      <div
        class="col-xs-12 col-sm-12 col-md-12 col-lg-12 row m-0 d-flex align-items-center p-0"
      >
        <div class="col-xs-3 col-sm-3 col-md-3 col-lg-3 p-0">
          <img src="assets/card/profile1.png" style="width: 70px; height: 70px;border-radius: 50%;" />
        </div>
        <div class="col-xs-9 col-sm-9 col-md-9 col-lg-9 p-0">
          <div
            class="col-xs-12 col-sm-12 col-md-12 col-lg-12 d-flex flex-column ms-4"
          >
            <div
              class="col-xs-12 col-sm-12 col-md-12 col-lg-12 pt-2 d-flex justify-content-start fw-bolder"
            >
            ${d.data.pos_name}
            </div>

              <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 py-1 fw-light " style="color: #007672;">
            ${d.data.desig_name}
            </div>

            <div class="col-xs-12 col-sm-12 col-md-12 col-lg-12 py-1 fw-light "  style="color: #868585;">
            ${d.data.member}
            </div>
          
          </div>
        </div>
      </div>

    </div>`;
                })

            const zoom: any = d3
                .zoom<SVGSVGElement, any>()
                .scaleExtent([1, 10])
                .on('zoom', (event: any) => {
                    chartContainer.attr('transform', event.transform);
                });
            chartContainer.call(zoom);

            console.log("Chart after expandAll:", this.chart);
            console.log("Chart after render:", this.chart);
            this.chart.expandAll();

            this.chart.render();






        }

    }


    ngAfterViewInit() {
        if (!this.chart) {

        }
        this.updateChart();
    }



    ngOnChanges() {
        this.updateChart();
    }
    updateChart() {
        if (!this.data) {
            return;
        }
        if (!this.chart) {
            return;
        }
        this.chart
            .container('.chart-container')
            .data(this.data)
            .svgWidth(500)

            .onNodeClick((d: any) => console.log(d + ' node clicked'))
            .render();
    }


}

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.