├── .babelrc
├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── assets
├── tree.svg
└── vue-orgchart.jpg
├── build
├── rollup.config.js
└── webpack.config.js
├── dist
├── style.css
├── style.min.css
├── vue-orgchart.common.js
├── vue-orgchart.common.min.js
├── vue-orgchart.esm.js
├── vue-orgchart.js
└── vue-orgchart.min.js
├── docs
├── .nojekyll
├── README.md
├── _assets
│ └── tree.svg
├── _coverpage.md
├── _navbar.md
├── _sidebar.md
├── basic.md
├── drag.md
├── edit.md
├── exportpic.md
├── favicon.ico
├── index.html
├── index.min.js
├── panzoom.md
├── props.md
├── quickstart.md
├── style.css
├── style.min.css
└── zh-cn
│ ├── README.md
│ ├── _navbar.md
│ ├── _sidebar.md
│ ├── basic.md
│ ├── drag.md
│ ├── edit.md
│ ├── exportpic.md
│ ├── panzoom.md
│ ├── props.md
│ └── quickstart.md
├── examples
├── Ajax.vue
├── App.vue
├── data
│ ├── basic.js
│ ├── edit.js
│ └── index.js
├── index.html
├── main.js
└── store
│ ├── index.js
│ └── service.js
├── package-lock.json
├── package.json
├── src
├── components
│ ├── VoBasic.vue
│ └── VoEdit.vue
├── index.js
└── lib
│ ├── lodash.js
│ ├── orgchart.js
│ └── utils.js
└── test
├── index.js
├── karma.conf.js
└── load
└── webpack
├── basic
├── App.vue
├── index.js
└── webpack.config.js
├── edit
├── App.vue
├── index.js
└── webpack.config.js
└── index.html
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["latest", {
4 | "es2015": { "modules": false }
5 | }],
6 | "stage-2"
7 | ],
8 | "plugins": [["transform-object-assign"],[
9 | "transform-runtime",
10 | {
11 | "helpers": false,
12 | "polyfill": false,
13 | "regenerator": true,
14 | "moduleName": "babel-runtime"
15 | }
16 | ]]
17 | }
18 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | webpack.config.js
2 | /src/lib/orgchart.js
3 | /src/main.js
4 | /src/index.js
5 | /dist
6 | /examples
7 | /build
8 | /docs
9 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | // http://eslint.org/docs/user-guide/configuring
2 |
3 | module.exports = {
4 | root: true,
5 | parser: 'babel-eslint',
6 | parserOptions: {
7 | sourceType: 'module'
8 | },
9 | env: {
10 | browser: true,
11 | },
12 | extends: 'standard',
13 | plugins: [
14 | 'html'
15 | ],
16 | rules: {
17 | 'no-mixed-operators': 'off'
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | npm-debug.log
4 | yarn-error.log
5 |
6 | # Editor directories and files
7 | .idea
8 | *.suo
9 | *.ntvs*
10 | *.njsproj
11 | *.sln
12 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: node_js
3 | node_js: stable
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017-present, spiritree
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
13 | all 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
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | A Vue wrapper for OrgChart.js.
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ## Intro
18 |
19 | - First of all, thanks a lot for dabeng's great work -- [OrgChart.js](https://github.com/dabeng/OrgChart.js)
20 | - If you prefer the Vue.js Wrapper for Orgchart.js,you could try [my project](https://github.com/spiritree/vue-orgchart)
21 |
22 | ## Links
23 |
24 | - [Documentation](https://spiritree.github.io/vue-orgchart)
25 |
26 | ### Feature
27 |
28 | - Support import and export JSON
29 | - Supports exporting chart as a picture
30 | - draggable Orgchart
31 | - Editable Orgchart
32 |
33 | ...
34 | ## Install
35 | ```shell
36 | npm install vue-orgchart -S
37 | ```
38 | ## Quick Start
39 |
40 | > In `main.js`
41 |
42 | `import 'vue-orgchart/dist/style.min.css'`
43 |
44 | > In `*.vue`
45 |
46 | ```javascript
47 |
48 |
49 |
50 |
51 |
52 |
53 |
74 | ```
75 | ## Development
76 |
77 | ``` bash
78 | # install dependencies
79 | npm install
80 |
81 | # serve with hot reload at localhost:8999
82 | npm run dev
83 |
84 | # unit test
85 | npm run test
86 |
87 | # build by rollup
88 | npm run rollup
89 | ```
90 |
91 | ## License
92 |
93 | MIT
94 |
--------------------------------------------------------------------------------
/assets/tree.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/assets/vue-orgchart.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spiritree/vue-orgchart/c8de4152e2839e28af5561bcce9b4af0d3f046a4/assets/vue-orgchart.jpg
--------------------------------------------------------------------------------
/build/rollup.config.js:
--------------------------------------------------------------------------------
1 | const rollup = require('rollup')
2 | const vue = require('rollup-plugin-vue')
3 | const resolve = require('rollup-plugin-node-resolve')
4 | const babel = require('rollup-plugin-babel')
5 | const uglify = require('rollup-plugin-uglify')
6 | const autoprefixer = require('autoprefixer')
7 | const cssnano = require('cssnano')
8 |
9 | const outputOptions = [
10 | {
11 | min: true,
12 | format: 'umd',
13 | name: 'vue-orgchart',
14 | file: 'dist/vue-orgchart.min.js'
15 | },
16 | {
17 | min: false,
18 | format: 'umd',
19 | name: 'vue-orgchart',
20 | file: 'dist/vue-orgchart.js'
21 | },
22 | {
23 | min: true,
24 | format: 'cjs',
25 | name: 'vue-orgchart',
26 | file: 'dist/vue-orgchart.common.min.js'
27 | },
28 | {
29 | min: false,
30 | format: 'cjs',
31 | name: 'vue-orgchart',
32 | file: 'dist/vue-orgchart.common.js'
33 | },
34 | {
35 | min: false,
36 | format: 'es',
37 | name: 'vue-orgchart',
38 | file: 'dist/vue-orgchart.esm.js'
39 | }
40 | ]
41 |
42 | async function build(item) {
43 | const vueSettings = item.min
44 | ? { css: 'dist/style.min.css', postcss: [autoprefixer, cssnano] }
45 | : { css: 'dist/style.css', postcss: [autoprefixer] }
46 |
47 | const inputOptions = {
48 | input: 'src/index.js',
49 | plugins: [
50 | vue(vueSettings),
51 | resolve({
52 | extensions: ['.js', '.vue']
53 | }),
54 | babel({
55 | exclude: 'node_modules/**',
56 | plugins: ['external-helpers']
57 | })
58 | ]
59 | }
60 | if (item.min) inputOptions.plugins.push(uglify())
61 |
62 | const bundle = await rollup.rollup(inputOptions)
63 | await bundle.write(item)
64 | }
65 |
66 | outputOptions.forEach(item => {
67 | build(item)
68 | .then(() => item.min
69 | ? console.log(`rollup: ${item.name}.${item.format}.min built successfully`)
70 | : console.log(`rollup: ${item.name}.${item.format} built successfully`))
71 | .catch(err => console.error(err))
72 | })
73 |
--------------------------------------------------------------------------------
/build/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path')
2 | const webpack = require('webpack')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 | const opn = require('opn')
5 |
6 | opn('http://localhost:8999')
7 |
8 | function resolve (dir) {
9 | return path.join(__dirname, '..', dir)
10 | }
11 |
12 | module.exports = {
13 | entry: './examples/main.js',
14 | output: {
15 | path: path.resolve(__dirname, '../dist'),
16 | publicPath: '/',
17 | filename: 'build.js'
18 | },
19 | module: {
20 | rules: [
21 | {
22 | test: /\.css$/,
23 | use: [
24 | 'vue-style-loader',
25 | 'css-loader'
26 | ],
27 | },
28 | {
29 | test: /\.vue$/,
30 | loader: 'vue-loader',
31 | options: {
32 | loaders: {
33 | }
34 | // other vue-loader options go here
35 | }
36 | },
37 | {
38 | test: /\.js$/,
39 | loader: 'babel-loader',
40 | exclude: /node_modules/
41 | },
42 | {
43 | test: /\.(png|jpg|gif|svg)$/,
44 | loader: 'file-loader',
45 | options: {
46 | name: '[name].[ext]?[hash]'
47 | }
48 | }
49 | ]
50 | },
51 | resolve: {
52 | alias: {
53 | 'vue$': 'vue/dist/vue.esm.js'
54 | },
55 | extensions: ['*', '.js', '.vue', '.json']
56 | },
57 | devServer: {
58 | port: '8999',
59 | hot: true,
60 | contentBase: path.join(__dirname, 'dist'),
61 | stats: 'errors-only'
62 | },
63 | performance: {
64 | hints: false
65 | },
66 | devtool: '#eval-source-map',
67 | plugins: [
68 | new webpack.DefinePlugin({
69 | 'process.env': {
70 | NODE_ENV: '"development"'
71 | }
72 | }),
73 | new webpack.HotModuleReplacementPlugin(),
74 | new HtmlWebpackPlugin({
75 | filename: 'index.html',
76 | template: './examples/index.html',
77 | inject: true
78 | })
79 | ]
80 | }
81 |
--------------------------------------------------------------------------------
/dist/style.css:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | #wrapper {
69 | width: 50%;
70 | margin: 0 auto;
71 | }
72 |
73 | #wrapper li {
74 | margin-top: 20px;
75 | }
76 |
77 | #wrapper a {
78 | font-size: 24px;
79 | }
80 |
81 | #wrapper span {
82 | font-size: 24px;
83 | }
84 |
85 | #chart-container {
86 | position: relative;
87 | display: inline-block;
88 | top: 10px;
89 | left: 10px;
90 | height: 50%;
91 | width: calc(100% - 24px);
92 | border-radius: 5px;
93 | overflow: auto;
94 | overflow-x: hidden;
95 | text-align: center;
96 | font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
97 | font-size: 14px;
98 | }
99 | .orgchart {
100 | display: inline-block;
101 | min-height: 100%;
102 | min-width: 100%;
103 | -webkit-touch-callout: none;
104 | -webkit-user-select: none;
105 | -moz-user-select: none;
106 | -ms-user-select: none;
107 | user-select: none;
108 | background-size: 10px 10px;
109 | border: 1px dashed transparent;
110 | }
111 |
112 | .orgchart .hidden, .orgchart~.hidden {
113 | display: none;
114 | }
115 |
116 | .orgchart div,
117 | .orgchart div::before,
118 | .orgchart div::after {
119 | -webkit-box-sizing: border-box;
120 | box-sizing: border-box;
121 | }
122 |
123 | .orgchart.b2t {
124 | -webkit-transform: rotate(180deg);
125 | transform: rotate(180deg);
126 | }
127 |
128 | .orgchart.l2r {
129 | -webkit-transform: rotate(-90deg) rotateY(180deg);
130 | transform: rotate(-90deg) rotateY(180deg);
131 | }
132 |
133 | .orgchart .verticalNodes ul {
134 | list-style: none;
135 | margin: 0;
136 | padding-left: 18px;
137 | text-align: left;
138 | }
139 |
140 | .orgchart .verticalNodes ul:first-child {
141 | margin-top: 3px;
142 | }
143 |
144 | .orgchart .verticalNodes>td::before {
145 | content: '';
146 | border: 1px solid rgba(217, 83, 79, 0.8);
147 | }
148 |
149 | .orgchart .verticalNodes>td>ul>li:first-child::before {
150 | top: -4px;
151 | height: 30px;
152 | width: calc(50% - 2px);
153 | border-width: 2px 0 0 2px;
154 | }
155 |
156 | .orgchart .verticalNodes ul>li {
157 | position: relative;
158 | }
159 |
160 | .orgchart .verticalNodes ul>li::before,
161 | .orgchart .verticalNodes ul>li::after {
162 | content: '';
163 | position: absolute;
164 | left: -6px;
165 | border-color: rgba(217, 83, 79, 0.8);
166 | border-style: solid;
167 | border-width: 0 0 2px 2px;
168 | -webkit-box-sizing: border-box;
169 | box-sizing: border-box;
170 | }
171 |
172 | .orgchart .verticalNodes ul>li::before {
173 | top: -4px;
174 | height: 30px;
175 | width: 11px;
176 | }
177 |
178 | .orgchart .verticalNodes ul>li::after {
179 | top: 1px;
180 | height: 100%;
181 | }
182 |
183 | .orgchart .verticalNodes ul>li:first-child::after {
184 | top: 24px;
185 | width: 11px;
186 | border-width: 2px 0 0 2px;
187 | }
188 |
189 | .orgchart .verticalNodes ul>li:last-child::after {
190 | border-width: 2px 0 0;
191 | }
192 |
193 | .orgchart.r2l {
194 | -webkit-transform: rotate(90deg);
195 | transform: rotate(90deg);
196 | }
197 |
198 | .orgchart>.spinner {
199 | font-size: 100px;
200 | margin-top: 30px;
201 | color: rgba(68, 157, 68, 0.8);
202 | }
203 |
204 | .orgchart table {
205 | border-spacing: 0;
206 | border-collapse: separate;
207 | }
208 |
209 | .orgchart>table:first-child{
210 | margin: 20px auto;
211 | }
212 |
213 | .orgchart td {
214 | text-align: center;
215 | vertical-align: top;
216 | padding: 0;
217 | }
218 |
219 | .orgchart tr.lines .topLine {
220 | border-top: 2px solid #616161;
221 | }
222 |
223 | .orgchart tr.lines .rightLine {
224 | border-right: 1px solid #616161;
225 | float: none;
226 | border-radius: 0;
227 | }
228 |
229 | .orgchart tr.lines .leftLine {
230 | border-left: 1px solid #616161;
231 | float: none;
232 | border-radius: 0;
233 | }
234 |
235 | .orgchart tr.lines .downLine {
236 | background-color: #616161;
237 | margin: 0 auto;
238 | height: 20px;
239 | width: 2px;
240 | float: none;
241 | }
242 |
243 | /* node styling */
244 | .orgchart .node {
245 | display: inline-block;
246 | position: relative;
247 | margin: 0;
248 | padding: 3px;
249 | border: 2px dashed transparent;
250 | text-align: center;
251 | width: 130px;
252 | }
253 |
254 | .orgchart.l2r .node, .orgchart.r2l .node {
255 | width: 40px;
256 | height: 130px;
257 | }
258 |
259 | .orgchart .node>.hazy {
260 | opacity: 0.2;
261 | }
262 |
263 | .orgchart .node>.spinner {
264 | position: absolute;
265 | top: calc(50% - 15px);
266 | left: calc(50% - 15px);
267 | vertical-align: middle;
268 | font-size: 30px;
269 | color: rgba(68, 157, 68, 0.8);
270 | }
271 |
272 | .orgchart .node:hover {
273 | background-color: rgba(238, 217, 54, 0.5);
274 | -webkit-transition: .5s;
275 | transition: .5s;
276 | cursor: default;
277 | z-index: 20;
278 | }
279 |
280 | .orgchart .node.focused {
281 | background-color: rgba(238, 217, 54, 0.5);
282 | }
283 |
284 | .orgchart .ghost-node {
285 | position: fixed;
286 | left: -10000px;
287 | top: -10000px;
288 | }
289 |
290 | .orgchart .ghost-node rect {
291 | fill: #ffffff;
292 | stroke: #bf0000;
293 | }
294 |
295 | .orgchart .node.allowedDrop {
296 | border-color: rgba(68, 157, 68, 0.9);
297 | }
298 |
299 | .orgchart .node .title {
300 | text-align: center;
301 | font-size: 12px;
302 | font-weight: 300;
303 | height: 20px;
304 | line-height: 20px;
305 | overflow: hidden;
306 | text-overflow: ellipsis;
307 | white-space: nowrap;
308 | background-color: #42b983;
309 | color: #fff;
310 | border-radius: 4px 4px 0 0;
311 | }
312 |
313 | .orgchart.b2t .node .title {
314 | -webkit-transform: rotate(-180deg);
315 | transform: rotate(-180deg);
316 | -webkit-transform-origin: center bottom;
317 | transform-origin: center bottom;
318 | }
319 |
320 | .orgchart.l2r .node .title {
321 | -webkit-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
322 | transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
323 | -webkit-transform-origin: bottom center;
324 | transform-origin: bottom center;
325 | width: 120px;
326 | }
327 |
328 | .orgchart.r2l .node .title {
329 | -webkit-transform: rotate(-90deg) translate(-40px, -40px);
330 | transform: rotate(-90deg) translate(-40px, -40px);
331 | -webkit-transform-origin: bottom center;
332 | transform-origin: bottom center;
333 | width: 120px;
334 | }
335 |
336 | .orgchart .node .title .symbol {
337 | float: left;
338 | margin-top: 4px;
339 | margin-left: 2px;
340 | }
341 |
342 | .orgchart .node .content {
343 | width: 100%;
344 | height: 20px;
345 | font-size: 11px;
346 | line-height: 18px;
347 | border: 1px solid #42b983;
348 | border-radius: 0 0 4px 4px;
349 | text-align: center;
350 | background-color: #fff;
351 | color: #333;
352 | overflow: hidden;
353 | text-overflow: ellipsis;
354 | white-space: nowrap;
355 | }
356 |
357 | .orgchart.b2t .node .content {
358 | -webkit-transform: rotate(180deg);
359 | transform: rotate(180deg);
360 | -webkit-transform-origin: center top;
361 | transform-origin: center top;
362 | }
363 |
364 | .orgchart.l2r .node .content {
365 | -webkit-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
366 | transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
367 | -webkit-transform-origin: top center;
368 | transform-origin: top center;
369 | width: 120px;
370 | }
371 |
372 | .orgchart.r2l .node .content {
373 | -webkit-transform: rotate(-90deg) translate(-40px, -40px);
374 | transform: rotate(-90deg) translate(-40px, -40px);
375 | -webkit-transform-origin: top center;
376 | transform-origin: top center;
377 | width: 120px;
378 | }
379 |
380 | .orgchart .node .edge {
381 | font-size: 15px;
382 | position: absolute;
383 | color: rgba(68, 157, 68, 0.5);
384 | cursor: default;
385 | transition: .2s;
386 | -webkit-transition: .2s;
387 | }
388 |
389 | .orgchart.noncollapsable .node .edge {
390 | display: none;
391 | }
392 |
393 | .orgchart .edge:hover {
394 | color: #449d44;
395 | cursor: pointer;
396 | }
397 |
398 | .orgchart .node .verticalEdge {
399 | width: calc(100% - 10px);
400 | width: -moz-calc(100% - 10px);
401 | left: 5px;
402 | }
403 |
404 | .orgchart .node .topEdge {
405 | top: -4px;
406 | }
407 |
408 | .orgchart .node .bottomEdge {
409 | bottom: -4px;
410 | }
411 |
412 | .orgchart .node .horizontalEdge {
413 | width: 15px;
414 | height: calc(100% - 10px);
415 | height: -moz-calc(100% - 10px);
416 | top: 5px;
417 | }
418 |
419 | .orgchart .node .rightEdge {
420 | right: -4px;
421 | }
422 |
423 | .orgchart .node .leftEdge {
424 | left: -4px;
425 | }
426 |
427 | .orgchart .node .horizontalEdge::before {
428 | position: absolute;
429 | top: calc(50% - 7px);
430 | top: -moz-calc(50% - 7px);
431 | }
432 |
433 | .orgchart .node .rightEdge::before {
434 | right: 3px;
435 | }
436 |
437 | .orgchart .node .leftEdge::before {
438 | left: 3px;
439 | }
440 |
441 | .orgchart .node .toggleBtn {
442 | position: absolute;
443 | left: 5px;
444 | bottom: -2px;
445 | color: rgba(68, 157, 68, 0.6);
446 | }
447 |
448 | .orgchart .node .toggleBtn:hover {
449 | color: rgba(68, 157, 68, 0.8);
450 | }
451 |
452 | .oc-export-btn {
453 | display: inline-block;
454 | position: absolute;
455 | right: 5px;
456 | bottom: 5px;
457 | padding: 6px 12px;
458 | margin-bottom: 0;
459 | font-size: 14px;
460 | font-weight: 400;
461 | line-height: 1.42857143;
462 | text-align: center;
463 | white-space: nowrap;
464 | vertical-align: middle;
465 | -ms-touch-action: manipulation;
466 | touch-action: manipulation;
467 | cursor: pointer;
468 | -webkit-user-select: none;
469 | -moz-user-select: none;
470 | -ms-user-select: none;
471 | user-select: none;
472 | color: #fff;
473 | background-color: #409eff;
474 | border: 1px solid transparent;
475 | border-color: #409eff;
476 | border-radius: 4px;
477 | }
478 |
479 | .oc-export-btn:hover,.oc-export-btn:focus,.oc-export-btn:active {
480 | background-color: #409eff;
481 | border-color: #409eff;
482 | }
483 |
484 | .orgchart~.mask {
485 | position: absolute;
486 | top: 0;
487 | right: 0;
488 | bottom: 0;
489 | left: 0;
490 | z-index: 999;
491 | text-align: center;
492 | background-color: rgba(0,0,0,0.3);
493 | }
494 |
495 | .orgchart~.mask .spinner {
496 | position: absolute;
497 | top: calc(50% - 54px);
498 | left: calc(50% - 54px);
499 | color: rgba(255,255,255,0.8);
500 | font-size: 108px;
501 | }
502 |
503 | .orgchart .node {
504 | -webkit-transition: all 0.3s;
505 | transition: all 0.3s;
506 | top: 0;
507 | left: 0;
508 | }
509 |
510 | .orgchart .slide-down {
511 | opacity: 0;
512 | top: 40px;
513 | }
514 |
515 | .orgchart.l2r .node.slide-down, .orgchart.r2l .node.slide-down {
516 | top: 130px;
517 | }
518 |
519 | .orgchart .slide-up {
520 | opacity: 0;
521 | top: -40px;
522 | }
523 |
524 | .orgchart.l2r .node.slide-up, .orgchart.r2l .node.slide-up {
525 | top: -130px;
526 | }
527 |
528 | .orgchart .slide-right {
529 | opacity: 0;
530 | left: 130px;
531 | }
532 |
533 | .orgchart.l2r .node.slide-right, .orgchart.r2l .node.slide-right {
534 | left: 40px;
535 | }
536 |
537 | .orgchart .slide-left {
538 | opacity: 0;
539 | left: -130px;
540 | }
541 |
542 | .orgchart.l2r .node.slide-left, .orgchart.r2l .node.slide-left {
543 | left: -40px;
544 | }
545 | #edit-panel {
546 | position: relative;
547 | left: 10px;
548 | width: calc(100% - 40px);
549 | border-radius: 4px;
550 | float: left;
551 | margin-top: 20px;
552 | padding: 10px 5px 10px 10px;
553 | font-size: 14px;
554 | line-height: 1.5;
555 | border-radius: 2px;
556 | color: rgba(0, 0, 0, 0.65);
557 | background-color: #fff;
558 | }
559 |
560 | #edit-panel .btn-inputs {
561 | font-size: 24px;
562 | }
563 |
564 | #edit-panel label {
565 | font-weight: bold;
566 | }
567 |
568 | #edit-panel .new-node {
569 | height: 24px;
570 | -webkit-appearance: none;
571 | background-color:#fff;
572 | background-image: none;
573 | border-radius: 4px;
574 | line-height: 1;
575 | border: 1px solid #d8dce5;
576 | -webkit-box-sizing: border-box;
577 | box-sizing: border-box;
578 | color: #5a5e66;
579 | display: inline-block;
580 | -webkit-transition: border-color .2s cubic-bezier(.645,.045,.355,1);
581 | transition: border-color .2s cubic-bezier(.645,.045,.355,1);
582 | }
583 |
584 | #edit-panel .new-node:focus {
585 | border-color: #409eff;
586 | outline: none;
587 | }
588 |
589 | #edit-panel .new-node:hover {
590 | border-color: #b4bccc;
591 | }
592 |
593 | #edit-panel.edit-parent-node .selected-node-group{
594 | display: none;
595 | }
596 |
597 | #chart-state-panel, #selected-node, #btn-remove-input {
598 | margin-right: 20px;
599 | }
600 |
601 | #edit-panel button {
602 | /* color: #333;
603 | background-color: #fff; */
604 | display: inline-block;
605 | padding: 6px 12px;
606 | margin-bottom: 0;
607 | line-height: 1.42857143;
608 | text-align: center;
609 | white-space: nowrap;
610 | border-radius: 4px;
611 | vertical-align: middle;
612 | -ms-touch-action: manipulation;
613 | touch-action: manipulation;
614 | cursor: pointer;
615 | -webkit-user-select: none;
616 | -moz-user-select: none;
617 | -ms-user-select: none;
618 | user-select: none;
619 | background-image: none;
620 | }
621 |
622 | #edit-panel.edit-parent-node button:not(#btn-add-nodes) {
623 | display: none;
624 | }
625 |
626 | #edit-panel button:hover,.edit-panel button:focus,.edit-panel button:active {
627 | border-color: #409eff;
628 | -webkit-box-shadow: 0 0 10px #409eff;
629 | box-shadow: 0 0 10px #409eff;
630 | }
631 |
632 | #new-nodelist {
633 | display: inline-block;
634 | list-style:none;
635 | margin-top: -2px;
636 | padding: 0;
637 | vertical-align: text-top;
638 | }
639 |
640 | #new-nodelist>* {
641 | padding-bottom: 4px;
642 | }
643 |
644 | .btn-inputs {
645 | vertical-align: sub;
646 | }
647 |
648 |
649 | .btn-inputs:hover {
650 | text-shadow: 0 0 4px #fff;
651 | }
652 |
653 | .radio-panel input[type='radio'] {
654 | border: 1px solid #d8dce5;
655 | border-radius: 100%;
656 | cursor: pointer;
657 | -webkit-box-sizing: border-box;
658 | box-sizing: border-box;
659 | display: inline-block;
660 | height: 14px;
661 | width: 14px;
662 | vertical-align: top;
663 | }
664 |
665 | #edit-panel.view-state .radio-panel input[type='radio']+label {
666 | font-size: 14px;
667 | font-weight: 500;
668 | /* color: #5a5e66; */
669 | line-height: 1;
670 | }
671 |
672 | #btn-add-nodes {
673 | margin-left: 20px;
674 | }
675 |
676 |
--------------------------------------------------------------------------------
/dist/style.min.css:
--------------------------------------------------------------------------------
1 | #wrapper{width:50%;margin:0 auto}#wrapper li{margin-top:20px}#wrapper a,#wrapper span{font-size:24px}#chart-container{position:relative;display:inline-block;top:10px;left:10px;height:50%;width:calc(100% - 24px);border-radius:5px;overflow:auto;overflow-x:hidden;text-align:center;font-family:Source Sans Pro,Helvetica Neue,Arial,sans-serif;font-size:14px}.orgchart{display:inline-block;min-height:100%;min-width:100%;-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-size:10px 10px;border:1px dashed transparent}.orgchart .hidden,.orgchart~.hidden{display:none}.orgchart div,.orgchart div:after,.orgchart div:before{-webkit-box-sizing:border-box;box-sizing:border-box}.orgchart.b2t{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.orgchart.l2r{-webkit-transform:rotate(-90deg) rotateY(180deg);transform:rotate(-90deg) rotateY(180deg)}.orgchart .verticalNodes ul{list-style:none;margin:0;padding-left:18px;text-align:left}.orgchart .verticalNodes ul:first-child{margin-top:3px}.orgchart .verticalNodes>td:before{content:"";border:1px solid rgba(217,83,79,.8)}.orgchart .verticalNodes>td>ul>li:first-child:before{top:-4px;height:30px;width:calc(50% - 2px);border-width:2px 0 0 2px}.orgchart .verticalNodes ul>li{position:relative}.orgchart .verticalNodes ul>li:after,.orgchart .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;box-sizing:border-box}.orgchart .verticalNodes ul>li:before{top:-4px;height:30px;width:11px}.orgchart .verticalNodes ul>li:after{top:1px;height:100%}.orgchart .verticalNodes ul>li:first-child:after{top:24px;width:11px;border-width:2px 0 0 2px}.orgchart .verticalNodes ul>li:last-child:after{border-width:2px 0 0}.orgchart.r2l{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.orgchart>.spinner{font-size:100px;margin-top:30px;color:rgba(68,157,68,.8)}.orgchart table{border-spacing:0;border-collapse:separate}.orgchart>table:first-child{margin:20px auto}.orgchart td{text-align:center;vertical-align:top;padding:0}.orgchart tr.lines .topLine{border-top:2px solid #616161}.orgchart tr.lines .rightLine{border-right:1px solid #616161;float:none;border-radius:0}.orgchart tr.lines .leftLine{border-left:1px solid #616161;float:none;border-radius:0}.orgchart tr.lines .downLine{background-color:#616161;margin:0 auto;height:20px;width:2px;float:none}.orgchart .node{display:inline-block;position:relative;margin:0;padding:3px;border:2px dashed transparent;text-align:center;width:130px}.orgchart.l2r .node,.orgchart.r2l .node{width:40px;height:130px}.orgchart .node>.hazy{opacity:.2}.orgchart .node>.spinner{position:absolute;top:calc(50% - 15px);left:calc(50% - 15px);vertical-align:middle;font-size:30px;color:rgba(68,157,68,.8)}.orgchart .node:hover{-webkit-transition:.5s;transition:.5s;cursor:default;z-index:1}.orgchart .node.focused,.orgchart .node:hover{background-color:rgba(238,217,54,.5)}.orgchart .ghost-node{position:fixed;left:-10000px;top:-10000px}.orgchart .ghost-node rect{fill:#fff;stroke:#bf0000}.orgchart .node.allowedDrop{border-color:rgba(68,157,68,.9)}.orgchart .node .title{text-align:center;font-size:12px;font-weight:300;height:20px;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#42b983;color:#fff;border-radius:4px 4px 0 0}.orgchart.b2t .node .title{-webkit-transform:rotate(-180deg);transform:rotate(-180deg);-webkit-transform-origin:center bottom;transform-origin:center bottom}.orgchart.l2r .node .title{-webkit-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-webkit-transform-origin:bottom center;transform-origin:bottom center;width:120px}.orgchart.r2l .node .title{-webkit-transform:rotate(-90deg) translate(-40px,-40px);transform:rotate(-90deg) translate(-40px,-40px);-webkit-transform-origin:bottom center;transform-origin:bottom center;width:120px}.orgchart .node .title .symbol{float:left;margin-top:4px;margin-left:2px}.orgchart .node .content{width:100%;height:20px;font-size:11px;line-height:18px;border:1px solid #42b983;border-radius:0 0 4px 4px;text-align:center;background-color:#fff;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.orgchart.b2t .node .content{-webkit-transform:rotate(180deg);transform:rotate(180deg);-webkit-transform-origin:center top;transform-origin:center top}.orgchart.l2r .node .content{-webkit-transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);transform:rotate(-90deg) translate(-40px,-40px) rotateY(180deg);-webkit-transform-origin:top center;transform-origin:top center;width:120px}.orgchart.r2l .node .content{-webkit-transform:rotate(-90deg) translate(-40px,-40px);transform:rotate(-90deg) translate(-40px,-40px);-webkit-transform-origin:top center;transform-origin:top center;width:120px}.orgchart .node .edge{font-size:15px;position:absolute;color:rgba(68,157,68,.5);cursor:default;transition:.2s;-webkit-transition:.2s}.orgchart.noncollapsable .node .edge{display:none}.orgchart .edge:hover{color:#449d44;cursor:pointer}.orgchart .node .verticalEdge{width:calc(100% - 10px);width:-moz-calc(100% - 10px);left:5px}.orgchart .node .topEdge{top:-4px}.orgchart .node .bottomEdge{bottom:-4px}.orgchart .node .horizontalEdge{width:15px;height:calc(100% - 10px);height:-moz-calc(100% - 10px);top:5px}.orgchart .node .rightEdge{right:-4px}.orgchart .node .leftEdge{left:-4px}.orgchart .node .horizontalEdge:before{position:absolute;top:calc(50% - 7px);top:-moz-calc(50% - 7px)}.orgchart .node .rightEdge:before{right:3px}.orgchart .node .leftEdge:before{left:3px}.orgchart .node .toggleBtn{position:absolute;left:5px;bottom:-2px;color:rgba(68,157,68,.6)}.orgchart .node .toggleBtn:hover{color:rgba(68,157,68,.8)}.oc-export-btn{display:inline-block;position:absolute;right:5px;bottom: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:#409eff;border:1px solid transparent;border-color:#409eff;border-radius:4px}.oc-export-btn:active,.oc-export-btn:focus,.oc-export-btn:hover{background-color:#409eff;border-color:#409eff}.orgchart~.mask{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;text-align:center;background-color:rgba(0,0,0,.3)}.orgchart~.mask .spinner{position:absolute;top:calc(50% - 54px);left:calc(50% - 54px);color:hsla(0,0%,100%,.8);font-size:108px}.orgchart .node{-webkit-transition:all .3s;transition:all .3s;top:0;left:0}.orgchart .slide-down{opacity:0;top:40px}.orgchart.l2r .node.slide-down,.orgchart.r2l .node.slide-down{top:130px}.orgchart .slide-up{opacity:0;top:-40px}.orgchart.l2r .node.slide-up,.orgchart.r2l .node.slide-up{top:-130px}.orgchart .slide-right{opacity:0;left:130px}.orgchart.l2r .node.slide-right,.orgchart.r2l .node.slide-right{left:40px}.orgchart .slide-left{opacity:0;left:-130px}.orgchart.l2r .node.slide-left,.orgchart.r2l .node.slide-left{left:-40px}#edit-panel{position:relative;left:10px;width:calc(100% - 40px);border-radius:4px;float:left;margin-top:20px;padding:10px 5px 10px 10px;font-size:14px;line-height:1.5;border-radius:2px;color:rgba(0,0,0,.65);background-color:#fff}#edit-panel .btn-inputs{font-size:24px}#edit-panel label{font-weight:700}#edit-panel .new-node{height:24px;-webkit-appearance:none;background-color:#fff;background-image:none;border-radius:4px;line-height:1;border:1px solid #d8dce5;-webkit-box-sizing:border-box;box-sizing:border-box;color:#5a5e66;display:inline-block;-webkit-transition:border-color .2s cubic-bezier(.645,.045,.355,1);transition:border-color .2s cubic-bezier(.645,.045,.355,1)}#edit-panel .new-node:focus{border-color:#409eff;outline:none}#edit-panel .new-node:hover{border-color:#b4bccc}#edit-panel.edit-parent-node .selected-node-group{display:none}#btn-remove-input,#chart-state-panel,#selected-node{margin-right:20px}#edit-panel button{display:inline-block;padding:6px 12px;margin-bottom:0;line-height:1.42857143;text-align:center;white-space:nowrap;border-radius:4px;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;background-image:none}#edit-panel.edit-parent-node button:not(#btn-add-nodes){display:none}#edit-panel button:hover,.edit-panel button:active,.edit-panel button:focus{border-color:#409eff;-webkit-box-shadow:0 0 10px #409eff;box-shadow:0 0 10px #409eff}#new-nodelist{display:inline-block;list-style:none;margin-top:-2px;padding:0;vertical-align:text-top}#new-nodelist>*{padding-bottom:4px}.btn-inputs{vertical-align:sub}.btn-inputs:hover{text-shadow:0 0 4px #fff}.radio-panel input[type=radio]{border:1px solid #d8dce5;border-radius:100%;cursor:pointer;-webkit-box-sizing:border-box;box-sizing:border-box;display:inline-block;height:14px;width:14px;vertical-align:top}#edit-panel.view-state .radio-panel input[type=radio]+label{font-size:14px;font-weight:500;line-height:1}#btn-add-nodes{margin-left:20px}
2 |
--------------------------------------------------------------------------------
/docs/.nojekyll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spiritree/vue-orgchart/c8de4152e2839e28af5561bcce9b4af0d3f046a4/docs/.nojekyll
--------------------------------------------------------------------------------
/docs/README.md:
--------------------------------------------------------------------------------
1 | ## vue-orgchart
2 |
3 | > A vue wrapper for OrgChart.js.
4 |
5 | ### Intro
6 | - First of all, thanks a lot for dabeng's great work -- [OrgChart.js](https://github.com/dabeng/OrgChart.js)
7 | - If you prefer the Vue.js Wrapper for Orgchart.js,you could try [my project](https://github.com/spiritree/vue-orgchart)
8 |
9 | ### Feature
10 | - Support import and export JSON
11 | - Supports exporting chart as a picture
12 | - draggable Orgchart
13 | - Editable Orgchart
14 |
15 | ...
16 |
--------------------------------------------------------------------------------
/docs/_assets/tree.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/_coverpage.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # vue-orgchart 1.0.0
4 |
5 | > A Vue.js wrapper for OrgChart.js.
6 |
7 | - Support import and export JSON
8 | - Supports exporting chart as a picture
9 | - Editable Orgchart
10 |
11 |
12 | [GitHub](https://github.com/spiritree/vue-orgchart)
13 | [Get Started](#vue-orgchart)
14 |
15 |
16 | 
17 |
--------------------------------------------------------------------------------
/docs/_navbar.md:
--------------------------------------------------------------------------------
1 | - Translations
2 | - [:cn: 中文](/zh-cn/)
3 | - [:uk: English](/)
4 |
--------------------------------------------------------------------------------
/docs/_sidebar.md:
--------------------------------------------------------------------------------
1 | - Getting started
2 | - [Quick Start](quickstart)
3 | - [Chart Props](props)
4 | - Charts
5 | - [Basic Orgchart](basic)
6 | - [Pan/Zoom Orgchart](panzoom)
7 | - [Draggable Orgchart](drag)
8 | - [Export Picture Orgchart](exportpic)
9 | - [Editable Orgchart](edit)
10 |
--------------------------------------------------------------------------------
/docs/basic.md:
--------------------------------------------------------------------------------
1 | ## Basic OrgChart
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
7 |
8 |
9 |
29 | ```
30 |
--------------------------------------------------------------------------------
/docs/drag.md:
--------------------------------------------------------------------------------
1 | ## Draggable OrgChart
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
7 |
8 |
9 |
29 | ```
30 |
31 |
--------------------------------------------------------------------------------
/docs/edit.md:
--------------------------------------------------------------------------------
1 | ## Editable OrgChart
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
33 |
34 |
35 |
170 | ```
171 | ```json
172 | ```
173 |
--------------------------------------------------------------------------------
/docs/exportpic.md:
--------------------------------------------------------------------------------
1 | ## Export Picture OrgChart
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
7 |
8 |
9 |
30 | ```
31 |
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spiritree/vue-orgchart/c8de4152e2839e28af5561bcce9b4af0d3f046a4/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue-orgchart - A vue wrapper for OrgChart.js
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/docs/index.min.js:
--------------------------------------------------------------------------------
1 | !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t(e["vue-orgchart"]={})}(this,function(e){"use strict";function t(e,t){return e===t||e!=e&&t!=t}function n(e,n){for(var r=e.length;r--;)if(t(e[r][0],n))return r;return-1}function r(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t-1&&e%1==0&&e<=Oe}function _(e){return null!=e&&b(e.length)&&!s(e)}function E(e,n,r){var i=e[n];Ze.call(e,n)&&t(i,r)&&(void 0!==r||n in e)||f(e,n,r)}function S(e,t){return!!(t=null==t?Ke:t)&&("number"==typeof e||Qe.test(e))&&e>-1&&e%1==0&&e0?t.split(" ").forEach(function(t){return e.classList.add(t)}):e.classList.add(t)})}},{key:"_removeClass",value:function(e,t){e.forEach(function(e){t.indexOf(" ")>0?t.split(" ").forEach(function(t){return e.classList.remove(t)}):e.classList.remove(t)})}},{key:"_css",value:function(e,t,n){e.forEach(function(e){e.style[t]=n})}},{key:"_removeAttr",value:function(e,t){e.forEach(function(e){e.removeAttribute(t)})}},{key:"_one",value:function(e,t,n,r){e.addEventListener(t,function i(o){try{n.call(r,o)}finally{e.removeEventListener(t,i)}})}},{key:"_getDescElements",value:function(e,t){var n=[];return e.forEach(function(e){return n.push.apply(n,D(e.querySelectorAll(t)))}),n}},{key:"_getJSON",value:function(e){return new Promise(function(t,n){var r=new XMLHttpRequest;r.open("GET",e),r.onreadystatechange=function(){4===this.readyState&&(200===this.status?t(JSON.parse(this.response)):n(new Error(this.statusText)))},r.responseType="json",r.setRequestHeader("Content-Type","application/json"),r.send()})}},{key:"_buildJsonDS",value:function(e){var t=this,n={name:e.firstChild.textContent.trim(),relationship:("LI"===e.parentNode.parentNode.nodeName?"1":"0")+(e.parentNode.children.length>1?1:0)+(e.children.length?1:0)};return e.id&&(n.id=e.id),e.querySelector("ul")&&Array.from(e.querySelector("ul").children).forEach(function(e){n.children||(n.children=[]),n.children.push(t._buildJsonDS(e))}),n}},{key:"_attachRel",value:function(e,t){if(e.relationship=t+(e.children&&e.children.length>0?1:0),e.children){var n=!0,r=!1,i=void 0;try{for(var o,s=e.children[Symbol.iterator]();!(n=(o=s.next()).done);n=!0){var a=o.value;this._attachRel(a,"1"+(e.children.length>1?1:0))}}catch(e){r=!0,i=e}finally{try{!n&&s.return&&s.return()}finally{if(r)throw i}}}return e}},{key:"_repaint",value:function(e){e&&(e.style.offsetWidth=e.offsetWidth)}},{key:"_isInAction",value:function(e){return e.querySelector(":scope > .edge").className.indexOf("fa-")>-1}},{key:"_getNodeState",value:function(e,t){var n=this,r=void 0,i={exist:!1,visible:!1};return"parent"===t?((r=this._closest(e,function(e){return e.classList&&e.classList.contains("nodes")}))&&(i.exist=!0),i.exist&&this._isVisible(r.parentNode.children[0])&&(i.visible=!0)):"children"===t?((r=this._closest(e,function(e){return"TR"===e.nodeName}).nextElementSibling)&&(i.exist=!0),i.exist&&this._isVisible(r)&&(i.visible=!0)):"siblings"===t&&((r=this._siblings(this._closest(e,function(e){return"TABLE"===e.nodeName}).parentNode)).length&&(i.exist=!0),i.exist&&r.some(function(e){return n._isVisible(e)})&&(i.visible=!0)),i}},{key:"getRelatedNodes",value:function(e,t){return"parent"===t?this._closest(e,function(e){return e.classList.contains("nodes")}).parentNode.children[0].querySelector(".node"):"children"===t?Array.from(this._closest(e,function(e){return"TABLE"===e.nodeName}).lastChild.children).map(function(e){return e.querySelector(".node")}):"siblings"===t?this._siblings(this._closest(e,function(e){return"TABLE"===e.nodeName}).parentNode).map(function(e){return e.querySelector(".node")}):[]}},{key:"_switchHorizontalArrow",value:function(e){var t=this.options,n=e.querySelector(".leftEdge"),r=e.querySelector(".rightEdge"),i=this._closest(e,function(e){return"TABLE"===e.nodeName}).parentNode;if(t.toggleSiblingsResp&&(void 0===t.ajaxURL||this._closest(e,function(e){return e.classList.contains(".nodes")}).dataset.siblingsLoaded)){var o=i.previousElementSibling,s=i.nextElementSibling;o&&(o.classList.contains("hidden")?(n.classList.add("fa-chevron-left"),n.classList.remove("fa-chevron-right")):(n.classList.add("fa-chevron-right"),n.classList.remove("fa-chevron-left"))),s&&(s.classList.contains("hidden")?(r.classList.add("fa-chevron-right"),r.classList.remove("fa-chevron-left")):(r.classList.add("fa-chevron-left"),r.classList.remove("fa-chevron-right")))}else{var a=this._siblings(i),l=!!a.length&&!a.some(function(e){return e.classList.contains("hidden")});n.classList.toggle("fa-chevron-right",l),n.classList.toggle("fa-chevron-left",!l),r.classList.toggle("fa-chevron-left",l),r.classList.toggle("fa-chevron-right",!l)}}},{key:"_hoverNode",value:function(e){var t=e.target,n=!1,r=t.querySelector(":scope > .topEdge"),i=t.querySelector(":scope > .bottomEdge"),o=t.querySelector(":scope > .leftEdge");"mouseenter"===e.type?(r&&(n=this._getNodeState(t,"parent").visible,r.classList.toggle("fa-chevron-up",!n),r.classList.toggle("fa-chevron-down",n)),i&&(n=this._getNodeState(t,"children").visible,i.classList.toggle("fa-chevron-down",!n),i.classList.toggle("fa-chevron-up",n)),o&&this._switchHorizontalArrow(t)):Array.from(t.querySelectorAll(":scope > .edge")).forEach(function(e){e.classList.remove("fa-chevron-up","fa-chevron-down","fa-chevron-right","fa-chevron-left")})}},{key:"_clickNode",value:function(e){var t=e.currentTarget,n=this.chart.querySelector(".focused");n&&n.classList.remove("focused"),t.classList.add("focused")}},{key:"_buildParentNode",value:function(e,t,n){var r=this,i=document.createElement("table");t.relationship=t.relationship||"001",this._createNode(t,0).then(function(e){var t=r.chart;e.classList.remove("slide-up"),e.classList.add("slide-down");var o=document.createElement("tr"),s=document.createElement("tr"),a=document.createElement("tr"),l=document.createElement("tr");o.setAttribute("class","hidden"),o.innerHTML=' ',i.appendChild(o),s.setAttribute("class","lines hidden"),s.innerHTML='
',i.appendChild(s),a.setAttribute("class","lines hidden"),a.innerHTML=' ',i.appendChild(a),l.setAttribute("class","nodes"),l.innerHTML=' ',i.appendChild(l),i.querySelector("td").appendChild(e),t.insertBefore(i,t.children[0]),i.children[3].children[0].appendChild(t.lastChild),n()}).catch(function(e){console.error("Failed to create parent node",e)})}},{key:"_switchVerticalArrow",value:function(e){e.classList.toggle("fa-chevron-up"),e.classList.toggle("fa-chevron-down")}},{key:"showParent",value:function(e){var t=this._prevAll(this._closest(e,function(e){return e.classList.contains("nodes")}));this._removeClass(t,"hidden"),this._addClass(Array(t[0].children).slice(1,-1),"hidden");var n=t[2].querySelector(".node");this._one(n,"transitionend",function(){n.classList.remove("slide"),this._isInAction(e)&&this._switchVerticalArrow(e.querySelector(":scope > .topEdge"))},this),this._repaint(n),n.classList.add("slide"),n.classList.remove("slide-down")}},{key:"showSiblings",value:function(e,t){var n=this,r=[],i=this._closest(e,function(e){return"TABLE"===e.nodeName}).parentNode;r=t?"left"===t?this._prevAll(i):this._nextAll(i):this._siblings(i),this._removeClass(r,"hidden");var o=this._prevAll(this._closest(e,function(e){return e.classList.contains("nodes")}));if(i=Array.from(o[0].querySelectorAll(":scope > .hidden")),t?this._removeClass(i.slice(0,2*r.length),"hidden"):this._removeClass(i,"hidden"),!this._getNodeState(e,"parent").visible){this._removeClass(o,"hidden");var s=o[2].querySelector(".node");this._one(s,"transitionend",function(e){e.target.classList.remove("slide")},this),this._repaint(s),s.classList.add("slide"),s.classList.remove("slide-down")}r.forEach(function(e){Array.from(e.querySelectorAll(".node")).forEach(function(e){n._isVisible(e)&&(e.classList.add("slide"),e.classList.remove("slide-left","slide-right"))})}),this._one(r[0].querySelector(".slide"),"transitionend",function(){var t=this;r.forEach(function(e){t._removeClass(Array.from(e.querySelectorAll(".slide")),"slide")}),this._isInAction(e)&&(this._switchHorizontalArrow(e),e.querySelector(".topEdge").classList.remove("fa-chevron-up"),e.querySelector(".topEdge").classList.add("fa-chevron-down"))},this)}},{key:"hideSiblings",value:function(e,t){var n=this,r=this._closest(e,function(e){return"TABLE"===e.nodeName}).parentNode;if(this._siblings(r).forEach(function(e){e.querySelector(".spinner")&&(n.chart.dataset.inAjax=!1)}),!t||t&&"left"===t){this._prevAll(r).forEach(function(e){Array.from(e.querySelectorAll(".node")).forEach(function(e){n._isVisible(e)&&e.classList.add("slide","slide-right")})})}if(!t||t&&"left"!==t){this._nextAll(r).forEach(function(e){Array.from(e.querySelectorAll(".node")).forEach(function(e){n._isVisible(e)&&e.classList.add("slide","slide-left")})})}var i=[];this._siblings(r).forEach(function(e){Array.prototype.push.apply(i,Array.from(e.querySelectorAll(".slide")))});var o=[],s=!0,a=!1,l=void 0;try{for(var c,d=i[Symbol.iterator]();!(s=(c=d.next()).done);s=!0){var u=c.value,h=this._closest(u,function(e){return e.classList.contains("nodes")}).previousElementSibling;o.push(h),o.push(h.previousElementSibling)}}catch(e){a=!0,l=e}finally{try{!s&&d.return&&d.return()}finally{if(a)throw l}}(o=[].concat(D(new Set(o)))).forEach(function(e){e.style.visibility="hidden"}),this._one(i[0],"transitionend",function(n){var s=this;o.forEach(function(e){e.removeAttribute("style")});var a=[];a=t?"left"===t?this._prevAll(r,":not(.hidden)"):this._nextAll(r,":not(.hidden)"):this._siblings(r);var l=Array.from(this._closest(r,function(e){return e.classList.contains("nodes")}).previousElementSibling.querySelectorAll(":scope > :not(.hidden)")).slice(1,t?2*a.length+1:-1);this._addClass(l,"hidden"),this._removeClass(i,"slide"),a.forEach(function(e){Array.from(e.querySelectorAll(".node")).slice(1).forEach(function(e){s._isVisible(e)&&(e.classList.remove("slide-left","slide-right"),e.classList.add("slide-up"))})}),a.forEach(function(e){s._addClass(Array.from(e.querySelectorAll(".lines")),"hidden"),s._addClass(Array.from(e.querySelectorAll(".nodes")),"hidden"),s._addClass(Array.from(e.querySelectorAll(".verticalNodes")),"hidden")}),this._addClass(a,"hidden"),this._isInAction(e)&&this._switchHorizontalArrow(e)},this)}},{key:"hideParent",value:function(e){var t=Array.from(this._closest(e,function(e){return e.classList.contains("nodes")}).parentNode.children).slice(0,3);t[0].querySelector(".spinner")&&(this.chart.dataset.inAjax=!1),this._getNodeState(e,"siblings").visible&&this.hideSiblings(e);var n=t.slice(1);this._css(n,"visibility","hidden");var r=t[0].querySelector(".node"),i=this._getNodeState(r,"parent").visible;r&&this._isVisible(r)&&(r.classList.add("slide","slide-down"),this._one(r,"transitionend",function(){r.classList.remove("slide"),this._removeAttr(n,"style"),this._addClass(t,"hidden")},this)),r&&i&&this.hideParent(r)}},{key:"addParent",value:function(e,t){var n=this;this._buildParentNode(e,t,function(){if(!e.querySelector(":scope > .topEdge")){var t=document.createElement("i");t.setAttribute("class","edge verticalEdge topEdge fa"),e.appendChild(t)}n.showParent(e)})}},{key:"_startLoading",value:function(e,t){var n=this.options,r=this.chart;if(void 0!==r.dataset.inAjax&&"true"===r.dataset.inAjax)return!1;e.classList.add("hidden");var i=document.createElement("i");i.setAttribute("class","fa fa-circle-o-notch fa-spin spinner"),t.appendChild(i),this._addClass(Array.from(t.querySelectorAll(":scope > *:not(.spinner)")),"hazy"),r.dataset.inAjax=!0;var o=this.chartContainer.querySelector(".oc-export-btn"+(""!==n.chartClass?"."+n.chartClass:""));return o&&(o.disabled=!0),!0}},{key:"_endLoading",value:function(e,t){var n=this.options;e.classList.remove("hidden"),t.querySelector(":scope > .spinner").remove(),this._removeClass(Array.from(t.querySelectorAll(":scope > .hazy")),"hazy"),this.chart.dataset.inAjax=!1;var r=this.chartContainer.querySelector(".oc-export-btn"+(""!==n.chartClass?"."+n.chartClass:""));r&&(r.disabled=!1)}},{key:"_clickTopEdge",value:function(e){e.stopPropagation();var t=this,n=e.target,r=n.parentNode,i=this._getNodeState(r,"parent"),o=this.options;if(i.exist){var s=this._closest(r,function(e){return e.classList.contains("nodes")}).parentNode.firstChild.querySelector(".node");if(s.classList.contains("slide"))return;i.visible?(this.hideParent(r),this._one(s,"transitionend",function(){this._isInAction(r)&&(this._switchVerticalArrow(n),this._switchHorizontalArrow(r))},this)):this.showParent(r)}else{var a=n.parentNode.id;this._startLoading(n,r)&&this._getJSON("function"==typeof o.ajaxURL.parent?o.ajaxURL.parent(r.dataset.source):o.ajaxURL.parent+a).then(function(e){"true"===t.chart.dataset.inAjax&&Object.keys(e).length&&t.addParent(r,e)}).catch(function(e){console.error("Failed to get parent node data.",e)}).finally(function(){t._endLoading(n,r)})}}},{key:"hideChildren",value:function(e){var t=this,n=this._nextAll(e.parentNode.parentNode),r=n[n.length-1],i=[];r.querySelector(".spinner")&&(this.chart.dataset.inAjax=!1);var o=Array.from(r.querySelectorAll(".node")).filter(function(e){return t._isVisible(e)}),s=r.classList.contains("verticalNodes");s||(o.forEach(function(e){Array.prototype.push.apply(i,t._prevAll(t._closest(e,function(e){return e.classList.contains("nodes")}),".lines"))}),i=[].concat(D(new Set(i))),this._css(i,"visibility","hidden")),this._one(o[0],"transitionend",function(a){this._removeClass(o,"slide"),s?t._addClass(n,"hidden"):(i.forEach(function(e){e.removeAttribute("style"),e.classList.add("hidden"),e.parentNode.lastChild.classList.add("hidden")}),this._addClass(Array.from(r.querySelectorAll(".verticalNodes")),"hidden")),this._isInAction(e)&&this._switchVerticalArrow(e.querySelector(".bottomEdge"))},this),this._addClass(o,"slide slide-up")}},{key:"showChildren",value:function(e){var t=this,n=this,r=this._nextAll(e.parentNode.parentNode),i=[];this._removeClass(r,"hidden"),r.some(function(e){return e.classList.contains("verticalNodes")})?r.forEach(function(e){Array.prototype.push.apply(i,Array.from(e.querySelectorAll(".node")).filter(function(e){return n._isVisible(e)}))}):Array.from(r[2].children).forEach(function(e){Array.prototype.push.apply(i,Array.from(e.querySelector("tr").querySelectorAll(".node")).filter(function(e){return n._isVisible(e)}))}),this._repaint(i[0]),this._one(i[0],"transitionend",function(n){t._removeClass(i,"slide"),t._isInAction(e)&&t._switchVerticalArrow(e.querySelector(".bottomEdge"))},this),this._addClass(i,"slide"),this._removeClass(i,"slide-up")}},{key:"_buildChildNode",value:function(e,t,n){var r=t.children||t.siblings;e.querySelector("td").setAttribute("colSpan",2*r.length),this.buildHierarchy(e,{children:r},0,n)}},{key:"addChildren",value:function(e,t){var n=this,r=this.options,i=0;this.chart.dataset.inEdit="addChildren",this._buildChildNode.call(this,this._closest(e,function(e){return"TABLE"===e.nodeName}),t,function(){if(++i===t.children.length){if(!e.querySelector(".bottomEdge")){var o=document.createElement("i");o.setAttribute("class","edge verticalEdge bottomEdge fa"),e.appendChild(o)}if(!e.querySelector(".symbol")){var s=document.createElement("i");s.setAttribute("class","fa "+r.parentNodeSymbol+" symbol"),e.querySelector(":scope > .title").appendChild(s)}n.showChildren(e),n.chart.dataset.inEdit=""}})}},{key:"_clickBottomEdge",value:function(e){var t=this;e.stopPropagation();var n=this,r=this.options,i=e.target,o=i.parentNode,s=this._getNodeState(o,"children");if(s.exist){var a=this._closest(o,function(e){return"TR"===e.nodeName}).parentNode.lastChild;if(Array.from(a.querySelectorAll(".node")).some(function(e){return t._isVisible(e)&&e.classList.contains("slide")}))return;s.visible?this.hideChildren(o):this.showChildren(o)}else{var l=i.parentNode.id;this._startLoading(i,o)&&this._getJSON("function"==typeof r.ajaxURL.children?r.ajaxURL.children(o.dataset.source):r.ajaxURL.children+l).then(function(e){"true"===n.chart.dataset.inAjax&&e.children.length&&n.addChildren(o,e)}).catch(function(e){console.error("Failed to get children nodes data",e)}).finally(function(){n._endLoading(i,o)})}}},{key:"_complementLine",value:function(e,t,n){var r=e.parentNode.parentNode.children;r[0].children[0].setAttribute("colspan",2*t),r[1].children[0].setAttribute("colspan",2*t);for(var i=0;i1?Math.floor(a/2-1):0;if("TD"===e.parentNode.nodeName){var c=this._prevAll(e.parentNode.parentNode);c[0].remove(),c[1].remove();var d=0;i._buildChildNode.call(i,i._closest(e.parentNode,function(e){return"TABLE"===e.nodeName}),t,function(){if(++d===o){var t=Array.from(i._closest(e.parentNode,function(e){return"TABLE"===e.nodeName}).lastChild.children);if(s>1){var r=e.parentNode.parentNode;Array.from(r.children).forEach(function(e){t[0].parentNode.insertBefore(e,t[0])}),r.remove(),i._complementLine(t[0],a,s),i._addClass(t,"hidden"),t.forEach(function(e){i._addClass(e.querySelectorAll(".node"),"slide-left")})}else{var c=e.parentNode.parentNode;t[l].parentNode.insertBefore(e.parentNode,t[l+1]),c.remove(),i._complementLine(t[l],a,1),i._addClass(t,"hidden"),i._addClass(i._getDescElements(t.slice(0,l+1),".node"),"slide-right"),i._addClass(i._getDescElements(t.slice(l+1),".node"),"slide-left")}n()}})}else{var u=0;i.buildHierarchy.call(i,i.chart,t,0,function(){if(++u===a){var t=e.nextElementSibling.children[3].children[l],o=document.createElement("td");o.setAttribute("colspan",2),o.appendChild(e),t.parentNode.insertBefore(o,t.nextElementSibling),i._complementLine(t,a,1);var s=i._closest(e,function(e){return e.classList&&e.classList.contains("nodes")}).parentNode.children[0];s.classList.add("hidden"),i._addClass(Array.from(s.querySelectorAll(".node")),"slide-down");var c=r._siblings(e.parentNode);i._addClass(c,"hidden"),i._addClass(i._getDescElements(c.slice(0,l),".node"),"slide-right"),i._addClass(i._getDescElements(c.slice(l),".node"),"slide-left"),n()}})}}},{key:"addSiblings",value:function(e,t){var n=this;this.chart.dataset.inEdit="addSiblings",this._buildSiblingNode.call(this,this._closest(e,function(e){return"TABLE"===e.nodeName}),t,function(){if(n._closest(e,function(e){return e.classList&&e.classList.contains("nodes")}).dataset.siblingsLoaded=!0,!e.querySelector(".leftEdge")){var t=document.createElement("i"),r=document.createElement("i");t.setAttribute("class","edge horizontalEdge rightEdge fa"),e.appendChild(t),r.setAttribute("class","edge horizontalEdge leftEdge fa"),e.appendChild(r)}n.showSiblings(e),n.chart.dataset.inEdit=""})}},{key:"removeNodes",value:function(e){var t=this._closest(e,function(e){return"TABLE"===e.nodeName}).parentNode,n=this._siblings(t.parentNode);"TD"===t.nodeName?this._getNodeState(e,"siblings").exist?(n[2].querySelector(".topLine").nextElementSibling.remove(),n[2].querySelector(".topLine").remove(),n[0].children[0].setAttribute("colspan",n[2].children.length),n[1].children[0].setAttribute("colspan",n[2].children.length),t.remove()):(n[0].children[0].removeAttribute("colspan"),n[0].querySelector(".bottomEdge").remove(),this._siblings(n[0]).forEach(function(e){return e.remove()})):Array.from(t.parentNode.children).forEach(function(e){return e.remove()})}},{key:"_clickHorizontalEdge",value:function(e){var t=this;e.stopPropagation();var n=this,r=this.options,i=e.target,o=i.parentNode,s=this._getNodeState(o,"siblings");if(s.exist){var a=this._closest(o,function(e){return"TABLE"===e.nodeName}).parentNode;if(this._siblings(a).some(function(e){var n=e.querySelector(".node");return t._isVisible(n)&&n.classList.contains("slide")}))return;if(r.toggleSiblingsResp){var l=this._closest(o,function(e){return"TABLE"===e.nodeName}).parentNode.previousElementSibling,c=this._closest(o,function(e){return"TABLE"===e.nodeName}).parentNode.nextElementSibling;i.classList.contains("leftEdge")?l.classList.contains("hidden")?this.showSiblings(o,"left"):this.hideSiblings(o,"left"):c.classList.contains("hidden")?this.showSiblings(o,"right"):this.hideSiblings(o,"right")}else s.visible?this.hideSiblings(o):this.showSiblings(o)}else{var d=i.parentNode.id,u=this._getNodeState(o,"parent").exist?"function"==typeof r.ajaxURL.siblings?r.ajaxURL.siblings(JSON.parse(o.dataset.source)):r.ajaxURL.siblings+d:"function"==typeof r.ajaxURL.families?r.ajaxURL.families(JSON.parse(o.dataset.source)):r.ajaxURL.families+d;this._startLoading(i,o)&&this._getJSON(u).then(function(e){"true"===n.chart.dataset.inAjax&&(e.siblings||e.children)&&n.addSiblings(o,e)}).catch(function(e){console.error("Failed to get sibling nodes data",e)}).finally(function(){n._endLoading(i,o)})}}},{key:"_clickToggleButton",value:function(e){var t=this,n=e.target,r=n.parentNode.nextElementSibling,i=Array.from(r.querySelectorAll(".node")),o=Array.from(r.children).map(function(e){return e.querySelector(".node")});o.some(function(e){return e.classList.contains("slide")})||(n.classList.toggle("fa-plus-square"),n.classList.toggle("fa-minus-square"),i[0].classList.contains("slide-up")?(r.classList.remove("hidden"),this._repaint(o[0]),this._addClass(o,"slide"),this._removeClass(o,"slide-up"),this._one(o[0],"transitionend",function(){t._removeClass(o,"slide")})):(this._addClass(i,"slide slide-up"),this._one(i[0],"transitionend",function(){t._removeClass(i,"slide"),i.forEach(function(e){t._closest(e,function(e){return"UL"===e.nodeName}).classList.add("hidden")})}),i.forEach(function(e){var n=Array.from(e.querySelectorAll(".toggleBtn"));t._removeClass(n,"fa-minus-square"),t._addClass(n,"fa-plus-square")})))}},{key:"_dispatchClickEvent",value:function(e){var t=e.target.classList;t.contains("topEdge")?this._clickTopEdge(e):t.contains("rightEdge")||t.contains("leftEdge")?this._clickHorizontalEdge(e):t.contains("bottomEdge")?this._clickBottomEdge(e):t.contains("toggleBtn")?this._clickToggleButton(e):this._clickNode(e)}},{key:"_onDragStart",value:function(e){var t=e.target,n=this.options,r=/firefox/.test(window.navigator.userAgent.toLowerCase());if(r&&e.dataTransfer.setData("text/html","hack for firefox"),this.chart.style.transform){var i=void 0,o=void 0;document.querySelector(".ghost-node")?o=(i=this.chart.querySelector(":scope > .ghost-node")).children[0]:((i=document.createElementNS("http://www.w3.org/2000/svg","svg")).classList.add("ghost-node"),o=document.createElementNS("http://www.w3.org/2000/svg","rect"),i.appendChild(o),this.chart.appendChild(i));var s=this.chart.style.transform.split(","),a=Math.abs(window.parseFloat("t2b"===n.direction||"b2t"===n.direction?s[0].slice(s[0].indexOf("(")+1):s[1]));i.setAttribute("width",t.offsetWidth),i.setAttribute("height",t.offsetHeight),o.setAttribute("x",5*a),o.setAttribute("y",5*a),o.setAttribute("width",120*a),o.setAttribute("height",40*a),o.setAttribute("rx",4*a),o.setAttribute("ry",4*a),o.setAttribute("stroke-width",1*a);var l=e.offsetX*a,c=e.offsetY*a;if("l2r"===n.direction?(l=e.offsetY*a,c=e.offsetX*a):"r2l"===n.direction?(l=t.offsetWidth-e.offsetY*a,c=e.offsetX*a):"b2t"===n.direction&&(l=t.offsetWidth-e.offsetX*a,c=t.offsetHeight-e.offsetY*a),r){var d=document.createElement("img");d.src="data:image/svg+xml;utf8,"+(new XMLSerializer).serializeToString(i),e.dataTransfer.setDragImage(d,l,c),o.setAttribute("fill","rgb(255, 255, 255)"),o.setAttribute("stroke","rgb(191, 0, 0)")}else e.dataTransfer.setDragImage(i,l,c)}var u=e.target,h=this._closest(u,function(e){return e.classList&&e.classList.contains("nodes")}).parentNode.children[0].querySelector(".node"),f=Array.from(this._closest(u,function(e){return"TABLE"===e.nodeName}).querySelectorAll(".node"));this.dragged=u,Array.from(this.chart.querySelectorAll(".node")).forEach(function(e){f.includes(e)||(n.dropCriteria?n.dropCriteria(u,h,e)&&e.classList.add("allowedDrop"):e.classList.add("allowedDrop"))})}},{key:"_onDragOver",value:function(e){e.preventDefault();e.currentTarget.classList.contains("allowedDrop")||(e.dataTransfer.dropEffect="none")}},{key:"_onDragEnd",value:function(e){Array.from(this.chart.querySelectorAll(".allowedDrop")).forEach(function(e){e.classList.remove("allowedDrop")})}},{key:"_onDrop",value:function(e){var t=e.currentTarget,n=this.chart,r=this.dragged,i=this._closest(r,function(e){return e.classList&&e.classList.contains("nodes")}).parentNode.children[0].children[0];if(this._removeClass(Array.from(n.querySelectorAll(".allowedDrop")),"allowedDrop"),t.parentNode.parentNode.nextElementSibling){var o=window.parseInt(t.parentNode.colSpan)+2;if(t.parentNode.setAttribute("colspan",o),t.parentNode.parentNode.nextElementSibling.children[0].setAttribute("colspan",o),!r.querySelector(".horizontalEdge")){var s=document.createElement("i"),a=document.createElement("i");s.setAttribute("class","edge horizontalEdge rightEdge fa"),r.appendChild(s),a.setAttribute("class","edge horizontalEdge leftEdge fa"),r.appendChild(a)}var l=t.parentNode.parentNode.nextElementSibling.nextElementSibling,c=document.createElement("td"),d=document.createElement("td");c.setAttribute("class","leftLine topLine"),c.innerHTML=" ",l.insertBefore(c,l.children[1]),d.setAttribute("class","rightLine topLine"),d.innerHTML=" ",l.insertBefore(d,l.children[2]),l.nextElementSibling.appendChild(this._closest(r,function(e){return"TABLE"===e.nodeName}).parentNode);var u=this._siblings(this._closest(r,function(e){return"TABLE"===e.nodeName}).parentNode).map(function(e){return e.querySelector(".node")});if(1===u.length){var h=document.createElement("i"),f=document.createElement("i");h.setAttribute("class","edge horizontalEdge rightEdge fa"),u[0].appendChild(h),f.setAttribute("class","edge horizontalEdge leftEdge fa"),u[0].appendChild(f)}}else{var p=document.createElement("i");p.setAttribute("class","edge verticalEdge bottomEdge fa"),t.appendChild(p),t.parentNode.setAttribute("colspan",2);var v=this._closest(t,function(e){return"TABLE"===e.nodeName}),g=document.createElement("tr"),y=document.createElement("tr"),m=document.createElement("tr");g.setAttribute("class","lines"),g.innerHTML='
',v.appendChild(g),y.setAttribute("class","lines"),y.innerHTML=' ',v.appendChild(y),m.setAttribute("class","nodes"),v.appendChild(m),Array.from(r.querySelectorAll(".horizontalEdge")).forEach(function(e){r.removeChild(e)});var b=this._closest(r,function(e){return"TABLE"===e.nodeName}).parentNode;m.appendChild(b)}var _=window.parseInt(i.colSpan);if(_>2){i.setAttribute("colspan",_-2),i.parentNode.nextElementSibling.children[0].setAttribute("colspan",_-2);var E=i.parentNode.nextElementSibling.nextElementSibling;E.children[1].remove(),E.children[1].remove();var S=Array.from(i.parentNode.parentNode.children[3].children).map(function(e){return e.querySelector(".node")});1===S.length&&(S[0].querySelector(".leftEdge").remove(),S[0].querySelector(".rightEdge").remove())}else i.removeAttribute("colspan"),i.querySelector(".node").removeChild(i.querySelector(".bottomEdge")),Array.from(i.parentNode.parentNode.children).slice(1).forEach(function(e){return e.remove()});var A=new CustomEvent("nodedropped.orgchart",{detail:{draggedNode:r,dragZone:i.children[0],dropZone:t}});n.dispatchEvent(A)}},{key:"_createNode",value:function(e,t){var n=this,r=this.options;return new Promise(function(i,o){if(e.children){var s=!0,a=!1,l=void 0;try{for(var c,d=e.children[Symbol.iterator]();!(s=(c=d.next()).done);s=!0){c.value.parentId=e.id}}catch(e){a=!0,l=e}finally{try{!s&&d.return&&d.return()}finally{if(a)throw l}}}var u=document.createElement("div");delete e.children,u.dataset.source=JSON.stringify(e),e[r.nodeId]&&(u.id=e[r.nodeId]);var h=n.chart.dataset.inEdit,f=void 0;f=h?"addChildren"===h?" slide-up":"":t>=r.depth?" slide-up":"",u.setAttribute("class","node "+(e.className||"")+f),r.draggable&&u.setAttribute("draggable",!0),e.parentId&&u.setAttribute("data-parent",e.parentId),u.innerHTML='\n '+e[r.nodeTitle]+"
\n "+(r.nodeContent?''+e[r.nodeContent]+"
":"")+"\n ";var p=e.relationship||"";if(r.verticalDepth&&t+2>r.verticalDepth){if(t+1>=r.verticalDepth&&Number(p.substr(2,1))){var v=document.createElement("i"),g=t+1>=r.depth?"plus":"minus";v.setAttribute("class","toggleBtn fa fa-"+g+"-square"),u.appendChild(v)}}else{if(Number(p.substr(0,1))){var y=document.createElement("i");y.setAttribute("class","edge verticalEdge topEdge fa"),u.appendChild(y)}if(Number(p.substr(1,1))){var m=document.createElement("i"),b=document.createElement("i");m.setAttribute("class","edge horizontalEdge rightEdge fa"),u.appendChild(m),b.setAttribute("class","edge horizontalEdge leftEdge fa"),u.appendChild(b)}if(Number(p.substr(2,1))){var _=document.createElement("i"),E=document.createElement("i"),S=u.querySelector(":scope > .title");_.setAttribute("class","edge verticalEdge bottomEdge fa"),u.appendChild(_),E.setAttribute("class","fa "+r.parentNodeSymbol+" symbol"),S.insertBefore(E,S.children[0])}}u.addEventListener("mouseenter",n._hoverNode.bind(n)),u.addEventListener("mouseleave",n._hoverNode.bind(n)),u.addEventListener("click",n._dispatchClickEvent.bind(n)),r.draggable&&(u.addEventListener("dragstart",n._onDragStart.bind(n)),u.addEventListener("dragover",n._onDragOver.bind(n)),u.addEventListener("dragend",n._onDragEnd.bind(n)),u.addEventListener("drop",n._onDrop.bind(n))),r.createNode&&r.createNode(u,e),i(u)})}},{key:"buildHierarchy",value:function(e,t,n,r){var i=this,o=this.options,s=void 0,a=t.children,l=o.verticalDepth&&n+1>=o.verticalDepth;if(Object.keys(t).length>1&&(s=l?e:document.createElement("table"),l||e.appendChild(s),this._createNode(t,n).then(function(e){if(l)s.insertBefore(e,s.firstChild);else{var t=document.createElement("tr");t.innerHTML="\n \n \n ",t.children[0].appendChild(e),s.insertBefore(t,s.children[0]?s.children[0]:null)}r&&r()}).catch(function(e){console.error("Failed to creat node",e)})),a){1===Object.keys(t).length&&(s=e);var c=void 0,d=o.verticalDepth&&n+2>=o.verticalDepth,u=i.chart.dataset.inEdit;if(c=u?"addSiblings"===u?"":" hidden":n+1>=o.depth?" hidden":"",!d){var h=document.createElement("tr");h.setAttribute("class","lines"+c),h.innerHTML='\n \n
\n \n ',s.appendChild(h)}var f=document.createElement("tr");f.setAttribute("class","lines"+c),f.innerHTML='\n \n '+a.slice(1).map(function(){return'\n \n \n '}).join("")+'\n \n ';var p=void 0;if(d)if(p=document.createElement("ul"),c&&p.classList.add(c.trim()),n+2===o.verticalDepth){var v=document.createElement("tr");v.setAttribute("class","verticalNodes"+c),v.innerHTML=" ",v.firstChild.appendChild(p),s.appendChild(v)}else s.appendChild(p);else(p=document.createElement("tr")).setAttribute("class","nodes"+c),s.appendChild(f),s.appendChild(p);a.forEach(function(e){var t=void 0;d?t=document.createElement("li"):(t=document.createElement("td")).setAttribute("colspan",2),p.appendChild(t),i.buildHierarchy(t,e,n+1,r)})}}},{key:"_clickChart",value:function(e){!this._closest(e.target,function(e){return e.classList&&e.classList.contains("node")})&&this.chart.querySelector(".node.focused")&&this.chart.querySelector(".node.focused").classList.remove("focused")}},{key:"_clickExportButton",value:function(){var e=this.options,t=this.chartContainer,n=t.querySelector(":scope > .mask"),r=t.querySelector(".orgchart:not(.hidden)"),i="l2r"===e.direction||"r2l"===e.direction;n?n.classList.remove("hidden"):((n=document.createElement("div")).setAttribute("class","mask"),n.innerHTML=' ',t.appendChild(n)),t.classList.add("canvasContainer"),window.html2canvas(r,{width:i?r.clientHeight:r.clientWidth,height:i?r.clientWidth:r.clientHeight,onclone:function(e){var t=e.querySelector(".canvasContainer");t.style.overflow="visible",t.querySelector(".orgchart:not(.hidden)").transform=""}}).then(function(e){var n=t.querySelector(".oc-download-btn");t.querySelector(".mask").classList.add("hidden"),n.setAttribute("href",e.toDataURL()),n.click()}).catch(function(e){console.error("Failed to export the curent orgchart!",e)}).finally(function(){t.classList.remove("canvasContainer")})}},{key:"_loopChart",value:function(e){var t=this,n={id:e.querySelector(".node").id};return e.children[3]&&Array.from(e.children[3].children).forEach(function(e){n.children||(n.children=[]),n.children.push(t._loopChart(e.firstChild))}),n}},{key:"_loopChartDataset",value:function(e){var t=this,n=JSON.parse(e.querySelector(".node").dataset.source);return e.children[3]&&Array.from(e.children[3].children).forEach(function(e){n.children||(n.children=[]),n.children.push(t._loopChartDataset(e.firstChild))}),n}},{key:"getChartJSON",value:function(){return this.chart.querySelector(".node").id?this._loopChartDataset(this.chart.querySelector("table")):"Error: Nodes of orghcart to be exported must have id attribute!"}},{key:"getHierarchy",value:function(){return this.chart.querySelector(".node").id?this._loopChart(this.chart.querySelector("table")):"Error: Nodes of orghcart to be exported must have id attribute!"}},{key:"_onPanStart",value:function(e){var t=e.currentTarget;if(this._closest(e.target,function(e){return e.classList&&e.classList.contains("node")})||e.touches&&e.touches.length>1)t.dataset.panning=!1;else{t.style.cursor="move",t.dataset.panning=!0;var n=0,r=0,i=window.getComputedStyle(t).transform;if("none"!==i){var o=i.split(",");i.includes("3d")?(n=Number.parseInt(o[12],10),r=Number.parseInt(o[13],10)):(n=Number.parseInt(o[4],10),r=Number.parseInt(o[5],10))}var s=0,a=0;if(e.targetTouches){if(1===e.targetTouches.length)s=e.targetTouches[0].pageX-n,a=e.targetTouches[0].pageY-r;else if(e.targetTouches.length>1)return}else s=e.pageX-n,a=e.pageY-r;t.dataset.panStart=JSON.stringify({startX:s,startY:a}),t.addEventListener("mousemove",this._onPanning.bind(this)),t.addEventListener("touchmove",this._onPanning.bind(this))}}},{key:"_onPanning",value:function(e){var t=e.currentTarget;if("false"!==t.dataset.panning){var n=0,r=0,i=JSON.parse(t.dataset.panStart),o=i.startX,s=i.startY;if(e.targetTouches){if(1===e.targetTouches.length)n=e.targetTouches[0].pageX-o,r=e.targetTouches[0].pageY-s;else if(e.targetTouches.length>1)return}else n=e.pageX-o,r=e.pageY-s;var a=window.getComputedStyle(t).transform;if("none"===a)a.includes("3d")?t.style.transform="matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, "+n+", "+r+", 0, 1)":t.style.transform="matrix(1, 0, 0, 1, "+n+", "+r+")";else{var l=a.split(",");a.includes("3d")?(l[12]=n,l[13]=r):(l[4]=n,l[5]=r+")"),t.style.transform=l.join(",")}}}},{key:"_onPanEnd",value:function(e){var t=this.chart;"true"===t.dataset.panning&&(t.dataset.panning=!1,t.style.cursor="default",document.body.removeEventListener("mousemove",this._onPanning),document.body.removeEventListener("touchmove",this._onPanning))}},{key:"_setChartScale",value:function(e,t){var n=window.getComputedStyle(e).transform;if("none"===n)e.style.transform="scale("+t+","+t+")";else{var r=n.split(",");n.includes("3d")?e.style.transform=n+" scale3d("+t+","+t+", 1)":(r[0]="matrix("+t,r[3]=t,e.style.transform=n+" scale("+t+","+t+")")}e.dataset.scale=t}},{key:"_onWheeling",value:function(e){e.preventDefault();var t=e.deltaY>0?.8:1.2;this._setChartScale(this.chart,t)}},{key:"_getPinchDist",value:function(e){return Math.sqrt((e.touches[0].clientX-e.touches[1].clientX)*(e.touches[0].clientX-e.touches[1].clientX)+(e.touches[0].clientY-e.touches[1].clientY)*(e.touches[0].clientY-e.touches[1].clientY))}},{key:"_onTouchStart",value:function(e){var t=this.chart;if(e.touches&&2===e.touches.length){var n=this._getPinchDist(e);t.dataset.pinching=!0,t.dataset.pinchDistStart=n}}},{key:"_onTouchMove",value:function(e){var t=this.chart;if(t.dataset.pinching){var n=this._getPinchDist(e);t.dataset.pinchDistEnd=n}}},{key:"_onTouchEnd",value:function(e){var t=this.chart;if(t.dataset.pinching){t.dataset.pinching=!1;var n=t.dataset.pinchDistEnd-t.dataset.pinchDistStart;n>0?this._setChartScale(t,1):n<0&&this._setChartScale(t,-1)}}},{key:"name",get:function(){return this._name}}]),e}(),z=Array.prototype.splice;r.prototype.clear=function(){this.__data__=[],this.size=0},r.prototype.delete=function(e){var t=this.__data__,r=n(t,e);return!(r<0||(r==t.length-1?t.pop():z.call(t,r,1),--this.size,0))},r.prototype.get=function(e){var t=this.__data__,r=n(t,e);return r<0?void 0:t[r][1]},r.prototype.has=function(e){return n(this.__data__,e)>-1},r.prototype.set=function(e,t){var r=this.__data__,i=n(r,e);return i<0?(++this.size,r.push([e,t])):r[i][1]=t,this};var H="object"==typeof global&&global&&global.Object===Object&&global,R="object"==typeof self&&self&&self.Object===Object&&self,I=H||R||Function("return this")(),M=I.Symbol,F=Object.prototype,U=F.hasOwnProperty,V=F.toString,J=M?M.toStringTag:void 0,X=Object.prototype.toString,Y="[object Null]",$="[object Undefined]",W=M?M.toStringTag:void 0,G="[object AsyncFunction]",Z="[object Function]",K="[object GeneratorFunction]",Q="[object Proxy]",ee=I["__core-js_shared__"],te=function(){var e=/[^.]+$/.exec(ee&&ee.keys&&ee.keys.IE_PROTO||"");return e?"Symbol(src)_1."+e:""}(),ne=Function.prototype.toString,re=/^\[object .+?Constructor\]$/,ie=Function.prototype,oe=Object.prototype,se=ie.toString,ae=oe.hasOwnProperty,le=RegExp("^"+se.call(ae).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),ce=l(I,"Map"),de=l(Object,"create"),ue="__lodash_hash_undefined__",he=Object.prototype.hasOwnProperty,fe=Object.prototype.hasOwnProperty,pe="__lodash_hash_undefined__";c.prototype.clear=function(){this.__data__=de?de(null):{},this.size=0},c.prototype.delete=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t},c.prototype.get=function(e){var t=this.__data__;if(de){var n=t[e];return n===ue?void 0:n}return he.call(t,e)?t[e]:void 0},c.prototype.has=function(e){var t=this.__data__;return de?void 0!==t[e]:fe.call(t,e)},c.prototype.set=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=de&&void 0===t?pe:t,this},u.prototype.clear=function(){this.size=0,this.__data__={hash:new c,map:new(ce||r),string:new c}},u.prototype.delete=function(e){var t=d(this,e).delete(e);return this.size-=t?1:0,t},u.prototype.get=function(e){return d(this,e).get(e)},u.prototype.has=function(e){return d(this,e).has(e)},u.prototype.set=function(e,t){var n=d(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this};var ve=200;h.prototype.clear=function(){this.__data__=new r,this.size=0},h.prototype.delete=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n},h.prototype.get=function(e){return this.__data__.get(e)},h.prototype.has=function(e){return this.__data__.has(e)},h.prototype.set=function(e,t){var n=this.__data__;if(n instanceof r){var i=n.__data__;if(!ce||i.length0){if(++t>=it)return arguments[0]}else t=0;return e.apply(void 0,arguments)}}(rt),lt=function(e){return q(function(n,r){var i=-1,s=r.length,a=s>1?r[s-1]:void 0,l=s>2?r[2]:void 0;for(a=e.length>3&&"function"==typeof a?(s--,a):void 0,l&&function(e,n,r){if(!o(r))return!1;var i=typeof n;return!!("number"==i?_(r)&&S(n,r.length):"string"==i&&n in r)&&t(r[n],e)}(r[0],r[1],l)&&(a=s<3?void 0:a,s=1),n=Object(n);++i
6 |
7 |
8 |
9 |
30 | ```
31 |
--------------------------------------------------------------------------------
/docs/props.md:
--------------------------------------------------------------------------------
1 | ### Vue-OrgChart props
2 |
3 | ### Example
4 |
5 | ` `
6 |
7 | ` `
8 |
9 | ### Props
10 |
11 |
12 |
13 | Name Type Required Default Description
14 |
15 |
16 |
17 | 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.
18 |
19 |
20 | pan boolean no false Users could pan the orgchart by mouse drag&drop if they enable this option.
21 |
22 |
23 | zoom boolean no false Users could zoomin/zoomout the orgchart by mouse wheel if they enable this option.
24 |
25 |
26 | 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").
27 |
28 |
29 | verticalDepth integer no Users can make use of this option to align the nodes vertically from the specified depth.
30 |
31 |
32 | toggleSiblingsResp boolean no false Once enable this option, users can show/hide left/right sibling nodes respectively by clicking left/right arrow.
33 |
34 |
35 | toggleCollapse boolean no true Show the arrow and you can click it to collapse the node
36 |
37 |
38 | 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.
39 |
40 |
41 | depth positive integer no 999 It indicates the level that at the very beginning orgchart is expanded to.
42 |
43 |
44 | 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.
45 |
46 |
47 | parentNodeSymbol string no " " Using font awesome icon to imply that the node has child nodes.
48 |
49 |
50 | nodeContent string no It sets one property of datasource as text content of content section of orgchart node.
51 |
52 |
53 | nodeId string no "id" It sets one property of datasource as unique identifier of every orgchart node.
54 |
55 |
56 | 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.
57 |
58 |
59 | exportButton boolean no false It enable the export button for orgchart.
60 |
61 |
62 | exportButtonName string no the name for export Button
63 |
64 |
65 | exportFilename string no "Orgchart" It's filename when you export current orgchart as a picture.
66 |
67 |
68 | chartClass string no "" when you wanna instantiate multiple orgcharts on one page, you should add diffent classname to them in order to distinguish them.
69 |
70 |
71 | 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.
72 |
73 |
74 | 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.
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/docs/quickstart.md:
--------------------------------------------------------------------------------
1 | ## Quick Start
2 |
3 | ### Install
4 | ```shell
5 | npm install vue-orgchart -S
6 | ```
7 |
8 | ### Import in your project
9 |
10 | > `main.js`
11 |
12 | ```js
13 | import 'vue-orgchart/dist/style.min.css'
14 | ```
15 |
16 | > In `*.vue`
17 |
18 | ```js
19 |
20 | import { VoBasic } from 'vue-orgchart'
21 | export default {
22 | components: { VoEdit },
23 | created () {
24 | this.chartData = {
25 | name: 'JavaScript',
26 | children: [
27 | { name: 'Angular' },
28 | {
29 | name: 'React',
30 | children: [{ name: 'Preact' }]
31 | },
32 | {
33 | name: 'Vue',
34 | children: [{ name: 'Moon' }]
35 | }
36 | ]
37 | }
38 | }
39 | }
40 | ```
41 |
42 | ### CDN
43 | ```html
44 |
45 |
46 | ```
47 |
--------------------------------------------------------------------------------
/docs/style.css:
--------------------------------------------------------------------------------
1 | iframe {
2 | border: 2px solid #eee;
3 | }
4 |
5 | * {
6 | -webkit-font-smoothing: inherit !important
7 | }
8 |
9 | .vuep {
10 | height: 460px;
11 | }
12 |
13 | .cm-error {
14 | color: rgba(255, 83, 112, 1) !important;
15 | background-color: inherit !important;
16 | }
17 |
18 | .data-empty {
19 | position: absolute;
20 | left: 0;
21 | right: 0;
22 | top: 0;
23 | bottom: 0;
24 | display: flex;
25 | justify-content: center;
26 | align-items: center;
27 | background-color: rgba(255, 255, 255, .7);
28 | color: #888;
29 | font-size: 14px;
30 | }
31 |
32 | .demo-block .source {
33 | text-align: center;
34 | }
35 |
36 | .markdown-section tr {
37 | border: 1px solid #fff;
38 | background:#fff;
39 | }
40 |
--------------------------------------------------------------------------------
/docs/style.min.css:
--------------------------------------------------------------------------------
1 | #wrapper {
2 | width: 50%;
3 | margin: 0 auto;
4 | }
5 |
6 | #wrapper li {
7 | margin-top: 20px;
8 | }
9 |
10 | #wrapper a {
11 | font-size: 24px;
12 | }
13 |
14 | #wrapper span {
15 | font-size: 24px;
16 | }
17 |
18 | #chart-container {
19 | position: relative;
20 | display: inline-block;
21 | border-radius: 5px;
22 | overflow: auto;
23 | overflow-x: hidden;
24 | text-align: center;
25 | font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif;
26 | font-size: 14px;
27 | }
28 | .markdown-section p.tip, .markdown-section tr:nth-child(2n) {
29 | background:#fff !important;
30 | }
31 | .vuep-error, .vuep-preview {
32 | padding: 0;
33 | }
34 | #edit-panel button {
35 | background-color:#fff;
36 | }
37 | table {
38 | border-color:#fff;
39 | }
40 | .orgchart {
41 | display: inline-block;
42 | min-height: 100%;
43 | min-width: 100%;
44 | -webkit-touch-callout: none;
45 | -webkit-user-select: none;
46 | -khtml-user-select: none;
47 | -moz-user-select: none;
48 | -ms-user-select: none;
49 | user-select: none;
50 | background-size: 10px 10px;
51 | border: 1px dashed transparent;
52 | }
53 |
54 | .orgchart .hidden, .orgchart~.hidden {
55 | display: none;
56 | }
57 |
58 | .orgchart div,
59 | .orgchart div::before,
60 | .orgchart div::after {
61 | -webkit-box-sizing: border-box;
62 | -moz-box-sizing: border-box;
63 | box-sizing: border-box;
64 | }
65 |
66 | .orgchart.b2t {
67 | -ms-transform: rotate(180deg);
68 | -moz-transform: rotate(180deg);
69 | -webkit-transform: rotate(180deg);
70 | transform: rotate(180deg);
71 | }
72 |
73 | .orgchart.l2r {
74 | position: absolute;
75 | -ms-transform: rotate(-90deg) rotateY(180deg);
76 | -moz-transform: rotate(-90deg) rotateY(180deg);
77 | -webkit-transform: rotate(-90deg) rotateY(180deg);
78 | transform: rotate(-90deg) rotateY(180deg);
79 | -ms-transform-origin: left top;
80 | -moz-transform-origin: left top;
81 | -webkit-transform-origin: left top;
82 | transform-origin: left top;
83 | }
84 |
85 | .orgchart .verticalNodes ul {
86 | list-style: none;
87 | margin: 0;
88 | padding-left: 18px;
89 | text-align: left;
90 | }
91 |
92 | .orgchart .verticalNodes ul:first-child {
93 | margin-top: 3px;
94 | }
95 |
96 | .orgchart .verticalNodes>td::before {
97 | content: '';
98 | border: 1px solid rgba(217, 83, 79, 0.8);
99 | }
100 |
101 | .orgchart .verticalNodes>td>ul>li:first-child::before {
102 | top: -4px;
103 | height: 30px;
104 | width: calc(50% - 2px);
105 | border-width: 2px 0 0 2px;
106 | }
107 |
108 | .orgchart .verticalNodes ul>li {
109 | position: relative;
110 | }
111 |
112 | .orgchart .verticalNodes ul>li::before,
113 | .orgchart .verticalNodes ul>li::after {
114 | content: '';
115 | position: absolute;
116 | left: -6px;
117 | border-color: rgba(217, 83, 79, 0.8);
118 | border-style: solid;
119 | border-width: 0 0 2px 2px;
120 | -webkit-box-sizing: border-box;
121 | -moz-box-sizing: border-box;
122 | box-sizing: border-box;
123 | }
124 |
125 | .orgchart .verticalNodes ul>li::before {
126 | top: -4px;
127 | height: 30px;
128 | width: 11px;
129 | }
130 |
131 | .orgchart .verticalNodes ul>li::after {
132 | top: 1px;
133 | height: 100%;
134 | }
135 |
136 | .orgchart .verticalNodes ul>li:first-child::after {
137 | top: 24px;
138 | width: 11px;
139 | border-width: 2px 0 0 2px;
140 | }
141 |
142 | .orgchart .verticalNodes ul>li:last-child::after {
143 | border-width: 2px 0 0;
144 | }
145 |
146 | .orgchart.r2l {
147 | position: absolute;
148 | -ms-transform: rotate(90deg);
149 | -moz-transform: rotate(90deg);
150 | -webkit-transform: rotate(90deg);
151 | transform: rotate(90deg);
152 | -ms-transform-origin: left top;
153 | -moz-transform-origin: left top;
154 | -webkit-transform-origin: left top;
155 | transform-origin: left top;
156 | }
157 |
158 | .orgchart>.spinner {
159 | font-size: 100px;
160 | margin-top: 30px;
161 | color: rgba(68, 157, 68, 0.8);
162 | }
163 |
164 | .orgchart table {
165 | overflow: hidden;
166 | border-spacing: 0;
167 | border-collapse: separate;
168 | }
169 |
170 | .orgchart>table:first-child{
171 | margin: 20px auto;
172 | }
173 |
174 | .orgchart td {
175 | text-align: center;
176 | vertical-align: top;
177 | padding: 0;
178 | border:#fff;
179 | }
180 |
181 | .orgchart tr.lines .topLine {
182 | border-top: 2px solid #616161;
183 | }
184 |
185 | .orgchart tr.lines .rightLine {
186 | border-right: 1px solid #616161;
187 | float: none;
188 | border-radius: 0;
189 | }
190 |
191 | .orgchart tr.lines .leftLine {
192 | border-left: 1px solid #616161;
193 | float: none;
194 | border-radius: 0;
195 | }
196 |
197 | .orgchart tr.lines .downLine {
198 | background-color: #616161;
199 | margin: 0 auto;
200 | height: 20px;
201 | width: 2px;
202 | float: none;
203 | }
204 |
205 | /* node styling */
206 | .orgchart .node {
207 | display: inline-block;
208 | position: relative;
209 | margin: 0;
210 | padding: 3px;
211 | border: 2px transparent;
212 | text-align: center;
213 | width: 130px;
214 | }
215 |
216 | .orgchart.l2r .node, .orgchart.r2l .node {
217 | width: 50px;
218 | height: 130px;
219 | }
220 |
221 | .orgchart .node>.hazy {
222 | opacity: 0.2;
223 | }
224 |
225 | .orgchart .node>.spinner {
226 | position: absolute;
227 | top: calc(50% - 15px);
228 | left: calc(50% - 15px);
229 | vertical-align: middle;
230 | font-size: 30px;
231 | color: rgba(68, 157, 68, 0.8);
232 | }
233 |
234 | .orgchart .node:hover {
235 | background-color: rgba(238, 217, 54, 0.5);
236 | transition: .5s;
237 | cursor: default;
238 | z-index: 20;
239 | }
240 |
241 | .orgchart .node.focused {
242 | background-color: rgba(238, 217, 54, 0.5);
243 | }
244 |
245 | .orgchart .ghost-node {
246 | position: fixed;
247 | left: -10000px;
248 | top: -10000px;
249 | }
250 |
251 | .orgchart .ghost-node rect {
252 | fill: #ffffff;
253 | stroke: #bf0000;
254 | }
255 |
256 | .orgchart .node.allowedDrop {
257 | border-color: rgba(68, 157, 68, 0.9);
258 | }
259 |
260 | .orgchart .node .title {
261 | text-align: center;
262 | font-size: 12px;
263 | font-weight: 300;
264 | height: 20px;
265 | line-height: 20px;
266 | overflow: hidden;
267 | text-overflow: ellipsis;
268 | white-space: nowrap;
269 | background-color: #42b983;
270 | color: #fff;
271 | border-radius: 4px 4px 0 0;
272 | }
273 |
274 | .orgchart.b2t .node .title {
275 | -ms-transform: rotate(-180deg);
276 | -moz-transform: rotate(-180deg);
277 | -webkit-transform: rotate(-180deg);
278 | transform: rotate(-180deg);
279 | -ms-transform-origin: center bottom;
280 | -moz-transform-origin: center bottom;
281 | -webkit-transform-origin: center bottom;
282 | transform-origin: center bottom;
283 | }
284 |
285 | .orgchart.l2r .node .title {
286 | -ms-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
287 | -moz-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
288 | -webkit-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
289 | transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
290 | -ms-transform-origin: bottom center;
291 | -moz-transform-origin: bottom center;
292 | -webkit-transform-origin: bottom center;
293 | transform-origin: bottom center;
294 | width: 120px;
295 | }
296 |
297 | .orgchart.r2l .node .title {
298 | -ms-transform: rotate(-90deg) translate(-40px, -40px);
299 | -moz-transform: rotate(-90deg) translate(-40px, -40px);
300 | -webkit-transform: rotate(-90deg) translate(-40px, -40px);
301 | transform: rotate(-90deg) translate(-40px, -40px);
302 | -ms-transform-origin: bottom center;
303 | -moz-transform-origin: bottom center;
304 | -webkit-transform-origin: bottom center;
305 | transform-origin: bottom center;
306 | width: 120px;
307 | }
308 |
309 | .orgchart .node .title .symbol {
310 | float: left;
311 | margin-top: 4px;
312 | margin-left: 2px;
313 | }
314 |
315 | .orgchart .node .content {
316 | width: 100%;
317 | height: 20px;
318 | font-size: 11px;
319 | line-height: 18px;
320 | border: 1px solid #42b983;
321 | border-radius: 0 0 4px 4px;
322 | text-align: center;
323 | background-color: #fff;
324 | color: #333;
325 | overflow: hidden;
326 | text-overflow: ellipsis;
327 | white-space: nowrap;
328 | }
329 |
330 | .orgchart.b2t .node .content {
331 | -ms-transform: rotate(180deg);
332 | -moz-transform: rotate(180deg);
333 | -webkit-transform: rotate(180deg);
334 | transform: rotate(180deg);
335 | -ms-transform-origin: center top;
336 | -moz-transform-origin: center top;
337 | -webkit-transform-origin: center top;
338 | transform-origin: center top;
339 | }
340 |
341 | .orgchart.l2r .node .content {
342 | -ms-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
343 | -moz-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
344 | -webkit-transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
345 | transform: rotate(-90deg) translate(-40px, -40px) rotateY(180deg);
346 | -ms-transform-origin: top center;
347 | -moz-transform-origin: top center;
348 | -webkit-transform-origin: top center;
349 | transform-origin: top center;
350 | width: 120px;
351 | }
352 |
353 | .orgchart.r2l .node .content {
354 | -ms-transform: rotate(-90deg) translate(-40px, -40px);
355 | -moz-transform: rotate(-90deg) translate(-40px, -40px);
356 | -webkit-transform: rotate(-90deg) translate(-40px, -40px);
357 | transform: rotate(-90deg) translate(-40px, -40px);
358 | -ms-transform-origin: top center;
359 | -moz-transform-origin: top center;
360 | -webkit-transform-origin: top center;
361 | transform-origin: top center;
362 | width: 120px;
363 | }
364 |
365 | .orgchart .node .edge {
366 | font-size: 15px;
367 | position: absolute;
368 | color: rgba(68, 157, 68, 0.5);
369 | cursor: default;
370 | transition: .2s;
371 | -webkit-transition: .2s;
372 | }
373 |
374 | .orgchart.noncollapsable .node .edge {
375 | display: none;
376 | }
377 |
378 | .orgchart .edge:hover {
379 | color: #449d44;
380 | cursor: pointer;
381 | }
382 |
383 | .orgchart .node .verticalEdge {
384 | width: calc(100% - 10px);
385 | width: -webkit-calc(100% - 10px);
386 | width: -moz-calc(100% - 10px);
387 | left: 5px;
388 | }
389 |
390 | .orgchart .node .topEdge {
391 | top: -4px;
392 | }
393 |
394 | .orgchart .node .bottomEdge {
395 | bottom: -4px;
396 | }
397 |
398 | .orgchart .node .horizontalEdge {
399 | width: 15px;
400 | height: calc(100% - 10px);
401 | height: -webkit-calc(100% - 10px);
402 | height: -moz-calc(100% - 10px);
403 | top: 5px;
404 | }
405 |
406 | .orgchart .node .rightEdge {
407 | right: -4px;
408 | }
409 |
410 | .orgchart .node .leftEdge {
411 | left: -4px;
412 | }
413 |
414 | .orgchart .node .horizontalEdge::before {
415 | position: absolute;
416 | top: calc(50% - 7px);
417 | top: -webkit-calc(50% - 7px);
418 | top: -moz-calc(50% - 7px);
419 | }
420 |
421 | .orgchart .node .rightEdge::before {
422 | right: 3px;
423 | }
424 |
425 | .orgchart .node .leftEdge::before {
426 | left: 3px;
427 | }
428 |
429 | .orgchart .node .toggleBtn {
430 | position: absolute;
431 | left: 5px;
432 | bottom: -2px;
433 | color: rgba(68, 157, 68, 0.6);
434 | }
435 |
436 | .orgchart .node .toggleBtn:hover {
437 | color: rgba(68, 157, 68, 0.8);
438 | }
439 |
440 | .oc-export-btn {
441 | display: inline-block;
442 | position: absolute;
443 | right: 5px;
444 | bottom: 5px;
445 | padding: 6px 12px;
446 | margin-bottom: 0;
447 | font-size: 14px;
448 | font-weight: 400;
449 | line-height: 1.42857143;
450 | text-align: center;
451 | white-space: nowrap;
452 | vertical-align: middle;
453 | -ms-touch-action: manipulation;
454 | touch-action: manipulation;
455 | cursor: pointer;
456 | -webkit-user-select: none;
457 | -moz-user-select: none;
458 | -ms-user-select: none;
459 | user-select: none;
460 | color: #fff;
461 | background-color: #409eff;
462 | border: 1px solid transparent;
463 | border-color: #409eff;
464 | border-radius: 4px;
465 | }
466 |
467 | .oc-export-btn:hover,.oc-export-btn:focus,.oc-export-btn:active {
468 | background-color: #409eff;
469 | border-color: #409eff;
470 | }
471 |
472 | .orgchart~.mask {
473 | position: absolute;
474 | top: 0;
475 | right: 0;
476 | bottom: 0;
477 | left: 0;
478 | z-index: 999;
479 | text-align: center;
480 | background-color: rgba(0,0,0,0.3);
481 | }
482 |
483 | .orgchart~.mask .spinner {
484 | position: absolute;
485 | top: calc(50% - 54px);
486 | left: calc(50% - 54px);
487 | color: rgba(255,255,255,0.8);
488 | font-size: 108px;
489 | }
490 |
491 | .orgchart .node {
492 | -webkit-transition: all 0.3s;
493 | transition: all 0.3s;
494 | top: 0;
495 | left: 0;
496 | }
497 |
498 | .orgchart .slide-down {
499 | opacity: 0;
500 | top: 40px;
501 | }
502 |
503 | .orgchart.l2r .node.slide-down, .orgchart.r2l .node.slide-down {
504 | top: 130px;
505 | }
506 |
507 | .orgchart .slide-up {
508 | opacity: 0;
509 | top: -40px;
510 | }
511 |
512 | .orgchart.l2r .node.slide-up, .orgchart.r2l .node.slide-up {
513 | top: -130px;
514 | }
515 |
516 | .orgchart .slide-right {
517 | opacity: 0;
518 | left: 130px;
519 | }
520 |
521 | .orgchart.l2r .node.slide-right, .orgchart.r2l .node.slide-right {
522 | left: 40px;
523 | }
524 |
525 | .orgchart .slide-left {
526 | opacity: 0;
527 | left: -130px;
528 | }
529 |
530 | .orgchart.l2r .node.slide-left, .orgchart.r2l .node.slide-left {
531 | left: -40px;
532 | }
533 | #edit-panel {
534 | position: relative;
535 | left: 10px;
536 | width: calc(100% - 40px);
537 | border-radius: 4px;
538 | float: left;
539 | margin-top: 20px;
540 | padding: 10px 5px 10px 10px;
541 | font-size: 14px;
542 | line-height: 1.5;
543 | border-radius: 2px;
544 | color: rgba(0, 0, 0, 0.65);
545 | background-color: #fff;
546 | }
547 |
548 | #edit-panel .btn-inputs {
549 | font-size: 24px;
550 | }
551 |
552 | #edit-panel label {
553 | font-weight: bold;
554 | }
555 |
556 | #edit-panel .new-node {
557 | height: 24px;
558 | -webkit-appearance: none;
559 | background-color:#fff;
560 | background-image: none;
561 | border-radius: 4px;
562 | line-height: 1;
563 | border: 1px solid #d8dce5;
564 | box-sizing: border-box;
565 | color: #5a5e66;
566 | display: inline-block;
567 | transition: border-color .2s cubic-bezier(.645,.045,.355,1);
568 | }
569 |
570 | #edit-panel .new-node:focus {
571 | border-color: #409eff;
572 | outline: none;
573 | }
574 |
575 | #edit-panel .new-node:hover {
576 | border-color: #b4bccc;
577 | }
578 |
579 | #edit-panel.edit-parent-node .selected-node-group{
580 | display: none;
581 | }
582 |
583 | #chart-state-panel, #selected-node, #btn-remove-input {
584 | margin-right: 20px;
585 | }
586 |
587 | #edit-panel button {
588 | /* color: #333;
589 | background-color: #fff; */
590 | display: inline-block;
591 | padding: 6px 12px;
592 | margin-bottom: 0;
593 | line-height: 1.42857143;
594 | text-align: center;
595 | white-space: nowrap;
596 | border-radius: 4px;
597 | vertical-align: middle;
598 | -ms-touch-action: manipulation;
599 | touch-action: manipulation;
600 | cursor: pointer;
601 | -webkit-user-select: none;
602 | -moz-user-select: none;
603 | -ms-user-select: none;
604 | user-select: none;
605 | background-image: none;
606 | }
607 |
608 | #edit-panel.edit-parent-node button:not(#btn-add-nodes) {
609 | display: none;
610 | }
611 |
612 | #edit-panel button:hover,.edit-panel button:focus,.edit-panel button:active {
613 | border-color: #409eff;
614 | box-shadow: 0 0 10px #409eff;
615 | }
616 |
617 | #new-nodelist {
618 | display: inline-block;
619 | list-style:none;
620 | margin-top: -2px;
621 | padding: 0;
622 | vertical-align: text-top;
623 | }
624 |
625 | #new-nodelist>* {
626 | padding-bottom: 4px;
627 | }
628 |
629 | .btn-inputs {
630 | vertical-align: sub;
631 | }
632 |
633 |
634 | .btn-inputs:hover {
635 | text-shadow: 0 0 4px #fff;
636 | }
637 |
638 | .radio-panel input[type='radio'] {
639 | border: 1px solid #d8dce5;
640 | border-radius: 100%;
641 | cursor: pointer;
642 | box-sizing: border-box;
643 | display: inline-block;
644 | height: 14px;
645 | width: 14px;
646 | vertical-align: top;
647 | }
648 |
649 | #edit-panel.view-state .radio-panel input[type='radio']+label {
650 | font-size: 14px;
651 | font-weight: 500;
652 | /* color: #5a5e66; */
653 | line-height: 1;
654 | }
655 |
656 | #btn-add-nodes {
657 | margin-left: 20px;
658 | }
659 |
--------------------------------------------------------------------------------
/docs/zh-cn/README.md:
--------------------------------------------------------------------------------
1 | ## vue-orgchart
2 |
3 | > A vue wrapper for OrgChart.js.
4 |
5 | ### 前言
6 | - 首先感谢dabeng的Orgchart.js -- [OrgChart.js](https://github.com/dabeng/OrgChart.js)
7 | - 如果你想用OrgChart.js的Vue封装,可以直接用 [我的项目](https://github.com/spiritree/vue-orgchart)
8 |
9 | ### 功能
10 | - JSON格式导入导出树形关系图
11 | - 支持树形关系图导出图片
12 | - 可拖拉树形关系图
13 | - 可编辑树形关系图
14 |
15 | ...
16 |
--------------------------------------------------------------------------------
/docs/zh-cn/_navbar.md:
--------------------------------------------------------------------------------
1 | - Translations
2 | - [:cn: 中文](/zh-cn/)
3 | - [:uk: English](/)
4 |
--------------------------------------------------------------------------------
/docs/zh-cn/_sidebar.md:
--------------------------------------------------------------------------------
1 | - 入门
2 | - [快速开始](zh-cn/quickstart)
3 | - [图表属性](zh-cn/props)
4 | - 图表
5 | - [基础组织树图](zh-cn/basic)
6 | - [缩放组织树图](zh-cn/panzoom)
7 | - [可拖拉组织树图](zh-cn/drag)
8 | - [可导出组织树形图图片](zh-cn/exportpic)
9 | - [可编辑组织树图](zh-cn/edit)
10 |
--------------------------------------------------------------------------------
/docs/zh-cn/basic.md:
--------------------------------------------------------------------------------
1 | ## 基础组织树图
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
7 |
8 |
9 |
29 | ```
30 |
--------------------------------------------------------------------------------
/docs/zh-cn/drag.md:
--------------------------------------------------------------------------------
1 | ## 可拖拉组织树图
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
7 |
8 |
9 |
29 | ```
30 |
31 |
--------------------------------------------------------------------------------
/docs/zh-cn/edit.md:
--------------------------------------------------------------------------------
1 | ## 可编辑组织树图
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
33 |
34 |
35 |
170 | ```
171 | ```json
172 | ```
173 |
--------------------------------------------------------------------------------
/docs/zh-cn/exportpic.md:
--------------------------------------------------------------------------------
1 | ## 可导出组织树图图片
2 |
3 | ```html
4 | /*vue*/
5 |
6 |
7 |
8 |
9 |
30 | ```
31 |
--------------------------------------------------------------------------------
/docs/zh-cn/panzoom.md:
--------------------------------------------------------------------------------
1 | ## 缩放组织树图
2 |
3 |
4 | ```html
5 | /*vue*/
6 |
7 |
8 |
9 |
10 |
31 | ```
32 |
--------------------------------------------------------------------------------
/docs/zh-cn/props.md:
--------------------------------------------------------------------------------
1 | ### 图表属性
2 |
3 | ### 例子
4 |
5 | ` `
6 |
7 | ` `
8 |
9 | !> 在非webpack等编译打包环境中,注意将camelCase (驼峰式命名) 的 prop 需要转换为相对应的 kebab-case (短横线分隔式命名),如`chartName`=>`chart-name`
10 |
11 | ### 属性
12 |
13 |
14 |
15 | 配置项 类型 需要 默认 描述
16 |
17 |
18 |
19 | data Object,String yes 图表数据
20 |
21 |
22 | pan Boolean no false 鼠标拖放来平移该组织图
23 |
24 |
25 | zoom Boolean no false 通过鼠标滚轮放大/缩小组织图
26 |
27 |
28 | direction String no "t2b" t2b(表示 "top to bottom", it's default value), b2t(表示 "bottom to top"), l2r(表示 "left to right"), r2l(表示 "right to left").
29 |
30 |
31 | verticalDepth Interger no 垂直深度
32 |
33 |
34 | toggleSiblingsResp Boolean no false 一旦启用此选项,用户可以显示/隐藏左/右兄弟节点分别点击左/右箭头
35 |
36 |
37 | toggleCollapse Boolean no true 你可以设值为false来关闭节点的箭头图标
38 |
39 |
40 | ajaxURL String no Ajax获取JSON数据
41 |
42 |
43 | depth Positive Interger no 999 最大级别
44 |
45 |
46 | nodeTitle String no "name" 树形组织图中的元素名称
47 |
48 |
49 | parentNodeSymbol String no "" 父元素节点的图标class
50 |
51 |
52 | nodeContent String no 树形组织图中二级元素名称
53 |
54 |
55 | nodeId String no "id" 节点的ID值
56 |
57 |
58 | createNode Function no 一个回调函数来定制创造节点的规则
59 |
60 |
61 | exportButton Boolean no false 导出图片
62 |
63 |
64 | exportButtonName string no 导出图片按钮标题
65 |
66 |
67 | exportFilename String no "Orgchart" 导出图片名称
68 |
69 |
70 | chartClass String no "" 图标的class
71 |
72 |
73 | draggable Boolean no false 可拖拉选项
74 |
75 |
76 | dropCriteria Function no 可以通过函数来限制拖拽节点和放置区之间的关系。另外,这个函数接受三个参数(draggedNode,dragZone,dropZone),只返回boolean值。
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/docs/zh-cn/quickstart.md:
--------------------------------------------------------------------------------
1 | ## 快速开始
2 |
3 | ### 安装
4 | ```shell
5 | npm install vue-orgchart -S
6 | ```
7 |
8 | ### 在项目中导入
9 |
10 | > `main.js`
11 |
12 | ```js
13 | import 'vue-orgchart/dist/style.min.css'
14 | ```
15 |
16 | > In `*.vue`
17 |
18 | ```js
19 |
20 | import { VoBasic } from 'vue-orgchart'
21 | export default {
22 | components: { VoEdit },
23 | created () {
24 | this.chartData = {
25 | name: 'JavaScript',
26 | children: [
27 | { name: 'Angular' },
28 | {
29 | name: 'React',
30 | children: [{ name: 'Preact' }]
31 | },
32 | {
33 | name: 'Vue',
34 | children: [{ name: 'Moon' }]
35 | }
36 | ]
37 | }
38 | }
39 | }
40 | ```
41 |
42 | ### CDN
43 | ```html
44 |
45 |
46 | ```
47 |
--------------------------------------------------------------------------------
/examples/Ajax.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
34 |
35 |
36 | JSON
37 |
38 |
39 |
40 |
41 |
42 |
189 |
239 |
240 |
--------------------------------------------------------------------------------
/examples/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
10 |
11 |
35 |
36 |
37 | JSON
38 |
39 |
40 |
41 |
42 |
43 |
170 |
220 |
--------------------------------------------------------------------------------
/examples/data/basic.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '基础树形关系图(Basic orgchart)',
3 | type: 'basic',
4 | data: [
5 | {
6 | name: 'Basic orgchart',
7 | data: {
8 | name: 'JavaScript',
9 | children: [
10 | { name: 'Angular' },
11 | {
12 | name: 'React',
13 | children: [{ name: 'Preact' }]
14 | },
15 | {
16 | name: 'Vue',
17 | children: [{ name: 'Moon' }]
18 | }
19 | ]
20 | }
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/examples/data/edit.js:
--------------------------------------------------------------------------------
1 | export default {
2 | name: '可编辑树形关系图(Editable orgchart)',
3 | type: 'edit',
4 | data: [
5 | {
6 | name: 'Editable orgchart',
7 | data: {
8 | name: 'JavaScript',
9 | children: [
10 | { name: 'Angular' },
11 | {
12 | name: 'React',
13 | children: [{ name: 'Preact' }]
14 | },
15 | {
16 | name: 'Vue',
17 | children: [{ name: 'Moon' }]
18 | }
19 | ]
20 | }
21 | }
22 | ]
23 | }
24 |
--------------------------------------------------------------------------------
/examples/data/index.js:
--------------------------------------------------------------------------------
1 | import basic from './basic'
2 | import edit from './edit'
3 |
4 | export default {
5 | basic,
6 | edit
7 | }
8 |
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-orgchart
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/examples/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import store from './store'
4 | import '../dist/style.min.css'
5 |
6 | new Vue({
7 | el: '#app',
8 | store,
9 | render: h => h(App)
10 | })
11 |
--------------------------------------------------------------------------------
/examples/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 | import { getData } from './service'
4 |
5 | Vue.use(Vuex)
6 |
7 | const state = {
8 | treeData: {}
9 | }
10 |
11 | const actions = {
12 | async getAreas ({ commit }) {
13 | const res = await getData()
14 | commit('getAreas', res)
15 | },
16 | }
17 |
18 | const mutations = {
19 | 'getAreas' (state, treeData) {
20 | state.treeData = treeData
21 | },
22 | }
23 |
24 | export default new Vuex.Store({
25 | state,
26 | // getters,
27 | actions,
28 | mutations
29 | })
30 |
--------------------------------------------------------------------------------
/examples/store/service.js:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 |
3 | export const getData = () => {
4 | return axios
5 | .get("https://easy-mock.com/mock/5a2f9181c430642f15c5fef8/chart/orgtree")
6 | .then((res) => res.data)
7 | }
8 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-orgchart",
3 | "description": "A vue wrapper for OrgChart.js",
4 | "version": "1.1.7",
5 | "author": {
6 | "name": "spiritree",
7 | "email": "spiritreess@gmail.com",
8 | "url": "https://github.com/spiritree"
9 | },
10 | "files": [
11 | "dist",
12 | "src",
13 | "docs"
14 | ],
15 | "main": "dist/vue-orgchart.min.js",
16 | "license": "MIT",
17 | "homepage": "https://spiritree.github.io/vue-orgchart",
18 | "bugs": {
19 | "url": "https://github.com/spiritree/vue-orgchart/issues"
20 | },
21 | "scripts": {
22 | "dev": "webpack-dev-server --config ./build/webpack.config.js",
23 | "build": "webpack --progress --hide-modules --config ./build/webpack.config.build.js && cross-env NODE_ENV=production webpack --progress --hide-modules --config ./build/webpack.config.build.min.js",
24 | "rollup": "node build/rollup.config.js",
25 | "docs": "docsify serve docs --port 3002",
26 | "test": "karma start ./test/karma.conf.js"
27 | },
28 | "repository": {
29 | "type": "git",
30 | "url": "git+https://github.com/spiritree/vue-orgchart.git"
31 | },
32 | "keywords": [
33 | "vue",
34 | "orgchart"
35 | ],
36 | "dependencies": {
37 | "axios": "^0.17.1",
38 | "orgchart.js": "0.0.4",
39 | "vue": "^2.5.13",
40 | "vue-loader": "^14.1.1",
41 | "vue-style-loader": "^3.1.2",
42 | "vue-template-compiler": "^2.5.13",
43 | "vuex": "^3.0.1"
44 | },
45 | "browserslist": [
46 | "> 1%",
47 | "last 2 versions",
48 | "not ie <= 8"
49 | ],
50 | "devDependencies": {
51 | "autoprefixer": "^7.1.6",
52 | "babel-core": "^6.26.0",
53 | "babel-eslint": "^8.0.2",
54 | "babel-loader": "^7.1.2",
55 | "babel-plugin-external-helpers": "^6.22.0",
56 | "babel-plugin-transform-object-assign": "^6.22.0",
57 | "babel-plugin-transform-runtime": "^6.23.0",
58 | "babel-preset-env": "^1.6.0",
59 | "babel-preset-es2015": "^6.24.1",
60 | "babel-preset-latest": "^6.24.1",
61 | "babel-preset-stage-2": "^6.24.1",
62 | "cross-env": "^5.0.5",
63 | "css-loader": "^0.28.7",
64 | "cssnano": "^3.10.0",
65 | "docsify-cli": "^4.2.0",
66 | "es6-promise": "^4.1.1",
67 | "eslint": "^4.12.0",
68 | "eslint-config-standard": "^10.2.1",
69 | "eslint-friendly-formatter": "^3.0.0",
70 | "eslint-loader": "^1.9.0",
71 | "eslint-plugin-html": "^4.0.1",
72 | "eslint-plugin-import": "^2.8.0",
73 | "eslint-plugin-node": "^5.2.1",
74 | "eslint-plugin-promise": "^3.6.0",
75 | "eslint-plugin-standard": "^3.0.1",
76 | "extract-text-webpack-plugin": "^3.0.2",
77 | "file-loader": "^1.1.4",
78 | "html-webpack-plugin": "^2.30.1",
79 | "jasmine-core": "^2.8.0",
80 | "json-loader": "^0.5.7",
81 | "karma": "^1.7.0",
82 | "karma-babel-preprocessor": "^6.0.1",
83 | "karma-chrome-launcher": "^2.1.1",
84 | "karma-commonjs": "^1.0.0",
85 | "karma-jasmine": "^1.1.0",
86 | "karma-phantomjs-launcher": "^1.0.4",
87 | "karma-spec-reporter": "^0.0.31",
88 | "karma-webpack": "^2.0.3",
89 | "lodash-es": "^4.17.4",
90 | "opn": "^5.1.0",
91 | "rollup": "^0.52.0",
92 | "rollup-plugin-alias": "^1.4.0",
93 | "rollup-plugin-babel": "^3.0.2",
94 | "rollup-plugin-commonjs": "^8.2.6",
95 | "rollup-plugin-node-resolve": "^3.0.0",
96 | "rollup-plugin-uglify": "^2.0.1",
97 | "rollup-plugin-vue": "^2.5.2",
98 | "webpack": "^3.8.0",
99 | "webpack-dev-server": "^2.9.1"
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/src/components/VoBasic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
66 |
67 |
676 |
--------------------------------------------------------------------------------
/src/components/VoEdit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
75 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import VoBasic from '../src/components/VoBasic.vue'
2 | import VoEdit from '../src/components/VoEdit.vue'
3 |
4 | export {
5 | VoBasic,
6 | VoEdit
7 | }
8 |
9 | if (typeof window !== 'undefined' && window.Vue) {
10 | window.Vue.component('vo-basic', VoBasic)
11 | window.Vue.component('vo-edit', VoEdit)
12 | }
13 |
--------------------------------------------------------------------------------
/src/lib/lodash.js:
--------------------------------------------------------------------------------
1 | import merge from 'lodash-es/merge'
2 |
3 | export const mergeOptions = (obj, src) => {
4 | return merge(obj, src)
5 | }
6 |
--------------------------------------------------------------------------------
/src/lib/utils.js:
--------------------------------------------------------------------------------
1 | export const closest = (el, fn) => {
2 | return el && ((fn(el) && el !== document.querySelector('.orgchart')) ? el : closest(el.parentNode, fn))
3 | }
4 |
5 | export const addClass = (elements, classNames) => {
6 | elements.forEach((el) => {
7 | if (classNames.includes(' ')) {
8 | classNames.split(' ').forEach((className) => el.classList.add(className))
9 | } else {
10 | el.classList.add(classNames)
11 | }
12 | })
13 | }
14 |
15 | export const removeClass = (elements, classNames) => {
16 | elements.forEach((el) => {
17 | if (classNames.includes(' ')) {
18 | classNames.split(' ').forEach((className) => el.classList.remove(className))
19 | } else {
20 | el.classList.remove(classNames)
21 | }
22 | })
23 | }
24 |
25 | export const bindEventHandler = (selector, type, fn, parentSelector) => {
26 | if (parentSelector) {
27 | document.querySelector(parentSelector).addEventListener(type, function (event) {
28 | if ((event.target.classList && event.target.classList.contains(selector.slice(1))) ||
29 | closest(event.target, el => el.classList && el.classList.contains(selector.slice(1)))) {
30 | fn(event)
31 | }
32 | })
33 | } else {
34 | document.querySelectorAll(selector).forEach(element => {
35 | element.addEventListener(type, fn)
36 | })
37 | }
38 | }
39 |
40 | export const clickNode = (event) => {
41 | let sNode = closest(event.target, el => el.classList && el.classList.contains('node'))
42 | let sNodeInput = document.getElementById('selected-node')
43 |
44 | sNodeInput.value = sNode.querySelector('.title').textContent
45 | sNodeInput.dataset.node = sNode.id
46 | }
47 |
48 | export const clickChart = (event) => {
49 | if (!closest(event.target, el => el.classList && el.classList.contains('node'))) {
50 | document.getElementById('selected-node').textContent = ''
51 | }
52 | }
53 |
54 | export const addInputs = () => {
55 | let newNode = document.createElement('li')
56 | newNode.innerHTML = ` `
57 | document.getElementById('new-nodelist').appendChild(newNode)
58 | }
59 |
60 | export const removeInputs = () => {
61 | let inputs = Array.from(document.getElementById('new-nodelist').children)
62 | if (inputs.length > 1) {
63 | inputs.pop().remove()
64 | }
65 | }
66 |
67 | export const addNodes = (orgchart) => {
68 | let chartContainer = document.getElementById('chart-container')
69 | let nodeVals = []
70 |
71 | Array.from(document.getElementById('new-nodelist').querySelectorAll('.new-node'))
72 | .forEach(item => {
73 | let validVal = item.value.trim()
74 |
75 | if (validVal) {
76 | nodeVals.push(validVal)
77 | }
78 | })
79 | let selectedNode = document.getElementById(document.getElementById('selected-node').dataset.node)
80 |
81 | if (!nodeVals.length) {
82 | alert('Please input value for new node')
83 | return
84 | }
85 | let nodeType = document.querySelector('input[name="node-type"]:checked')
86 |
87 | if (!nodeType) {
88 | alert('Please select a node type')
89 | return
90 | }
91 | if (nodeType.value !== 'parent' && !document.querySelector('.orgchart')) {
92 | alert('Please creat the root node firstly when you want to build up the orgchart from the scratch')
93 | return
94 | }
95 | if (nodeType.value !== 'parent' && !selectedNode) {
96 | alert('Please select one node in orgchart')
97 | return
98 | }
99 | /* eslint-disable */
100 | if (nodeType.value === 'parent') {
101 | if (!chartContainer.children.length) {// if the original chart has been deleted
102 | orgchart = new OrgChart({
103 | 'chartContainer': '#chart-container',
104 | 'data': { 'name': nodeVals[0] },
105 | 'parentNodeSymbol': 'fa-th-large',
106 | 'createNode': function (node, data) {
107 | node.id = getId()
108 | }
109 | })
110 | orgchart.chart.classList.add('view-state')
111 | } else {
112 | orgchart.addParent(chartContainer.querySelector('.node'), { 'name': nodeVals[0], 'Id': getId() })
113 | }
114 | } else if (nodeType.value === 'siblings') {
115 | orgchart.addSiblings(selectedNode, {
116 | 'siblings': nodeVals.map(item => {
117 | return { 'name': item, 'relationship': '110', 'Id': getId() }
118 | })
119 | })
120 | } else {
121 | let hasChild = selectedNode.parentNode.colSpan > 1
122 |
123 | if (!hasChild) {
124 | let rel = nodeVals.length > 1 ? '110' : '100'
125 |
126 | orgchart.addChildren(selectedNode, {
127 | 'children': nodeVals.map(item => {
128 | return { 'name': item, 'relationship': rel, 'Id': getId() }
129 | })
130 | })
131 | } else {
132 | orgchart.addSiblings(closest(selectedNode, el => el.nodeName === 'TABLE').querySelector('.nodes').querySelector('.node'),
133 | { 'siblings': nodeVals.map(function (item) { return { 'name': item, 'relationship': '110', 'Id': getId() } })
134 | })
135 | }
136 | }
137 | }
138 |
139 | export const deleteNodes = (orgchart) => {
140 | let sNodeInput = document.getElementById('selected-node')
141 | let sNode = document.getElementById(sNodeInput.dataset.node)
142 |
143 | if (!sNode) {
144 | alert('Please select one node in orgchart')
145 | return
146 | } else if (sNode === document.querySelector('.orgchart').querySelector('.node')) {
147 | if (!window.confirm('Are you sure you want to delete the whole chart?')) {
148 | return
149 | }
150 | }
151 | orgchart.removeNodes(sNode)
152 | sNodeInput.value = ''
153 | sNodeInput.dataset.node = ''
154 | }
155 |
156 | export const resetPanel = () => {
157 | let fNode = document.querySelector('.orgchart').querySelector('.focused')
158 |
159 | if (fNode) {
160 | fNode.classList.remove('focused')
161 | }
162 | document.getElementById('selected-node').value = ''
163 | document.getElementById('new-nodelist').querySelector('input').value = ''
164 | Array.from(document.getElementById('new-nodelist').children).slice(1).forEach(item => item.remove())
165 | document.getElementById('node-type-panel').querySelectorAll('input').forEach(item => {
166 | item.checked = false
167 | })
168 | }
169 |
170 | export const getId = () => {
171 | return (new Date().getTime()) * 1000 + Math.floor(Math.random() * 1001)
172 | }
173 |
174 | export const exportJSON = (orgchart) => {
175 | let datasourceJSON = {}
176 | let ChartJSON = orgchart.getChartJSON()
177 | datasourceJSON = JSON.stringify(ChartJSON, null, 2)
178 | if(document.getElementsByTagName('code')[1]) {
179 | let code = document.getElementsByTagName('code')[1]
180 | code.innerHTML = datasourceJSON
181 | }
182 | return datasourceJSON
183 | }
184 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable*/
2 | import Vue from 'vue'
3 | import chartData from '../examples/data/index.js'
4 |
5 | window.Promise = require('es6-promise').Promise
6 | import {
7 | VoBasic,
8 | VoEdit
9 | } from '../dist/vue-orgchart.esm.js'
10 |
11 | const comps = {
12 | basic: VoBasic,
13 | edit: VoEdit,
14 | }
15 |
16 | let box
17 | let vm = {}
18 | createBox()
19 |
20 | afterEach(() => {
21 | if (vm.$el) document.body.removeChild(vm.$el)
22 | createBox()
23 | })
24 |
25 | Object.keys(comps).forEach(type => {
26 | chartData[type].data.forEach(item => {
27 | describe(type + ': ', () => {
28 | testMount(type, comps[type], item)
29 | })
30 | })
31 | })
32 |
33 | function testMount (type, comp, item) {
34 | it(item.name, () => {
35 | const Ctor = Vue.extend(comp)
36 | const vm = new Ctor({
37 | propsData: { data: item.data }
38 | }).$mount(box)
39 | expect(vm.$el.classList.contains('vo-' + type)).toEqual(true)
40 | })
41 | }
42 |
43 | function createBox () {
44 | box = document.createElement('div')
45 | box.id = 'app'
46 | document.body.appendChild(box)
47 | }
48 |
--------------------------------------------------------------------------------
/test/karma.conf.js:
--------------------------------------------------------------------------------
1 | module.exports = function (config) {
2 | config.set({
3 | frameworks: ['jasmine'],
4 | files: [
5 | './index.js'
6 | ],
7 | browsers: ['PhantomJS'],
8 | reporters: ['spec'],
9 | preprocessors: {
10 | './index.js': ['webpack']
11 | },
12 | webpack: {
13 | devtool: 'inline-source-map',
14 | module: {
15 | loaders: [
16 | {
17 | test: /\.(js)$/,
18 | loader: 'babel-loader'
19 | }
20 | ]
21 | },
22 | resolve: {
23 | extensions: ['.js', '.vue']
24 | }
25 | },
26 | singleRun: true
27 | })
28 | }
29 |
--------------------------------------------------------------------------------
/test/load/webpack/basic/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
--------------------------------------------------------------------------------
/test/load/webpack/basic/index.js:
--------------------------------------------------------------------------------
1 |
2 | import Vue from 'vue'
3 | import App from './App.vue'
4 |
5 | Vue.config.productionTip = false
6 |
7 | /* eslint-disable no-new */
8 | new Vue({
9 | el: '#app',
10 | render: h => h(App)
11 | })
12 |
--------------------------------------------------------------------------------
/test/load/webpack/basic/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | function resolve (dir) {
6 | return path.join(__dirname, '..', dir)
7 | }
8 |
9 | module.exports = {
10 | entry: {
11 | app: './index.js'
12 | },
13 | output: {
14 | path: path.resolve(__dirname, '../dist'),
15 | filename: 'index.js',
16 | publicPath: '/'
17 | },
18 | resolve: {
19 | alias: {
20 | 'vue$': 'vue/dist/vue.esm.js'
21 | },
22 | extensions: ['*', '.js', '.vue', '.json']
23 | },
24 | devServer: {
25 | port: '8180',
26 | hot: true,
27 | stats: 'errors-only'
28 | },
29 | performance: {
30 | hints: false
31 | },
32 | module: {
33 | rules: [
34 | {
35 | test: /\.vue$/,
36 | loader: 'vue-loader'
37 | },
38 | {
39 | test: /\.js$/,
40 | loader: 'babel-loader'
41 | },
42 | {
43 | test: /\.css$/,
44 | use: ['style-loader', 'css-loader']
45 | }
46 | ]
47 | },
48 | plugins: [
49 | new webpack.DefinePlugin({
50 | 'process.env': {
51 | NODE_ENV: '"development"'
52 | }
53 | }),
54 | new webpack.HotModuleReplacementPlugin(),
55 | new HtmlWebpackPlugin({
56 | filename: 'index.html',
57 | template: '../index.html',
58 | inject: true
59 | })
60 | ]
61 | }
62 |
--------------------------------------------------------------------------------
/test/load/webpack/edit/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
27 |
--------------------------------------------------------------------------------
/test/load/webpack/edit/index.js:
--------------------------------------------------------------------------------
1 |
2 | import Vue from 'vue'
3 | import App from './App.vue'
4 |
5 | Vue.config.productionTip = false
6 |
7 | /* eslint-disable no-new */
8 | new Vue({
9 | el: '#app',
10 | render: h => h(App)
11 | })
12 |
--------------------------------------------------------------------------------
/test/load/webpack/edit/webpack.config.js:
--------------------------------------------------------------------------------
1 | const webpack = require('webpack')
2 | const path = require('path')
3 | const HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | function resolve (dir) {
6 | return path.join(__dirname, '..', dir)
7 | }
8 |
9 | module.exports = {
10 | entry: {
11 | app: './index.js'
12 | },
13 | output: {
14 | path: path.resolve(__dirname, '../dist'),
15 | filename: 'index.js',
16 | publicPath: '/'
17 | },
18 | resolve: {
19 | alias: {
20 | 'vue$': 'vue/dist/vue.esm.js'
21 | },
22 | extensions: ['*', '.js', '.vue', '.json']
23 | },
24 | devServer: {
25 | port: '8180',
26 | hot: true,
27 | stats: 'errors-only'
28 | },
29 | performance: {
30 | hints: false
31 | },
32 | module: {
33 | rules: [
34 | {
35 | test: /\.vue$/,
36 | loader: 'vue-loader'
37 | },
38 | {
39 | test: /\.js$/,
40 | loader: 'babel-loader'
41 | },
42 | {
43 | test: /\.css$/,
44 | use: ['style-loader', 'css-loader']
45 | }
46 | ]
47 | },
48 | plugins: [
49 | new webpack.DefinePlugin({
50 | 'process.env': {
51 | NODE_ENV: '"development"'
52 | }
53 | }),
54 | new webpack.HotModuleReplacementPlugin(),
55 | new HtmlWebpackPlugin({
56 | filename: 'index.html',
57 | template: '../index.html',
58 | inject: true
59 | })
60 | ]
61 | }
62 |
--------------------------------------------------------------------------------
/test/load/webpack/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vue-orgchart
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------