感谢wesnolte的非常棒的作品-- jOrgChart。用嵌套的table来构造树状结构,用td的border来构造节点间的连线,非常有创意。天然地降低了前端程序员在构造树状结构时的工作量和难度,要知道,利用D3.js中的脑图去达到同样效果,开发周期就会长好多。哪怕你对svg,canvas等高级的制图API了然于胸,当你的树状结构图激发出HR大姐的各种天马行空的需求时,你会坦诚的承认svg或canvas这种重型武器拖累了你的快速解决一小戳敌人的能力。相比较而言,用单纯的HTML5 + CSS3的解决方案就像是 “小米 + 步枪”的轻步兵,天然地降低了你在实现树状结构图的难度,同时给予你更大的定制空间去面对基于这个结构图衍生出的种种琐碎需求。只要你的需求足够多,基于这个树状结构图,打造出一个完备的HR系统,也是可以期待的。实际上,网络上很多OrgChart商业软件就是围绕着一个树状结构核心模型展开的业务逻辑实现。
- 支持本地和远程的数据源。
- 用户可以展开/折叠节点或子树,方便地浏览局部的结构图。
- 上下左右4个方向的布局。
- 用户可以通过拖放节点或子树的方式来改变组织结构图的形态。
- 用户可以编辑组织结构图的层次结构并将最终结果保存为JSON对象。
- 支持将组织结构图导出为png图片或pdf文档。
- 支持对组织结构图的缩放/平移
- 用户可以自行定制节点的内部结构,例如插入员工照到节点中。
- 用户可以采用不同的数据源构建多层级的组织结构图(请参考多层组织结构图和混合布局组织结构图的实例)。
- 支持移动设备上的多点触控操作。
可以在CDN上找到本插件的对应资源。
https://cdnjs.com/libraries/orgchart
# From version 1.0.2 on, users can install orgchart and add it to bower.json dependencies
$ bower install orgchart
# From version 1.0.4 on, users can install orgchart with npm
$ npm install orgchart
require('orgchart')
会把orgchart插件追加到jQuery对象上。orgchart模块本身并不导出任何东西。
基于嵌套table的实例集合 (过时)
-
ul数据源(感谢 Tobyee的好点子 😊)
-
我想以不同的方向布局组织结构图(感谢 fvlima 和 badulesia 的好点子 😊)
从上到下 -- 默认的布局方向
这里使用了第三方的工具html2canvas.
注意:
(1) 如果你想在IE或Edge导出,请先引入es6-promise.auto.js到项目中.
(2) 如果你的操作系统是Windows,请先检查“缩放设置”,需调整"Change the size of text, apps, and other items" to 100%.(感谢sayamkrai的研究)
(3) 此外,如果你想导出成pdf文件, 请先引入jspdf到项目中,然后设置"exportFileextension"选项为"pdf"。
这里,我们需要求助于OpenLayers。
本插件中暴露来若干方法--addParent(), addSiblings(), addChildren(), removeNodes(),可以帮助开发者很方便的实现上述需求。
一旦启用了"draggable"选项,我们就可以通过拖放来改变组织结构图的层次结构了。但是注意,这个特性在IE浏览器上不工作。后续地,我们还可以利用dropCriteria选项,来定制更细致的拖放限制准则。默认情况下,插件只提供了一条限制准则--不能直接把父节点放到它的子节点里。
我们有个getHierarchy()方法,专门干这事。
我们只需要把css的样式与数据源中的id字段或css类字段关联起来就好。
这个特性的灵感来源于这两个话题的讨论--Aligning Children Vertical, Hybrid(horizontal + vertical) OrgChart。感谢mfahadi和Destructrix建设性的讨论:blush:尤其感谢tedliang提供了非常棒的混合布局的解决方案。
这个好办。在数据源中,给父节点追加'collapsed': true
,给子节点追加'className': 'slide-up'
。
我们暴露了init()方法帮你完成上述任务,把新的option传到init()方法里就好了。
没问题,我们推荐使用ES6的模版字符串。
你需要的是一个复合的解决方案: levelOffset data prop + callback createNode() + CSS custom properties(variables)
hybrid data property 就派上用场了. 在数据源的某个节点中提供"hybrid"属性,那么它的所有后代节点都会垂直布局.
compact data property 就派上用场了. 在数据源的某个节点里提供了"compact"属性,并赋为真值,那么它和它的子节点就会展示为压缩模式。
我们使用如下的二维数组数据源来构建家谱。“outsider”代表外姓人。
var datascource = [
[
{ 'id': '8', 'name': 'Lao Ye', 'title': 'Grandfather', 'gender': 'male' },
{
'id': '1', 'name': 'Lao Lao', 'title': 'Grandmother', 'gender': 'female', 'outsider': true,
'children': [
[
{ 'id': '2', 'name': 'Bo miao', 'title': 'Aunt', 'gender': 'female'}
],
[
{ 'id': '3', 'name': 'Su Miao', 'title': 'Mother', 'gender': 'female',
'children': [
[
{ 'id': '12', 'name': 'Pang Pang', 'title': 'Wife', 'gender': 'female', 'outsider': true,
'children': [
[{ 'id': '7', 'name': 'Dan Dan', 'title': 'Daughter', 'gender': 'female' }],
[{ 'id': '6', 'name': 'Er Dan', 'title': 'Daughter', 'gender': 'female' }],
]
},
{ 'id': '5', 'name': 'Hei Hei', 'title': 'Me', 'gender': 'male' },
]
]
},
{ 'id': '9', 'name': 'Tie Hua', 'title': 'Father', 'gender': 'male', 'outsider': true }
],
[
{ 'id': '10', 'name': 'Hong miao', 'title': 'Aunt', 'gender': 'female'}
]
]
}
]
];
- 必须安装node.js v6+,因为我们的单元测试是基于jsdom v11。
- 必须安装现代浏览器(忽略IE浏览器)。因为orgchart插件几乎所有的行为和特性都是基于HTML5和CSS3环境下开发与测试的。
- 运行命令
npm install
来安装必要的依赖。 - 运行命令
npm test
来跑所有的测试(单元测试,集成测试,端到端测试,以及视觉回归测试) - 运行命令
npm run build
来生成生产版本的js,css文件。 - 运行命令
npm start
来启动本地web server,在这个地址http://localhost:3000 上查看满足不同场景需求的Demo。
var oc = $('#chartContainerId').orgchart(options);
{
'id': 'rootNode', // 可选属性。将来插件会基于它,创建节点的id,data-parent(当前节点的父节点的id属性)等特性
'collapsed': true, // 默认初始化时,当前节点处于折叠状态,其子节点不显示
'className': 'top-level', // 可选属性。将来组件会把它的值追加到节点的CSS 类中
'nodeTitle': 'name', // 可选属性。插件会以该属性的值为属性,
// 来检索数据源,然后渲染默认结构样式的节点的上半部分
'nodeContent': 'title', // 可选属性。插件会以该属性的值为属性,
// 来检索数据源,然后渲染默认结构样式的节点的下半部分
'relationship': relationshipValue, // 注意:当你激活按需载入节点特性时
// 你应该使用JSON数据源(不论本地或远程)并设置本属性
// 本属性标识当前节点是否具有父节点,兄弟节点,子节点
// relationshipValue的值是由“0”或“1”组成的长度为3的字符串
// 第1个字符代表当前节点是否具有父节点
// 第2个字符代表当前节点是否具有兄弟节点
// 第三个字符代表当前节点是否具有孩子节点
'children': [ // The property stands for nested nodes.
{ 'name': 'Bo Miao', 'title': 'department manager', 'relationship': '110' },
{ 'name': 'Su Miao', 'title': 'department manager', 'relationship': '111',
'children': [
{ 'name': 'Tie Hua', 'title': 'senior engineer', 'relationship': '110' },
{ 'name': 'Hei Hei', 'title': 'senior engineer', 'relationship': '110' }
]
},
{ 'name': 'Yu Jie', 'title': 'department manager', 'relationship': '110' }
],
'otherPro': anyValue // 数据源中可以追加任意其他字段,只要你觉得
// 在之后的渲染和操作组织结构图时派得上用场
};
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
data | json / jquery object | 是 | 用于构造组织结构图的数据源。它的值可以是JSON或能提供数据的ul元素。 | |
pan | boolean | 否 | false | 启用本选项,用户可以通过鼠标拖拽组织结构图。 |
zoom | boolean | 否 | false | 启动本选项,用户可以通过鼠标滚轮或触摸板对组织结构图进行缩放。 |
zoominLimit | number | 否 | 7 | 放大的上限值 |
zoomoutLimit | number | 否 | 0.5 | 缩小的下限值 |
direction | string | 否 | "t2b" | 该选项用来设置布局方向。"t2b"代表从上到下,是默认值。"b2t"代表从下到上。"l2r"代表从左到右。"r2l"代表从右到左。 |
verticalLevel | integer(>=2) | 否 | 表示组织结构图从哪一层开始,从水平布局节点转变为垂直布局节点。 | |
toggleSiblingsResp | boolean | 否 | false | 启动该选项,用户点击了节点的两侧箭头按钮时,会展开/折叠一侧的兄弟节点;默认的行为是用户点击了节点任何一侧的箭头按钮,都会折叠起所有的兄弟节点,不区分左右。 |
visibleLevel | positive integer | 否 | 999 | 该选项为用户指定初始化组织结构图时,可见的展开的层级是多少 |
nodeTitle | string | 否 | "name" | 将默认节点结构中的标题部分关联到数据源中的一个属性 |
parentNodeSymbol | string | 否 | "oci-leader" | 为所有父节点的icon标识指定CSS类名 |
nodeContent | string | 否 | 将默认节点结构中的内容部分关联到数据源中的一个属性 | |
nodeId | string | no | "id" | 选取一个数据源中的字段作为组织结构图中的每个节点的唯一标识 |
nodeTemplate | function | 否 | 应该为该选项提供一个节点结构模版生成函数,该函数只接收一个参数,就是涵盖子树渲染的数据源片段。 | |
createNode | function | 否 | 为该选项提供的函数,会在默认节点结构创建完毕后调用。利用传入的两个参数--"$node"和"data",可以帮助开发者定制或改动现有的节点结构。 | |
exportButton | boolean | 否 | false | 启用该选项,插件会追加“导出”按钮到组织结构图的容器DIV里。 |
exportButtonName | string | 否 | "Export" | 导出按钮的名字。 |
exportFilename | string | 否 | "Orgchart" | 导出文件的文件名。 |
exportFileextension | string | 否 | "png" | 导出文件的扩展名。 |
chartClass | string | 否 | "" | 通过指定该选项,来给组织结构图追加自定义的CSSl类名,尤其是在你的组织结构图容器中要承载夺冠chart的时候,这个选项就显得很重要了。 |
draggable | boolean | 否 | false | 启用该选项,用户就可以拖放节点的方式改变组织结构图的结构了。**注意:**将当前的某个父节点拖放到其下面的某个子节点里,这样的操作是不允许的。因为如果插件顺从了这样的操作,会产生孤立的子树;本选项在IE浏览器上不可用。 |
dropCriteria | function | 否 | 用户可以通过该选项定制更细致的拖放节点的限制准则。你需要为该选项提供一个返回boolean值的函数,该函数用来判断当拖放操作结束时,是否允许将当前拖拽的节点从拖动区域摘出来插入到松放区域里。该函数接受3个参数--draggedNode, dragZone, dropZone。 | |
initCompleted | function | 否 | 组织结构图初始化完成后,该选项指定的回调函数被触发。该函数接受一个参数--"$chart", 即初始化后的组织结构图jquery对象。 |
我们相信当你研究了edit orgchart这个Demo后,会基本掌握orgchart插件的所有方法。
在指定容器元素内嵌入一个组织结构图。该方法接受的options参数的细节可以到上面的“选项”一节中查看。这里的oc是OrgChart类的实例。
当你想基于新的options或数据源刷新组织结构图时,这个方法就派上用场了。
为当前的组织结构图增加祖先节点,可以不止一个层级。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
data | json | 是 | 用于构造祖先节点的数据源 | |
parentId | string | yes | 将当前的组织结构图追加到某一个祖先节点里,该节点的id |
为指定的父节点增加后代节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
data | array | yes | 用于构造后代节点的数据源 | |
$parent | jquery object | yes | 后代节点要追加到的父节点对象 |
为当前的组织结构图增加父节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
data | json object | 是 | 构造根节点的数据源 |
为指定的节点增加兄弟节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | jquery object | 是 | 基于该节点增加其兄弟节点 | |
data | array | 是 | 用于构造兄弟节点的数据源 |
为指定的节点增加孩子节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | jquery object | 是 | 基于该节点增加其孩子节点 | |
data | array | 是 | 构造孩子节点的数据源 |
删除指定的节点及其后代节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | jquery object | 是 | 待删除的节点。 |
这个方法被设计用来提供组织结构图的层次结构关系。举个例子,当你采取某种手段对当前的组织结构图的结构进行了改动后,可以调用本方法获得最新的结构,并将其保存到后台。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
includeNodeData | Boolean | 否 | false | 如果传入的该参数为true,那么导出的层次结构对象中就加入nodeData数据。 |
隐藏指定节点的父节点。当然其兄弟节点及祖先节点也一并隐藏了。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | Yes | None | 指定节点的jquery对象。 |
显示指定节点的父节点。但不包括更上一层的祖先节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | 指定节点的jquery对象。 |
隐藏指定节点的孩子节点。当然这其中包含了所有的后代节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | 指定节点的jquery对象。 |
显示指定节点的孩子节点。默认只显示紧邻的下一个层级,并不包括所有的后代节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | 指定节点的jquery对象。 |
隐藏指定节点的兄弟节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | 指定节点的jquery对象。 | |
direction | string | 否 | 可供选择的值有"left"和"rigth". 如果指定某一侧,就只隐藏某一侧的兄弟节点。如果不提供该参数,就隐藏所有的兄弟节点 |
显示指定节点的兄弟节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | It's the desired JQuery Object to show its siblings nodes | |
direction | string | 否 | 可供选择的值有"left"和"rigth". 如果指定某一侧,就只显示某一侧的兄弟节点。如果不提供该参数,就显示所有的兄弟节点 |
该方法帮你了解指定节点的相关节点的显示状况。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | 指定节点的jquery对象。 | |
relation | String | 是 | 可选的值有--"parent", "children" 和 "siblings"。 指定明确的关系,然后本方法返回给你相关节点的显示状态。 |
本方法的返回对象的结构如下:
{
"exist": true|false, // 标识你想了解的父节点,孩子节点,兄弟节点是否存在
"visible":true|false, // 标识相关节点当前是否可见
}
获得指定节点的关联节点。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$node | JQuery Object | 是 | 指定节点的jquery对象。 | |
relation | String | 是 | 可选的值有--"parent", "children" 和 "siblings"。用来指定具体的关系。 |
用这个方法可以帮你为指定的组织结构图设置新的scale系数。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
$chart | JQuery Object | 是 | None | 组织结构图容器中的某一个图。 |
newScale | Float | 是 | None | 用于缩放组织结构图的缩放系数。 |
将当前的组织结构图导出为png图片或pdf文档。
名称 | 类型 | 必填 | 默认值 | 描述 |
---|---|---|---|---|
exportFilename | String | 否 | 'OrgChart' | 导出文件的文件名。 |
exportFileextension | String | 否 | 'png' | 导出文件的扩展名 |
类型 | 附带参数 | 描述 |
---|---|---|
nodedrop.orgchart | draggedNode, dragZone, dropZone | 当你拖拽一个节点,然后在目前区域松放时,该事件被触发。请参考实例 example drag & drop。 |
init.orgchart | chart | 当组织结构图初始化完成时,该事件触发。在响应事件处理器中,你可以访问到渲染出的任意节点。 |
show-[relation].orgchart | 在显示指定节点的关联节点时,触发该事件。 | |
hide-[relation].orgchart | 在隐藏指定节点的关联节点时,触发该事件。 |
关于这个需求的展开讨论可以看这个问题。感谢der-robert和ActiveScottShaw的非常有建设性的讨论:blush:
我们提供了一个CSS类"noncollapsable",可以方便地完成这件事。
$('.orgchart').addClass('noncollapsable'); // 禁掉展开/折叠
$('.orgchart').removeClass('noncollapsable'); // 开启展开/折叠
比如说我渲染了一个非常庞大的组织结构图,同时我启用了“平移”特性,这时如果我隐藏掉某个节点的大量的后代节点,可能会导致上层的一些节点在当前可视区域内消失。 跟多的细节,可以参考这个问题的讨论。感谢manuel-84 的问题抛出 😊
- Chrome 19+
- Firefox 4+
- Safari 6+
- Opera 15+
- IE 10+