Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SistemaGestionAdministrativa
ModuloPersonalCliente
Commits
76b82545
Commit
76b82545
authored
Jul 21, 2016
by
D’jalmar Gutierrez Titirico
🚲
Browse files
se agrego la opcion de modificar el orden del organigrama
parent
de1fea12
Changes
23
Hide whitespace changes
Inline
Side-by-side
client/app/app.scss
View file @
76b82545
...
...
@@ -228,9 +228,9 @@ input[type=checkbox].with-font:checked ~ label:before {
@import
'tiposEntidad/tiposEntidad.scss'
;
@import
'../components/footer/footer.scss'
;
@import
'../components/modal/modal.scss'
;
@import
'../components/organigrama/framework/angular-treant-js/Treant.scss'
;
@import
'../components/organigrama/framework/angular-treant-js/collapsable.scss'
;
@import
'../components/organigrama/framework/angular-treant-js/custom-colored.scss'
;
@import
'../components/organigrama/framework/angular-treant-js/vendor/perfect-scrollbar/perfect-scrollbar.scss'
;
@import
'../components/organigrama/framework/jquery.orgchart.scss'
;
@import
'../components/organigrama/framework/treant-js/Treant.scss'
;
@import
'../components/organigrama/framework/treant-js/collapsable.scss'
;
@import
'../components/organigrama/framework/treant-js/custom-colored.scss'
;
@import
'../components/organigrama/framework/treant-js/vendor/perfect-scrollbar/perfect-scrollbar.scss'
;
// endinjector
client/app/entidades/entidades.service.js
View file @
76b82545
...
...
@@ -34,6 +34,11 @@
tiposCargo
:
{
method
:
'
GET
'
,
url
:
appConfig
.
serverAddress
+
'
/api/entidades/:id/tiposCargo
'
},
ordenarUnidades
:
{
method
:
'
PUT
'
,
isArray
:
true
,
url
:
appConfig
.
serverAddress
+
'
/api/entidades/:id/ordenarUnidades
'
}
})
}
...
...
@@ -48,7 +53,7 @@
return
this
.
resource
.
get
(
parametros
).
$promise
;
}
getO
rganigrama
(
id
)
{
o
rganigrama
(
id
)
{
return
this
.
resource
.
organigrama
({
id
:
id
}).
$promise
;
}
...
...
@@ -82,6 +87,10 @@
return
this
.
resource
.
tiposCargo
({
id
:
id
}).
$promise
;
}
ordenarUnidades
(
id
,
parametros
)
{
return
this
.
resource
.
ordenarUnidades
({
id
:
id
},
parametros
).
$promise
;
}
}
angular
.
module
(
'
moduloPersonalApp
'
)
...
...
client/app/entidades/organigrama/entidades.organigrama.controller.js
View file @
76b82545
...
...
@@ -4,72 +4,1474 @@
'
use strict
'
;
(()
=>
{
class
EntidadOrganigramaController
{
constructor
(
EntidadService
,
$stateParams
)
{
this
.
service
=
EntidadService
;
this
.
id
=
$stateParams
.
entidadId
;
EntidadService
.
getOrganigrama
(
this
.
id
).
then
(
arbol
=>
{
this
.
arbol
=
arbol
;
$
(
'
#chart
'
).
orgchart
({
'
data
'
:
this
.
arbol
,
'
nodeTitle
'
:
'
name
'
,
'
nodeContent
'
:
'
title
'
,
'
draggable
'
:
true
,
'
createNode
'
:
function
(
$node
,
data
)
{
switch
(
data
.
tipo
)
{
case
'
oficina
'
:
$node
.
addClass
(
'
success
'
);
break
;
case
'
unidadOrganizacional
'
:
$node
.
addClass
(
'
success
'
);
break
;
case
'
cargo
'
:
$node
.
addClass
(
'
info
'
);
break
;
case
'
entidad
'
:
$node
.
addClass
(
'
primary
'
);
break
;
case
'
tipoCargo
'
:
$node
.
addClass
(
'
small
'
);
$node
.
addClass
(
'
primary
'
);
break
;
default
:
break
;
//region Angular-Treant
class
Treant
{
static
JSONconfig
=
{
make
:
function
(
configArray
)
{
var
i
=
configArray
.
length
,
node
;
this
.
jsonStructure
=
{
chart
:
null
,
nodeStructure
:
null
};
//fist loop: find config, find root;
while
(
i
--
)
{
node
=
configArray
[
i
];
if
(
node
.
hasOwnProperty
(
'
container
'
))
{
this
.
jsonStructure
.
chart
=
node
;
continue
;
}
if
(
!
node
.
hasOwnProperty
(
'
parent
'
)
&&
!
node
.
hasOwnProperty
(
'
container
'
))
{
this
.
jsonStructure
.
nodeStructure
=
node
;
node
.
myID
=
this
.
getID
();
}
}
this
.
findChildren
(
configArray
);
return
this
.
jsonStructure
;
},
findChildren
:
function
(
nodes
)
{
var
parents
=
[
0
];
// start witha a root node
while
(
parents
.
length
)
{
var
parentId
=
parents
.
pop
(),
parent
=
this
.
findNode
(
this
.
jsonStructure
.
nodeStructure
,
parentId
),
i
=
0
,
len
=
nodes
.
length
,
children
=
[];
for
(;
i
<
len
;
i
++
)
{
var
node
=
nodes
[
i
];
if
(
node
.
parent
&&
(
node
.
parent
.
myID
==
parentId
))
{
// skip config and root nodes
node
.
myID
=
this
.
getID
();
delete
node
.
parent
;
children
.
push
(
node
);
parents
.
push
(
node
.
myID
);
}
}
});
this
.
arbolFormateado
=
this
.
formatearArbol
(
this
.
arbol
);
this
.
arbolFormateado
.
collapsed
=
true
;
this
.
chart_config
=
{
chart
:
{
container
:
"
#collapsable-example
"
,
animateOnInit
:
true
,
node
:
{
collapsable
:
true
,
HTMLclass
:
'
nodeExample1
'
},
connectors
:
{
type
:
'
curve
'
},
nodeAlign
:
'
BOTTOM
'
,
animation
:
{
nodeAnimation
:
"
easeOutQuart
"
,
nodeSpeed
:
700
,
connectorsAnimation
:
"
easeOutQuart
"
,
connectorsSpeed
:
300
if
(
children
.
length
)
{
parent
.
children
=
children
;
}
}
},
findNode
:
function
(
node
,
nodeId
)
{
var
childrenLen
,
found
;
if
(
node
.
myID
===
nodeId
)
{
return
node
;
}
else
if
(
node
.
children
)
{
childrenLen
=
node
.
children
.
length
;
while
(
childrenLen
--
)
{
found
=
this
.
findNode
(
node
.
children
[
childrenLen
],
nodeId
);
if
(
found
)
{
return
found
;
}
},
nodeStructure
:
this
.
arbolFormateado
}
}
},
getID
:
(
function
()
{
var
i
=
0
;
return
function
()
{
return
i
++
;
};
var
chart
=
new
Treant
(
this
.
chart_config
);
})()
};
constructor
(
jsonConfig
,
callback
)
{
if
(
jsonConfig
instanceof
Array
)
{
jsonConfig
=
Treant
.
JSONconfig
.
make
(
jsonConfig
);
}
var
newTree
=
TreeStore
.
createTree
(
jsonConfig
);
newTree
.
positionTree
(
callback
);
this
.
tree_id
=
newTree
.
id
;
}
static
destroy
(
tree_id
)
{
TreeStore
.
destroy
(
tree_id
);
};
}
class
ImageLoader
{
constructor
()
{
this
.
loading
=
[];
}
processNode
(
node
)
{
var
images
=
node
.
nodeDOM
.
getElementsByTagName
(
'
img
'
),
i
=
images
.
length
;
while
(
i
--
)
{
this
.
create
(
node
,
images
[
i
]);
}
}
removeAll
(
img_src
)
{
var
i
=
this
.
loading
.
length
;
while
(
i
--
)
{
if
(
this
.
loading
[
i
]
===
img_src
)
{
this
.
loading
.
splice
(
i
,
1
);
}
}
}
create
(
node
,
image
)
{
var
self
=
this
,
source
=
image
.
src
;
this
.
loading
.
push
(
source
);
function
imgTrigger
()
{
self
.
removeAll
(
source
);
node
.
width
=
node
.
nodeDOM
.
offsetWidth
;
node
.
height
=
node
.
nodeDOM
.
offsetHeight
;
}
if
(
image
.
complete
)
{
return
imgTrigger
();
}
UTIL
.
addEvent
(
image
,
'
load
'
,
imgTrigger
);
UTIL
.
addEvent
(
image
,
'
error
'
,
imgTrigger
);
// handle broken url-s
// load event is not fired for cached images, force the load event
image
.
src
+=
"
?
"
+
new
Date
().
getTime
();
}
isNotLoading
()
{
return
this
.
loading
.
length
===
0
;
}
}
class
NodeDB
{
constructor
(
nodeStructure
,
tree
)
{
this
.
db
=
[];
var
self
=
this
;
function
itterateChildren
(
node
,
parentId
)
{
var
newNode
=
self
.
createNode
(
node
,
parentId
,
tree
,
null
);
if
(
node
.
children
)
{
newNode
.
children
=
[];
// pseudo node is used for descending children to the next level
if
(
node
.
childrenDropLevel
&&
node
.
childrenDropLevel
>
0
)
{
while
(
node
.
childrenDropLevel
--
)
{
// pseudo node needs to inherit the connection style from its parent for continuous connectors
var
connStyle
=
UTIL
.
cloneObj
(
newNode
.
connStyle
);
newNode
=
self
.
createNode
(
'
pseudo
'
,
newNode
.
id
,
tree
,
null
);
newNode
.
connStyle
=
connStyle
;
newNode
.
children
=
[];
}
}
var
stack
=
(
node
.
stackChildren
&&
!
self
.
hasGrandChildren
(
node
))
?
newNode
.
id
:
null
;
// svildren are position on separate leves, one beneeth the other
if
(
stack
!==
null
)
{
newNode
.
stackChildren
=
[];
}
for
(
var
i
=
0
,
len
=
node
.
children
.
length
;
i
<
len
;
i
++
)
{
if
(
stack
!==
null
)
{
newNode
=
self
.
createNode
(
node
.
children
[
i
],
newNode
.
id
,
tree
,
stack
);
if
((
i
+
1
)
<
len
)
newNode
.
children
=
[];
// last node cant have children
}
else
{
itterateChildren
(
node
.
children
[
i
],
newNode
.
id
);
}
}
}
}
if
(
tree
.
CONFIG
.
animateOnInit
)
nodeStructure
.
collapsed
=
true
;
itterateChildren
(
nodeStructure
,
-
1
);
// root node
this
.
createGeometries
(
tree
);
}
createGeometries
(
tree
)
{
var
i
=
this
.
db
.
length
,
node
;
while
(
i
--
)
{
this
.
get
(
i
).
createGeometry
(
tree
);
}
}
get
(
nodeId
)
{
return
this
.
db
[
nodeId
];
// get node by ID
}
createNode
(
nodeStructure
,
parentId
,
tree
,
stackParentId
)
{
var
node
=
new
TreeNode
(
nodeStructure
,
this
.
db
.
length
,
parentId
,
tree
,
stackParentId
);
this
.
db
.
push
(
node
);
if
(
parentId
>=
0
)
this
.
get
(
parentId
).
children
.
push
(
node
.
id
);
//skip root node
if
(
stackParentId
)
{
this
.
get
(
stackParentId
).
stackParent
=
true
;
this
.
get
(
stackParentId
).
stackChildren
.
push
(
node
.
id
);
}
return
node
;
}
getMinMaxCoord
(
dim
,
parent
,
MinMax
)
{
// used for getting the dimensions of the tree, dim = 'X' || 'Y'
// looks for min and max (X and Y) within the set of nodes
var
parent
=
parent
||
this
.
get
(
0
),
i
=
parent
.
childrenCount
(),
MinMax
=
MinMax
||
{
// start with root node dimensions
min
:
parent
[
dim
],
max
:
parent
[
dim
]
+
((
dim
==
'
X
'
)
?
parent
.
width
:
parent
.
height
)
};
while
(
i
--
)
{
var
node
=
parent
.
childAt
(
i
),
maxTest
=
node
[
dim
]
+
((
dim
==
'
X
'
)
?
node
.
width
:
node
.
height
),
minTest
=
node
[
dim
];
if
(
maxTest
>
MinMax
.
max
)
{
MinMax
.
max
=
maxTest
;
}
if
(
minTest
<
MinMax
.
min
)
{
MinMax
.
min
=
minTest
;
}
this
.
getMinMaxCoord
(
dim
,
node
,
MinMax
);
}
return
MinMax
;
}
static
hasGrandChildren
(
nodeStructure
)
{
var
i
=
nodeStructure
.
children
.
length
;
while
(
i
--
)
{
if
(
nodeStructure
.
children
[
i
].
children
)
return
true
;
}
}
}
class
Tree
{
static
CONFIG
=
{
maxDepth
:
100
,
rootOrientation
:
'
NORTH
'
,
// NORTH || EAST || WEST || SOUTH
nodeAlign
:
'
CENTER
'
,
// CENTER || TOP || BOTTOM
levelSeparation
:
30
,
siblingSeparation
:
30
,
subTeeSeparation
:
30
,
hideRootNode
:
false
,
animateOnInit
:
false
,
animateOnInitDelay
:
500
,
padding
:
15
,
// the difference is seen only when the scrollbar is shown
scrollbar
:
'
native
'
,
// "native" || "fancy" || "None" (PS: "fancy" requires jquery and perfect-scrollbar)
connectors
:
{
type
:
'
curve
'
,
// 'curve' || 'step' || 'straight' || 'bCurve'
style
:
{
stroke
:
'
black
'
},
stackIndent
:
15
},
node
:
{
// each node inherits this, it can all be overrifen in node config
// HTMLclass: 'node',
// drawLineThrough: false,
// collapsable: false,
link
:
{
target
:
'
_self
'
}
},
animation
:
{
// each node inherits this, it can all be overrifen in node config
nodeSpeed
:
450
,
nodeAnimation
:
'
linear
'
,
connectorsSpeed
:
450
,
connectorsAnimation
:
'
linear
'
}
};
constructor
(
jsonConfig
,
treeId
)
{
this
.
id
=
treeId
;
this
.
imageLoader
=
new
ImageLoader
();
this
.
CONFIG
=
UTIL
.
createMerge
(
Tree
.
CONFIG
,
jsonConfig
.
chart
);
this
.
drawArea
=
document
.
getElementById
(
this
.
CONFIG
.
container
.
substring
(
1
));
this
.
drawArea
.
className
+=
"
Treant
"
;
this
.
nodeDB
=
new
NodeDB
(
jsonConfig
.
nodeStructure
,
this
);
// key store for storing reference to node connectors,
// key = nodeId where the connector ends
this
.
connectionStore
=
{};
}
positionTree
(
callback
)
{
var
self
=
this
;
if
(
this
.
imageLoader
.
isNotLoading
())
{
var
root
=
this
.
root
(),
orient
=
this
.
CONFIG
.
rootOrientation
;
this
.
resetLevelData
();
this
.
firstWalk
(
root
,
0
);
this
.
secondWalk
(
root
,
0
,
0
,
0
);
this
.
positionNodes
();
if
(
this
.
CONFIG
.
animateOnInit
)
{
setTimeout
(
function
()
{
root
.
toggleCollapse
();
},
this
.
CONFIG
.
animateOnInitDelay
);
}
if
(
!
this
.
loaded
)
{
this
.
drawArea
.
className
+=
"
Treant-loaded
"
;
// nodes are hidden until .loaded class is add
if
(
Object
.
prototype
.
toString
.
call
(
callback
)
===
"
[object Function]
"
)
{
callback
(
self
);
}
this
.
loaded
=
true
;
}
}
else
{
setTimeout
(
function
()
{
self
.
positionTree
(
callback
);
},
10
);
}
}
/*
* In a first post-order walk, every node of the tree is
* assigned a preliminary x-coordinate (held in field
* node->flPrelim). In addition, internal nodes are
* given modifiers, which will be used to move their
* children to the right (held in field
* node->flModifier).
*/
firstWalk
(
node
,
level
)
{
node
.
prelim
=
null
;
node
.
modifier
=
null
;
this
.
setNeighbors
(
node
,
level
);
this
.
calcLevelDim
(
node
,
level
);
var
leftSibling
=
node
.
leftSibling
();
if
(
node
.
childrenCount
()
===
0
||
level
==
this
.
CONFIG
.
maxDepth
)
{
// set preliminary x-coordinate
if
(
leftSibling
)
{
node
.
prelim
=
leftSibling
.
prelim
+
leftSibling
.
size
()
+
this
.
CONFIG
.
siblingSeparation
;
}
else
{
node
.
prelim
=
0
;
}
}
else
{
//node is not a leaf, firstWalk for each child
for
(
var
i
=
0
,
n
=
node
.
childrenCount
();
i
<
n
;
i
++
)
{
this
.
firstWalk
(
node
.
childAt
(
i
),
level
+
1
);
}
var
midPoint
=
node
.
childrenCenter
()
-
node
.
size
()
/
2
;
if
(
leftSibling
)
{
node
.
prelim
=
leftSibling
.
prelim
+
leftSibling
.
size
()
+
this
.
CONFIG
.
siblingSeparation
;
node
.
modifier
=
node
.
prelim
-
midPoint
;
this
.
apportion
(
node
,
level
);
}
else
{
node
.
prelim
=
midPoint
;
}
// handle stacked children positioning
if
(
node
.
stackParent
)
{
// hadle the parent of stacked children
node
.
modifier
+=
this
.
nodeDB
.
get
(
node
.
stackChildren
[
0
]).
size
()
/
2
+
node
.
connStyle
.
stackIndent
;
}
else
if
(
node
.
stackParentId
)
{
// handle stacked children
node
.
prelim
=
0
;
}
}
}
/*
* Clean up the positioning of small sibling subtrees.
* Subtrees of a node are formed independently and
* placed as close together as possible. By requiring
* that the subtrees be rigid at the time they are put
* together, we avoid the undesirable effects that can
* accrue from positioning nodes rather than subtrees.
*/
apportion
(
node
,
level
)
{
var
firstChild
=
node
.
firstChild
(),
firstChildLeftNeighbor
=
firstChild
.
leftNeighbor
(),
compareDepth
=
1
,
depthToStop
=
this
.
CONFIG
.
maxDepth
-
level
;
while
(
firstChild
&&
firstChildLeftNeighbor
&&
compareDepth
<=
depthToStop
)
{
// calculate the position of the firstChild, according to the position of firstChildLeftNeighbor
var
modifierSumRight
=
0
,
modifierSumLeft
=
0
,
leftAncestor
=
firstChildLeftNeighbor
,
rightAncestor
=
firstChild
;
for
(
var
i
=
0
;
i
<
compareDepth
;
i
++
)
{
leftAncestor
=
leftAncestor
.
parent
();
rightAncestor
=
rightAncestor
.
parent
();
modifierSumLeft
+=
leftAncestor
.
modifier
;
modifierSumRight
+=
rightAncestor
.
modifier
;
// all the stacked children are oriented towards right so use right variables
if
(
rightAncestor
.
stackParent
!==
undefined
)
modifierSumRight
+=
rightAncestor
.
size
()
/
2
;
}
// find the gap between two trees and apply it to subTrees
// and mathing smaller gaps to smaller subtrees
var
totalGap
=
(
firstChildLeftNeighbor
.
prelim
+
modifierSumLeft
+
firstChildLeftNeighbor
.
size
()
+
this
.
CONFIG
.
subTeeSeparation
)
-
(
firstChild
.
prelim
+
modifierSumRight
);
if
(
totalGap
>
0
)
{
var
subtreeAux
=
node
,
numSubtrees
=
0
;
// count all the subtrees in the LeftSibling
while
(
subtreeAux
&&
subtreeAux
.
id
!=
leftAncestor
.
id
)
{
subtreeAux
=
subtreeAux
.
leftSibling
();
numSubtrees
++
;
}
if
(
subtreeAux
)
{
var
subtreeMoveAux
=
node
,
singleGap
=
totalGap
/
numSubtrees
;
while
(
subtreeMoveAux
.
id
!=
leftAncestor
.
id
)
{
subtreeMoveAux
.
prelim
+=
totalGap
;
subtreeMoveAux
.
modifier
+=
totalGap
;
totalGap
-=
singleGap
;
subtreeMoveAux
=
subtreeMoveAux
.
leftSibling
();
}
}
}
compareDepth
++
;
if
(
firstChild
.
childrenCount
()
===
0
)
{
firstChild
=
node
.
leftMost
(
0
,
compareDepth
);
}
else
{