{
  "$schema": "https://ai.syncfusion.com/schema/registry-item.json",
  "name": "diagram-organization-chart",
  "framework": "react",
  "type": "registry:component",
  "component": "Diagram",
  "variant": "organization-chart",
  "dependencies": [
    "@syncfusion/ej2-react-diagrams",
    "@syncfusion/ej2-react-inputs",
    "@syncfusion/ej2-data"
  ],
  "description": "Organization chart arranges local employee data in a horizontally aligned hierarchy.",
  "meta": {
    "essentialStudioRelease": "2026 Volume 2 (v34.1.29)",
    "license": "commercial-or-community",
    "licenseNote": "The Syncfusion package is licensed. The composition in this file is source you own and edit. See https://ai.syncfusion.com/licensing.md",
    "requiresLicenseKey": true,
    "requiresServerEndpoint": false,
    "platformIndex": "https://ai.syncfusion.com/react/llms.txt",
    "skillPack": "syncfusion/react-ui-components-skills",
    "docs": "https://ai.syncfusion.com/gallery/react/js/diagram-organization-chart.md"
  },
  "files": [
    {
      "target": "src/components/diagram-organization-chart/Diagram.jsx",
      "content": "import { LayoutAnimation, HierarchicalTree, DataBinding, DiagramComponent, ConnectorConstraints, SnapConstraints, Inject, DiagramTools } from \"@syncfusion/ej2-react-diagrams\";\nimport { DataManager } from \"@syncfusion/ej2-data\";\n\nlet localBindData = [\n    { 'Id': 'parent', 'Role': 'Board', 'color': '#71AF17' },\n    { 'Id': '1', 'Role': 'General Manager', 'Manager': 'parent', 'ChartType': 'right', 'color': '#71AF17' },\n    { 'Id': '11', 'Role': 'Assistant General Manager', 'Manager': '1', 'color': '#71AF17' },\n    { 'Id': '2', 'Role': 'Human Resource Manager', 'Manager': '1', 'ChartType': 'right', 'color': '#1859B7' },\n    { 'Id': '3', 'Role': 'Trainers', 'Manager': '2', 'color': '#2E95D8' },\n    { 'Id': '4', 'Role': 'Recruiting Team', 'Manager': '2', 'color': '#2E95D8' },\n    { 'Id': '5', 'Role': 'Finance Asst. Manager', 'Manager': '2', 'color': '#2E95D8' },\n    { 'Id': '6', 'Role': 'Design Manager', 'Manager': '1', 'ChartType': 'right', 'color': '#1859B7' },\n    { 'Id': '7', 'Role': 'Design Supervisor', 'Manager': '6', 'color': '#2E95D8' },\n    { 'Id': '8', 'Role': 'Development Supervisor', 'Manager': '6', 'color': '#2E95D8' },\n    { 'Id': '9', 'Role': 'Drafting Supervisor', 'Manager': '6', 'color': '#2E95D8' },\n    { 'Id': '10', 'Role': 'Operations Manager', 'Manager': '1', 'ChartType': 'right', 'color': '#1859B7' },\n    { 'Id': '11', 'Role': 'Statistics Department', 'Manager': '10', 'color': '#2E95D8' },\n    { 'Id': '12', 'Role': 'Logistics Department', 'Manager': '10', 'color': '#2E95D8' },\n    { 'Id': '16', 'Role': 'Marketing Manager', 'Manager': '1', 'ChartType': 'right', 'color': '#1859B7' },\n    { 'Id': '17', 'Role': 'Overseas Sales Manager', 'Manager': '16', 'color': '#2E95D8' },\n    { 'Id': '18', 'Role': 'Petroleum Manager', 'Manager': '16', 'color': '#2E95D8' },\n    { 'Id': '20', 'Role': 'Service Department Manager', 'Manager': '16', 'color': '#2E95D8' },\n    { 'Id': '21', 'Role': 'Quality Control Department', 'Manager': '16', 'color': '#2E95D8' }\n];\n\nconst SAMPLE_CSS = `\n/* Property panel orientation and sub tree alignment */\n.diagram-organization .image-pattern-style {\n        background-color: white;\n        background-size: contain;\n        background-repeat: no-repeat;\n        height: 75px;\n        width: calc((100% - 18px) / 3);\n        cursor: pointer;\n        border: 1px solid #D5D5D5;\n        background-position: center;\n        float: left;\n    }\n\n    .diagram-organization .image-pattern-style:hover {\n        border-color: gray;\n        border-width: 2px;\n    }\n\n    .diagram-organization .row {\n        margin-left: 0px;\n        margin-right: 0px;\n    }\n\n    .diagram-organization .row-header {\n        font-size: 13px;\n        font-weight: 500;\n    }\n\n    .diagram-organization .property-panel-header {\n      padding-top: 15px;\n      padding-bottom: 15px;\n    }\n\n    .diagram-organization .e-selected-orientation-style {\n        border-color: #006CE6;\n        border-width: 2px;\n    }\n\n    .diagram-organization .e-selected-pattern-style {\n        border-color: #006CE6;\n        border-width: 2px;\n    }\n\n    .diagram-organization .col-xs-6 {\n        padding-left: 0px;\n        padding-right: 0px;\n    }`;\nlet diagramInstance;\nlet horizontalSpacing;\nlet verticalSpacing;\nlet orientation;\nlet type;\nlet orientationInstance;\nlet patternInstance;\nfunction OrganizationModel() {\n    function rendereComplete() {\n        //Click Event for orientation of the PropertyPanel.\n        orientationInstance.onclick = (args) => {\n            let target = args.target;\n            let selectedElement = document.getElementsByClassName(\"e-selected-orientation-style\");\n            if (selectedElement.length) {\n                selectedElement[0].classList.remove(\"e-selected-orientation-style\");\n            }\n            if (!target.classList.contains(\"e-selected-orientation-style\")) {\n                target.classList.add(\"e-selected-orientation-style\");\n            }\n            if (target.className === \"image-pattern-style e-selected-orientation-style\") {\n                switch (target.id) {\n                    case \"toptobottom\":\n                        diagramInstance.layout.orientation = \"TopToBottom\";\n                        break;\n                    case \"bottomtotop\":\n                        diagramInstance.layout.orientation = \"BottomToTop\";\n                        break;\n                    case \"lefttoright\":\n                        diagramInstance.layout.orientation = \"LeftToRight\";\n                        break;\n                    case \"righttoleft\":\n                        diagramInstance.layout.orientation = \"RightToLeft\";\n                        break;\n                    default:\n                        if (selectedElement.length) {\n                            selectedElement[0].classList.remove(\"e-selected-orientation-style\");\n                        }\n                }\n                diagramInstance.dataBind();\n                diagramInstance.doLayout();\n            }\n        };\n        //Click Event for pattern of the PropertyPanel.\n        patternInstance.onclick = (args) => {\n            let target = args.target;\n            let selectedpatternElement = document.getElementsByClassName(\"e-selected-pattern-style\");\n            if (selectedpatternElement.length) {\n                selectedpatternElement[0].classList.remove(\"e-selected-pattern-style\");\n            }\n            if (!target.classList.contains(\"e-selected-pattern-style\")) {\n                target.classList.add(\"e-selected-pattern-style\");\n            }\n            if (target.className === \"image-pattern-style e-selected-pattern-style\") {\n                switch (target.id) {\n                    case \"pattern1\":\n                        orientation = \"Vertical\".toString();\n                        type = \"Alternate\";\n                        break;\n                    case \"pattern2\":\n                        orientation = \"Vertical\".toString();\n                        type = \"Left\";\n                        break;\n                    case \"pattern3\":\n                        orientation = \"Vertical\".toString();\n                        type = \"Left\";\n                        break;\n                    case \"pattern4\":\n                        orientation = \"Vertical\".toString();\n                        type = \"Right\";\n                        break;\n                    case \"pattern5\":\n                        orientation = \"Vertical\".toString();\n                        type = \"Right\";\n                        break;\n                    case \"pattern6\":\n                        orientation = \"Horizontal\".toString();\n                        type = \"Balanced\";\n                        break;\n                    case \"pattern7\":\n                        orientation = \"Horizontal\".toString();\n                        type = \"Center\";\n                        break;\n                    case \"pattern8\":\n                        orientation = \"Horizontal\".toString();\n                        type = \"Left\";\n                        break;\n                    case \"pattern9\":\n                        orientation = \"Horizontal\".toString();\n                        type = \"Right\";\n                        break;\n                    default:\n                        if (selectedpatternElement.length) {\n                            selectedpatternElement[0].classList.remove(\"e-selected-pattern-style\");\n                        }\n                }\n                diagramInstance.layout.getLayoutInfo = (node, options) => {\n                    if (target.id === \"pattern4\" || target.id === \"pattern3\") {\n                        options.offset = -50;\n                    }\n                    if (orientation) {\n                        getLayoutInfo(node, options, orientation, type);\n                    }\n                };\n                diagramInstance.dataBind();\n                diagramInstance.doLayout();\n            }\n        };\n    }\n    //set orientation and type of the Layout.\n    function getLayoutInfo(node, options, orientation, type) {\n        /* tslint:disable:no-string-literal */\n        if (node.data[\"Role\"] === \"General Manager\") {\n            options.assistants.push(options.children[0]);\n            options.children.splice(0, 1);\n        }\n        if (!options.hasSubTree) {\n            options.orientation = orientation;\n            options.type = type;\n        }\n    }\n    //sets default value for Node.\n    function nodeDefaults(obj, diagram) {\n        obj.backgroundColor = obj.data.color;\n        obj.style = { fill: \"none\", strokeColor: \"none\", color: \"white\" };\n        obj.expandIcon = {\n            height: 10,\n            width: 10,\n            shape: \"None\",\n            fill: \"lightgray\",\n            offset: { x: 0.5, y: 1 }\n        };\n        obj.expandIcon.verticalAlignment = \"Center\";\n        obj.expandIcon.margin = { left: 0, right: 0, top: 0, bottom: 0 };\n        obj.collapseIcon = { height: 10, width: 10, shape: \"None\", fill: \"lightgray\", offset: { x: 0.5, y: 1 } };\n        obj.collapseIcon.verticalAlignment = \"Center\";\n        obj.collapseIcon.margin = { left: 0, right: 0, top: 0, bottom: 0 };\n        obj.width = 120;\n        obj.height = 30;\n        return obj;\n    }\n    //sets default value for Connector.\n    function connectorDefaults(connector, diagram) {\n        connector.targetDecorator.shape = \"None\";\n        connector.type = \"Orthogonal\";\n        connector.constraints = ConnectorConstraints.None;\n        connector.cornerRadius = 0;\n        return connector;\n    }\n    // Updates expand and collapse icons of nodes based on args.checked state\n    function onExpandChange(args) {\n        for (let node of diagramInstance.nodes) {\n            if (args.checked) {\n                node.expandIcon.shape = 'Minus';\n                node.collapseIcon.shape = 'Plus';\n            }\n            else {\n                node.expandIcon.shape = 'None';\n                node.collapseIcon.shape = 'None';\n            }\n        }\n        diagramInstance.dataBind();\n        diagramInstance.doLayout();\n    }\n    ;\n    return (<div className=\"control-pane diagram-organization\">\n      <style>{SAMPLE_CSS}</style>\n      <div className=\"col-lg-8 control-section\">\n        <div style={{ width: \"100%\" }}>\n          <DiagramComponent id=\"diagram\" ref={(diagram) => (diagramInstance = diagram)} width={\"100%\"} height={\"700px\"} snapSettings={{ constraints: SnapConstraints.None }} \n    //configures data source settings\n    dataSourceSettings={{\n            id: \"Id\",\n            parentId: \"Manager\",\n            dataSource: new DataManager(localBindData),\n            doBinding: (nodeModel, data, diagram) => {\n                nodeModel.shape = {\n                    type: \"Text\",\n                    content: data.Role,\n                    margin: { left: 10, right: 10, top: 10, bottom: 10 },\n                };\n            },\n        }} \n    //Disables all interactions except zoom/pan\n    tool={DiagramTools.ZoomPan} \n    //Configures automatic layout\n    layout={{\n            type: \"OrganizationalChart\",\n            getLayoutInfo: (node, options) => {\n                /* tslint:disable:no-string-literal */\n                if (node.data[\"Role\"] === \"General Manager\") {\n                    options.assistants.push(options.children[0]);\n                    options.children.splice(0, 1);\n                }\n                if (!options.hasSubTree) {\n                    options.type = \"Right\";\n                }\n            },\n        }} \n    //Defines the default node and connector properties\n    getNodeDefaults={(obj, diagram) => {\n            /* tslint:disable:no-string-literal */\n            return nodeDefaults(obj, diagram);\n        }} getConnectorDefaults={(connector, diagram) => {\n            return connectorDefaults(connector, diagram);\n        }}>\n            <Inject services={[DataBinding, HierarchicalTree, LayoutAnimation]}/>\n          </DiagramComponent>\n        </div>\n      </div>\n\n    </div>);\n}\nexport default OrganizationModel;"
    }
  ]
}