node package manager

orgchart

OrgChart

Perhaps you'd prefer the native javascript(ES6) version

Perhaps you'd prefer the Web Components version

Foreword

  • First of all, thanks a lot for wesnolte's great workūüėä -- jOrgChart. The thought that using nested tables to build out the tree-like orgonization chart is amazing. This idea is more simple and direct than its counterparts based on svg
  • Unfortunately, it's long time not to see the update of jOrgChart. on the other hand, I got some interesting ideas to add, so I choose to create a new repo.
  • Font Awesome provides us with administration icon, second level menu icon and loading spinner.

Features

  • Supports both local data and remote data (JSON).
  • Smooth expand/collapse effects based on CSS3 transitions.
  • Align the chart in 4 orientations.
  • Allows user to change orgchart structure by drag/drop nodes.
  • Allows user to edit orgchart dynamically and save the final hierarchy as a JSON object.
  • Supports exporting chart as a picture or pdf document.
  • Supports pan and zoom
  • Users can adopt multiple solutions to build up a huge organization chart(please refer to multiple-layers or hybrid layout sections)
  • touch-enabled plugin for mobile divice

Installation

Of course, you can directly use the standalone build by including dist/js/jquery.orgchart.js and dist/css/jquery.orgchart.css in your webapps.

Install with Bower

# From version 1.0.2 on, users can install orgchart and add it to bower.json dependencies
$ bower install orgchart

Install with npm

# From version 1.0.4 on, users can install orgchart with npm
$ npm install orgchart

require('orgchart') will load orgchart plugin onto the jQuery object. The orgchart module itself does not export anything.

Demo

ul datasource

local datasource

pan & zoom

Bottom to Top

Left to Right

Left to Right

Right to Left

Right to Left

toggle siblings respectively

ajax datasource

Note: when users use ajaxURL option to build orghchart, they must use json datasource(both local and remote are OK) and set the relationship property of datasource by themselves. All of these staff are used to generate the correct expanding/collapsing arrows for nodes.

on-demand loading data

option--createNode

Here, we need the help from html2canvas.

export orgchart

Besides, if you wanna export a pdf format, you need to introduce jspdf as shown bellow:

<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.3.2/jspdf.debug.js"></script>

Note:

(1) if you wanna export something in IE or Edge, please introduce es6-promise.auto.js firstly.

(2) if your OS is windows, please check your display scaling settings. For the perfact exported picture, you'd better adjust "Change the size of text, apps, and other items" to 100%.(thanks for sayamkrai's exploration)

Here, we fall back on OpenLayers. It's the most aewsome open-source js library for Web GIS you sholdn't miss.

integrate map

With the help of exposed core methods(addParent(), addSiblings(), addChildren(), removeNodes()) of orgchart plugin, we can finish this task easily.

edit orgchart

Users are allowed to drag & drop the nodes of orgchart when option "draggable" is assigned to true(Note: this feature doesn't work on IE due to its poor support for HTML5 drag & drop API).

drag & drop

Furthermore, users can make use of option dropCriteria to inject their custom limitations on drag & drop. As shown below, we don't want an manager employee to be under a engineer under no circumstance.

That's where getHierarchy() comes in.

get hierarchy

It's a so easy task, we just need to append id or className property to node data.

color coded

In fact, this is a wonderful solution to display a orgchart which includes a huge number of node data.

multiple layers

This feature is inspired by the issues(Aligning Children Vertical, Hybrid(horizontal + vertical) OrgChart). Thank mfahadi and Destructrix for their constructive suggestionsūüėä Special thanks to tedliang for his wonderful hybrid mode solution.

From now on, users never have to worry about how to align a huge of nodes in one screen of browser. The option "verticalDepth" allows users to align child nodes vertically from the given depth.

Note: currently, this option is incompatible with many other options or methods, like direction, drag&drop, addChildren(), removeNodes(), getHierarchy() and so on. These conflicts will be solved one by one in the later versions.

hybrid layout

No problem. You just need to adjust a little detail of datasource with the help of option "collapse" and className "slide-up".

It's not a big deal. You just turn to the method init().

No problem. With the help of ES6 Template literals, we can customize the any complex node structure rather than the common title and content sections.

custom template

Usage

Instantiation Statement

var oc = $('#chartContainerId').orgchart(options);

Structure of Datasource

{
  'id': 'rootNode', // It's a optional property which will be used as id attribute of node 
  // and data-parent attribute, which contains the id of the parent node 
  'collapsed': true, // By default, the children nodes of current node is hidden. 
  'className': 'top-level', // It's a optional property which will be used as className attribute of node. 
  'nodeTitlePro': 'Lao Lao',
  'nodeContentPro': 'general manager',
  'relationship': relationshipValue, // Note: when you activate ondemand loading nodes feature, 
  // you should use json datsource (local or remote) and set this property. 
  // This property implies that whether this node has parent node, siblings nodes or children nodes. 
  // relationshipValue is a string composed of three "0/1" identifier. 
  // First character stands for wether current node has parent node; 
  // Scond character stands for wether current node has siblings nodes; 
  // Third character stands for wether current node has children node. 
  'children': [ // The property stands for nested nodes. "children" is just default name you can override. 
    { 'nodeTitlePro': 'Bo Miao', 'nodeContentPro': 'department manager', 'relationship': '110' },
    { 'nodeTitlePro': 'Su Miao', 'nodeContentPro': 'department manager', 'relationship': '111',
      'children': [
        { 'nodeTitlePro': 'Tie Hua', 'nodeContentPro': 'senior engineer', 'relationship': '110' },
        { 'nodeTitlePro': 'Hei Hei', 'nodeContentPro': 'senior engineer', 'relationship': '110' }
      ]
    },
    { 'nodeTitlePro': 'Yu Jie', 'nodeContentPro': 'department manager', 'relationship': '110' }
  ],
  'otherPro': anyValue
};

Options

NameTypeRequiredDefaultDescription
datajson or stringyesdatasource usded to build out structure of orgchart. It could be a json object or a string containing the URL to which the ajax request is sent.
panbooleannofalseUsers could pan the orgchart by mouse drag&drop if they enable this option.
zoombooleannofalseUsers could zoomin/zoomout the orgchart by mouse wheel if they enable this option.
zoominLimitnumberno7Users are allowed to set a zoom-in limit.
zoomoutLimitnumberno0.5Users are allowed to set a zoom-out limit.
directionstringno"t2b"The available values are t2b(implies "top to bottom", it's default value), b2t(implies "bottom to top"), l2r(implies "left to right"), r2l(implies "right to left").
verticalDepthintegernoUsers can make use of this option to align the nodes vertically from the specified depth.
toggleSiblingsRespbooleannofalseOnce enable this option, users can show/hide left/right sibling nodes respectively by clicking left/right arrow.
ajaxURLjsonnoIt inclueds four properites -- parent, children, siblings, families(ask for parent node and siblings nodes). As their names imply, different propety provides the URL to which ajax request for different nodes is sent.
depthpositive integerno999It indicates the level that at the very beginning orgchart is expanded to.
nodeTitlestringno"name"It sets one property of datasource as text content of title section of orgchart node. In fact, users can create a simple orghcart with only nodeTitle option.
parentNodeSymbolstringno"fa-users"Using font awesome icon to imply that the node has child nodes.
nodeContentstringnoIt sets one property of datasource as text content of content section of orgchart node.
nodeIdstringno"id"It sets one property of datasource as unique identifier of every orgchart node.
nodeTemplatefunctionnoIt's a template generation function used to customize any complex internal structure of node. It recieves only one parameter: "data" stands for json datasoure which will be use to render one node.
createNodefunctionnoIt's a callback function used to customize every orgchart node. It recieves two parameters: "$node" stands for jquery object of single node div; "data" stands for datasource of single node.
exportButtonbooleannofalseIt enable the export button for orgchart.
exportFilenamestringno"Orgchart"It's filename when you export current orgchart as a picture.
exportFileextensionstringno"png"Available values are png and pdf.
chartClassstringno""when you wanna instantiate multiple orgcharts on one page, you should add diffent classname to them in order to distinguish them.
draggablebooleannofalseUsers can drag & drop the nodes of orgchart if they enable this option. **Note**: this feature doesn't work on IE due to its poor support for HTML5 drag & drop API.
dropCriteriafunctionnoUsers can construct their own criteria to limit the relationships between dragged node and drop zone. Furtherly, this function accept three arguments(draggedNode, dragZone, dropZone) and just only return boolen values.
initCompletedfunctionnoIt can often be useful to know when your table has fully been initialised, data loaded and rendered, particularly when using an ajax data source. It recieves one parament: "$chart" stands for jquery object of initialised chart.

Methods

I'm sure that you can grasp the key points of the methods below after you try out demo -- edit orgchart.

var oc = $container.orgchart(options)

Embeds an organization chart in designated container. Accepts an options object and you can go through the "options" section to find which options are required. Variable oc is the instance of class OrgChart.

init(newOptions)

It's the useful way when users want to re-initialize or refresh orgchart based on new options or reload new data.

addParent(data, opts)

Adds parent node(actullay it's always root node) for current orgchart.

NameTypeRequiredDefaultDescription
datajson objectyesdatasource for building root node
optsjson objectnoinitial options of current orgchartoptions used for overriding initial options

addSiblings($node, data, opts)

Adds sibling nodes for designated node.

NameTypeRequiredDefaultDescription
$nodejquery objectyeswe'll add sibling nodes based on this node
datajson objectyesdatasource for building sibling nodes
optsjson objectnoinitial options of current orgchartoptions used for overriding initial options

addChildren($node, data, optsÔľČ

Adds child nodes for designed node.

NameTypeRequiredDefaultDescription
$nodejquery objectyeswe'll add child nodes based on this node
datajson objectyesdatasource for building child nodes
optsjson objectnoinitial options of current orgchartoptions used for overriding initial options

removeNodes($nodeÔľČ

Removes the designated node and its descedant nodes.

NameTypeRequiredDefaultDescription
$nodejquery objectyesnode to be removed

getHierarchy()

This method is designed to get the hierarchy relationships of orgchart for further processing. For example, after editing the orgchart, you could send the returned value of this method to server-side and save the new state of orghcart.

hideParent($node)

This method allows you to hide programatically the parent node of any specific node(.node element), if it has

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to hide its parent node. Of course, its sibling nodes will be hidden at the same time

showParent($node)

This method allows you to show programatically the parent node of any specific node(.node element), if it has

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to show its parent node

hideChildren($node)

This method allows you to hide programatically the children of any specific node(.node element), if it has

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to hide its children nodes

showChildren($node)

This method allows you to show programatically the children of any specific node(.node element), if it has

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to show its children nodes

hideSiblings($node, direction)

This method allows you to hide programatically the siblings of any specific node(.node element), if it has

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to hide its siblings nodes
direction string No None Possible values:"left","rigth". Specifies if hide the siblings at left or rigth. If not defined hide both of them.

showSiblings($node, direction)

This method allows you to show programatically the siblings of any specific node(.node element), if it has

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to show its siblings nodes
direction string No None Possible values:"left","rigth". Specifies if hide the siblings at left or rigth. If not defined hide both of them.

getNodeState($node, relation)

This method returns you the display state of related node of the specified node.

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to know its related nodes' display state.
relation String Yes None Possible values: "parent", "children" and "siblings". Specifies the desired relation to return.

The returning object will have the following structure:

{
  "exist": true|false,  //Indicates if has parent|children|siblings 
  "visible":true|false,  //Indicates if the relationship nodes are visible 
}

getRelatedNodes($node, relation)

This method returns you the nodes related to the specified node

Name Type Required Default Description
$node JQuery Object Yes None It's the desired JQuery Object to know its related nodes
relation String Yes None Possible values: "parent", "children" and "siblings". Specifies the desired relation to return.

setChartScale($chart, newScale)

This method returns you the nodes related to the specified node

Name Type Required Default Description
$chart JQuery Object Yes None It's a chart in your chart-container
newScale Float Yes None Positive float value which is used to zoom in/out the chart

Events

Event TypeAttached DataDescription
nodedropped.orgchartdraggedNode, dragZone, dropZoneThe event's handler is where you can place your customized function after node drop over. For more details, please refer to example drag & drop.
init.orgchartchartInitialisation complete event - fired when Organization Chart has been fully initialised and data loaded.

Tips

How can I deactivate expand/collapse feature of orgchart?

This use case is inspired by the issue. Thanks der-robert and ActiveScottShaw for their constructive discussionsūüėä

Users can enable/disable exapand/collapse feature with className "noncollapsable" as shown below.

$('.orgchart').addClass('noncollapsable'); // deactivate 
 
$('.orgchart').removeClass('noncollapsable'); // activate 

How can I search nodes and show the minimized chart?

This use case is inspired by the issue. Thanks Mmannem for his constructive discussionsūüėä The following statements show the core logic and this is the complete demo - filter node.

var $chart = $('.orgchart');
// disalbe the expand/collapse feture 
$chart.addClass('noncollapsable');
// distinguish the matched nodes and the unmatched nodes according to the given key word 
$chart.find('.node').filter(function(index, node) {
    return $(node).text().toLowerCase().indexOf(keyWord) > -1;
  }).addClass('matched')
  .closest('table').parents('table').find('tr:first').find('.node').addClass('retained');
// hide the unmatched nodes 
$chart.find('.matched,.retained').each(function(index, node) {
  var $unmatched = $(node).closest('table').parent().siblings().find('.node:first:not(.matched,.retained)')
    .closest('table').parent().addClass('hidden');
  $unmatched.parent().prev().children().slice(1, $unmatched.length * 2 + 1).addClass('hidden');
});
// hide the redundant descendant nodes of the matched nodes 
$chart.find('.matched').each(function(index, node) {
  if (!$(node).closest('tr').siblings(':last').find('.matched').length) {
    $(node).closest('tr').siblings().addClass('hidden');
  }
});

Why is the root node gone?

When I have a huge orgchart with enabled "pan" option, if I hide all the children of one of the topmost parents then the chart disappear from screen. It seems that we need to add a reset button to keep the chart visible. For details, please refer to the issue opened by manuel-84 ūüėä

Users can embed any clear up logics into the click handler of the reset buttton as shown below.

$('.orgchart').css('transform',''); // remove the tansform settings 

Browser Compatibility

  • Chrome 19+
  • Firefox 4+
  • Safari 6+
  • Opera 15+
  • IE 10+

Charts Show

I love NBA. 2016 NBA Playoff

We thank JordiCorbillaūüėä for his sharing how to save datasource after chart editing. save datasource