├── .eslintrc.json
├── .gitignore
├── LICENSE
├── README.md
├── demo
├── ajax-datasource
│ ├── index.html
│ └── scripts.js
├── color-coded
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── css
│ ├── orgchart-webcomponents.min.css
│ └── style.css
├── direction
│ ├── b2t.js
│ ├── bottom2top.html
│ ├── l2r.js
│ ├── left2right.html
│ ├── r2l.js
│ └── right2left.html
├── drag-drop
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── edit-orgchart
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── export-orgchart
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── get-hierarchy
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── img
│ ├── avatar
│ │ ├── 1.jpg
│ │ ├── 10.jpg
│ │ ├── 11.jpg
│ │ ├── 12.jpg
│ │ ├── 13.jpg
│ │ ├── 2.jpg
│ │ ├── 3.jpg
│ │ ├── 4.jpg
│ │ ├── 5.jpg
│ │ ├── 6.jpg
│ │ ├── 7.jpg
│ │ ├── 8.jpg
│ │ └── 9.jpg
│ ├── logo.jpg
│ └── orgchart-heading.png
├── index.html
├── integrate-map
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── local-datasource
│ ├── index.html
│ └── scripts.js
├── multiple-layers
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── ondemand-loading-data
│ ├── index.html
│ └── scripts.js
├── option-createNode
│ ├── index.html
│ ├── scripts.js
│ └── style.css
├── pan-zoom
│ ├── index.html
│ └── scripts.js
├── toggle-sibs-resp
│ ├── index.html
│ └── scripts.js
├── ul-datasource
│ ├── index.html
│ ├── scripts.js
│ └── style.css
└── vertical-depth
│ ├── index.html
│ └── scripts.js
├── gulpfile.js
├── package.json
├── src
├── orgchart-webcomponents.css
└── orgchart-webcomponents.js
└── webpack.config.js
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "es6": true,
5 | "node": true
6 | },
7 | "parserOptions": {
8 | "ecmaVersion": 6,
9 | "sourceType": "module",
10 | "ecmaFeatures": {
11 | "impliedStrict": true
12 | }
13 | },
14 | "globals": {
15 | "document": false,
16 | "navigator": false,
17 | "window": false
18 | },
19 | "rules": {
20 | "block-scoped-var": 2,
21 | "brace-style": [2, "1tbs", { "allowSingleLine": true }],
22 | "camelcase": [2, { "properties": "always" }],
23 | "comma-dangle": [2, "never"],
24 | "comma-spacing": [2, { "before": false, "after": true }],
25 | "comma-style": [2, "last"],
26 | "consistent-return": 2,
27 | "curly": [2, "multi-line"],
28 | "dot-location": [2, "property"],
29 | "eol-last": 2,
30 | "eqeqeq": [2, "allow-null"],
31 | "generator-star-spacing": [2, "both"],
32 | "handle-callback-err": [2, "^(err|error|anySpecificError)$" ],
33 | "indent": [2, 2, { "SwitchCase": 1 }],
34 | "key-spacing": [2, { "beforeColon": false, "afterColon": true }],
35 | "max-len": [2, 120, 4],
36 | "new-cap": [2, { "newIsCap": true, "capIsNew": false }],
37 | "newline-after-var": [1, "always"],
38 | "new-parens": 2,
39 | "no-array-constructor": 2,
40 | "no-caller": 2,
41 | "no-cond-assign": 2,
42 | "no-control-regex": 2,
43 | "no-debugger": 2,
44 | "no-delete-var": 2,
45 | "no-dupe-args": 2,
46 | "no-dupe-keys": 2,
47 | "no-duplicate-case": 2,
48 | "no-else-return": 2,
49 | "no-empty-character-class": 2,
50 | "no-labels": 2,
51 | "no-eval": 2,
52 | "no-ex-assign": 2,
53 | "no-extend-native": 1,
54 | "no-extra-bind": 2,
55 | "no-extra-boolean-cast": 2,
56 | "no-fallthrough": 2,
57 | "no-floating-decimal": 2,
58 | "no-func-assign": 2,
59 | "no-implied-eval": 2,
60 | "no-inner-declarations": [2, "functions"],
61 | "no-invalid-regexp": 2,
62 | "no-irregular-whitespace": 2,
63 | "no-iterator": 2,
64 | "no-label-var": 2,
65 | "no-labels": 2,
66 | "no-mixed-spaces-and-tabs": [2, false],
67 | "no-multi-spaces": 2,
68 | "no-multi-str": 2,
69 | "no-multiple-empty-lines": [1, { "max": 1 }],
70 | "no-native-reassign": 2,
71 | "no-negated-in-lhs": 2,
72 | "no-new": 2,
73 | "no-new-func": 2,
74 | "no-new-object": 2,
75 | "no-new-require": 2,
76 | "no-new-wrappers": 2,
77 | "no-obj-calls": 2,
78 | "no-octal": 2,
79 | "no-octal-escape": 2,
80 | "no-proto": 2,
81 | "no-redeclare": 2,
82 | "no-regex-spaces": 2,
83 | "no-return-assign": 2,
84 | "no-self-compare": 2,
85 | "no-sequences": 2,
86 | "no-shadow-restricted-names": 2,
87 | "no-spaced-func": 2,
88 | "no-sparse-arrays": 2,
89 | "no-throw-literal": 2,
90 | "no-trailing-spaces": 1,
91 | "no-undef": 2,
92 | "no-undef-init": 2,
93 | "no-unneeded-ternary": 2,
94 | "no-unreachable": 2,
95 | "no-unused-vars": [1, { "vars": "all", "args": "none" }],
96 | "no-use-before-define": 2,
97 | "no-with": 2,
98 | "operator-linebreak": [2, "after"],
99 | "radix": 2,
100 | "semi": [2, "always"],
101 | "keyword-spacing": [2, { "before": true, "after": true }],
102 | "space-before-blocks": [2, "always"],
103 | "space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
104 | "space-in-parens": [2, "never"],
105 | "space-infix-ops": 1,
106 | "keyword-spacing": 1,
107 | "space-unary-ops": [2, { "words": true, "nonwords": false }],
108 | "spaced-comment": [1, "always"],
109 | "use-isnan": 2,
110 | "valid-typeof": 2,
111 | "vars-on-top": 2,
112 | "wrap-iife": [2, "any"],
113 | "yoda": [2, "never"]
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Compiled binary addons (http://nodejs.org/api/addons.html)
7 | build/
8 |
9 | # Dependency directories
10 | node_modules
11 |
12 | # Optional npm cache directory
13 | .npm
14 |
15 | # Optional REPL history
16 | .node_repl_history
17 |
18 | # assets folder of demo
19 | demo/js
20 | demo/css/orgchart.min.css
21 | demo/css/fonts
22 | demo/css/vendor
23 |
24 | # bundle files after webpack
25 | bundle*.js
26 | bundle*.js.map
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 dabeng
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # [jQuery Version](http://github.com/dabeng/OrgChart)
4 | # [ES6 Version](http://github.com/dabeng/OrgChart-Webcomponents)
5 | # [Vue.js Version](https://github.com/dabeng/vue-orgchart)
6 | # [Angular Version](https://github.com/dabeng/ng-orgchart)
7 | # [React Version](https://github.com/dabeng/react-orgchart)
8 |
9 | ## Foreword
10 | - First of all, thanks a lot for [wesnolte](https://github.com/wesnolte)'s great work:blush: -- [jOrgChart](https://github.com/wesnolte/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.
11 | - 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.
12 | - Font Awesome provides us with administration icon, second level menu icon and loading spinner.
13 |
14 | ## Features
15 | - Supports both local data and remote data (JSON).
16 | - Smooth expand/collapse effects based on CSS3 transitions.
17 | - Align the chart in 4 orientations.
18 | - Allows user to change orgchart structure by drag/drop nodes.
19 | - Allows user to edit orgchart dynamically and save the final hierarchy as a JSON object.
20 | - Supports exporting chart as a picture.
21 | - Supports pan and zoom
22 | - Users can adopt multiple solutions to build up a huge organization chart(please refer to multiple-layers or hybrid layout sections)
23 | - touch-enabled plugin for mobile divice
24 |
25 | ## Getting started
26 | ### Build
27 | npm install
28 | gulp build
29 | ### Serve
30 | gulp serve
31 | Now, you can try out all the demos on http://localhost:3000.
32 |
33 | **Note**: your nodejs version should be 4+.
34 |
35 | ## Demo
36 | - **[using ul datasource](http://dabeng.github.io/OrgChart-Webcomponents/ul-datasource/)**(this feature comes from [Tobyee's good idea:blush:](https://github.com/dabeng/OrgChart/issues/1))
37 | ```html
38 |
39 |
40 | Lao Lao
41 |
42 | Bo Miao
43 | Su Miao
44 |
45 | Tie Hua
46 | Hei Hei
47 |
48 | Pang Pang
49 | Xiang Xiang
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | ```
58 | ```js
59 | let orgchart = new OrgChart({
60 | 'data' : '#ul-data'
61 | });
62 | document.querySelector('#chart-container').appendChild(orgchart);
63 | ```
64 | 
65 |
66 | - **[using local datasource](http://dabeng.github.io/OrgChart-Webcomponents/local-datasource/)**
67 | ```js
68 | let datascource = {
69 | 'name': 'Lao Lao',
70 | 'title': 'general manager',
71 | 'children': [
72 | { 'name': 'Bo Miao', 'title': 'department manager' },
73 | { 'name': 'Su Miao', 'title': 'department manager',
74 | 'children': [
75 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
76 | { 'name': 'Hei Hei', 'title': 'senior engineer',
77 | 'children': [
78 | { 'name': 'Pang Pang', 'title': 'engineer' },
79 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
80 | ]
81 | }
82 | ]
83 | },
84 | { 'name': 'Yu Jie', 'title': 'department manager' },
85 | { 'name': 'Yu Li', 'title': 'department manager' },
86 | { 'name': 'Hong Miao', 'title': 'department manager' },
87 | { 'name': 'Yu Wei', 'title': 'department manager' },
88 | { 'name': 'Chun Miao', 'title': 'department manager' },
89 | { 'name': 'Yu Tie', 'title': 'department manager' }
90 | ]
91 | },
92 | orgchart = new OrgChart({
93 | 'data' : datascource,
94 | 'depth': 2,
95 | 'nodeContent': 'title'
96 | });
97 | document.querySelector('#chart-container').appendChild(orgchart);
98 | ```
99 | 
100 |
101 | - **[I wanna pan&zoom the orgchart](http://dabeng.github.io/OrgChart-Webcomponents/pan-zoom/)**
102 |
103 | 
104 |
105 | - **I wanna align orgchart with different orientation**(this feature comes from [the good idea of fvlima and badulesia :blush:](https://github.com/dabeng/OrgChart/issues/5))
106 |
107 | Top to Bottom -- default direction, as you can see all other examples on this page.
108 |
109 | [Bottom to Top](http://dabeng.github.io/OrgChart-Webcomponents/direction/bottom2top)
110 | ```js
111 | // sample of core source code
112 | let orgchart = new OrgChart({
113 | 'data' : datascource,
114 | 'nodeContent': 'title',
115 | 'direction': 'b2t'
116 | });
117 | document.querySelector('#chart-container').appendChild(orgchart);
118 | ```
119 | 
120 |
121 | [Left to Right](http://dabeng.github.io/OrgChart-Webcomponents/direction/left2right)
122 | ```js
123 | // sample of core source code
124 | let orgchart = new OrgChart({
125 | 'data' : datascource,
126 | 'nodeContent': 'title',
127 | 'direction': 'l2r'
128 | });
129 | document.querySelector('#chart-container').appendChild(orgchart);
130 | ```
131 | 
132 |
133 | [Right to Left](http://dabeng.github.io/OrgChart-Webcomponents/direction/right2left)
134 | ```js
135 | // sample of core source code
136 | let orgchart = new OrgChart({
137 | 'data' : datascource,
138 | 'nodeContent': 'title',
139 | 'direction': 'r2l'
140 | });
141 | document.querySelector('#chart-container').appendChild(orgchart);
142 | ```
143 | 
144 |
145 | - **[I wanna show/hide left/right sibling nodes respectively by clicking left/right arrow](http://dabeng.github.io/OrgChart-Webcomponents/toggle-sibs-resp/)**
146 | ```js
147 | // sample of core source code
148 | let orgchart = new OrgChart({
149 | 'data' : datascource,
150 | 'nodeContent': 'title',
151 | 'toggleSiblingsResp': true
152 | });
153 | document.querySelector('#chart-container').appendChild(orgchart);
154 | ```
155 | 
156 |
157 | - **[I wanna load datasource through ajax](http://dabeng.github.io/OrgChart-Webcomponents/ajax-datasource/)**
158 | ```js
159 | // sample of core source code
160 | let orgchart = new OrgChart({
161 | 'data' : '/orgchart/initdata',
162 | 'depth': 2,
163 | 'nodeContent': 'title'
164 | });
165 | document.querySelector('#chart-container').appendChild(orgchart);
166 | ```
167 | 
168 |
169 | - **[I wanna load data on-demand](http://dabeng.github.io/OrgChart-Webcomponents/ondemand-loading-data/)**
170 |
171 | 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.
172 | ```js
173 | // sample of core source code
174 | let datascource = {
175 | 'id': '1',
176 | 'name': 'Su Miao',
177 | 'title': 'department manager',
178 | 'relationship': '111',
179 | 'children': [
180 | { 'id': '2','name': 'Tie Hua', 'title': 'senior engineer', 'relationship': '110' },
181 | { 'id': '3','name': 'Hei Hei', 'title': 'senior engineer', 'relationship': '111' }
182 | ]
183 | },
184 | ajaxURLs = {
185 | 'children': '/orgchart/children/',
186 | 'parent': '/orgchart/parent/',
187 | 'siblings': function(nodeData) {
188 | return '/orgchart/siblings/' + nodeData.id;
189 | },
190 | 'families': function(nodeData) {
191 | return '/orgchart/families/' + nodeData.id;
192 | }
193 | },
194 | orgchart = new OrgChart({
195 | 'data' : datascource,
196 | 'ajaxURL': ajaxURLs,
197 | 'nodeContent': 'title',
198 | 'nodeId': 'id'
199 | });
200 | document.querySelector('#chart-container').appendChild(orgchart);
201 | ```
202 | 
203 |
204 | - **[I wanna customize the structure of node](http://dabeng.github.io/OrgChart-Webcomponents/option-createNode/)**
205 | ```js
206 | // sample of core source code
207 | let orgchart = new OrgChart({
208 | 'data' : datascource,
209 | 'depth': 2,
210 | 'nodeContent': 'title',
211 | 'nodeID': 'id',
212 | 'createNode': function(node, data) {
213 | let secondMenuIcon = document.createElement('i'),
214 | secondMenu = document.createElement('div');
215 |
216 | secondMenuIcon.setAttribute('class', 'fa fa-info-circle second-menu-icon');
217 | secondMenuIcon.addEventListener('click', (event) => {
218 | event.target.nextElementSibling.classList.toggle('hidden');
219 | });
220 | secondMenu.setAttribute('class', 'second-menu hidden');
221 | secondMenu.innerHTML = ` `;
222 | node.appendChild(secondMenuIcon)
223 | node.appendChild(secondMenu);
224 | }
225 | });
226 | document.querySelector('#chart-container').appendChild(orgchart);
227 | ```
228 | 
229 |
230 | - **[I wanna export the organization chart as a picture](http://dabeng.github.io/OrgChart-Webcomponents/export-orgchart/)**
231 |
232 | Here, we need the help from [html2canvas](https://github.com/niklasvh/html2canvas).
233 | ```js
234 | // sample of core source code
235 | function clickExportButton() {
236 | let chartContainer = document.querySelector('#chart-container'),
237 | mask = chartContainer.querySelector(':scope > .mask'),
238 | sourceChart = chartContainer.querySelector('org-chart:not(.hidden)'),
239 | flag = sourceChart.classList.contains('l2r') || sourceChart.classList.contains('r2l');
240 |
241 | if (!mask) {
242 | mask = document.createElement('div');
243 | mask.setAttribute('class', 'mask');
244 | mask.innerHTML = ` `;
245 | chartContainer.appendChild(mask);
246 | } else {
247 | mask.classList.remove('hidden');
248 | }
249 | chartContainer.classList.add('canvasContainer');
250 | window.html2canvas(sourceChart, {
251 | 'width': flag ? sourceChart.clientHeight : sourceChart.clientWidth,
252 | 'height': flag ? sourceChart.clientWidth : sourceChart.clientHeight,
253 | 'onclone': function (cloneDoc) {
254 | let canvasContainer = cloneDoc.querySelector('.canvasContainer');
255 |
256 | canvasContainer.style.overflow = 'visible';
257 | canvasContainer.querySelector('org-chart:not(.hidden)').transform = '';
258 | }
259 | })
260 | .then((canvas) => {
261 | let downloadBtn = chartContainer.querySelector('.oc-download-btn');
262 |
263 | chartContainer.querySelector('.mask').classList.add('hidden');
264 | downloadBtn.setAttribute('href', canvas.toDataURL());
265 | downloadBtn.click();
266 | })
267 | .catch((err) => {
268 | console.error('Failed to export the curent orgchart!', err);
269 | })
270 | .finally(() => {
271 | chartContainer.classList.remove('canvasContainer');
272 | });
273 | }
274 |
275 | document.addEventListener('DOMContentLoaded', function () {
276 |
277 | let orgchart = new OrgChart({
278 | 'data' : datascource,
279 | 'depth': 2,
280 | 'nodeContent': 'title'
281 | }),
282 | chartContainer = document.querySelector('#chart-container');
283 |
284 | chartContainer.appendChild(orgchart);
285 | // append the export button to the chart-container
286 | let exportBtn = document.createElement('button'),
287 | downloadBtn = document.createElement('a');
288 |
289 | exportBtn.setAttribute('class', 'oc-export-btn');
290 | exportBtn.innerHTML = 'Export';
291 | exportBtn.addEventListener('click', clickExportButton);
292 | downloadBtn.setAttribute('class', 'oc-download-btn');
293 | downloadBtn.setAttribute('download', 'MyOrgChart.png');
294 | chartContainer.appendChild(exportBtn);
295 | chartContainer.appendChild(downloadBtn);
296 | });
297 | ```
298 | 
299 |
300 | - **[I wanna itegrate organization chart with geographic information](http://dabeng.github.io/OrgChart-Webcomponents/integrate-map/)**
301 |
302 | Here, we fall back on [OpenLayers](https://github.com/openlayers/ol3). It's the most aewsome open-source js library for Web GIS you sholdn't miss.
303 | ```js
304 | // sample of core source code
305 | let map = new ol.Map({
306 | layers: [
307 | new ol.layer.Tile({
308 | source: new ol.source.Stamen({
309 | layer: 'watercolor'
310 | }),
311 | preload: 4
312 | }),
313 | new ol.layer.Tile({
314 | source: new ol.source.Stamen({
315 | layer: 'terrain-labels'
316 | }),
317 | preload: 1
318 | })
319 | ],
320 | target: 'pageBody',
321 | view: new ol.View({
322 | center: ol.proj.transform([-87.6297980, 41.8781140], 'EPSG:4326', 'EPSG:3857'),
323 | zoom: 10
324 | })
325 | });
326 |
327 | document.body.insertBefore(document.querySelector('#chart-container'), map.getViewport());
328 |
329 | let datascource = {
330 | 'name': 'Lao Lao',
331 | 'title': 'President Office',
332 | 'position': [-87.6297980, 41.8781140],
333 | 'children': [
334 | { 'name': 'Bo Miao', 'title': 'Administration Dept.', 'position': [-83.0457540, 42.3314270]},
335 | { 'name': 'Su Miao', 'title': 'R & D Dept.', 'position': [-81.6943610, 41.4993200]},
336 | { 'name': 'Yu Jie', 'title': 'Product Dept.', 'position': [-71.0588800, 42.3600820]},
337 | { 'name': 'Yu Li', 'title': 'Legal Dept.', 'position': [-74.0059410, 40.7127840]},
338 | { 'name': 'Hong Miao', 'title': 'Finance Dept.', 'position': [-80.8431270, 35.2270870]},
339 | { 'name': 'Yu Wei', 'title': 'Security Dept.', 'position': [-81.6556510, 30.3321840]},
340 | { 'name': 'Chun Miao', 'title': 'HR Dept. ', 'position': [-81.3792360, 28.5383350]},
341 | { 'name': 'Yu Tie', 'title': 'Marketing Dept.', 'position': [-80.1917900, 25.7616800] }
342 | ]
343 | },
344 | orgchart = new OrgChart({
345 | 'data' : datascource,
346 | 'nodeContent': 'title',
347 | 'createNode': function(node, data) {
348 | node.addEventListener('click', () => {
349 | let view = map.getView(),
350 | duration = 2000,
351 | start = +new Date(),
352 | pan = ol.animation.pan({
353 | 'duration': duration,
354 | 'source': view.getCenter(),
355 | 'start': start
356 | }),
357 | bounce = ol.animation.bounce({
358 | 'duration': duration,
359 | 'resolution': 4 * view.getResolution(),
360 | 'start': start
361 | });
362 |
363 | map.beforeRender(pan, bounce);
364 | view.setCenter(ol.proj.transform(data.position, 'EPSG:4326', 'EPSG:3857'));
365 | });
366 | }
367 | });
368 | document.querySelector('#chart-container').appendChild(orgchart);
369 | ```
370 | 
371 |
372 | - **[I wanna edit orgchart](http://dabeng.github.io/OrgChart-Webcomponents/edit-orgchart/)**
373 |
374 | With the help of exposed core methods(addParent(), addSiblings(), addChildren(), removeNodes()) of orgchart plugin, we can finish this task easily.
375 | ```js
376 | function addNodes(orgchart) {
377 | let nodeVals = [];
378 |
379 | Array.from(document.getElementById('new-nodelist').querySelectorAll('.new-node'))
380 | .forEach(item => {
381 | let validVal = item.value.trim();
382 |
383 | if (validVal) {
384 | nodeVals.push(validVal);
385 | }
386 | });
387 | let selectedNode = document.getElementById(document.getElementById('selected-node').dataset.node);
388 |
389 | if (!nodeVals.length) {
390 | alert('Please input value for new node');
391 | return;
392 | }
393 | let nodeType = document.querySelector('input[name="node-type"]:checked');
394 |
395 | if (!nodeType) {
396 | alert('Please select a node type');
397 | return;
398 | }
399 | if (nodeType.value !== 'parent' && !document.querySelector('.orgchart')) {
400 | alert('Please creat the root node firstly when you want to build up the orgchart from the scratch');
401 | return;
402 | }
403 | if (nodeType.value !== 'parent' && !selectedNode) {
404 | alert('Please select one node in orgchart');
405 | return;
406 | }
407 |
408 | if (nodeType.value === 'parent') {
409 | if (!document.querySelector('#chart-container').children.length) {// if the original chart has been deleted
410 | orgchart = new OrgChart({
411 | 'data' : { 'name': nodeVals[0] },
412 | 'exportButton': true,
413 | 'exportFilename': 'SportsChart',
414 | 'parentNodeSymbol': 'fa-th-large',
415 | 'createNode': function(node, data) {
416 | node.id = getId();
417 | }
418 | });
419 | orgchart.chart.classList.add('view-state');
420 | } else {
421 | orgchart.addParent(orgchart.querySelector('.node'), { 'name': nodeVals[0], 'Id': getId() });
422 | }
423 | } else if (nodeType.value === 'siblings') {
424 | orgchart.addSiblings(selectedNode, {
425 | 'siblings': nodeVals.map(item => {
426 | return { 'name': item, 'relationship': '110', 'Id': getId() };
427 | })
428 | });
429 | } else {
430 | let hasChild = selectedNode.parentNode.colSpan > 1;
431 |
432 | if (!hasChild) {
433 | let rel = nodeVals.length > 1 ? '110' : '100';
434 |
435 | orgchart.addChildren(selectedNode, {
436 | 'children': nodeVals.map(item => {
437 | return { 'name': item, 'relationship': rel, 'Id': getId() };
438 | })
439 | });
440 | } else {
441 | orgchart.addSiblings(closest(selectedNode, el => el.nodeName === 'TABLE').querySelector('.nodes').querySelector('.node'),
442 | { 'siblings': nodeVals.map(function(item) { return { 'name': item, 'relationship': '110', 'Id': getId() }; })
443 | });
444 | }
445 | }
446 | }
447 |
448 | document.addEventListener('DOMContentLoaded', function () {
449 | let orgchart,
450 | datascource = {
451 | 'name': 'Ball game',
452 | 'children': [
453 | { 'name': 'Football' },
454 | { 'name': 'Basketball' },
455 | { 'name': 'Volleyball' }
456 | ]
457 | };
458 |
459 | orgchart = new OrgChart({
460 | 'data' : datascource,
461 | 'exportButton': true,
462 | 'exportFilename': 'SportsChart',
463 | 'parentNodeSymbol': 'fa-th-large',
464 | 'createNode': function(node, data) {
465 | node.id = getId();
466 | }
467 | });
468 | document.querySelector('#chart-container').appendChild(orgchart);
469 |
470 | bindEventHandler('.node', 'click', clickNode, '#chart-container');
471 | bindEventHandler('org-chart', 'click', clickChart, '#chart-container');
472 | bindEventHandler('input[name="chart-state"]', 'click', toggleViewState);
473 | bindEventHandler('input[name="node-type"]', 'click', toggleNodeType);
474 | document.getElementById('btn-add-input').addEventListener('click', addInputs);
475 | document.getElementById('btn-remove-input').addEventListener('click', removeInputs);
476 | document.getElementById('btn-add-nodes').addEventListener('click', () => addNodes(orgchart));
477 | document.getElementById('btn-delete-nodes').addEventListener('click', () => deleteNodes(orgchart));
478 | document.getElementById('btn-reset').addEventListener('click', resetPanel);
479 |
480 | });
481 | ```
482 | 
483 |
484 | - **[I wanna drag & drop the nodes of orgchart](http://dabeng.github.io/OrgChart-Webcomponents/drag-drop/)**
485 |
486 | 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).
487 |
488 | 
489 |
490 | 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.
491 | ```js
492 | // sample of core source code
493 | let orgchart = new OrgChart({
494 | 'data' : datascource,
495 | 'nodeContent': 'title',
496 | 'draggable': true,
497 | 'dropCriteria': function(draggedNode, dragZone, dropZone) {
498 | if(draggedNode.querySelector(':scope > .content').textContent.includes('manager') &&
499 | dropZone.querySelector(':scope > .content').textContent.includes('engineer')) {
500 | return false;
501 | }
502 | return true;
503 | }
504 | });
505 | document.querySelector('#chart-container').appendChild(orgchart);
506 | ```
507 |
508 | - **[I want a method that can decribe the hierarchy of orgchart](http://dabeng.github.io/OrgChart-Webcomponents/get-hierarchy/)**
509 |
510 | That's where getHierarchy() comes in.
511 | ```html
512 |
513 | Lao Lao
514 |
515 | Bo Miao
516 | Su Miao
517 |
518 | Tie Hua
519 | Hei Hei
520 |
521 | Pang Pang
522 | Xiang Xiang
523 |
524 |
525 |
526 |
527 |
528 |
529 |
530 | ```
531 | ```js
532 | let orgchart = new OrgChart({
533 | 'chartContainer': '#chart-container',
534 | 'data' : '#ul-data'
535 | });
536 | document.querySelector('#chart-container').appendChild(orgchart);
537 | document.querySelector('#btn-export-hier').addEventListener('click', () => {
538 | if (!document.querySelector('pre')) {
539 | let pre = document.createElement('pre'),
540 | hierarchy = orgchart.getHierarchy();
541 |
542 | pre.innerHTML = JSON.stringify(hierarchy, null, 2);
543 | document.querySelector('body').insertBefore(pre, document.querySelector('.home-link'));
544 | }
545 | });
546 | ```
547 | 
548 |
549 | - **[I want a color-coded chart](http://dabeng.github.io/OrgChart-Webcomponents/color-coded/)**
550 |
551 | It's a so easy task, we just need to append id or className property to node data.
552 | ```js
553 | let datasource = {
554 | 'name': 'Lao Lao',
555 | 'title': 'general manager',
556 | 'className': 'top-level',
557 | 'children': [
558 | { 'name': 'Bo Miao', 'title': 'department manager', 'className': 'middle-level',
559 | 'children': [
560 | { 'name': 'Li Jing', 'title': 'senior engineer', 'className': 'bottom-level' },
561 | { 'name': 'Li Xin', 'title': 'senior engineer', 'className': 'bottom-level' }
562 | ]
563 | }
564 | };
565 | ```
566 | ```css
567 | .orgchart .top-level .title {
568 | background-color: #006699;
569 | }
570 | .orgchart .top-level .content {
571 | border-color: #006699;
572 | }
573 | .orgchart .middle-level .title {
574 | background-color: #009933;
575 | }
576 | .orgchart .middle-level .content {
577 | border-color: #009933;
578 | }
579 | .orgchart .bottom-level .title {
580 | background-color: #993366;
581 | }
582 | .orgchart .bottom-level .content {
583 | border-color: #993366;
584 | }
585 | ```
586 | 
587 |
588 | - **[I want a multiple-layers chart](http://dabeng.github.io/OrgChart-Webcomponents/multiple-layers/)**
589 |
590 | In fact, this is a wonderful solution to display a orgchart which includes a huge number of node data.
591 |
592 | 
593 |
594 | - **[I want a hybrid(horizontal + vertical) chart](http://dabeng.github.io/OrgChart-Webcomponents/vertical-depth/)**
595 |
596 | This feature is inspired by the issues([Aligning Children Vertical](https://github.com/dabeng/OrgChart/issues/46), [Hybrid(horizontal + vertical) OrgChart](https://github.com/dabeng/OrgChart/issues/61)). Thank [mfahadi](https://github.com/mfahadi) and [Destructrix](https://github.com/Destructrix) for their constructive suggestions:blush:
597 |
598 | 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.
599 |
600 | **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.
601 |
602 | ```js
603 | let orgchart = new OrgChart({
604 | 'data' : datascource,
605 | 'nodeContent': 'title',
606 | 'verticalDepth': 3, // From the 3th level of orgchart, nodes will be aligned vertically.
607 | 'depth': 4
608 | });
609 | document.querySelector('#chart-container').appendChild(orgchart);
610 | ```
611 | 
612 |
613 | ## Usage
614 |
615 | ### Instantiation Statement
616 | ```js
617 | let orgchart = new OrgChart(options);
618 | ```
619 |
620 | ### Structure of Datasource
621 | ```js
622 | {
623 | 'id': 'rootNode', // It's a optional property which will be used as id attribute of node
624 | // and data-parent attribute, which contains the id of the parent node
625 | 'className': 'top-level', // It's a optional property which will be used as className attribute of node.
626 | 'nodeTitlePro': 'Lao Lao',
627 | 'nodeContentPro': 'general manager',
628 | 'relationship': relationshipValue, // Note: when you activate ondemand loading nodes feature,
629 | // you should use json datsource (local or remote) and set this property.
630 | // This property implies that whether this node has parent node, siblings nodes or children nodes.
631 | // relationshipValue is a string composed of three "0/1" identifier.
632 | // First character stands for wether current node has parent node;
633 | // Scond character stands for wether current node has siblings nodes;
634 | // Third character stands for wether current node has children node.
635 | 'children': [ // The property stands for nested nodes. "children" is just default name you can override.
636 | { 'nodeTitlePro': 'Bo Miao', 'nodeContentPro': 'department manager', 'relationship': '110' },
637 | { 'nodeTitlePro': 'Su Miao', 'nodeContentPro': 'department manager', 'relationship': '111',
638 | 'children': [
639 | { 'nodeTitlePro': 'Tie Hua', 'nodeContentPro': 'senior engineer', 'relationship': '110' },
640 | { 'nodeTitlePro': 'Hei Hei', 'nodeContentPro': 'senior engineer', 'relationship': '110' }
641 | ]
642 | },
643 | { 'nodeTitlePro': 'Yu Jie', 'nodeContentPro': 'department manager', 'relationship': '110' }
644 | ],
645 | 'otherPro': anyValue
646 | };
647 | ```
648 |
649 | ### Options
650 |
651 |
652 | Name Type Required Default Description
653 |
654 |
655 |
656 | chartContainer string no selector usded to query the wrapper element of orgchart. It could be an id or an unique className. Note: when you want to enable pan&zoom option, you must set "chartContainer" option at the same time.
657 |
658 |
659 | data json or string yes datasource 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.
660 |
661 |
662 | pan boolean no false Users could pan the orgchart by mouse drag&drop if they enable this option.
663 |
664 |
665 | zoom boolean no false Users could zoomin/zoomout the orgchart by mouse wheel if they enable this option.
666 |
667 |
668 | direction string no "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").
669 |
670 |
671 | verticalDepth integer no Users can make use of this option to align the nodes vertically from the specified depth.
672 |
673 |
674 | toggleSiblingsResp boolean no false Once enable this option, users can show/hide left/right sibling nodes respectively by clicking left/right arrow.
675 |
676 |
677 | ajaxURL json no It 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.
678 |
679 |
680 | depth positive integer no 999 It indicates the level that at the very beginning orgchart is expanded to.
681 |
682 |
683 | nodeTitle string no "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.
684 |
685 |
686 | parentNodeSymbol string no "fa-users" Using font awesome icon to imply that the node has child nodes.
687 |
688 |
689 | nodeContent string no It sets one property of datasource as text content of content section of orgchart node.
690 |
691 |
692 | nodeId string no "id" It sets one property of datasource as unique identifier of every orgchart node.
693 |
694 |
695 | createNode function no It's a callback function used to customize every orgchart node. It recieves two parament: "$node" stands for jquery object of single node div; "data" stands for datasource of single node.
696 |
697 |
698 | exportButton boolean no false It enable the export button for orgchart.
699 |
700 |
701 | exportFilename string no "Orgchart" It's filename when you export current orgchart as a picture.
702 |
703 |
704 | chartClass string no "" when you wanna instantiate multiple orgcharts on one page, you should add diffent classname to them in order to distinguish them.
705 |
706 |
707 | draggable boolean no false Users 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.
708 |
709 |
710 | dropCriteria function no Users 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.
711 |
712 |
713 |
714 |
715 | ### Methods
716 | I'm sure that you can grasp the key points of the methods below after you try out demo -- [edit orgchart](http://dabeng.github.io/OrgChart-Webcomponents/edit-orgchart/).
717 | ##### let orgchart = new OrgChart(options);
718 | 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.
719 | ##### .addParent(root, data)
720 | Adds parent node(actullay it's always root node) for current orgchart.
721 |
722 |
723 | Name Type Required Default Description
724 |
725 |
726 | root dom node yes root node of designated orgchart options used for overriding initial options
727 | data json object yes datasource for building root node
728 |
729 |
730 | ##### .addSiblings(node, data)
731 | Adds sibling nodes for designated node.
732 |
733 |
734 | Name Type Required Default Description
735 |
736 |
737 | node dom node yes we'll add sibling nodes based on this node
738 | data json object yes datasource for building sibling nodes
739 |
740 |
741 | ##### .addChildren(node, data)
742 | Adds child nodes for designed node.
743 |
744 |
745 | Name Type Required Default Description
746 |
747 |
748 | node dom node yes we'll add child nodes based on this node
749 | data json object yes datasource for building child nodes
750 |
751 |
752 | ##### .removeNodes(node)
753 | Removes the designated node and its descedant nodes.
754 |
755 |
756 | Name Type Required Default Description
757 |
758 |
759 | node dom node yes node to be removed
760 |
761 |
762 | ##### .getHierarchy()
763 | 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.
764 | ##### .hideChildren(node)
765 | This method allows you to hide programatically the children of any specific node(.node element), if it has
766 |
767 |
768 | Name
769 | Type
770 | Required
771 | Default
772 | Description
773 |
774 |
775 | node
776 | dom node
777 | Yes
778 | None
779 | It's the desired dom node that we'll hide its children nodes
780 |
781 |
782 | ##### .showChildren(node)
783 | This method allows you to show programatically the children of any specific node(.node element), if it has
784 |
785 |
786 | Name
787 | Type
788 | Required
789 | Default
790 | Description
791 |
792 |
793 | node
794 | dom node
795 | Yes
796 | None
797 | It's the desired dom node that we'll show its children nodes
798 |
799 |
800 | ##### .hideSiblings(node, direction)
801 | This method allows you to hide programatically the siblings of any specific node(.node element), if it has
802 |
803 |
804 | Name
805 | Type
806 | Required
807 | Default
808 | Description
809 |
810 |
811 | node
812 | dom node
813 | Yes
814 | None
815 | It's the desired dom node that we'll hide its siblings nodes
816 |
817 |
818 | direction
819 | string
820 | No
821 | None
822 | Possible values:"left","rigth". Specifies if hide the siblings at left or rigth. If not defined hide both of them.
823 |
824 |
825 | ##### .showSiblings(node, direction)
826 | This method allows you to show programatically the siblings of any specific node(.node element), if it has
827 |
828 |
829 | Name
830 | Type
831 | Required
832 | Default
833 | Description
834 |
835 |
836 | node
837 | dom node
838 | Yes
839 | None
840 | It's the desired dom node that we'll show its siblings nodes
841 |
842 |
843 | direction
844 | string
845 | No
846 | None
847 | Possible values:"left","rigth". Specifies if hide the siblings at left or rigth. If not defined hide both of them.
848 |
849 |
850 | ##### .getNodeState(node, relation)
851 | This method returns you the display state of the related nodes.
852 |
853 |
854 | Name
855 | Type
856 | Required
857 | Default
858 | Description
859 |
860 |
861 | node
862 | dom node
863 | Yes
864 | None
865 | It's the desired dom node that we wanna know its related nodes' display state.
866 |
867 |
868 | relation
869 | String
870 | Yes
871 | None
872 | Possible values: "parent", "children" and "siblings". Specifies the desired relation to return.
873 |
874 |
875 | The returning object will have the next structure:
876 | ```js
877 | {
878 | "exists": true|false, //Indicates if has parent|children|siblings
879 | "visible":true|false, //Indicates if the related nodes are visible
880 | }
881 | ```
882 | ##### .getRelatedNodes(node, relation)
883 | This method returns you the nodes related to the specified node
884 |
885 |
886 | Name
887 | Type
888 | Required
889 | Default
890 | Description
891 |
892 |
893 | node
894 | dom node
895 | Yes
896 | None
897 | It's the desired that we wanna get its related nodes
898 |
899 |
900 | relation
901 | String
902 | Yes
903 | None
904 | Possible values: "parent", "children" and "siblings". Specifies the desired relation to return.
905 |
906 |
907 |
908 | ### Events
909 |
910 |
911 | Event Type Attached Data Description
912 |
913 |
914 | nodedropped.orgchart draggedNode, dragZone, dropZone The event's handler is where you can place your customized function after node drop over. For more details, please refer to example drag & drop .
915 |
916 |
917 |
--------------------------------------------------------------------------------
/demo/ajax-datasource/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/ajax-datasource/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | Mock.mock('/orgchart/initdata', {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer',
14 | 'children': [
15 | { 'name': 'Pang Pang', 'title': 'engineer' },
16 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
17 | ]
18 | }
19 | ]
20 | },
21 | { 'name': 'Yu Jie', 'title': 'department manager' },
22 | { 'name': 'Yu Li', 'title': 'department manager' },
23 | { 'name': 'Hong Miao', 'title': 'department manager' },
24 | { 'name': 'Yu Wei', 'title': 'department manager' },
25 | { 'name': 'Chun Miao', 'title': 'department manager' },
26 | { 'name': 'Yu Tie', 'title': 'department manager' }
27 | ]
28 | });
29 | Mock.setup({ timeout: 1000 });
30 |
31 | let orgchart = new OrgChart({
32 | 'data' : '/orgchart/initdata',
33 | 'depth': 2,
34 | 'nodeContent': 'title'
35 | });
36 |
37 | document.querySelector('#chart-container').appendChild(orgchart);
38 |
39 | });
--------------------------------------------------------------------------------
/demo/color-coded/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/color-coded/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager', 'className': 'middle-level',
10 | 'children': [
11 | { 'name': 'Li Jing', 'title': 'senior engineer', 'className': 'product-dept' },
12 | { 'name': 'Li Xin', 'title': 'senior engineer', 'className': 'product-dept',
13 | 'children': [
14 | { 'name': 'To To', 'title': 'engineer', 'className': 'pipeline1' },
15 | { 'name': 'Fei Fei', 'title': 'engineer', 'className': 'pipeline1' },
16 | { 'name': 'Xuan Xuan', 'title': 'engineer', 'className': 'pipeline1' }
17 | ]
18 | }
19 | ]
20 | },
21 | { 'name': 'Su Miao', 'title': 'department manager', 'className': 'middle-level',
22 | 'children': [
23 | { 'name': 'Pang Pang', 'title': 'senior engineer', 'className': 'rd-dept' },
24 | { 'name': 'Hei Hei', 'title': 'senior engineer', 'className': 'rd-dept',
25 | 'children': [
26 | { 'name': 'Xiang Xiang', 'title': 'UE engineer', 'className': 'frontend1' },
27 | { 'name': 'Dan Dan', 'title': 'engineer', 'className': 'frontend1' },
28 | { 'name': 'Zai Zai', 'title': 'engineer', 'className': 'frontend1' }
29 | ]
30 | }
31 | ]
32 | }
33 | ]
34 | },
35 | orgchart = new OrgChart({
36 | 'data' : datascource,
37 | 'nodeContent': 'title'
38 | });
39 |
40 | document.querySelector('#chart-container').appendChild(orgchart);
41 |
42 | });
--------------------------------------------------------------------------------
/demo/color-coded/style.css:
--------------------------------------------------------------------------------
1 | .orgchart {
2 | background: #fff;
3 | }
4 | .orgchart td.left, .orgchart td.right, .orgchart td.top {
5 | border-color: #aaa;
6 | }
7 | .orgchart td>.down {
8 | background-color: #aaa;
9 | }
10 | .orgchart .middle-level .title {
11 | background-color: #006699;
12 | }
13 | .orgchart .middle-level .content {
14 | border-color: #006699;
15 | }
16 | .orgchart .product-dept .title {
17 | background-color: #009933;
18 | }
19 | .orgchart .product-dept .content {
20 | border-color: #009933;
21 | }
22 | .orgchart .rd-dept .title {
23 | background-color: #993366;
24 | }
25 | .orgchart .rd-dept .content {
26 | border-color: #993366;
27 | }
28 | .orgchart .pipeline1 .title {
29 | background-color: #996633;
30 | }
31 | .orgchart .pipeline1 .content {
32 | border-color: #996633;
33 | }
34 | .orgchart .frontend1 .title {
35 | background-color: #cc0066;
36 | }
37 | .orgchart .frontend1 .content {
38 | border-color: #cc0066;
39 | }
--------------------------------------------------------------------------------
/demo/css/orgchart-webcomponents.min.css:
--------------------------------------------------------------------------------
1 | #chart-container{position:relative;display:inline-block;top:10px;left:10px;height:420px;width:calc(100% - 24px);border:2px dashed #aaa;border-radius:5px;overflow:auto;text-align:center;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px}org-chart{display:inline-block;min-height:202px;min-width:202px;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:linear-gradient(90deg,rgba(200,0,0,.15) 10%,rgba(0,0,0,0) 10%),linear-gradient(rgba(200,0,0,.15) 10%,rgba(0,0,0,0) 10%);background-size:10px 10px;border:1px dashed transparent;padding:20px}org-chart .hidden,org-chart~.hidden{display:none}org-chart div,org-chart div::after,org-chart div::before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}org-chart.b2t{-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);transform:rotate(180deg)}org-chart.l2r{position:absolute;-ms-transform:rotate(-90deg) rotateY(180deg);-moz-transform:rotate(-90deg) rotateY(180deg);-webkit-transform:rotate(-90deg) rotateY(180deg);transform:rotate(-90deg) rotateY(180deg);-ms-transform-origin:left top;-moz-transform-origin:left top;-webkit-transform-origin:left top;transform-origin:left top}org-chart .verticalNodes ul{list-style:none;margin:0;padding-left:18px;text-align:left}org-chart .verticalNodes ul:first-child{margin-top:3px}org-chart .verticalNodes>td::before{content:'';border:1px solid rgba(217,83,79,.8)}org-chart .verticalNodes>td>ul>li:first-child::before{top:-4px;height:30px;width:calc(50% - 2px);border-width:2px 0 0 2px}org-chart .verticalNodes ul>li{position:relative}org-chart .verticalNodes ul>li::after,org-chart .verticalNodes ul>li::before{content:'';position:absolute;left:-6px;border-color:rgba(217,83,79,.8);border-style:solid;border-width:0 0 2px 2px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}org-chart .verticalNodes ul>li::before{top:-4px;height:30px;width:11px}org-chart .verticalNodes ul>li::after{top:1px;height:100%}org-chart .verticalNodes ul>li:first-child::after{top:24px;width:11px;border-width:2px 0 0 2px}org-chart .verticalNodes ul>li:last-child::after{border-width:2px 0 0}org-chart.r2l{position:absolute;-ms-transform:rotate(90deg);-moz-transform:rotate(90deg);-webkit-transform:rotate(90deg);transform:rotate(90deg);-ms-transform-origin:left top;-moz-transform-origin:left top;-webkit-transform-origin:left top;transform-origin:left top}org-chart>.spinner{font-size:100px;margin-top:30px;color:rgba(68,157,68,.8)}org-chart table{border-spacing:0;border-collapse:separate}org-chart>table:first-child{margin:20px auto}org-chart td{text-align:center;vertical-align:top;padding:0}org-chart tr.lines .topLine{border-top:2px solid rgba(217,83,79,.8)}org-chart tr.lines .rightLine{border-right:1px solid rgba(217,83,79,.8);float:none;border-radius:0}org-chart tr.lines .leftLine{border-left:1px solid rgba(217,83,79,.8);float:none;border-radius:0}org-chart tr.lines .downLine{background-color:rgba(217,83,79,.8);margin:0 auto;height:20px;width:2px;float:none}org-chart .node.focused,org-chart .node:hover{background-color:rgba(238,217,54,.5)}org-chart .node{display:inline-block;position:relative;margin:0;padding:3px;border:2px dashed transparent;text-align:center;width:130px}org-chart.l2r .node,org-chart.r2l .node{width:50px;height:130px}org-chart .node .content,org-chart .node .title{height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center}org-chart .node>.hazy{opacity:.2}org-chart .node>.spinner{position:absolute;top:calc(50% - 15px);left:calc(50% - 15px);vertical-align:middle;font-size:30px;color:rgba(68,157,68,.8)}org-chart .node:hover{transition:.5s;cursor:default;z-index:20}org-chart .ghost-node{position:fixed;left:-10000px;top:-10000px}org-chart .ghost-node rect{fill:#fff;stroke:#bf0000}org-chart .node.allowedDrop{border-color:rgba(68,157,68,.9)}org-chart .node .title{font-size:12px;font-weight:700;line-height:20px;background-color:rgba(217,83,79,.8);color:#fff;border-radius:4px 4px 0 0}org-chart.b2t .node .title{-ms-transform:rotate(-180deg);-moz-transform:rotate(-180deg);-webkit-transform:rotate(-180deg);transform:rotate(-180deg);-ms-transform-origin:center bottom;-moz-transform-origin:center bottom;-webkit-transform-origin:center bottom;transform-origin:center bottom}org-chart.l2r .node .title{-ms-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-moz-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-webkit-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-ms-transform-origin:bottom center;-moz-transform-origin:bottom center;-webkit-transform-origin:bottom center;transform-origin:bottom center;width:120px}org-chart.r2l .node .title{-ms-transform:rotate(-90deg) translate(-40px,-40px);-moz-transform:rotate(-90deg) translate(-40px,-40px);-webkit-transform:rotate(-90deg) translate(-40px,-40px);transform:rotate(-90deg) translate(-40px,-40px);-ms-transform-origin:bottom center;-moz-transform-origin:bottom center;-webkit-transform-origin:bottom center;transform-origin:bottom center;width:120px}org-chart .node .title .symbol{float:left;margin-top:4px;margin-left:2px}org-chart .node .content{width:100%;font-size:11px;line-height:18px;border:1px solid rgba(217,83,79,.8);border-radius:0 0 4px 4px;background-color:#fff;color:#333}org-chart.b2t .node .content{-ms-transform:rotate(180deg);-moz-transform:rotate(180deg);-webkit-transform:rotate(180deg);transform:rotate(180deg);-ms-transform-origin:center top;-moz-transform-origin:center top;-webkit-transform-origin:center top;transform-origin:center top}org-chart.l2r .node .content{-ms-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-moz-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-webkit-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-ms-transform-origin:top center;-moz-transform-origin:top center;-webkit-transform-origin:top center;transform-origin:top center;width:120px}org-chart.r2l .node .content{-ms-transform:rotate(-90deg) translate(-40px,-40px);-moz-transform:rotate(-90deg) translate(-40px,-40px);-webkit-transform:rotate(-90deg) translate(-40px,-40px);transform:rotate(-90deg) translate(-40px,-40px);-ms-transform-origin:top center;-moz-transform-origin:top center;-webkit-transform-origin:top center;transform-origin:top center;width:120px}org-chart .node .edge{font-size:15px;position:absolute;color:rgba(68,157,68,.5);cursor:default;transition:.2s;-webkit-transition:.2s}org-chart.noncollapsable .node .edge{display:none}org-chart .edge:hover{color:#449d44;cursor:pointer}org-chart .node .verticalEdge{width:calc(100% - 10px);width:-webkit-calc(100% - 10px);width:-moz-calc(100% - 10px);left:5px}org-chart .node .topEdge{top:-4px}org-chart .node .bottomEdge{bottom:-4px}org-chart .node .horizontalEdge{width:15px;height:calc(100% - 10px);height:-webkit-calc(100% - 10px);height:-moz-calc(100% - 10px);top:5px}org-chart .node .rightEdge{right:-4px}org-chart .node .leftEdge{left:-4px}org-chart .node .horizontalEdge::before{position:absolute;top:calc(50% - 7px);top:-webkit-calc(50% - 7px);top:-moz-calc(50% - 7px)}org-chart .node .rightEdge::before{right:3px}org-chart .node .leftEdge::before{left:3px}org-chart .node .toggleBtn{position:absolute;left:5px;bottom:-2px;color:rgba(68,157,68,.6)}org-chart .node .toggleBtn:hover{color:rgba(68,157,68,.8)}.oc-export-btn{display:inline-block;position:absolute;right:5px;top:5px;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;color:#fff;background-color:#5cb85c;border:1px solid #4cae4c;border-radius:4px}.oc-export-btn:active,.oc-export-btn:focus,.oc-export-btn:hover{background-color:#449d44;border-color:#347a34}org-chart~.mask{position:absolute;top:0;right:0;bottom:0;left:0;z-index:999;text-align:center;background-color:rgba(0,0,0,.3)}org-chart~.mask .spinner{position:absolute;top:calc(50% - 54px);left:calc(50% - 54px);color:rgba(255,255,255,.8);font-size:108px}org-chart .node{-webkit-transition:all .3s;transition:all .3s;top:0;left:0}org-chart .slide-down{opacity:0;top:40px}org-chart.l2r .node.slide-down,org-chart.r2l .node.slide-down{top:130px}org-chart .slide-up{opacity:0;top:-40px}org-chart.l2r .node.slide-up,org-chart.r2l .node.slide-up{top:-130px}org-chart .slide-right{opacity:0;left:130px}org-chart.l2r .node.slide-right,org-chart.r2l .node.slide-right{left:40px}org-chart .slide-left{opacity:0;left:-130px}org-chart.l2r .node.slide-left,org-chart.r2l .node.slide-left{left:-40px}
2 | /*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm9yZ2NoYXJ0LXdlYmNvbXBvbmVudHMuY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQVNBLGlCQUNFLFNBQVUsU0FDVixRQUFTLGFBQ1QsSUFBSyxLQUNMLEtBQU0sS0FDTixPQUFRLE1BQ1IsTUFBTyxrQkFDUCxPQUFRLElBQUksT0FBTyxLQUNuQixjQUFlLElBQ2YsU0FBVSxLQUNWLFdBQVksT0FDWixZQUFhLGlCQUFrQixVQUFXLE1BQU8sV0FDakQsVUFBVyxLQUdiLFVBQ0UsUUFBUyxhQUNULFdBQVksTUFDWixVQUFXLE1BQ1gsc0JBQXVCLEtBQ3ZCLG9CQUFxQixLQUNyQixtQkFBb0IsS0FDcEIsaUJBQWtCLEtBQ2xCLGdCQUFpQixLQUNqQixZQUFhLEtBQ2IsaUJBQWtCLCtEQUF5RSx5REFDM0YsZ0JBQWlCLEtBQUssS0FDdEIsT0FBUSxJQUFJLE9BQU8sWUFDbkIsUUFBUyxLQUdYLGtCQUFtQixrQkFDakIsUUFBUyxLQUdYLGNBRUEscUJBREEsc0JBRUUsbUJBQW9CLFdBQ3BCLGdCQUFpQixXQUNqQixXQUFZLFdBR2QsY0FDRSxjQUFlLGVBQ2YsZUFBZ0IsZUFDaEIsa0JBQW1CLGVBQ25CLFVBQVcsZUFHYixjQUNFLFNBQVUsU0FDVixjQUFlLGVBQWUsZ0JBQzlCLGVBQWdCLGVBQWUsZ0JBQy9CLGtCQUFtQixlQUFlLGdCQUNsQyxVQUFXLGVBQWUsZ0JBQzFCLHFCQUFzQixLQUFLLElBQzNCLHNCQUF1QixLQUFLLElBQzVCLHlCQUEwQixLQUFLLElBQy9CLGlCQUFrQixLQUFLLElBR3pCLDRCQUNFLFdBQVksS0FDWixPQUFRLEVBQ1IsYUFBYyxLQUNkLFdBQVksS0FHZCx3Q0FDRSxXQUFZLElBR2Qsb0NBQ0UsUUFBUyxHQUNULE9BQVEsSUFBSSxNQUFNLG1CQUdwQixzREFDRSxJQUFLLEtBQ0wsT0FBUSxLQUNSLE1BQU8sZ0JBQ1AsYUFBYyxJQUFJLEVBQUUsRUFBRSxJQUd4QiwrQkFDRSxTQUFVLFNBSVosc0NBREEsdUNBRUUsUUFBUyxHQUNULFNBQVUsU0FDVixLQUFNLEtBQ04sYUFBYyxtQkFDZCxhQUFjLE1BQ2QsYUFBYyxFQUFFLEVBQUUsSUFBSSxJQUN0QixtQkFBb0IsV0FDcEIsZ0JBQWlCLFdBQ2pCLFdBQVksV0FHZCx1Q0FDRSxJQUFLLEtBQ0wsT0FBUSxLQUNSLE1BQU8sS0FHVCxzQ0FDRSxJQUFLLElBQ0wsT0FBUSxLQUdWLGtEQUNFLElBQUssS0FDTCxNQUFPLEtBQ1AsYUFBYyxJQUFJLEVBQUUsRUFBRSxJQUd4QixpREFDRSxhQUFjLElBQUksRUFBRSxFQUd0QixjQUNFLFNBQVUsU0FDVixjQUFlLGNBQ2YsZUFBZ0IsY0FDaEIsa0JBQW1CLGNBQ25CLFVBQVcsY0FDWCxxQkFBc0IsS0FBSyxJQUMzQixzQkFBdUIsS0FBSyxJQUM1Qix5QkFBMEIsS0FBSyxJQUMvQixpQkFBa0IsS0FBSyxJQUd6QixtQkFDRSxVQUFXLE1BQ1gsV0FBWSxLQUNaLE1BQU8sbUJBR1QsZ0JBQ0UsZUFBZ0IsRUFDaEIsZ0JBQWlCLFNBR25CLDRCQUNFLE9BQVEsS0FBSyxLQUdmLGFBQ0UsV0FBWSxPQUNaLGVBQWdCLElBQ2hCLFFBQVMsRUFHWCw0QkFDRSxXQUFZLElBQUksTUFBTSxtQkFHeEIsOEJBQ0UsYUFBYyxJQUFJLE1BQU0sbUJBQ3hCLE1BQU8sS0FDUCxjQUFlLEVBR2pCLDZCQUNFLFlBQWEsSUFBSSxNQUFNLG1CQUN2QixNQUFPLEtBQ1AsY0FBZSxFQUdqQiw2QkFDRSxpQkFBa0IsbUJBQ2xCLE9BQVEsRUFBRSxLQUNWLE9BQVEsS0FDUixNQUFPLElBQ1AsTUFBTyxLQXVDVCx3QkFQQSxzQkFRRSxpQkFBa0Isb0JBcENwQixnQkFDRSxRQUFTLGFBQ1QsU0FBVSxTQUNWLE9BQVEsRUFDUixRQUFTLElBQ1QsT0FBUSxJQUFJLE9BQU8sWUFDbkIsV0FBWSxPQUNaLE1BQU8sTUFHVCxvQkFBcUIsb0JBQ25CLE1BQU8sS0FDUCxPQUFRLE1BaUdWLHlCQXZEQSx1QkF5REUsT0FBUSxLQVFSLFNBQVUsT0FDVixjQUFlLFNBNkhmLFlBQWEsT0E0QmIsV0FBWSxPQWxRZCxzQkFDRSxRQUFTLEdBR1gseUJBQ0UsU0FBVSxTQUNWLElBQUssaUJBQ0wsS0FBTSxpQkFDTixlQUFnQixPQUNoQixVQUFXLEtBQ1gsTUFBTyxtQkFHVCxzQkFFRSxXQUFZLElBQ1osT0FBUSxRQUNSLFFBQVMsR0FPWCxzQkFDRSxTQUFVLE1BQ1YsS0FBTSxTQUNOLElBQUssU0FHUCwyQkFDRSxLQUFNLEtBQ04sT0FBUSxRQUdWLDRCQUNFLGFBQWMsbUJBR2hCLHVCQUVFLFVBQVcsS0FDWCxZQUFhLElBRWIsWUFBYSxLQUliLGlCQUFrQixtQkFDbEIsTUFBTyxLQUNQLGNBQWUsSUFBSSxJQUFJLEVBQUUsRUFHM0IsMkJBQ0UsY0FBZSxnQkFDZixlQUFnQixnQkFDaEIsa0JBQW1CLGdCQUNuQixVQUFXLGdCQUNYLHFCQUFzQixPQUFPLE9BQzdCLHNCQUF1QixPQUFPLE9BQzlCLHlCQUEwQixPQUFPLE9BQ2pDLGlCQUFrQixPQUFPLE9BRzNCLDJCQUNFLGNBQWUsZUFBZSx1QkFBd0IsZ0JBQ3RELGVBQWdCLGVBQWUsdUJBQXdCLGdCQUN2RCxrQkFBbUIsZUFBZSx1QkFBd0IsZ0JBQzFELFVBQVcsZUFBZSx1QkFBd0IsZ0JBQ2xELHFCQUFzQixPQUFPLE9BQzdCLHNCQUF1QixPQUFPLE9BQzlCLHlCQUEwQixPQUFPLE9BQ2pDLGlCQUFrQixPQUFPLE9BQ3pCLE1BQU8sTUFHVCwyQkFDRSxjQUFlLGVBQWUsdUJBQzlCLGVBQWdCLGVBQWUsdUJBQy9CLGtCQUFtQixlQUFlLHVCQUNsQyxVQUFXLGVBQWUsdUJBQzFCLHFCQUFzQixPQUFPLE9BQzdCLHNCQUF1QixPQUFPLE9BQzlCLHlCQUEwQixPQUFPLE9BQ2pDLGlCQUFrQixPQUFPLE9BQ3pCLE1BQU8sTUFHVCwrQkFDRSxNQUFPLEtBQ1AsV0FBWSxJQUNaLFlBQWEsSUFHZix5QkFDRSxNQUFPLEtBRVAsVUFBVyxLQUNYLFlBQWEsS0FDYixPQUFRLElBQUksTUFBTSxtQkFDbEIsY0FBZSxFQUFFLEVBQUUsSUFBSSxJQUV2QixpQkFBa0IsS0FDbEIsTUFBTyxLQU1ULDZCQUNFLGNBQWUsZUFDZixlQUFnQixlQUNoQixrQkFBbUIsZUFDbkIsVUFBVyxlQUNYLHFCQUFzQixPQUFPLElBQzdCLHNCQUF1QixPQUFPLElBQzlCLHlCQUEwQixPQUFPLElBQ2pDLGlCQUFrQixPQUFPLElBRzNCLDZCQUNFLGNBQWUsZUFBZSx1QkFBd0IsZ0JBQ3RELGVBQWdCLGVBQWUsdUJBQXdCLGdCQUN2RCxrQkFBbUIsZUFBZSx1QkFBd0IsZ0JBQzFELFVBQVcsZUFBZSx1QkFBd0IsZ0JBQ2xELHFCQUFzQixJQUFJLE9BQzFCLHNCQUF1QixJQUFJLE9BQzNCLHlCQUEwQixJQUFJLE9BQzlCLGlCQUFrQixJQUFJLE9BQ3RCLE1BQU8sTUFHVCw2QkFDRSxjQUFlLGVBQWUsdUJBQzlCLGVBQWdCLGVBQWUsdUJBQy9CLGtCQUFtQixlQUFlLHVCQUNsQyxVQUFXLGVBQWUsdUJBQzFCLHFCQUFzQixJQUFJLE9BQzFCLHNCQUF1QixJQUFJLE9BQzNCLHlCQUEwQixJQUFJLE9BQzlCLGlCQUFrQixJQUFJLE9BQ3RCLE1BQU8sTUFHVCxzQkFDRSxVQUFXLEtBQ1gsU0FBVSxTQUNWLE1BQU8sbUJBQ1AsT0FBUSxRQUNSLFdBQVksSUFDWixtQkFBb0IsSUFHdEIscUNBQ0UsUUFBUyxLQUdYLHNCQUNFLE1BQU8sUUFDUCxPQUFRLFFBR1YsOEJBQ0UsTUFBTyxrQkFDUCxNQUFPLDBCQUNQLE1BQU8sdUJBQ1AsS0FBTSxJQUdSLHlCQUNFLElBQUssS0FHUCw0QkFDRSxPQUFRLEtBR1YsZ0NBQ0UsTUFBTyxLQUNQLE9BQVEsa0JBQ1IsT0FBUSwwQkFDUixPQUFRLHVCQUNSLElBQUssSUFHUCwyQkFDRSxNQUFPLEtBR1QsMEJBQ0UsS0FBTSxLQUdSLHdDQUNFLFNBQVUsU0FDVixJQUFLLGdCQUNMLElBQUssd0JBQ0wsSUFBSyxxQkFHUCxtQ0FDRSxNQUFPLElBR1Qsa0NBQ0UsS0FBTSxJQUdSLDJCQUNFLFNBQVUsU0FDVixLQUFNLElBQ04sT0FBUSxLQUNSLE1BQU8sbUJBR1QsaUNBQ0UsTUFBTyxtQkFHVCxlQUNFLFFBQVMsYUFDVCxTQUFVLFNBQ1YsTUFBTyxJQUNQLElBQUssSUFDTCxRQUFTLElBQUksS0FDYixjQUFlLEVBQ2YsVUFBVyxLQUNYLFlBQWEsSUFDYixZQUFhLFdBQ2IsV0FBWSxPQUNaLFlBQWEsT0FDYixlQUFnQixPQUNoQixpQkFBa0IsYUFDbEIsYUFBYyxhQUNkLE9BQVEsUUFDUixvQkFBcUIsS0FDckIsaUJBQWtCLEtBQ2xCLGdCQUFpQixLQUNqQixZQUFhLEtBQ2IsTUFBTyxLQUNQLGlCQUFrQixRQUNsQixPQUFRLElBQUksTUFDRSxRQUNkLGNBQWUsSUFHeUIsc0JBQXJCLHFCQUFyQixxQkFDRSxpQkFBa0IsUUFDbEIsYUFBYyxRQUdoQixnQkFDRSxTQUFVLFNBQ1YsSUFBSyxFQUNMLE1BQU8sRUFDUCxPQUFRLEVBQ1IsS0FBTSxFQUNOLFFBQVMsSUFDVCxXQUFZLE9BQ1osaUJBQWtCLGVBR3BCLHlCQUNFLFNBQVUsU0FDVixJQUFLLGlCQUNMLEtBQU0saUJBQ04sTUFBTyxxQkFDUCxVQUFXLE1BR2IsZ0JBQ0UsbUJBQW9CLElBQUksSUFDeEIsV0FBWSxJQUFJLElBQ2hCLElBQUssRUFDTCxLQUFNLEVBR1Isc0JBQ0UsUUFBUyxFQUNULElBQUssS0FHUCwrQkFBZ0MsK0JBQzlCLElBQUssTUFHUCxvQkFDRSxRQUFTLEVBQ1QsSUFBSyxNQUdQLDZCQUE4Qiw2QkFDNUIsSUFBSyxPQUdQLHVCQUNFLFFBQVMsRUFDVCxLQUFNLE1BR1IsZ0NBQWlDLGdDQUMvQixLQUFNLEtBR1Isc0JBQ0UsUUFBUyxFQUNULEtBQU0sT0FHUiwrQkFBZ0MsK0JBQzlCLEtBQU0iLCJmaWxlIjoib3JnY2hhcnQtd2ViY29tcG9uZW50cy5taW4uY3NzIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIE9yZ2FuaXphdGlvbiBDaGFydCBXZWIgQ29tcG9uZW50c1xuICogaHR0cHM6Ly9naXRodWIuY29tL2RhYmVuZy9vcmctY2hhcnQtV2ViY29tcG9uZW50c1xuICpcbiAqXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2U6XG4gKiBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVFxuICovXG5cbiNjaGFydC1jb250YWluZXIge1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIGRpc3BsYXk6IGlubGluZS1ibG9jaztcbiAgdG9wOiAxMHB4O1xuICBsZWZ0OiAxMHB4O1xuICBoZWlnaHQ6IDQyMHB4O1xuICB3aWR0aDogY2FsYygxMDAlIC0gMjRweCk7XG4gIGJvcmRlcjogMnB4IGRhc2hlZCAjYWFhO1xuICBib3JkZXItcmFkaXVzOiA1cHg7XG4gIG92ZXJmbG93OiBhdXRvO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtZmFtaWx5OiBcIkhlbHZldGljYSBOZXVlXCIsIEhlbHZldGljYSwgQXJpYWwsIHNhbnMtc2VyaWY7XG4gIGZvbnQtc2l6ZTogMTRweDtcbn1cblxub3JnLWNoYXJ0IHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBtaW4taGVpZ2h0OiAyMDJweDtcbiAgbWluLXdpZHRoOiAyMDJweDtcbiAgLXdlYmtpdC10b3VjaC1jYWxsb3V0OiBub25lO1xuICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xuICAta2h0bWwtdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tb3otdXNlci1zZWxlY3Q6IG5vbmU7XG4gIC1tcy11c2VyLXNlbGVjdDogbm9uZTtcbiAgdXNlci1zZWxlY3Q6IG5vbmU7XG4gIGJhY2tncm91bmQtaW1hZ2U6IGxpbmVhci1ncmFkaWVudCg5MGRlZywgcmdiYSgyMDAsIDAsIDAsIDAuMTUpIDEwJSwgcmdiYSgwLCAwLCAwLCAwKSAxMCUpLCBsaW5lYXItZ3JhZGllbnQocmdiYSgyMDAsIDAsIDAsIDAuMTUpIDEwJSwgcmdiYSgwLCAwLCAwLCAwKSAxMCUpO1xuICBiYWNrZ3JvdW5kLXNpemU6IDEwcHggMTBweDtcbiAgYm9yZGVyOiAxcHggZGFzaGVkIHRyYW5zcGFyZW50O1xuICBwYWRkaW5nOiAyMHB4O1xufVxuXG5vcmctY2hhcnQgLmhpZGRlbiwgb3JnLWNoYXJ0fi5oaWRkZW4ge1xuICBkaXNwbGF5OiBub25lO1xufVxuXG5vcmctY2hhcnQgZGl2LFxub3JnLWNoYXJ0IGRpdjo6YmVmb3JlLFxub3JnLWNoYXJ0IGRpdjo6YWZ0ZXIge1xuICAtd2Via2l0LWJveC1zaXppbmc6IGJvcmRlci1ib3g7XG4gIC1tb3otYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgYm94LXNpemluZzogYm9yZGVyLWJveDtcbn1cblxub3JnLWNoYXJ0LmIydCB7XG4gIC1tcy10cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpO1xuICAtbW96LXRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7XG4gIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTtcbiAgdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTtcbn1cblxub3JnLWNoYXJ0LmwyciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgLW1zLXRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgcm90YXRlWSgxODBkZWcpO1xuICAtbW96LXRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgcm90YXRlWSgxODBkZWcpO1xuICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgcm90YXRlWSgxODBkZWcpO1xuICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHJvdGF0ZVkoMTgwZGVnKTtcbiAgLW1zLXRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xuICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xuICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xuICB0cmFuc2Zvcm0tb3JpZ2luOiBsZWZ0IHRvcDtcbn1cblxub3JnLWNoYXJ0IC52ZXJ0aWNhbE5vZGVzIHVsIHtcbiAgbGlzdC1zdHlsZTogbm9uZTtcbiAgbWFyZ2luOiAwO1xuICBwYWRkaW5nLWxlZnQ6IDE4cHg7XG4gIHRleHQtYWxpZ246IGxlZnQ7XG59XG5cbm9yZy1jaGFydCAudmVydGljYWxOb2RlcyB1bDpmaXJzdC1jaGlsZCB7XG4gIG1hcmdpbi10b3A6IDNweDtcbn1cblxub3JnLWNoYXJ0IC52ZXJ0aWNhbE5vZGVzPnRkOjpiZWZvcmUge1xuICBjb250ZW50OiAnJztcbiAgYm9yZGVyOiAxcHggc29saWQgcmdiYSgyMTcsIDgzLCA3OSwgMC44KTtcbn1cblxub3JnLWNoYXJ0IC52ZXJ0aWNhbE5vZGVzPnRkPnVsPmxpOmZpcnN0LWNoaWxkOjpiZWZvcmUge1xuICB0b3A6IC00cHg7XG4gIGhlaWdodDogMzBweDtcbiAgd2lkdGg6IGNhbGMoNTAlIC0gMnB4KTtcbiAgYm9yZGVyLXdpZHRoOiAycHggMCAwIDJweDtcbn1cblxub3JnLWNoYXJ0IC52ZXJ0aWNhbE5vZGVzIHVsPmxpIHtcbiAgcG9zaXRpb246IHJlbGF0aXZlO1xufVxuXG5vcmctY2hhcnQgLnZlcnRpY2FsTm9kZXMgdWw+bGk6OmJlZm9yZSxcbm9yZy1jaGFydCAudmVydGljYWxOb2RlcyB1bD5saTo6YWZ0ZXIge1xuICBjb250ZW50OiAnJztcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICBsZWZ0OiAtNnB4O1xuICBib3JkZXItY29sb3I6IHJnYmEoMjE3LCA4MywgNzksIDAuOCk7XG4gIGJvcmRlci1zdHlsZTogc29saWQ7XG4gIGJvcmRlci13aWR0aDogMCAwIDJweCAycHg7XG4gIC13ZWJraXQtYm94LXNpemluZzogYm9yZGVyLWJveDtcbiAgLW1vei1ib3gtc2l6aW5nOiBib3JkZXItYm94O1xuICBib3gtc2l6aW5nOiBib3JkZXItYm94O1xufVxuXG5vcmctY2hhcnQgLnZlcnRpY2FsTm9kZXMgdWw+bGk6OmJlZm9yZSB7XG4gIHRvcDogLTRweDtcbiAgaGVpZ2h0OiAzMHB4O1xuICB3aWR0aDogMTFweDtcbn1cblxub3JnLWNoYXJ0IC52ZXJ0aWNhbE5vZGVzIHVsPmxpOjphZnRlciB7XG4gIHRvcDogMXB4O1xuICBoZWlnaHQ6IDEwMCU7XG59XG5cbm9yZy1jaGFydCAudmVydGljYWxOb2RlcyB1bD5saTpmaXJzdC1jaGlsZDo6YWZ0ZXIge1xuICB0b3A6IDI0cHg7XG4gIHdpZHRoOiAxMXB4O1xuICBib3JkZXItd2lkdGg6IDJweCAwIDAgMnB4O1xufVxuXG5vcmctY2hhcnQgLnZlcnRpY2FsTm9kZXMgdWw+bGk6bGFzdC1jaGlsZDo6YWZ0ZXIge1xuICBib3JkZXItd2lkdGg6IDJweCAwIDA7XG59XG5cbm9yZy1jaGFydC5yMmwge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIC1tcy10cmFuc2Zvcm06IHJvdGF0ZSg5MGRlZyk7XG4gIC1tb3otdHJhbnNmb3JtOiByb3RhdGUoOTBkZWcpO1xuICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDkwZGVnKTtcbiAgdHJhbnNmb3JtOiByb3RhdGUoOTBkZWcpO1xuICAtbXMtdHJhbnNmb3JtLW9yaWdpbjogbGVmdCB0b3A7XG4gIC1tb3otdHJhbnNmb3JtLW9yaWdpbjogbGVmdCB0b3A7XG4gIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogbGVmdCB0b3A7XG4gIHRyYW5zZm9ybS1vcmlnaW46IGxlZnQgdG9wO1xufVxuXG5vcmctY2hhcnQ+LnNwaW5uZXIge1xuICBmb250LXNpemU6IDEwMHB4O1xuICBtYXJnaW4tdG9wOiAzMHB4O1xuICBjb2xvcjogcmdiYSg2OCwgMTU3LCA2OCwgMC44KTtcbn1cblxub3JnLWNoYXJ0IHRhYmxlIHtcbiAgYm9yZGVyLXNwYWNpbmc6IDA7XG4gIGJvcmRlci1jb2xsYXBzZTogc2VwYXJhdGU7XG59XG5cbm9yZy1jaGFydD50YWJsZTpmaXJzdC1jaGlsZHtcbiAgbWFyZ2luOiAyMHB4IGF1dG87XG59XG5cbm9yZy1jaGFydCB0ZCB7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgdmVydGljYWwtYWxpZ246IHRvcDtcbiAgcGFkZGluZzogMDtcbn1cblxub3JnLWNoYXJ0IHRyLmxpbmVzIC50b3BMaW5lIHtcbiAgYm9yZGVyLXRvcDogMnB4IHNvbGlkIHJnYmEoMjE3LCA4MywgNzksIDAuOCk7XG59XG5cbm9yZy1jaGFydCB0ci5saW5lcyAucmlnaHRMaW5lIHtcbiAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgcmdiYSgyMTcsIDgzLCA3OSwgMC44KTtcbiAgZmxvYXQ6IG5vbmU7XG4gIGJvcmRlci1yYWRpdXM6IDA7XG59XG5cbm9yZy1jaGFydCB0ci5saW5lcyAubGVmdExpbmUge1xuICBib3JkZXItbGVmdDogMXB4IHNvbGlkIHJnYmEoMjE3LCA4MywgNzksIDAuOCk7XG4gIGZsb2F0OiBub25lO1xuICBib3JkZXItcmFkaXVzOiAwO1xufVxuXG5vcmctY2hhcnQgdHIubGluZXMgLmRvd25MaW5lIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMTcsIDgzLCA3OSwgMC44KTtcbiAgbWFyZ2luOiAwIGF1dG87XG4gIGhlaWdodDogMjBweDtcbiAgd2lkdGg6IDJweDtcbiAgZmxvYXQ6IG5vbmU7XG59XG5cbi8qIG5vZGUgc3R5bGluZyAqL1xub3JnLWNoYXJ0IC5ub2RlIHtcbiAgZGlzcGxheTogaW5saW5lLWJsb2NrO1xuICBwb3NpdGlvbjogcmVsYXRpdmU7XG4gIG1hcmdpbjogMDtcbiAgcGFkZGluZzogM3B4O1xuICBib3JkZXI6IDJweCBkYXNoZWQgdHJhbnNwYXJlbnQ7XG4gIHRleHQtYWxpZ246IGNlbnRlcjtcbiAgd2lkdGg6IDEzMHB4O1xufVxuXG5vcmctY2hhcnQubDJyIC5ub2RlLCBvcmctY2hhcnQucjJsIC5ub2RlIHtcbiAgd2lkdGg6IDUwcHg7XG4gIGhlaWdodDogMTMwcHg7XG59XG5cbm9yZy1jaGFydCAubm9kZT4uaGF6eSB7XG4gIG9wYWNpdHk6IDAuMjtcbn1cblxub3JnLWNoYXJ0IC5ub2RlPi5zcGlubmVyIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IGNhbGMoNTAlIC0gMTVweCk7XG4gIGxlZnQ6IGNhbGMoNTAlIC0gMTVweCk7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIGZvbnQtc2l6ZTogMzBweDtcbiAgY29sb3I6IHJnYmEoNjgsIDE1NywgNjgsIDAuOCk7XG59XG5cbm9yZy1jaGFydCAubm9kZTpob3ZlciB7XG4gIGJhY2tncm91bmQtY29sb3I6IHJnYmEoMjM4LCAyMTcsIDU0LCAwLjUpO1xuICB0cmFuc2l0aW9uOiAuNXM7XG4gIGN1cnNvcjogZGVmYXVsdDtcbiAgei1pbmRleDogMjA7XG59XG5cbm9yZy1jaGFydCAubm9kZS5mb2N1c2VkIHtcbiAgYmFja2dyb3VuZC1jb2xvcjogcmdiYSgyMzgsIDIxNywgNTQsIDAuNSk7XG59XG5cbm9yZy1jaGFydCAuZ2hvc3Qtbm9kZSB7XG4gIHBvc2l0aW9uOiBmaXhlZDtcbiAgbGVmdDogLTEwMDAwcHg7XG4gIHRvcDogLTEwMDAwcHg7XG59XG5cbm9yZy1jaGFydCAuZ2hvc3Qtbm9kZSByZWN0IHtcbiAgZmlsbDogI2ZmZmZmZjtcbiAgc3Ryb2tlOiAjYmYwMDAwO1xufVxuXG5vcmctY2hhcnQgLm5vZGUuYWxsb3dlZERyb3Age1xuICBib3JkZXItY29sb3I6IHJnYmEoNjgsIDE1NywgNjgsIDAuOSk7XG59XG5cbm9yZy1jaGFydCAubm9kZSAudGl0bGUge1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIGZvbnQtc2l6ZTogMTJweDtcbiAgZm9udC13ZWlnaHQ6IGJvbGQ7XG4gIGhlaWdodDogMjBweDtcbiAgbGluZS1oZWlnaHQ6IDIwcHg7XG4gIG92ZXJmbG93OiBoaWRkZW47XG4gIHRleHQtb3ZlcmZsb3c6IGVsbGlwc2lzO1xuICB3aGl0ZS1zcGFjZTogbm93cmFwO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDIxNywgODMsIDc5LCAwLjgpO1xuICBjb2xvcjogI2ZmZjtcbiAgYm9yZGVyLXJhZGl1czogNHB4IDRweCAwIDA7IFxufVxuXG5vcmctY2hhcnQuYjJ0IC5ub2RlIC50aXRsZSB7XG4gIC1tcy10cmFuc2Zvcm06IHJvdGF0ZSgtMTgwZGVnKTtcbiAgLW1vei10cmFuc2Zvcm06IHJvdGF0ZSgtMTgwZGVnKTtcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgtMTgwZGVnKTtcbiAgdHJhbnNmb3JtOiByb3RhdGUoLTE4MGRlZyk7XG4gIC1tcy10cmFuc2Zvcm0tb3JpZ2luOiBjZW50ZXIgYm90dG9tO1xuICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IGNlbnRlciBib3R0b207XG4gIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyIGJvdHRvbTtcbiAgdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyIGJvdHRvbTtcbn1cblxub3JnLWNoYXJ0LmwyciAubm9kZSAudGl0bGUge1xuICAtbXMtdHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKSB0cmFuc2xhdGUoLTQwcHgsIC00MHB4KSByb3RhdGVZKDE4MGRlZyk7XG4gIC1tb3otdHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKSB0cmFuc2xhdGUoLTQwcHgsIC00MHB4KSByb3RhdGVZKDE4MGRlZyk7XG4gIC13ZWJraXQtdHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKSB0cmFuc2xhdGUoLTQwcHgsIC00MHB4KSByb3RhdGVZKDE4MGRlZyk7XG4gIHRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgdHJhbnNsYXRlKC00MHB4LCAtNDBweCkgcm90YXRlWSgxODBkZWcpO1xuICAtbXMtdHJhbnNmb3JtLW9yaWdpbjogYm90dG9tIGNlbnRlcjtcbiAgLW1vei10cmFuc2Zvcm0tb3JpZ2luOiBib3R0b20gY2VudGVyO1xuICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IGJvdHRvbSBjZW50ZXI7XG4gIHRyYW5zZm9ybS1vcmlnaW46IGJvdHRvbSBjZW50ZXI7XG4gIHdpZHRoOiAxMjBweDtcbn1cblxub3JnLWNoYXJ0LnIybCAubm9kZSAudGl0bGUge1xuICAtbXMtdHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKSB0cmFuc2xhdGUoLTQwcHgsIC00MHB4KTtcbiAgLW1vei10cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHRyYW5zbGF0ZSgtNDBweCwgLTQwcHgpO1xuICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgdHJhbnNsYXRlKC00MHB4LCAtNDBweCk7XG4gIHRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgdHJhbnNsYXRlKC00MHB4LCAtNDBweCk7XG4gIC1tcy10cmFuc2Zvcm0tb3JpZ2luOiBib3R0b20gY2VudGVyO1xuICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IGJvdHRvbSBjZW50ZXI7XG4gIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogYm90dG9tIGNlbnRlcjtcbiAgdHJhbnNmb3JtLW9yaWdpbjogYm90dG9tIGNlbnRlcjtcbiAgd2lkdGg6IDEyMHB4O1xufVxuXG5vcmctY2hhcnQgLm5vZGUgLnRpdGxlIC5zeW1ib2wge1xuICBmbG9hdDogbGVmdDtcbiAgbWFyZ2luLXRvcDogNHB4O1xuICBtYXJnaW4tbGVmdDogMnB4O1xufVxuXG5vcmctY2hhcnQgLm5vZGUgLmNvbnRlbnQge1xuICB3aWR0aDogMTAwJTtcbiAgaGVpZ2h0OiAyMHB4O1xuICBmb250LXNpemU6IDExcHg7XG4gIGxpbmUtaGVpZ2h0OiAxOHB4O1xuICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDIxNywgODMsIDc5LCAwLjgpO1xuICBib3JkZXItcmFkaXVzOiAwIDAgNHB4IDRweDtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiAjZmZmO1xuICBjb2xvcjogIzMzMztcbiAgb3ZlcmZsb3c6IGhpZGRlbjtcbiAgdGV4dC1vdmVyZmxvdzogZWxsaXBzaXM7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG59XG5cbm9yZy1jaGFydC5iMnQgLm5vZGUgLmNvbnRlbnQge1xuICAtbXMtdHJhbnNmb3JtOiByb3RhdGUoMTgwZGVnKTtcbiAgLW1vei10cmFuc2Zvcm06IHJvdGF0ZSgxODBkZWcpO1xuICAtd2Via2l0LXRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7XG4gIHRyYW5zZm9ybTogcm90YXRlKDE4MGRlZyk7XG4gIC1tcy10cmFuc2Zvcm0tb3JpZ2luOiBjZW50ZXIgdG9wO1xuICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IGNlbnRlciB0b3A7XG4gIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyIHRvcDtcbiAgdHJhbnNmb3JtLW9yaWdpbjogY2VudGVyIHRvcDtcbn1cblxub3JnLWNoYXJ0LmwyciAubm9kZSAuY29udGVudCB7XG4gIC1tcy10cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHRyYW5zbGF0ZSgtNDBweCwgLTQwcHgpIHJvdGF0ZVkoMTgwZGVnKTtcbiAgLW1vei10cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHRyYW5zbGF0ZSgtNDBweCwgLTQwcHgpIHJvdGF0ZVkoMTgwZGVnKTtcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHRyYW5zbGF0ZSgtNDBweCwgLTQwcHgpIHJvdGF0ZVkoMTgwZGVnKTtcbiAgdHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKSB0cmFuc2xhdGUoLTQwcHgsIC00MHB4KSByb3RhdGVZKDE4MGRlZyk7XG4gIC1tcy10cmFuc2Zvcm0tb3JpZ2luOiB0b3AgY2VudGVyO1xuICAtbW96LXRyYW5zZm9ybS1vcmlnaW46IHRvcCBjZW50ZXI7XG4gIC13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjogdG9wIGNlbnRlcjtcbiAgdHJhbnNmb3JtLW9yaWdpbjogdG9wIGNlbnRlcjtcbiAgd2lkdGg6IDEyMHB4O1xufVxuXG5vcmctY2hhcnQucjJsIC5ub2RlIC5jb250ZW50IHtcbiAgLW1zLXRyYW5zZm9ybTogcm90YXRlKC05MGRlZykgdHJhbnNsYXRlKC00MHB4LCAtNDBweCk7XG4gIC1tb3otdHJhbnNmb3JtOiByb3RhdGUoLTkwZGVnKSB0cmFuc2xhdGUoLTQwcHgsIC00MHB4KTtcbiAgLXdlYmtpdC10cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHRyYW5zbGF0ZSgtNDBweCwgLTQwcHgpO1xuICB0cmFuc2Zvcm06IHJvdGF0ZSgtOTBkZWcpIHRyYW5zbGF0ZSgtNDBweCwgLTQwcHgpO1xuICAtbXMtdHJhbnNmb3JtLW9yaWdpbjogdG9wIGNlbnRlcjtcbiAgLW1vei10cmFuc2Zvcm0tb3JpZ2luOiB0b3AgY2VudGVyO1xuICAtd2Via2l0LXRyYW5zZm9ybS1vcmlnaW46IHRvcCBjZW50ZXI7XG4gIHRyYW5zZm9ybS1vcmlnaW46IHRvcCBjZW50ZXI7XG4gIHdpZHRoOiAxMjBweDtcbn1cblxub3JnLWNoYXJ0IC5ub2RlIC5lZGdlIHtcbiAgZm9udC1zaXplOiAxNXB4O1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGNvbG9yOiByZ2JhKDY4LCAxNTcsIDY4LCAwLjUpO1xuICBjdXJzb3I6IGRlZmF1bHQ7XG4gIHRyYW5zaXRpb246IC4ycztcbiAgLXdlYmtpdC10cmFuc2l0aW9uOiAuMnM7XG59XG5cbm9yZy1jaGFydC5ub25jb2xsYXBzYWJsZSAubm9kZSAuZWRnZSB7XG4gIGRpc3BsYXk6IG5vbmU7XG59XG5cbm9yZy1jaGFydCAuZWRnZTpob3ZlciB7XG4gIGNvbG9yOiAjNDQ5ZDQ0O1xuICBjdXJzb3I6IHBvaW50ZXI7XG59XG5cbm9yZy1jaGFydCAubm9kZSAudmVydGljYWxFZGdlIHtcbiAgd2lkdGg6IGNhbGMoMTAwJSAtIDEwcHgpO1xuICB3aWR0aDogLXdlYmtpdC1jYWxjKDEwMCUgLSAxMHB4KTtcbiAgd2lkdGg6IC1tb3otY2FsYygxMDAlIC0gMTBweCk7XG4gIGxlZnQ6IDVweDtcbn1cblxub3JnLWNoYXJ0IC5ub2RlIC50b3BFZGdlIHtcbiAgdG9wOiAtNHB4O1xufVxuXG5vcmctY2hhcnQgLm5vZGUgLmJvdHRvbUVkZ2Uge1xuICBib3R0b206IC00cHg7XG59XG5cbm9yZy1jaGFydCAubm9kZSAuaG9yaXpvbnRhbEVkZ2Uge1xuICB3aWR0aDogMTVweDtcbiAgaGVpZ2h0OiBjYWxjKDEwMCUgLSAxMHB4KTtcbiAgaGVpZ2h0OiAtd2Via2l0LWNhbGMoMTAwJSAtIDEwcHgpO1xuICBoZWlnaHQ6IC1tb3otY2FsYygxMDAlIC0gMTBweCk7XG4gIHRvcDogNXB4O1xufVxuXG5vcmctY2hhcnQgLm5vZGUgLnJpZ2h0RWRnZSB7XG4gIHJpZ2h0OiAtNHB4O1xufVxuXG5vcmctY2hhcnQgLm5vZGUgLmxlZnRFZGdlIHtcbiAgbGVmdDogLTRweDtcbn1cblxub3JnLWNoYXJ0IC5ub2RlIC5ob3Jpem9udGFsRWRnZTo6YmVmb3JlIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IGNhbGMoNTAlIC0gN3B4KTtcbiAgdG9wOiAtd2Via2l0LWNhbGMoNTAlIC0gN3B4KTtcbiAgdG9wOiAtbW96LWNhbGMoNTAlIC0gN3B4KTtcbn1cblxub3JnLWNoYXJ0IC5ub2RlIC5yaWdodEVkZ2U6OmJlZm9yZSB7XG4gIHJpZ2h0OiAzcHg7XG59XG5cbm9yZy1jaGFydCAubm9kZSAubGVmdEVkZ2U6OmJlZm9yZSB7XG4gIGxlZnQ6IDNweDtcbn1cblxub3JnLWNoYXJ0IC5ub2RlIC50b2dnbGVCdG4ge1xuICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gIGxlZnQ6IDVweDtcbiAgYm90dG9tOiAtMnB4O1xuICBjb2xvcjogcmdiYSg2OCwgMTU3LCA2OCwgMC42KTtcbn1cblxub3JnLWNoYXJ0IC5ub2RlIC50b2dnbGVCdG46aG92ZXIge1xuICBjb2xvcjogcmdiYSg2OCwgMTU3LCA2OCwgMC44KTtcbn1cblxuLm9jLWV4cG9ydC1idG4ge1xuICBkaXNwbGF5OiBpbmxpbmUtYmxvY2s7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgcmlnaHQ6IDVweDtcbiAgdG9wOiA1cHg7XG4gIHBhZGRpbmc6IDZweCAxMnB4O1xuICBtYXJnaW4tYm90dG9tOiAwO1xuICBmb250LXNpemU6IDE0cHg7XG4gIGZvbnQtd2VpZ2h0OiA0MDA7XG4gIGxpbmUtaGVpZ2h0OiAxLjQyODU3MTQzO1xuICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gIHdoaXRlLXNwYWNlOiBub3dyYXA7XG4gIHZlcnRpY2FsLWFsaWduOiBtaWRkbGU7XG4gIC1tcy10b3VjaC1hY3Rpb246IG1hbmlwdWxhdGlvbjtcbiAgdG91Y2gtYWN0aW9uOiBtYW5pcHVsYXRpb247XG4gIGN1cnNvcjogcG9pbnRlcjtcbiAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcbiAgLW1vei11c2VyLXNlbGVjdDogbm9uZTtcbiAgLW1zLXVzZXItc2VsZWN0OiBub25lO1xuICB1c2VyLXNlbGVjdDogbm9uZTtcbiAgY29sb3I6ICNmZmY7XG4gIGJhY2tncm91bmQtY29sb3I6ICM1Y2I4NWM7XG4gIGJvcmRlcjogMXB4IHNvbGlkIHRyYW5zcGFyZW50O1xuICBib3JkZXItY29sb3I6ICM0Y2FlNGM7XG4gIGJvcmRlci1yYWRpdXM6IDRweDtcbn1cblxuLm9jLWV4cG9ydC1idG46aG92ZXIsLm9jLWV4cG9ydC1idG46Zm9jdXMsLm9jLWV4cG9ydC1idG46YWN0aXZlICB7XG4gIGJhY2tncm91bmQtY29sb3I6ICM0NDlkNDQ7XG4gIGJvcmRlci1jb2xvcjogIzM0N2EzNDtcbn1cblxub3JnLWNoYXJ0fi5tYXNrIHtcbiAgcG9zaXRpb246IGFic29sdXRlO1xuICB0b3A6IDA7XG4gIHJpZ2h0OiAwO1xuICBib3R0b206IDA7XG4gIGxlZnQ6IDA7XG4gIHotaW5kZXg6IDk5OTtcbiAgdGV4dC1hbGlnbjogY2VudGVyO1xuICBiYWNrZ3JvdW5kLWNvbG9yOiByZ2JhKDAsMCwwLDAuMyk7XG59XG5cbm9yZy1jaGFydH4ubWFzayAuc3Bpbm5lciB7XG4gIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgdG9wOiBjYWxjKDUwJSAtIDU0cHgpO1xuICBsZWZ0OiBjYWxjKDUwJSAtIDU0cHgpO1xuICBjb2xvcjogcmdiYSgyNTUsMjU1LDI1NSwwLjgpO1xuICBmb250LXNpemU6IDEwOHB4O1xufVxuXG5vcmctY2hhcnQgLm5vZGUge1xuICAtd2Via2l0LXRyYW5zaXRpb246IGFsbCAwLjNzO1xuICB0cmFuc2l0aW9uOiBhbGwgMC4zcztcbiAgdG9wOiAwO1xuICBsZWZ0OiAwO1xufVxuXG5vcmctY2hhcnQgLnNsaWRlLWRvd24ge1xuICBvcGFjaXR5OiAwO1xuICB0b3A6IDQwcHg7XG59XG5cbm9yZy1jaGFydC5sMnIgLm5vZGUuc2xpZGUtZG93biwgb3JnLWNoYXJ0LnIybCAubm9kZS5zbGlkZS1kb3duIHtcbiAgdG9wOiAxMzBweDtcbn1cblxub3JnLWNoYXJ0IC5zbGlkZS11cCB7XG4gIG9wYWNpdHk6IDA7XG4gIHRvcDogLTQwcHg7XG59XG5cbm9yZy1jaGFydC5sMnIgLm5vZGUuc2xpZGUtdXAsIG9yZy1jaGFydC5yMmwgLm5vZGUuc2xpZGUtdXAge1xuICB0b3A6IC0xMzBweDtcbn1cblxub3JnLWNoYXJ0IC5zbGlkZS1yaWdodCB7XG4gIG9wYWNpdHk6IDA7XG4gIGxlZnQ6IDEzMHB4O1xufVxuXG5vcmctY2hhcnQubDJyIC5ub2RlLnNsaWRlLXJpZ2h0LCBvcmctY2hhcnQucjJsIC5ub2RlLnNsaWRlLXJpZ2h0IHtcbiAgbGVmdDogNDBweDtcbn1cblxub3JnLWNoYXJ0IC5zbGlkZS1sZWZ0IHtcbiAgb3BhY2l0eTogMDtcbiAgbGVmdDogLTEzMHB4O1xufVxuXG5vcmctY2hhcnQubDJyIC5ub2RlLnNsaWRlLWxlZnQsIG9yZy1jaGFydC5yMmwgLm5vZGUuc2xpZGUtbGVmdCB7XG4gIGxlZnQ6IC00MHB4O1xufSJdfQ== */
3 |
--------------------------------------------------------------------------------
/demo/css/style.css:
--------------------------------------------------------------------------------
1 | #wrapper {
2 | width: 860px;
3 | margin: 0 auto;
4 | font-family: "Arial";
5 | }
6 |
7 | #wrapper li {
8 | margin-top: 20px;
9 | }
10 |
11 | #wrapper a {
12 | font-size: 24px;
13 | }
14 |
15 | #wrapper span {
16 | font-size: 24px;
17 | }
--------------------------------------------------------------------------------
/demo/direction/b2t.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer' }
14 | ]
15 | },
16 | { 'name': 'Hong Miao', 'title': 'department manager' },
17 | { 'name': 'Chun Miao', 'title': 'department manager' }
18 | ]
19 | },
20 | orgchart = new OrgChart({
21 | 'data' : datascource,
22 | 'nodeContent': 'title',
23 | 'direction': 'b2t'
24 | });
25 |
26 | document.querySelector('#chart-container').appendChild(orgchart);
27 |
28 | });
--------------------------------------------------------------------------------
/demo/direction/bottom2top.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/demo/direction/l2r.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer' }
14 | ]
15 | },
16 | { 'name': 'Hong Miao', 'title': 'department manager' },
17 | { 'name': 'Chun Miao', 'title': 'department manager' }
18 | ]
19 | },
20 | orgchart = new OrgChart({
21 | 'data' : datascource,
22 | 'nodeContent': 'title',
23 | 'direction': 'l2r'
24 | });
25 |
26 | document.querySelector('#chart-container').appendChild(orgchart);
27 |
28 | });
--------------------------------------------------------------------------------
/demo/direction/left2right.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/demo/direction/r2l.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer' }
14 | ]
15 | },
16 | { 'name': 'Hong Miao', 'title': 'department manager' },
17 | { 'name': 'Chun Miao', 'title': 'department manager' }
18 | ]
19 | },
20 | orgchart = new OrgChart({
21 | 'data' : datascource,
22 | 'nodeContent': 'title',
23 | 'direction': 'r2l'
24 | });
25 |
26 | document.querySelector('#chart-container').appendChild(orgchart);
27 |
28 | });
--------------------------------------------------------------------------------
/demo/direction/right2left.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/demo/drag-drop/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/drag-drop/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager',
10 | 'children': [{ 'name': 'Li Xin', 'title': 'senior engineer' }]
11 | },
12 | { 'name': 'Su Miao', 'title': 'department manager',
13 | 'children': [
14 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
15 | { 'name': 'Hei Hei', 'title': 'senior engineer',
16 | 'children': [
17 | { 'name': 'Pang Pang', 'title': 'engineer' },
18 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
19 | ]
20 | }
21 | ]
22 | },
23 | { 'name': 'Hong Miao', 'title': 'department manager' },
24 | { 'name': 'Chun Miao', 'title': 'department manager' }
25 | ]
26 | },
27 | orgchart = new OrgChart({
28 | 'data' : datascource,
29 | 'nodeContent': 'title',
30 | 'draggable': true,
31 | 'dropCriteria': function(draggedNode, dragZone, dropZone) {
32 | if(draggedNode.querySelector(':scope > .content').textContent.includes('manager') &&
33 | dropZone.querySelector(':scope > .content').textContent.includes('engineer')) {
34 | return false;
35 | }
36 | return true;
37 | }
38 | });
39 | document.querySelector('#chart-container').appendChild(orgchart);
40 |
41 | orgchart.addEventListener('nodedropped.orgchart', function(event) {
42 | console.log('draggedNode:' + event.detail.draggedNode.querySelector(':scope > .title').textContent
43 | + ', dragZone:' + event.detail.dragZone.querySelector(':scope > .title').textContent
44 | + ', dropZone:' + event.detail.dropZone.querySelector(':scope > .title').textContent
45 | );
46 | });
47 |
48 | });
--------------------------------------------------------------------------------
/demo/drag-drop/style.css:
--------------------------------------------------------------------------------
1 | #chart-container {
2 | height: 600px;
3 | border: 2px solid #aaa;
4 | }
5 |
6 | .orgchart {
7 | background: #fff;
8 | }
--------------------------------------------------------------------------------
/demo/edit-orgchart/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/demo/edit-orgchart/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | function closest(el, fn) {
4 | return el && ((fn(el) && el !== document.querySelector('org-chart')) ? el : closest(el.parentNode, fn));
5 | }
6 |
7 | function addClass(elements, classNames) {
8 | elements.forEach((el) => {
9 | if (classNames.includes(' ')) {
10 | classNames.split(' ').forEach((className) => el.classList.add(className));
11 | } else {
12 | el.classList.add(classNames);
13 | }
14 | });
15 | }
16 |
17 | function removeClass(elements, classNames) {
18 | elements.forEach((el) => {
19 | if (classNames.includes(' ')) {
20 | classNames.split(' ').forEach((className) => el.classList.remove(className));
21 | } else {
22 | el.classList.remove(classNames);
23 | }
24 | });
25 | }
26 |
27 | function bindEventHandler(selector, type, fn, parentSelector) {
28 | if (parentSelector) {
29 | document.querySelector(parentSelector).addEventListener(type, function (event) {
30 | if ((event.target.classList && event.target.classList.contains(selector.slice(1))) ||
31 | closest(event.target, el => el.classList && el.classList.contains(selector.slice(1)))) {
32 | fn(event);
33 | }
34 | });
35 | } else {
36 | document.querySelectorAll(selector).forEach(element => {
37 | element.addEventListener(type, fn);
38 | });
39 | }
40 | }
41 |
42 | function clickNode(event) {
43 | let sNode = closest(event.target, el => el.classList && el.classList.contains('node')),
44 | sNodeInput = document.getElementById('selected-node');
45 |
46 | sNodeInput.value = sNode.querySelector('.title').textContent;
47 | sNodeInput.dataset.node = sNode.id;
48 | }
49 |
50 | function clickChart(event) {
51 | if (!closest(event.target, el => el.classList && el.classList.contains('node'))) {
52 | document.getElementById('selected-node').textContent = '';
53 | }
54 | }
55 |
56 | function toggleViewState() {
57 | let chart = document.querySelector('org-chart');
58 | chart.classList.toggle('view-state', this.value !== 'view');
59 | document.getElementById('edit-panel').classList.toggle('view-state', this.value === 'view');
60 | if (this.value === 'edit') {
61 | removeClass(Array.from(chart.querySelectorAll('tr')), 'hidden');
62 | removeClass(Array.from(chart.querySelectorAll('td')), 'hidden');
63 | removeClass(Array.from(chart.querySelectorAll('.node')), 'slide-up slide-down slide-right slide-left');
64 | } else {
65 | document.getElementById('btn-reset').click();
66 | }
67 | }
68 |
69 | function toggleNodeType() {
70 | if (this.value === 'parent') {
71 | document.getElementById('edit-panel').classList.add('edit-parent-node');
72 | Array.from(document.getElementById('new-nodelist').children)
73 | .slice(1).forEach(newNode => newNode.remove());
74 | } else {
75 | document.getElementById('edit-panel').classList.remove('edit-parent-node');
76 | }
77 | }
78 |
79 | function addInputs() {
80 | let newNode = document.createElement('li');
81 |
82 | newNode.innerHTML = ` `;
83 | document.getElementById('new-nodelist').appendChild(newNode);
84 | }
85 |
86 | function removeInputs() {
87 | let inputs = Array.from(document.getElementById('new-nodelist').children);
88 |
89 | if (inputs.length > 1) {
90 | inputs.pop().remove();
91 | }
92 | }
93 |
94 | function addNodes(orgchart) {
95 | let nodeVals = [];
96 |
97 | Array.from(document.getElementById('new-nodelist').querySelectorAll('.new-node'))
98 | .forEach(item => {
99 | let validVal = item.value.trim();
100 |
101 | if (validVal) {
102 | nodeVals.push(validVal);
103 | }
104 | });
105 | let selectedNode = document.getElementById(document.getElementById('selected-node').dataset.node);
106 |
107 | if (!nodeVals.length) {
108 | alert('Please input value for new node');
109 | return;
110 | }
111 | let nodeType = document.querySelector('input[name="node-type"]:checked');
112 |
113 | if (!nodeType) {
114 | alert('Please select a node type');
115 | return;
116 | }
117 | if (nodeType.value !== 'parent' && !document.querySelector('.orgchart')) {
118 | alert('Please creat the root node firstly when you want to build up the orgchart from the scratch');
119 | return;
120 | }
121 | if (nodeType.value !== 'parent' && !selectedNode) {
122 | alert('Please select one node in orgchart');
123 | return;
124 | }
125 |
126 | if (nodeType.value === 'parent') {
127 | if (!document.querySelector('#chart-container').children.length) {// if the original chart has been deleted
128 | orgchart = new OrgChart({
129 | 'data' : { 'name': nodeVals[0] },
130 | 'exportButton': true,
131 | 'exportFilename': 'SportsChart',
132 | 'parentNodeSymbol': 'fa-th-large',
133 | 'createNode': function(node, data) {
134 | node.id = getId();
135 | }
136 | });
137 | orgchart.chart.classList.add('view-state');
138 | } else {
139 | orgchart.addParent(orgchart.querySelector('.node'), { 'name': nodeVals[0], 'Id': getId() });
140 | }
141 | } else if (nodeType.value === 'siblings') {
142 | orgchart.addSiblings(selectedNode, {
143 | 'siblings': nodeVals.map(item => {
144 | return { 'name': item, 'relationship': '110', 'Id': getId() };
145 | })
146 | });
147 | } else {
148 | let hasChild = selectedNode.parentNode.colSpan > 1;
149 |
150 | if (!hasChild) {
151 | let rel = nodeVals.length > 1 ? '110' : '100';
152 |
153 | orgchart.addChildren(selectedNode, {
154 | 'children': nodeVals.map(item => {
155 | return { 'name': item, 'relationship': rel, 'Id': getId() };
156 | })
157 | });
158 | } else {
159 | orgchart.addSiblings(closest(selectedNode, el => el.nodeName === 'TABLE').querySelector('.nodes').querySelector('.node'),
160 | { 'siblings': nodeVals.map(function(item) { return { 'name': item, 'relationship': '110', 'Id': getId() }; })
161 | });
162 | }
163 | }
164 | }
165 |
166 | function deleteNodes(orgchart) {
167 | let sNodeInput = document.getElementById('selected-node'),
168 | sNode = document.getElementById(sNodeInput.dataset.node);
169 |
170 | if (!sNode) {
171 | alert('Please select one node in orgchart');
172 | return;
173 | } else if (sNode === document.querySelector('.orgchart').querySelector('.node')) {
174 | if (!window.confirm('Are you sure you want to delete the whole chart?')) {
175 | return;
176 | }
177 | }
178 | orgchart.removeNodes(sNode);
179 | sNodeInput.value = '';
180 | sNodeInput.dataset.node = '';
181 | }
182 |
183 | function resetPanel() {
184 | let fNode = document.querySelector('.orgchart').querySelector('.focused');
185 |
186 | if (fNode) {
187 | fNode.classList.remove('focused');
188 | }
189 | document.getElementById('selected-node').value = '';
190 | document.getElementById('new-nodelist').querySelector('input').value = '';
191 | Array.from(document.getElementById('new-nodelist').children).slice(1).forEach(item => item.remove());
192 | document.getElementById('node-type-panel').querySelectorAll('input').forEach(item => {
193 | item.checked = false;
194 | });
195 | }
196 |
197 | function getId() {
198 | return (new Date().getTime()) * 1000 + Math.floor(Math.random() * 1001);
199 | }
200 |
201 | document.addEventListener('DOMContentLoaded', function () {
202 | let orgchart,
203 | datascource = {
204 | 'name': 'Ball game',
205 | 'children': [
206 | { 'name': 'Football' },
207 | { 'name': 'Basketball' },
208 | { 'name': 'Volleyball' }
209 | ]
210 | };
211 |
212 | orgchart = new OrgChart({
213 | 'data' : datascource,
214 | 'exportButton': true,
215 | 'exportFilename': 'SportsChart',
216 | 'parentNodeSymbol': 'fa-th-large',
217 | 'createNode': function(node, data) {
218 | node.id = getId();
219 | }
220 | });
221 | document.querySelector('#chart-container').appendChild(orgchart);
222 |
223 | bindEventHandler('.node', 'click', clickNode, '#chart-container');
224 | bindEventHandler('org-chart', 'click', clickChart, '#chart-container');
225 | bindEventHandler('input[name="chart-state"]', 'click', toggleViewState);
226 | bindEventHandler('input[name="node-type"]', 'click', toggleNodeType);
227 | document.getElementById('btn-add-input').addEventListener('click', addInputs);
228 | document.getElementById('btn-remove-input').addEventListener('click', removeInputs);
229 | document.getElementById('btn-add-nodes').addEventListener('click', () => addNodes(orgchart));
230 | document.getElementById('btn-delete-nodes').addEventListener('click', () => deleteNodes(orgchart));
231 | document.getElementById('btn-reset').addEventListener('click', resetPanel);
232 |
233 | });
--------------------------------------------------------------------------------
/demo/edit-orgchart/style.css:
--------------------------------------------------------------------------------
1 | #chart-container {
2 | background-color: #eee;
3 | height: 300px;
4 | }
5 | org-chart {
6 | background: #fff;
7 | }
8 |
9 | org-chart.view-state .edge {
10 | display: none;
11 | }
12 |
13 | org-chart .node {
14 | width: 150px;
15 | }
16 |
17 | org-chart .node .title .symbol {
18 | margin-top: 1px;
19 | }
20 |
21 | #edit-panel {
22 | position: relative;
23 | left: 10px;
24 | width: calc(100% - 40px);
25 | border-radius: 4px;
26 | float: left;
27 | margin-top: 10px;
28 | padding: 10px;
29 | color: #fff;
30 | background-color: #449d44;
31 | }
32 |
33 | #edit-panel .btn-inputs {
34 | font-size: 24px;
35 | }
36 |
37 | #edit-panel.view-state>:not(#chart-state-panel) {
38 | display: none;
39 | }
40 |
41 | #edit-panel label {
42 | font-weight: bold;
43 | }
44 |
45 | #edit-panel.edit-parent-node .selected-node-group{
46 | display: none;
47 | }
48 |
49 | #chart-state-panel, #selected-node, #btn-remove-input {
50 | margin-right: 20px;
51 | }
52 |
53 | #edit-panel button {
54 | color: #333;
55 | background-color: #fff;
56 | display: inline-block;
57 | padding: 6px 12px;
58 | margin-bottom: 0;
59 | line-height: 1.42857143;
60 | text-align: center;
61 | white-space: nowrap;
62 | vertical-align: middle;
63 | -ms-touch-action: manipulation;
64 | touch-action: manipulation;
65 | cursor: pointer;
66 | -webkit-user-select: none;
67 | -moz-user-select: none;
68 | -ms-user-select: none;
69 | user-select: none;
70 | background-image: none;
71 | border: 1px solid #ccc;
72 | border-radius: 4px;
73 | }
74 |
75 | #edit-panel.edit-parent-node button:not(#btn-add-nodes) {
76 | display: none;
77 | }
78 |
79 | #edit-panel button:hover,.edit-panel button:focus,.edit-panel button:active {
80 | border-color: #eea236;
81 | box-shadow: 0 0 10px #eea236;
82 | }
83 |
84 | #new-nodelist {
85 | display: inline-block;
86 | list-style:none;
87 | margin-top: -2px;
88 | padding: 0;
89 | vertical-align: text-top;
90 | }
91 |
92 | #new-nodelist>* {
93 | padding-bottom: 4px;
94 | }
95 |
96 | .btn-inputs {
97 | vertical-align: sub;
98 | }
99 |
100 | #edit-panel.edit-parent-node .btn-inputs {
101 | display: none;
102 | }
103 |
104 | .btn-inputs:hover {
105 | text-shadow: 0 0 4px #fff;
106 | }
107 |
108 | .radio-panel input[type='radio'] {
109 | display: inline-block;
110 | height: 24px;
111 | width: 24px;
112 | vertical-align: top;
113 | }
114 |
115 | #edit-panel.view-state .radio-panel input[type='radio']+label {
116 | vertical-align: -webkit-baseline-middle;
117 | }
118 |
119 | #btn-add-nodes {
120 | margin-left: 20px;
121 | }
--------------------------------------------------------------------------------
/demo/export-orgchart/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/demo/export-orgchart/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js'
2 |
3 | function clickExportButton() {
4 | let chartContainer = document.querySelector('#chart-container'),
5 | mask = chartContainer.querySelector(':scope > .mask'),
6 | sourceChart = chartContainer.querySelector('org-chart:not(.hidden)'),
7 | flag = sourceChart.classList.contains('l2r') || sourceChart.classList.contains('r2l');
8 |
9 | if (!mask) {
10 | mask = document.createElement('div');
11 | mask.setAttribute('class', 'mask');
12 | mask.innerHTML = ` `;
13 | chartContainer.appendChild(mask);
14 | } else {
15 | mask.classList.remove('hidden');
16 | }
17 | chartContainer.classList.add('canvasContainer');
18 | window.html2canvas(sourceChart, {
19 | 'width': flag ? sourceChart.clientHeight : sourceChart.clientWidth,
20 | 'height': flag ? sourceChart.clientWidth : sourceChart.clientHeight,
21 | 'onclone': function (cloneDoc) {
22 | let canvasContainer = cloneDoc.querySelector('.canvasContainer');
23 |
24 | canvasContainer.style.overflow = 'visible';
25 | canvasContainer.querySelector('org-chart:not(.hidden)').transform = '';
26 | }
27 | })
28 | .then((canvas) => {
29 | let downloadBtn = chartContainer.querySelector('.oc-download-btn');
30 |
31 | chartContainer.querySelector('.mask').classList.add('hidden');
32 | downloadBtn.setAttribute('href', canvas.toDataURL());
33 | downloadBtn.click();
34 | })
35 | .catch((err) => {
36 | console.error('Failed to export the curent orgchart!', err);
37 | })
38 | .finally(() => {
39 | chartContainer.classList.remove('canvasContainer');
40 | });
41 | }
42 |
43 | document.addEventListener('DOMContentLoaded', function () {
44 |
45 | let datascource = {
46 | 'name': 'Lao Lao',
47 | 'title': 'general manager',
48 | 'children': [
49 | { 'name': 'Bo Miao', 'title': 'department manager' },
50 | { 'name': 'Su Miao', 'title': 'department manager',
51 | 'children': [
52 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
53 | { 'name': 'Hei Hei', 'title': 'senior engineer',
54 | 'children': [
55 | { 'name': 'Pang Pang', 'title': 'engineer' },
56 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
57 | ]
58 | }
59 | ]
60 | },
61 | { 'name': 'Yu Jie', 'title': 'department manager' },
62 | { 'name': 'Yu Li', 'title': 'department manager' },
63 | { 'name': 'Hong Miao', 'title': 'department manager' },
64 | { 'name': 'Yu Wei', 'title': 'department manager' },
65 | { 'name': 'Chun Miao', 'title': 'department manager' },
66 | { 'name': 'Yu Tie', 'title': 'department manager' }
67 | ]
68 | },
69 | orgchart = new OrgChart({
70 | 'data' : datascource,
71 | 'depth': 2,
72 | 'nodeContent': 'title'
73 | }),
74 | chartContainer = document.querySelector('#chart-container');
75 |
76 | chartContainer.appendChild(orgchart);
77 | // append the export button to the chart-container
78 | let exportBtn = document.createElement('button'),
79 | downloadBtn = document.createElement('a');
80 |
81 | exportBtn.setAttribute('class', 'oc-export-btn');
82 | exportBtn.innerHTML = 'Export';
83 | exportBtn.addEventListener('click', clickExportButton);
84 | downloadBtn.setAttribute('class', 'oc-download-btn');
85 | downloadBtn.setAttribute('download', 'MyOrgChart.png');
86 | chartContainer.appendChild(exportBtn);
87 | chartContainer.appendChild(downloadBtn);
88 |
89 | });
--------------------------------------------------------------------------------
/demo/export-orgchart/style.css:
--------------------------------------------------------------------------------
1 | #chart-container {
2 | background-color: #eee;
3 | }
4 | .orgchart {
5 | background: #fff;
6 | }
--------------------------------------------------------------------------------
/demo/get-hierarchy/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Lao Lao
19 |
20 | Bo Miao
21 | Su Miao
22 |
23 | Tie Hua
24 | Hei Hei
25 |
26 | Pang Pang
27 | Xiang Xiang
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Export Hierarchy
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/demo/get-hierarchy/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let orgchart = new OrgChart({
6 | 'data' : '#ul-data'
7 | });
8 |
9 | document.querySelector('#chart-container').appendChild(orgchart);
10 |
11 | document.querySelector('#btn-export-hier').addEventListener('click', () => {
12 | if (!document.querySelector('pre')) {
13 | let pre = document.createElement('pre'),
14 | hierarchy = orgchart.getHierarchy();
15 |
16 | pre.innerHTML = JSON.stringify(hierarchy, null, 2);
17 | document.querySelector('body').insertBefore(pre, document.querySelector('.home-link'));
18 | }
19 | });
20 |
21 | });
22 |
--------------------------------------------------------------------------------
/demo/get-hierarchy/style.css:
--------------------------------------------------------------------------------
1 |
2 | #chart-container {
3 | display: inline-block;
4 | width: 50%;
5 | margin-left: 10px;
6 | }
7 |
8 | pre {
9 | display: inline-block;
10 | vertical-align: top;
11 | font-size: 16px;
12 | font-weight: bold;
13 | margin-left: 20px;
14 | }
15 |
16 | #btn-export-hier {
17 | display: inline-block;
18 | position: relative;
19 | top: -200px;
20 | left: 10px;
21 | padding: 6px 12px;
22 | margin-bottom: 0;
23 | font-size: 14px;
24 | font-weight: bold;
25 | line-height: 1.42857143;
26 | text-align: center;
27 | white-space: nowrap;
28 | vertical-align: middle;
29 | -ms-touch-action: manipulation;
30 | touch-action: manipulation;
31 | cursor: pointer;
32 | -webkit-user-select: none;
33 | -moz-user-select: none;
34 | -ms-user-select: none;
35 | user-select: none;
36 | color: #fff;
37 | background-color: #5cb85c;
38 | border: 1px solid transparent;
39 | border-color: #4cae4c;
40 | border-radius: 4px;
41 | }
--------------------------------------------------------------------------------
/demo/img/avatar/1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/1.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/10.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/10.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/11.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/11.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/12.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/12.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/13.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/13.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/2.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/3.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/4.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/5.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/6.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/7.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/8.jpg
--------------------------------------------------------------------------------
/demo/img/avatar/9.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/avatar/9.jpg
--------------------------------------------------------------------------------
/demo/img/logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/logo.jpg
--------------------------------------------------------------------------------
/demo/img/orgchart-heading.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dabeng/OrgChart-Webcomponents/322e55f7a5fd8dcb2f162c6f9f09bd1f7656f786/demo/img/orgchart-heading.png
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Plugin
9 |
10 |
11 |
12 |
13 |
14 |
15 |
42 |
43 |
--------------------------------------------------------------------------------
/demo/integrate-map/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/demo/integrate-map/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let map = new ol.Map({
6 | layers: [
7 | new ol.layer.Tile({
8 | source: new ol.source.Stamen({
9 | layer: 'watercolor'
10 | }),
11 | preload: 4
12 | }),
13 | new ol.layer.Tile({
14 | source: new ol.source.Stamen({
15 | layer: 'terrain-labels'
16 | }),
17 | preload: 1
18 | })
19 | ],
20 | target: 'pageBody',
21 | view: new ol.View({
22 | center: ol.proj.transform([-87.6297980, 41.8781140], 'EPSG:4326', 'EPSG:3857'),
23 | zoom: 10
24 | })
25 | });
26 |
27 | document.body.insertBefore(document.querySelector('#chart-container'), map.getViewport());
28 |
29 | let datascource = {
30 | 'name': 'Lao Lao',
31 | 'title': 'President Office',
32 | 'position': [-87.6297980, 41.8781140],
33 | 'children': [
34 | { 'name': 'Bo Miao', 'title': 'Administration Dept.', 'position': [-83.0457540, 42.3314270]},
35 | { 'name': 'Su Miao', 'title': 'R & D Dept.', 'position': [-81.6943610, 41.4993200]},
36 | { 'name': 'Yu Jie', 'title': 'Product Dept.', 'position': [-71.0588800, 42.3600820]},
37 | { 'name': 'Yu Li', 'title': 'Legal Dept.', 'position': [-74.0059410, 40.7127840]},
38 | { 'name': 'Hong Miao', 'title': 'Finance Dept.', 'position': [-80.8431270, 35.2270870]},
39 | { 'name': 'Yu Wei', 'title': 'Security Dept.', 'position': [-81.6556510, 30.3321840]},
40 | { 'name': 'Chun Miao', 'title': 'HR Dept. ', 'position': [-81.3792360, 28.5383350]},
41 | { 'name': 'Yu Tie', 'title': 'Marketing Dept.', 'position': [-80.1917900, 25.7616800] }
42 | ]
43 | },
44 | orgchart = new OrgChart({
45 | 'data' : datascource,
46 | 'nodeContent': 'title',
47 | 'createNode': function(node, data) {
48 | node.addEventListener('click', () => {
49 | let view = map.getView(),
50 | duration = 2000,
51 | start = +new Date(),
52 | pan = ol.animation.pan({
53 | 'duration': duration,
54 | 'source': view.getCenter(),
55 | 'start': start
56 | }),
57 | bounce = ol.animation.bounce({
58 | 'duration': duration,
59 | 'resolution': 4 * view.getResolution(),
60 | 'start': start
61 | });
62 |
63 | map.beforeRender(pan, bounce);
64 | view.setCenter(ol.proj.transform(data.position, 'EPSG:4326', 'EPSG:3857'));
65 | });
66 | }
67 | });
68 |
69 | document.querySelector('#chart-container').appendChild(orgchart);
70 |
71 | });
--------------------------------------------------------------------------------
/demo/integrate-map/style.css:
--------------------------------------------------------------------------------
1 | #chart-container {
2 | position: absolute;
3 | top: 10px;
4 | left:40px;
5 | height: auto;
6 | max-height: 330px;
7 | width: calc(100% - 80px);
8 | z-index: 1;
9 | border-color: rgba(217, 83, 79, 0.9);
10 | }
11 |
12 | org-chart {
13 | background: rgba(255,255,255,0.75);
14 | }
--------------------------------------------------------------------------------
/demo/local-datasource/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/demo/local-datasource/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 | let datascource = {
5 | 'name': 'Lao Lao',
6 | 'title': 'general manager',
7 | 'children': [
8 | { 'name': 'Bo Miao', 'title': 'department manager' },
9 | { 'name': 'Su Miao', 'title': 'department manager',
10 | 'children': [
11 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
12 | { 'name': 'Hei Hei', 'title': 'senior engineer',
13 | 'children': [
14 | { 'name': 'Pang Pang', 'title': 'engineer' },
15 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
16 | ]
17 | }
18 | ]
19 | },
20 | { 'name': 'Yu Jie', 'title': 'department manager' },
21 | { 'name': 'Yu Li', 'title': 'department manager' },
22 | { 'name': 'Hong Miao', 'title': 'department manager' },
23 | { 'name': 'Yu Wei', 'title': 'department manager' },
24 | { 'name': 'Chun Miao', 'title': 'department manager' },
25 | { 'name': 'Yu Tie', 'title': 'department manager' }
26 | ]
27 | },
28 | orgchart = new OrgChart({
29 | 'data' : datascource,
30 | 'depth': 2,
31 | 'nodeContent': 'title'
32 | });
33 |
34 | document.querySelector('#chart-container').appendChild(orgchart);
35 |
36 | });
--------------------------------------------------------------------------------
/demo/multiple-layers/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/demo/multiple-layers/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | Mock.mock('/orgchart/root-node', {
4 | 'className': 'root-node',
5 | 'name': 'Lao Lao',
6 | 'dept': 'president office',
7 | 'children': [
8 | { 'name': 'Bo Miao', 'dept': 'product dept' },
9 | { 'className': 'drill-down asso-rd', 'name': 'Su Miao', 'dept': 'R&D dept' },
10 | { 'name': 'Hong Miao', 'dept': 'finance dept' },
11 | { 'name': 'Chun Miao', 'dept': 'HR dept' }
12 | ]
13 | });
14 |
15 | Mock.mock('/orgchart/asso-rd', {
16 | 'className': 'asso-rd drill-up',
17 | 'name': 'Su Miao',
18 | 'dept': 'R&D dept',
19 | 'children': [
20 | { 'name': 'Tie Hua', 'dept': 'backend group' },
21 | { 'className': 'drill-down asso-frontend', 'name': 'Hei Hei', 'dept': 'frontend group' }
22 | ]
23 | });
24 |
25 | Mock.mock('/orgchart/asso-frontend', {
26 | 'className': 'asso-frontend drill-up',
27 | 'name': 'Hei Hei',
28 | 'dept': 'frontend group',
29 | 'children': [
30 | { 'name': 'Pang Pang', 'dept': 'frontend group' },
31 | { 'name': 'Xiang Xiang', 'dept': 'frontend group',
32 | 'children': [
33 | { 'name': 'Xiao Xiao', 'dept': 'frontend group' },
34 | { 'name': 'Dan Dan', 'dept': 'frontend group' },
35 | { 'name': 'Zai Zai', 'dept': 'frontend group' }
36 | ]
37 | }
38 | ]
39 | });
40 |
41 | Mock.setup({ timeout: 1000 });
42 |
43 | function closest(el, fn) {
44 | return el && (fn(el) && el.id !== 'chart-container' ? el : closest(el.parentNode, fn));
45 | }
46 |
47 | function initOrgchart(rootClass) {
48 | let orgchart = new OrgChart({
49 | 'chartClass': rootClass,
50 | 'data' : '/orgchart/' + rootClass,
51 | 'nodeContent': 'dept',
52 | 'createNode': function(node, data) {
53 | let chartContainer = document.querySelector('#chart-container');
54 |
55 | if (node.classList.contains('drill-down')) {
56 | let drillDownIcon = document.createElement('i'),
57 | assoClass = data.className.match(/asso-\w+/)[0];
58 |
59 | drillDownIcon.setAttribute('class', 'fa fa-arrow-circle-down drill-icon');
60 | drillDownIcon.addEventListener('click', function() {
61 | chartContainer.querySelector('org-chart:not(.hidden)').classList.add('hidden');
62 | let assoChart = chartContainer.querySelector('org-chart.' + assoClass);
63 |
64 | if (!assoChart) {
65 | initOrgchart(assoClass);
66 | } else {
67 | assoChart.classList.remove('hidden');
68 | }
69 | });
70 | node.appendChild(drillDownIcon);
71 | } else if (node.classList.contains('drill-up')) {
72 | let drillUpIcon = document.createElement('i'),
73 | assoClass = data.className.match(/asso-\w+/)[0];
74 |
75 | drillUpIcon.setAttribute('class', 'fa fa-arrow-circle-up drill-icon');
76 | drillUpIcon.addEventListener('click', function() {
77 | chartContainer.querySelector('org-chart:not(.hidden)').classList.add('hidden');
78 | closest(chartContainer.querySelector('.drill-down.' + assoClass), (el) => {
79 | return el.nodeName === 'ORG-CHART';
80 | }).classList.remove('hidden');
81 | });
82 | node.appendChild(drillUpIcon);
83 | }
84 | }
85 | });
86 | document.querySelector('#chart-container').appendChild(orgchart);
87 | }
88 |
89 | document.addEventListener('DOMContentLoaded', function () {
90 |
91 | initOrgchart('root-node');
92 |
93 | });
--------------------------------------------------------------------------------
/demo/multiple-layers/style.css:
--------------------------------------------------------------------------------
1 | .hidden {
2 | display: none;
3 | }
4 |
5 | org-chart .drill-icon {
6 | transition: opacity .5s;
7 | opacity: 0;
8 | right: -10px;
9 | top: -10px;
10 | z-index: 2;
11 | color: rgba(68, 157, 68, 0.5);
12 | font-size: 24px;
13 | position: absolute;
14 | }
15 |
16 | org-chart .drill-icon:hover {
17 | color: #449d44;
18 | }
19 |
20 | org-chart .node:hover .drill-icon {
21 | opacity: 1;
22 | }
--------------------------------------------------------------------------------
/demo/ondemand-loading-data/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/ondemand-loading-data/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | Mock.mock('/orgchart/children/3', { 'children': [
6 | { 'id': '4', 'name': 'Pang Pang', 'title': 'engineer', 'relationship': '110' },
7 | { 'id': '5', 'name': 'Xiang Xiang', 'title': 'UE engineer', 'relationship': '110'}
8 | ]});
9 |
10 | Mock.mock('/orgchart/parent/1', { 'id': '6','name': 'Lao Lao', 'title': 'general manager', 'relationship': '001' });
11 |
12 | Mock.mock('/orgchart/siblings/1', { 'siblings': [
13 | { 'id': '7','name': 'Bo Miao', 'title': 'department engineer', 'relationship': '110' },
14 | { 'id': '8', 'name': 'Yu Jie', 'title': 'department engineer', 'relationship': '110' },
15 | { 'id': '9', 'name': 'Yu Li', 'title': 'department engineer', 'relationship': '110' },
16 | { 'id': '10', 'name': 'Hong Miao', 'title': 'department engineer', 'relationship': '110' },
17 | { 'id': '11', 'name': 'Yu Wei', 'title': 'department engineer', 'relationship': '110' },
18 | { 'id': '12', 'name': 'Chun Miao', 'title': 'department engineer', 'relationship': '110' },
19 | { 'id': '13', 'name': 'Yu Tie', 'title': 'department engineer', 'relationship': '110' }
20 | ]});
21 |
22 | Mock.mock('/orgchart/families/1', {
23 | 'id': '6',
24 | 'name': 'Lao Lao',
25 | 'title': 'general manager',
26 | 'relationship': '001',
27 | 'children': [
28 | { 'id': '7','name': 'Bo Miao', 'title': 'department engineer', 'relationship': '110' },
29 | { 'id': '8', 'name': 'Yu Jie', 'title': 'department engineer', 'relationship': '110' },
30 | { 'id': '9', 'name': 'Yu Li', 'title': 'department engineer', 'relationship': '110' },
31 | { 'id': '10', 'name': 'Hong Miao', 'title': 'department engineer', 'relationship': '110' },
32 | { 'id': '11', 'name': 'Yu Wei', 'title': 'department engineer', 'relationship': '110' },
33 | { 'id': '12', 'name': 'Chun Miao', 'title': 'department engineer', 'relationship': '110' },
34 | { 'id': '13', 'name': 'Yu Tie', 'title': 'department engineer', 'relationship': '110' }
35 | ]
36 | });
37 |
38 | Mock.setup({ timeout: 1000 });
39 |
40 | let datascource = {
41 | 'id': '1',
42 | 'name': 'Su Miao',
43 | 'title': 'department manager',
44 | 'relationship': '111',
45 | 'children': [
46 | { 'id': '2','name': 'Tie Hua', 'title': 'senior engineer', 'relationship': '110' },
47 | { 'id': '3','name': 'Hei Hei', 'title': 'senior engineer', 'relationship': '111' }
48 | ]
49 | },
50 | ajaxURLs = {
51 | 'children': '/orgchart/children/',
52 | 'parent': '/orgchart/parent/',
53 | 'siblings': function(nodeData) {
54 | return '/orgchart/siblings/' + nodeData.id;
55 | },
56 | 'families': function(nodeData) {
57 | return '/orgchart/families/' + nodeData.id;
58 | }
59 | },
60 | orgchart = new OrgChart({
61 | 'data' : datascource,
62 | 'ajaxURL': ajaxURLs,
63 | 'nodeContent': 'title',
64 | 'nodeId': 'id'
65 | });
66 |
67 | document.querySelector('#chart-container').appendChild(orgchart);
68 |
69 | });
--------------------------------------------------------------------------------
/demo/option-createNode/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/demo/option-createNode/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'id': '1',
7 | 'name': 'Lao Lao',
8 | 'title': 'general manager',
9 | 'children': [
10 | { 'id': '2', 'name': 'Bo Miao', 'title': 'department manager' },
11 | { 'id': '3', 'name': 'Su Miao', 'title': 'department manager',
12 | 'children': [
13 | { 'id': '4', 'name': 'Tie Hua', 'title': 'senior engineer' },
14 | { 'id': '5', 'name': 'Hei Hei', 'title': 'senior engineer',
15 | 'children': [
16 | { 'id': '6', 'name': 'Pang Pang', 'title': 'engineer' },
17 | { 'id': '7', 'name': 'Xiang Xiang', 'title': 'UE engineer' }
18 | ]
19 | }
20 | ]
21 | },
22 | { 'id': '8', 'name': 'Yu Jie', 'title': 'department manager' },
23 | { 'id': '9', 'name': 'Yu Li', 'title': 'department manager' },
24 | { 'id': '10', 'name': 'Hong Miao', 'title': 'department manager' },
25 | { 'id': '11', 'name': 'Yu Wei', 'title': 'department manager' },
26 | { 'id': '12', 'name': 'Chun Miao', 'title': 'department manager' },
27 | { 'id': '13', 'name': 'Yu Tie', 'title': 'department manager' }
28 | ]
29 | },
30 | orgchart = new OrgChart({
31 | 'data' : datascource,
32 | 'depth': 2,
33 | 'nodeContent': 'title',
34 | 'nodeID': 'id',
35 | 'createNode': function(node, data) {
36 | let secondMenuIcon = document.createElement('i'),
37 | secondMenu = document.createElement('div');
38 |
39 | secondMenuIcon.setAttribute('class', 'fa fa-info-circle second-menu-icon');
40 | secondMenuIcon.addEventListener('click', (event) => {
41 | event.target.nextElementSibling.classList.toggle('hidden');
42 | });
43 | secondMenu.setAttribute('class', 'second-menu hidden');
44 | secondMenu.innerHTML = ` `;
45 | node.appendChild(secondMenuIcon)
46 | node.appendChild(secondMenu);
47 | }
48 | });
49 |
50 | document.querySelector('#chart-container').appendChild(orgchart);
51 |
52 | });
53 |
--------------------------------------------------------------------------------
/demo/option-createNode/style.css:
--------------------------------------------------------------------------------
1 | .orgchart .second-menu-icon {
2 | transition: opacity .5s;
3 | opacity: 0;
4 | right: -5px;
5 | top: -5px;
6 | z-index: 2;
7 | color: rgba(68, 157, 68, 0.5);
8 | font-size: 18px;
9 | position: absolute;
10 | }
11 | .orgchart .second-menu-icon:hover {
12 | color: #449d44;
13 | }
14 | .orgchart .node:hover .second-menu-icon {
15 | opacity: 1;
16 | }
17 | .orgchart .node .second-menu {
18 | position: absolute;
19 | top: 0;
20 | right: -70px;
21 | border-radius: 35px;
22 | box-shadow: 0 0 10px 1px #999;
23 | background-color: #fff;
24 | z-index: 1;
25 | }
26 | .orgchart .node .second-menu .avatar {
27 | width: 60px;
28 | height: 60px;
29 | border-radius: 30px;
30 | float: left;
31 | margin: 5px;
32 | }
--------------------------------------------------------------------------------
/demo/pan-zoom/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/demo/pan-zoom/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer',
14 | 'children': [
15 | { 'name': 'Pang Pang', 'title': 'engineer' },
16 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
17 | ]
18 | }
19 | ]
20 | },
21 | { 'name': 'Yu Jie', 'title': 'department manager' },
22 | { 'name': 'Yu Li', 'title': 'department manager' },
23 | { 'name': 'Hong Miao', 'title': 'department manager' },
24 | { 'name': 'Yu Wei', 'title': 'department manager' },
25 | { 'name': 'Chun Miao', 'title': 'department manager' },
26 | { 'name': 'Yu Tie', 'title': 'department manager' }
27 | ]
28 | },
29 | orgchart = new OrgChart({
30 | 'data' : datascource,
31 | 'nodeContent': 'title',
32 | 'pan': true,
33 | 'zoom': true,
34 | 'chartContainer': '#chart-container'
35 | });
36 |
37 | document.querySelector('#chart-container').appendChild(orgchart);
38 |
39 | });
--------------------------------------------------------------------------------
/demo/toggle-sibs-resp/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/demo/toggle-sibs-resp/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer',
14 | 'children': [
15 | { 'name': 'Pang Pang', 'title': 'engineer' },
16 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' }
17 | ]
18 | }
19 | ]
20 | },
21 | { 'name': 'Hong Miao', 'title': 'department manager' },
22 | { 'name': 'Chun Miao', 'title': 'department manager' },
23 | ]
24 | },
25 | orgchart = new OrgChart({
26 | 'data' : datascource,
27 | 'nodeContent': 'title',
28 | 'toggleSiblingsResp': true
29 | });
30 |
31 | document.querySelector('#chart-container').appendChild(orgchart);
32 |
33 | });
--------------------------------------------------------------------------------
/demo/ul-datasource/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Lao Lao
19 |
20 | Bo Miao
21 | Su Miao
22 |
23 | Tie Hua
24 | Hei Hei
25 |
26 | Pang Pang
27 | Xiang Xiang
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/demo/ul-datasource/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let orgchart = new OrgChart({
6 | 'data' : '#ul-data'
7 | });
8 |
9 | document.querySelector('#chart-container').appendChild(orgchart);
10 |
11 | });
--------------------------------------------------------------------------------
/demo/ul-datasource/style.css:
--------------------------------------------------------------------------------
1 | #ul-data {
2 | position: relative;
3 | top: -60px;
4 | display: inline-block;
5 | margin-left: 10%;
6 | width: 30%;
7 | margin-right: 6%;
8 | }
9 | #chart-container {
10 | display: inline-block;
11 | width: 50%;
12 | }
13 | #ul-data li {
14 | font-size: 32px;
15 | }
--------------------------------------------------------------------------------
/demo/vertical-depth/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | Organization Chart Web Components
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/demo/vertical-depth/scripts.js:
--------------------------------------------------------------------------------
1 | import OrgChart from '../js/orgchart-webcomponents.min.js';
2 |
3 | document.addEventListener('DOMContentLoaded', function () {
4 |
5 | let datascource = {
6 | 'name': 'Lao Lao',
7 | 'title': 'general manager',
8 | 'children': [
9 | { 'name': 'Bo Miao', 'title': 'department manager' },
10 | { 'name': 'Su Miao', 'title': 'department manager',
11 | 'children': [
12 | { 'name': 'Tie Hua', 'title': 'senior engineer' },
13 | { 'name': 'Hei Hei', 'title': 'senior engineer',
14 | 'children': [
15 | { 'name': 'Pang Pang', 'title': 'engineer' },
16 | { 'name': 'Xiang Xiang', 'title': 'UE engineer' ,
17 | 'children': [
18 | { 'name': 'Dan Dan', 'title': 'Intern' },
19 | { 'name': 'Zai Zai', 'title': 'Intern',
20 | 'children': [
21 | { 'name': 'Mao Mao', 'title': 'Intern' },
22 | { 'name': 'Lv Lv', 'title': 'Intern' }
23 | ]
24 | }
25 | ]
26 | }
27 | ]
28 | }
29 | ]
30 | },
31 | { 'name': 'Hong Miao', 'title': 'department manager' },
32 | { 'name': 'Chun Miao', 'title': 'department manager',
33 | 'children': [
34 | { 'name': 'Bing Qin', 'title': 'senior engineer' },
35 | { 'name': 'Yue Yue', 'title': 'senior engineer',
36 | 'children': [
37 | { 'name': 'Er Yue', 'title': 'engineer' },
38 | { 'name': 'San Yue', 'title': 'UE engineer' }
39 | ]
40 | }
41 | ]
42 | }
43 | ]
44 | },
45 | orgchart = new OrgChart({
46 | 'data' : datascource,
47 | 'nodeContent': 'title',
48 | 'verticalDepth': 3,
49 | 'depth': 4
50 | });
51 |
52 | document.querySelector('#chart-container').appendChild(orgchart);
53 |
54 | });
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | var gulp = require('gulp'),
2 | eslint = require('gulp-eslint'),
3 | babel = require('gulp-babel'),
4 | uglify = require('gulp-uglify'),
5 | rename = require("gulp-rename"),
6 | csslint = require('gulp-csslint'),
7 | browserSync = require('browser-sync').create(),
8 | gutil = require('gulp-util'),
9 | webpack = require('webpack'),
10 | cleanCSS = require('gulp-clean-css'),
11 | sourcemaps = require('gulp-sourcemaps'),
12 | path = require('path'),
13 | del = require('del'),
14 | merge = require('merge-stream'),
15 | plumber = require('gulp-plumber');
16 |
17 | gulp.task('cleanCSS', function() {
18 | return del(['build/css']);
19 | });
20 | gulp.task('cleanJS', function() {
21 | return del(['build/js']);
22 | });
23 |
24 | gulp.task('csslint', function() {
25 | gulp.src('src/*.css')
26 | .pipe(csslint({
27 | 'adjoining-classes': false,
28 | 'box-sizing': false,
29 | 'box-model': false,
30 | 'fallback-colors': false,
31 | 'order-alphabetical': false
32 | }))
33 | .pipe(csslint.formatter());
34 | });
35 |
36 | gulp.task('css', ['csslint', 'cleanCSS'], function() {
37 | return gulp.src('src/*.css')
38 | .pipe(sourcemaps.init())
39 | .pipe(cleanCSS())
40 | .pipe(rename('orgchart-webcomponents.min.css'))
41 | .pipe(sourcemaps.write())
42 | .pipe(gulp.dest('build/css'))
43 | .pipe(gulp.dest('demo/css'));
44 | });
45 |
46 | gulp.task('eslint', function () {
47 | return gulp.src(['src/*.js'])
48 | .pipe(eslint('.eslintrc.json'))
49 | .pipe(eslint.format())
50 | .pipe(eslint.failOnError());
51 | });
52 |
53 | gulp.task('js', ['eslint', 'cleanJS'], function () {
54 | return gulp.src(['src/*.js'])
55 | .pipe(sourcemaps.init())
56 | .pipe(babel(
57 | {presets: ['es2015']}
58 | ))
59 | .pipe(uglify())
60 | .pipe(rename('orgchart-webcomponents.min.js'))
61 | .pipe(sourcemaps.write())
62 | .pipe(gulp.dest('build/js'))
63 | .pipe(gulp.dest('demo/js'));
64 | });
65 |
66 | gulp.task('watch', function () {
67 | gulp.watch('src/*.js', ['js']);
68 | gulp.watch('src/*.css', ['css']);
69 | });
70 |
71 | gulp.task('copyVendorAssets', function() {
72 | var fontawesomeCSS = gulp.src('node_modules/font-awesome/css/font-awesome.min.css')
73 | .pipe(gulp.dest('demo/css/vendor'));
74 |
75 | var fontawesomeFonts = gulp.src('node_modules/font-awesome/fonts/*')
76 | .pipe(gulp.dest('demo/css/fonts'));
77 |
78 | var webcomponents = gulp.src('node_modules/webcomponents.js/webcomponents.min.js')
79 | .pipe(gulp.dest('demo/js/vendor'));
80 |
81 | return merge(fontawesomeCSS, fontawesomeFonts, webcomponents);
82 | });
83 |
84 | gulp.task('build', ['css', 'js', 'watch']);
85 |
86 | gulp.task('webpack', ['build'], function () {
87 | webpack(require('./webpack.config.js'), function(err, stats) {
88 | if (err) {
89 | throw new gutil.PluginError('webpack', err);
90 | }
91 | gutil.log('[webpack]', stats.toString());
92 | });
93 | });
94 |
95 | gulp.task('serve', ['copyVendorAssets', 'webpack'], function () {
96 | browserSync.init({
97 | files: ['src/*.css', 'demo/**/*.html', 'demo/**/*.css', '!demo/css/vendor/*.css'],
98 | server: 'demo',
99 | socket: {
100 | domain: 'localhost:3000'
101 | }
102 | });
103 |
104 | gulp.watch('src/*.js', ['webpack']);
105 |
106 | gulp.watch('demo/js/*').on('change', browserSync.reload);
107 |
108 | gulp.watch(['demo/**/*.js', '!demo/js/*', '!demo/js/vendor/*', '!demo/**/bundle*.js']).on('change', function(file) {
109 | webpack({
110 | entry: file.path,
111 | output: {
112 | path: path.dirname(file.path),
113 | filename: 'bundle.js'
114 | },
115 | devtool: 'source-map',
116 | module: {
117 | loaders: [
118 | {
119 | loader: 'babel',
120 | query: {
121 | presets: ['es2015']
122 | }
123 | }
124 | ]
125 | }
126 | }, function(err, stats) {
127 | if (err) {
128 | throw new gutil.PluginError('webpack', err);
129 | }
130 | browserSync.reload();
131 | });
132 | });
133 |
134 | });
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "orgchart-webcomponents",
3 | "version": "0.0.1",
4 | "description": "It's a simple and direct organization chart plugin. Anytime you want a tree-like chart, you can turn to OrgChart. Edit",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "devDependencies": {
10 | "babel-core": "^6.18.2",
11 | "babel-loader": "^6.2.8",
12 | "babel-preset-es2015": "^6.18.0",
13 | "browser-sync": "^2.18.2",
14 | "del": "^2.2.2",
15 | "gulp": "^3.9.1",
16 | "gulp-babel": "^6.1.2",
17 | "gulp-clean-css": "^2.2.0",
18 | "gulp-csslint": "^1.0.0",
19 | "gulp-eslint": "^3.0.1",
20 | "gulp-plumber": "^1.1.0",
21 | "gulp-rename": "^1.2.2",
22 | "gulp-sourcemaps": "^1.9.1",
23 | "gulp-uglify": "^2.0.0",
24 | "gulp-util": "^3.0.7",
25 | "merge-stream": "^1.0.1",
26 | "run-sequence": "^1.2.2",
27 | "webpack": "^1.14.0"
28 | },
29 | "dependencies": {
30 | "font-awesome": "^4.7.0",
31 | "webcomponents.js": "^0.7.23"
32 | },
33 | "repository": {
34 | "type": "git",
35 | "url": "git+https://github.com/dabeng/OrgChart-Webcomponents.git"
36 | },
37 | "keywords": [
38 | "web components",
39 | "es6",
40 | "ES2015",
41 | "organization chart",
42 | "tree-like"
43 | ],
44 | "author": "dabeng",
45 | "license": "MIT",
46 | "bugs": {
47 | "url": "https://github.com/dabeng/OrgChart-Webcomponents/issues"
48 | },
49 | "homepage": "https://github.com/dabeng/OrgChart-Webcomponents#readme"
50 | }
51 |
--------------------------------------------------------------------------------
/src/orgchart-webcomponents.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Organization Chart Web Components
3 | * https://github.com/dabeng/org-chart-Webcomponents
4 | *
5 | *
6 | * Licensed under the MIT license:
7 | * http://www.opensource.org/licenses/MIT
8 | */
9 |
10 | #chart-container {
11 | position: relative;
12 | display: inline-block;
13 | top: 10px;
14 | left: 10px;
15 | height: 420px;
16 | width: calc(100% - 24px);
17 | border: 2px dashed #aaa;
18 | border-radius: 5px;
19 | overflow: auto;
20 | text-align: center;
21 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
22 | font-size: 14px;
23 | }
24 |
25 | org-chart {
26 | display: inline-block;
27 | min-height: 202px;
28 | min-width: 202px;
29 | -webkit-touch-callout: none;
30 | -webkit-user-select: none;
31 | -khtml-user-select: none;
32 | -moz-user-select: none;
33 | -ms-user-select: none;
34 | user-select: none;
35 | background-image: linear-gradient(90deg, rgba(200, 0, 0, 0.15) 10%, rgba(0, 0, 0, 0) 10%), linear-gradient(rgba(200, 0, 0, 0.15) 10%, rgba(0, 0, 0, 0) 10%);
36 | background-size: 10px 10px;
37 | border: 1px dashed transparent;
38 | padding: 20px;
39 | }
40 |
41 | org-chart .hidden, org-chart~.hidden {
42 | display: none;
43 | }
44 |
45 | org-chart div,
46 | org-chart div::before,
47 | org-chart div::after {
48 | -webkit-box-sizing: border-box;
49 | -moz-box-sizing: border-box;
50 | box-sizing: border-box;
51 | }
52 |
53 | org-chart.b2t {
54 | -ms-transform: rotate(180deg);
55 | -moz-transform: rotate(180deg);
56 | -webkit-transform: rotate(180deg);
57 | transform: rotate(180deg);
58 | }
59 |
60 | org-chart.l2r {
61 | position: absolute;
62 | -ms-transform: rotate(-90deg) rotateY(180deg);
63 | -moz-transform: rotate(-90deg) rotateY(180deg);
64 | -webkit-transform: rotate(-90deg) rotateY(180deg);
65 | transform: rotate(-90deg) rotateY(180deg);
66 | -ms-transform-origin: left top;
67 | -moz-transform-origin: left top;
68 | -webkit-transform-origin: left top;
69 | transform-origin: left top;
70 | }
71 |
72 | org-chart .verticalNodes ul {
73 | list-style: none;
74 | margin: 0;
75 | padding-left: 18px;
76 | text-align: left;
77 | }
78 |
79 | org-chart .verticalNodes ul:first-child {
80 | margin-top: 3px;
81 | }
82 |
83 | org-chart .verticalNodes>td::before {
84 | content: '';
85 | border: 1px solid rgba(217, 83, 79, 0.8);
86 | }
87 |
88 | org-chart .verticalNodes>td>ul>li:first-child::before {
89 | top: -4px;
90 | height: 30px;
91 | width: calc(50% - 2px);
92 | border-width: 2px 0 0 2px;
93 | }
94 |
95 | org-chart .verticalNodes ul>li {
96 | position: relative;
97 | }
98 |
99 | org-chart .verticalNodes ul>li::before,
100 | org-chart .verticalNodes ul>li::after {
101 | content: '';
102 | position: absolute;
103 | left: -6px;
104 | border-color: rgba(217, 83, 79, 0.8);
105 | border-style: solid;
106 | border-width: 0 0 2px 2px;
107 | -webkit-box-sizing: border-box;
108 | -moz-box-sizing: border-box;
109 | box-sizing: border-box;
110 | }
111 |
112 | org-chart .verticalNodes ul>li::before {
113 | top: -4px;
114 | height: 30px;
115 | width: 11px;
116 | }
117 |
118 | org-chart .verticalNodes ul>li::after {
119 | top: 1px;
120 | height: 100%;
121 | }
122 |
123 | org-chart .verticalNodes ul>li:first-child::after {
124 | top: 24px;
125 | width: 11px;
126 | border-width: 2px 0 0 2px;
127 | }
128 |
129 | org-chart .verticalNodes ul>li:last-child::after {
130 | border-width: 2px 0 0;
131 | }
132 |
133 | org-chart.r2l {
134 | position: absolute;
135 | -ms-transform: rotate(90deg);
136 | -moz-transform: rotate(90deg);
137 | -webkit-transform: rotate(90deg);
138 | transform: rotate(90deg);
139 | -ms-transform-origin: left top;
140 | -moz-transform-origin: left top;
141 | -webkit-transform-origin: left top;
142 | transform-origin: left top;
143 | }
144 |
145 | org-chart>.spinner {
146 | font-size: 100px;
147 | margin-top: 30px;
148 | color: rgba(68, 157, 68, 0.8);
149 | }
150 |
151 | org-chart table {
152 | border-spacing: 0;
153 | border-collapse: separate;
154 | }
155 |
156 | org-chart>table:first-child{
157 | margin: 20px auto;
158 | }
159 |
160 | org-chart td {
161 | text-align: center;
162 | vertical-align: top;
163 | padding: 0;
164 | }
165 |
166 | org-chart tr.lines .topLine {
167 | border-top: 2px solid rgba(217, 83, 79, 0.8);
168 | }
169 |
170 | org-chart tr.lines .rightLine {
171 | border-right: 1px solid rgba(217, 83, 79, 0.8);
172 | float: none;
173 | border-radius: 0;
174 | }
175 |
176 | org-chart tr.lines .leftLine {
177 | border-left: 1px solid rgba(217, 83, 79, 0.8);
178 | float: none;
179 | border-radius: 0;
180 | }
181 |
182 | org-chart tr.lines .downLine {
183 | background-color: rgba(217, 83, 79, 0.8);
184 | margin: 0 auto;
185 | height: 20px;
186 | width: 2px;
187 | float: none;
188 | }
189 |
190 | /* node styling */
191 | org-chart .node {
192 | display: inline-block;
193 | position: relative;
194 | margin: 0;
195 | padding: 3px;
196 | border: 2px dashed transparent;
197 | text-align: center;
198 | width: 130px;
199 | }
200 |
201 | org-chart.l2r .node, org-chart.r2l .node {
202 | width: 50px;
203 | height: 130px;
204 | }
205 |
206 | org-chart .node>.hazy {
207 | opacity: 0.2;
208 | }
209 |
210 | org-chart .node>.spinner {
211 | position: absolute;
212 | top: calc(50% - 15px);
213 | left: calc(50% - 15px);
214 | vertical-align: middle;
215 | font-size: 30px;
216 | color: rgba(68, 157, 68, 0.8);
217 | }
218 |
219 | org-chart .node:hover {
220 | background-color: rgba(238, 217, 54, 0.5);
221 | transition: .5s;
222 | cursor: default;
223 | z-index: 20;
224 | }
225 |
226 | org-chart .node.focused {
227 | background-color: rgba(238, 217, 54, 0.5);
228 | }
229 |
230 | org-chart .ghost-node {
231 | position: fixed;
232 | left: -10000px;
233 | top: -10000px;
234 | }
235 |
236 | org-chart .ghost-node rect {
237 | fill: #ffffff;
238 | stroke: #bf0000;
239 | }
240 |
241 | org-chart .node.allowedDrop {
242 | border-color: rgba(68, 157, 68, 0.9);
243 | }
244 |
245 | org-chart .node .title {
246 | text-align: center;
247 | font-size: 12px;
248 | font-weight: bold;
249 | height: 20px;
250 | line-height: 20px;
251 | overflow: hidden;
252 | text-overflow: ellipsis;
253 | white-space: nowrap;
254 | background-color: rgba(217, 83, 79, 0.8);
255 | color: #fff;
256 | border-radius: 4px 4px 0 0;
257 | }
258 |
259 | org-chart.b2t .node .title {
260 | -ms-transform: rotate(-180deg);
261 | -moz-transform: rotate(-180deg);
262 | -webkit-transform: rotate(-180deg);
263 | transform: rotate(-180deg);
264 | -ms-transform-origin: center bottom;
265 | -moz-transform-origin: center bottom;
266 | -webkit-transform-origin: center bottom;
267 | transform-origin: center bottom;
268 | }
269 |
270 | org-chart.l2r .node .title {
271 | -ms-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
272 | -moz-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
273 | -webkit-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
274 | transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
275 | -ms-transform-origin: bottom center;
276 | -moz-transform-origin: bottom center;
277 | -webkit-transform-origin: bottom center;
278 | transform-origin: bottom center;
279 | width: 120px;
280 | }
281 |
282 | org-chart.r2l .node .title {
283 | -ms-transform: rotate(-90deg) translate(-40px, -40px);
284 | -moz-transform: rotate(-90deg) translate(-40px, -40px);
285 | -webkit-transform: rotate(-90deg) translate(-40px, -40px);
286 | transform: rotate(-90deg) translate(-40px, -40px);
287 | -ms-transform-origin: bottom center;
288 | -moz-transform-origin: bottom center;
289 | -webkit-transform-origin: bottom center;
290 | transform-origin: bottom center;
291 | width: 120px;
292 | }
293 |
294 | org-chart .node .title .symbol {
295 | float: left;
296 | margin-top: 4px;
297 | margin-left: 2px;
298 | }
299 |
300 | org-chart .node .content {
301 | width: 100%;
302 | height: 20px;
303 | font-size: 11px;
304 | line-height: 18px;
305 | border: 1px solid rgba(217, 83, 79, 0.8);
306 | border-radius: 0 0 4px 4px;
307 | text-align: center;
308 | background-color: #fff;
309 | color: #333;
310 | overflow: hidden;
311 | text-overflow: ellipsis;
312 | white-space: nowrap;
313 | }
314 |
315 | org-chart.b2t .node .content {
316 | -ms-transform: rotate(180deg);
317 | -moz-transform: rotate(180deg);
318 | -webkit-transform: rotate(180deg);
319 | transform: rotate(180deg);
320 | -ms-transform-origin: center top;
321 | -moz-transform-origin: center top;
322 | -webkit-transform-origin: center top;
323 | transform-origin: center top;
324 | }
325 |
326 | org-chart.l2r .node .content {
327 | -ms-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
328 | -moz-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
329 | -webkit-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
330 | transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
331 | -ms-transform-origin: top center;
332 | -moz-transform-origin: top center;
333 | -webkit-transform-origin: top center;
334 | transform-origin: top center;
335 | width: 120px;
336 | }
337 |
338 | org-chart.r2l .node .content {
339 | -ms-transform: rotate(-90deg) translate(-40px, -40px);
340 | -moz-transform: rotate(-90deg) translate(-40px, -40px);
341 | -webkit-transform: rotate(-90deg) translate(-40px, -40px);
342 | transform: rotate(-90deg) translate(-40px, -40px);
343 | -ms-transform-origin: top center;
344 | -moz-transform-origin: top center;
345 | -webkit-transform-origin: top center;
346 | transform-origin: top center;
347 | width: 120px;
348 | }
349 |
350 | org-chart .node .edge {
351 | font-size: 15px;
352 | position: absolute;
353 | color: rgba(68, 157, 68, 0.5);
354 | cursor: default;
355 | transition: .2s;
356 | -webkit-transition: .2s;
357 | }
358 |
359 | org-chart.noncollapsable .node .edge {
360 | display: none;
361 | }
362 |
363 | org-chart .edge:hover {
364 | color: #449d44;
365 | cursor: pointer;
366 | }
367 |
368 | org-chart .node .verticalEdge {
369 | width: calc(100% - 10px);
370 | width: -webkit-calc(100% - 10px);
371 | width: -moz-calc(100% - 10px);
372 | left: 5px;
373 | }
374 |
375 | org-chart .node .topEdge {
376 | top: -4px;
377 | }
378 |
379 | org-chart .node .bottomEdge {
380 | bottom: -4px;
381 | }
382 |
383 | org-chart .node .horizontalEdge {
384 | width: 15px;
385 | height: calc(100% - 10px);
386 | height: -webkit-calc(100% - 10px);
387 | height: -moz-calc(100% - 10px);
388 | top: 5px;
389 | }
390 |
391 | org-chart .node .rightEdge {
392 | right: -4px;
393 | }
394 |
395 | org-chart .node .leftEdge {
396 | left: -4px;
397 | }
398 |
399 | org-chart .node .horizontalEdge::before {
400 | position: absolute;
401 | top: calc(50% - 7px);
402 | top: -webkit-calc(50% - 7px);
403 | top: -moz-calc(50% - 7px);
404 | }
405 |
406 | org-chart .node .rightEdge::before {
407 | right: 3px;
408 | }
409 |
410 | org-chart .node .leftEdge::before {
411 | left: 3px;
412 | }
413 |
414 | org-chart .node .toggleBtn {
415 | position: absolute;
416 | left: 5px;
417 | bottom: -2px;
418 | color: rgba(68, 157, 68, 0.6);
419 | }
420 |
421 | org-chart .node .toggleBtn:hover {
422 | color: rgba(68, 157, 68, 0.8);
423 | }
424 |
425 | .oc-export-btn {
426 | display: inline-block;
427 | position: absolute;
428 | right: 5px;
429 | top: 5px;
430 | padding: 6px 12px;
431 | margin-bottom: 0;
432 | font-size: 14px;
433 | font-weight: 400;
434 | line-height: 1.42857143;
435 | text-align: center;
436 | white-space: nowrap;
437 | vertical-align: middle;
438 | -ms-touch-action: manipulation;
439 | touch-action: manipulation;
440 | cursor: pointer;
441 | -webkit-user-select: none;
442 | -moz-user-select: none;
443 | -ms-user-select: none;
444 | user-select: none;
445 | color: #fff;
446 | background-color: #5cb85c;
447 | border: 1px solid transparent;
448 | border-color: #4cae4c;
449 | border-radius: 4px;
450 | }
451 |
452 | .oc-export-btn:hover,.oc-export-btn:focus,.oc-export-btn:active {
453 | background-color: #449d44;
454 | border-color: #347a34;
455 | }
456 |
457 | org-chart~.mask {
458 | position: absolute;
459 | top: 0;
460 | right: 0;
461 | bottom: 0;
462 | left: 0;
463 | z-index: 999;
464 | text-align: center;
465 | background-color: rgba(0,0,0,0.3);
466 | }
467 |
468 | org-chart~.mask .spinner {
469 | position: absolute;
470 | top: calc(50% - 54px);
471 | left: calc(50% - 54px);
472 | color: rgba(255,255,255,0.8);
473 | font-size: 108px;
474 | }
475 |
476 | org-chart .node {
477 | -webkit-transition: all 0.3s;
478 | transition: all 0.3s;
479 | top: 0;
480 | left: 0;
481 | }
482 |
483 | org-chart .slide-down {
484 | opacity: 0;
485 | top: 40px;
486 | }
487 |
488 | org-chart.l2r .node.slide-down, org-chart.r2l .node.slide-down {
489 | top: 130px;
490 | }
491 |
492 | org-chart .slide-up {
493 | opacity: 0;
494 | top: -40px;
495 | }
496 |
497 | org-chart.l2r .node.slide-up, org-chart.r2l .node.slide-up {
498 | top: -130px;
499 | }
500 |
501 | org-chart .slide-right {
502 | opacity: 0;
503 | left: 130px;
504 | }
505 |
506 | org-chart.l2r .node.slide-right, org-chart.r2l .node.slide-right {
507 | left: 40px;
508 | }
509 |
510 | org-chart .slide-left {
511 | opacity: 0;
512 | left: -130px;
513 | }
514 |
515 | org-chart.l2r .node.slide-left, org-chart.r2l .node.slide-left {
516 | left: -40px;
517 | }
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | entry: {
3 | 'ajax-datasource/bundle': './demo/ajax-datasource/scripts.js',
4 | 'color-coded/bundle': './demo/color-coded/scripts.js',
5 | 'direction/bundle-b2t': './demo/direction/b2t.js',
6 | 'direction/bundle-l2r': './demo/direction/l2r.js',
7 | 'direction/bundle-r2l': './demo/direction/r2l.js',
8 | 'drag-drop/bundle': './demo/drag-drop/scripts.js',
9 | 'edit-orgchart/bundle': './demo/edit-orgchart/scripts.js',
10 | 'export-orgchart/bundle': './demo/export-orgchart/scripts.js',
11 | 'get-hierarchy/bundle': './demo/get-hierarchy/scripts.js',
12 | 'integrate-map/bundle': './demo/integrate-map/scripts.js',
13 | 'local-datasource/bundle': './demo/local-datasource/scripts.js',
14 | 'multiple-layers/bundle': './demo/multiple-layers/scripts.js',
15 | 'ondemand-loading-data/bundle': './demo/ondemand-loading-data/scripts.js',
16 | 'option-createNode/bundle': './demo/option-createNode/scripts.js',
17 | 'pan-zoom/bundle': './demo/pan-zoom/scripts.js',
18 | 'toggle-sibs-resp/bundle': './demo/toggle-sibs-resp/scripts.js',
19 | 'ul-datasource/bundle': './demo/ul-datasource/scripts.js',
20 | 'vertical-depth/bundle': './demo/vertical-depth/scripts.js'
21 | },
22 | output: {
23 | path: './demo/',
24 | filename: '[name].js'
25 | },
26 | devtool: 'source-map',
27 | module: {
28 | loaders: [
29 | {
30 | loader: 'babel',
31 | query: {
32 | presets: ['es2015']
33 | }
34 | }
35 | ]
36 | }
37 | };
38 |
--------------------------------------------------------------------------------