Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Open sidebar
MUR Drupal
d3-library
Commits
b567b5d1
Commit
b567b5d1
authored
May 17, 2014
by
Mike Bostock
Browse files
Non-recursive hierarchy layout.
parent
9d0bbefa
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
283 additions
and
291 deletions
+283
-291
d3.js
d3.js
+210
-211
d3.min.js
d3.min.js
+5
-5
src/layout/cluster.js
src/layout/cluster.js
+2
-2
src/layout/hierarchy.js
src/layout/hierarchy.js
+56
-45
src/layout/pack.js
src/layout/pack.js
+5
-6
src/layout/tree.js
src/layout/tree.js
+4
-21
test/layout/tree-test.js
test/layout/tree-test.js
+1
-1
No files found.
d3.js
View file @
b567b5d1
...
...
@@ -6332,41 +6332,30 @@
var
d3_layout_forceLinkDistance
=
20
,
d3_layout_forceLinkStrength
=
1
,
d3_layout_forceChargeDistance2
=
Infinity
;
d3
.
layout
.
hierarchy
=
function
()
{
var
sort
=
d3_layout_hierarchySort
,
children
=
d3_layout_hierarchyChildren
,
value
=
d3_layout_hierarchyValue
;
function
recurse
(
node
,
depth
,
nodes
)
{
var
childs
=
children
.
call
(
hierarchy
,
node
,
depth
);
node
.
depth
=
depth
;
function
hierarchy
(
root
)
{
var
stack
=
[
root
],
nodes
=
[],
node
;
root
.
depth
=
0
;
while
((
node
=
stack
.
pop
())
!=
null
)
{
nodes
.
push
(
node
);
if
(
childs
&&
(
n
=
childs
.
length
))
{
var
i
=
-
1
,
n
,
c
=
node
.
children
=
new
Array
(
n
),
v
=
0
,
j
=
depth
+
1
,
d
;
while
(
++
i
<
n
)
{
d
=
c
[
i
]
=
recurse
(
childs
[
i
],
j
,
nodes
);
d
.
parent
=
node
;
v
+=
d
.
value
;
if
(
(
childs
=
children
.
call
(
hierarchy
,
node
,
node
.
depth
))
&&
(
n
=
childs
.
length
))
{
var
n
,
childs
,
chil
d
;
while
(
--
n
>=
0
)
{
stack
.
push
(
child
=
childs
[
n
]
);
chil
d
.
parent
=
node
;
child
.
depth
=
node
.
depth
+
1
;
}
if
(
sort
)
c
.
sort
(
sort
)
;
if
(
value
)
node
.
value
=
v
;
if
(
value
)
node
.
value
=
0
;
node
.
children
=
childs
;
}
else
{
if
(
value
)
node
.
value
=
+
value
.
call
(
hierarchy
,
node
,
node
.
depth
)
||
0
;
delete
node
.
children
;
if
(
value
)
{
node
.
value
=
+
value
.
call
(
hierarchy
,
node
,
depth
)
||
0
;
}
}
return
node
;
}
function
revalue
(
node
,
depth
)
{
var
children
=
node
.
children
,
v
=
0
;
if
(
children
&&
(
n
=
children
.
length
))
{
var
i
=
-
1
,
n
,
j
=
depth
+
1
;
while
(
++
i
<
n
)
v
+=
revalue
(
children
[
i
],
j
);
}
else
if
(
value
)
{
v
=
+
value
.
call
(
hierarchy
,
node
,
depth
)
||
0
;
}
if
(
value
)
node
.
value
=
v
;
return
v
;
}
function
hierarchy
(
d
)
{
var
nodes
=
[];
recurse
(
d
,
0
,
nodes
);
d3_layout_hierarchyVisitAfter
(
root
,
function
(
node
)
{
var
childs
,
parent
;
if
(
sort
&&
(
childs
=
node
.
children
))
childs
.
sort
(
sort
);
if
(
value
&&
(
parent
=
node
.
parent
))
parent
.
value
+=
node
.
value
;
});
return
nodes
;
}
hierarchy
.
sort
=
function
(
x
)
{
...
...
@@ -6385,7 +6374,11 @@
return
hierarchy
;
};
hierarchy
.
revalue
=
function
(
root
)
{
revalue
(
root
,
0
);
if
(
value
)
d3_layout_hierarchyVisitAfter
(
root
,
function
(
node
)
{
var
parent
;
node
.
value
=
node
.
children
?
0
:
+
value
.
call
(
hierarchy
,
node
,
node
.
depth
)
||
0
;
if
(
parent
=
node
.
parent
)
parent
.
value
+=
node
.
value
;
});
return
root
;
};
return
hierarchy
;
...
...
@@ -6396,6 +6389,29 @@
object
.
links
=
d3_layout_hierarchyLinks
;
return
object
;
}
function
d3_layout_hierarchyVisitBefore
(
node
,
callback
)
{
var
nodes
=
[
node
];
while
((
node
=
nodes
.
pop
())
!=
null
)
{
callback
(
node
);
if
((
children
=
node
.
children
)
&&
(
n
=
children
.
length
))
{
var
n
,
children
;
while
(
--
n
>=
0
)
nodes
.
push
(
children
[
n
]);
}
}
}
function
d3_layout_hierarchyVisitAfter
(
node
,
callback
)
{
var
nodes
=
[
node
],
nodes2
=
[];
while
((
node
=
nodes
.
pop
())
!=
null
)
{
nodes2
.
push
(
node
);
if
((
children
=
node
.
children
)
&&
(
n
=
children
.
length
))
{
var
i
=
-
1
,
n
,
children
;
while
(
++
i
<
n
)
nodes
.
push
(
children
[
i
]);
}
}
while
((
node
=
nodes2
.
pop
())
!=
null
)
{
callback
(
node
);
}
}
function
d3_layout_hierarchyChildren
(
d
)
{
return
d
.
children
;
}
...
...
@@ -6711,20 +6727,174 @@
function
d3_layout_histogramRange
(
values
)
{
return
[
d3
.
min
(
values
),
d3
.
max
(
values
)
];
}
d3
.
layout
.
pack
=
function
()
{
var
hierarchy
=
d3
.
layout
.
hierarchy
().
sort
(
d3_layout_packSort
),
padding
=
0
,
size
=
[
1
,
1
],
radius
;
function
pack
(
d
,
i
)
{
var
nodes
=
hierarchy
.
call
(
this
,
d
,
i
),
root
=
nodes
[
0
],
w
=
size
[
0
],
h
=
size
[
1
],
r
=
radius
==
null
?
Math
.
sqrt
:
typeof
radius
===
"
function
"
?
radius
:
function
()
{
return
radius
;
};
root
.
x
=
root
.
y
=
0
;
d3_layout_hierarchyVisitAfter
(
root
,
function
(
d
)
{
d
.
r
=
+
r
(
d
.
value
);
});
d3_layout_hierarchyVisitAfter
(
root
,
d3_layout_packSiblings
);
if
(
padding
)
{
var
dr
=
padding
*
(
radius
?
1
:
Math
.
max
(
2
*
root
.
r
/
w
,
2
*
root
.
r
/
h
))
/
2
;
d3_layout_hierarchyVisitAfter
(
root
,
function
(
d
)
{
d
.
r
+=
dr
;
});
d3_layout_hierarchyVisitAfter
(
root
,
d3_layout_packSiblings
);
d3_layout_hierarchyVisitAfter
(
root
,
function
(
d
)
{
d
.
r
-=
dr
;
});
}
d3_layout_packTransform
(
root
,
w
/
2
,
h
/
2
,
radius
?
1
:
1
/
Math
.
max
(
2
*
root
.
r
/
w
,
2
*
root
.
r
/
h
));
return
nodes
;
}
pack
.
size
=
function
(
_
)
{
if
(
!
arguments
.
length
)
return
size
;
size
=
_
;
return
pack
;
};
pack
.
radius
=
function
(
_
)
{
if
(
!
arguments
.
length
)
return
radius
;
radius
=
_
==
null
||
typeof
_
===
"
function
"
?
_
:
+
_
;
return
pack
;
};
pack
.
padding
=
function
(
_
)
{
if
(
!
arguments
.
length
)
return
padding
;
padding
=
+
_
;
return
pack
;
};
return
d3_layout_hierarchyRebind
(
pack
,
hierarchy
);
};
function
d3_layout_packSort
(
a
,
b
)
{
return
a
.
value
-
b
.
value
;
}
function
d3_layout_packInsert
(
a
,
b
)
{
var
c
=
a
.
_pack_next
;
a
.
_pack_next
=
b
;
b
.
_pack_prev
=
a
;
b
.
_pack_next
=
c
;
c
.
_pack_prev
=
b
;
}
function
d3_layout_packSplice
(
a
,
b
)
{
a
.
_pack_next
=
b
;
b
.
_pack_prev
=
a
;
}
function
d3_layout_packIntersects
(
a
,
b
)
{
var
dx
=
b
.
x
-
a
.
x
,
dy
=
b
.
y
-
a
.
y
,
dr
=
a
.
r
+
b
.
r
;
return
.
999
*
dr
*
dr
>
dx
*
dx
+
dy
*
dy
;
}
function
d3_layout_packSiblings
(
node
)
{
if
(
!
(
nodes
=
node
.
children
)
||
!
(
n
=
nodes
.
length
))
return
;
var
nodes
,
xMin
=
Infinity
,
xMax
=
-
Infinity
,
yMin
=
Infinity
,
yMax
=
-
Infinity
,
a
,
b
,
c
,
i
,
j
,
k
,
n
;
function
bound
(
node
)
{
xMin
=
Math
.
min
(
node
.
x
-
node
.
r
,
xMin
);
xMax
=
Math
.
max
(
node
.
x
+
node
.
r
,
xMax
);
yMin
=
Math
.
min
(
node
.
y
-
node
.
r
,
yMin
);
yMax
=
Math
.
max
(
node
.
y
+
node
.
r
,
yMax
);
}
nodes
.
forEach
(
d3_layout_packLink
);
a
=
nodes
[
0
];
a
.
x
=
-
a
.
r
;
a
.
y
=
0
;
bound
(
a
);
if
(
n
>
1
)
{
b
=
nodes
[
1
];
b
.
x
=
b
.
r
;
b
.
y
=
0
;
bound
(
b
);
if
(
n
>
2
)
{
c
=
nodes
[
2
];
d3_layout_packPlace
(
a
,
b
,
c
);
bound
(
c
);
d3_layout_packInsert
(
a
,
c
);
a
.
_pack_prev
=
c
;
d3_layout_packInsert
(
c
,
b
);
b
=
a
.
_pack_next
;
for
(
i
=
3
;
i
<
n
;
i
++
)
{
d3_layout_packPlace
(
a
,
b
,
c
=
nodes
[
i
]);
var
isect
=
0
,
s1
=
1
,
s2
=
1
;
for
(
j
=
b
.
_pack_next
;
j
!==
b
;
j
=
j
.
_pack_next
,
s1
++
)
{
if
(
d3_layout_packIntersects
(
j
,
c
))
{
isect
=
1
;
break
;
}
}
if
(
isect
==
1
)
{
for
(
k
=
a
.
_pack_prev
;
k
!==
j
.
_pack_prev
;
k
=
k
.
_pack_prev
,
s2
++
)
{
if
(
d3_layout_packIntersects
(
k
,
c
))
{
break
;
}
}
}
if
(
isect
)
{
if
(
s1
<
s2
||
s1
==
s2
&&
b
.
r
<
a
.
r
)
d3_layout_packSplice
(
a
,
b
=
j
);
else
d3_layout_packSplice
(
a
=
k
,
b
);
i
--
;
}
else
{
d3_layout_packInsert
(
a
,
c
);
b
=
c
;
bound
(
c
);
}
}
}
}
var
cx
=
(
xMin
+
xMax
)
/
2
,
cy
=
(
yMin
+
yMax
)
/
2
,
cr
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
c
=
nodes
[
i
];
c
.
x
-=
cx
;
c
.
y
-=
cy
;
cr
=
Math
.
max
(
cr
,
c
.
r
+
Math
.
sqrt
(
c
.
x
*
c
.
x
+
c
.
y
*
c
.
y
));
}
node
.
r
=
cr
;
nodes
.
forEach
(
d3_layout_packUnlink
);
}
function
d3_layout_packLink
(
node
)
{
node
.
_pack_next
=
node
.
_pack_prev
=
node
;
}
function
d3_layout_packUnlink
(
node
)
{
delete
node
.
_pack_next
;
delete
node
.
_pack_prev
;
}
function
d3_layout_packTransform
(
node
,
x
,
y
,
k
)
{
var
children
=
node
.
children
;
node
.
x
=
x
+=
k
*
node
.
x
;
node
.
y
=
y
+=
k
*
node
.
y
;
node
.
r
*=
k
;
if
(
children
)
{
var
i
=
-
1
,
n
=
children
.
length
;
while
(
++
i
<
n
)
d3_layout_packTransform
(
children
[
i
],
x
,
y
,
k
);
}
}
function
d3_layout_packPlace
(
a
,
b
,
c
)
{
var
db
=
a
.
r
+
c
.
r
,
dx
=
b
.
x
-
a
.
x
,
dy
=
b
.
y
-
a
.
y
;
if
(
db
&&
(
dx
||
dy
))
{
var
da
=
b
.
r
+
c
.
r
,
dc
=
dx
*
dx
+
dy
*
dy
;
da
*=
da
;
db
*=
db
;
var
x
=
.
5
+
(
db
-
da
)
/
(
2
*
dc
),
y
=
Math
.
sqrt
(
Math
.
max
(
0
,
2
*
da
*
(
db
+
dc
)
-
(
db
-=
dc
)
*
db
-
da
*
da
))
/
(
2
*
dc
);
c
.
x
=
a
.
x
+
x
*
dx
+
y
*
dy
;
c
.
y
=
a
.
y
+
x
*
dy
-
y
*
dx
;
}
else
{
c
.
x
=
a
.
x
+
db
;
c
.
y
=
a
.
y
;
}
}
d3
.
layout
.
tree
=
function
()
{
var
hierarchy
=
d3
.
layout
.
hierarchy
().
sort
(
null
).
value
(
null
),
separation
=
d3_layout_treeSeparation
,
size
=
[
1
,
1
],
nodeSize
=
false
;
function
tree
(
d
,
i
)
{
var
nodes
=
hierarchy
.
call
(
this
,
d
,
i
),
root0
=
nodes
[
0
],
root1
=
wrapTree
(
root0
);
d3_layout_
tree
VisitAfter
(
root1
,
firstWalk
),
root1
.
parent
.
mod
=
-
root1
.
prelim
;
d3_layout_
tree
VisitBefore
(
root1
,
secondWalk
);
d3_layout_
hierarchy
VisitAfter
(
root1
,
firstWalk
),
root1
.
parent
.
mod
=
-
root1
.
prelim
;
d3_layout_
hierarchy
VisitBefore
(
root1
,
secondWalk
);
if
(
nodeSize
)
{
d3_layout_
tree
VisitBefore
(
root1
,
function
(
node
)
{
d3_layout_
hierarchy
VisitBefore
(
root1
,
function
(
node
)
{
node
.
node
.
x
*=
size
[
0
];
node
.
node
.
y
=
node
.
node
.
depth
*
size
[
1
];
});
}
else
{
var
left
=
d3_layout_treeSearch
(
root0
,
d3_layout_treeLeftmost
),
right
=
d3_layout_treeSearch
(
root0
,
d3_layout_treeRightmost
),
x0
=
left
.
x
-
separation
(
left
,
right
)
/
2
,
x1
=
right
.
x
+
separation
(
right
,
left
)
/
2
,
y1
=
d3_layout_treeSearch
(
root0
,
d3_layout_treeDeepest
).
depth
||
1
;
d3_layout_
tree
VisitBefore
(
root1
,
function
(
node
)
{
d3_layout_
hierarchy
VisitBefore
(
root1
,
function
(
node
)
{
node
.
node
.
x
=
(
node
.
node
.
x
-
x0
)
/
(
x1
-
x0
)
*
size
[
0
];
node
.
node
.
y
=
node
.
node
.
depth
/
y1
*
size
[
1
];
});
...
...
@@ -6845,23 +7015,6 @@
function
d3_layout_treeDeepest
(
a
,
b
)
{
return
a
.
depth
-
b
.
depth
;
}
function
d3_layout_treeVisitBefore
(
node
,
callback
)
{
var
nodes
=
[
node
];
while
((
node
=
nodes
.
pop
())
!=
null
)
{
callback
(
node
);
if
((
children
=
node
.
children
)
&&
(
n
=
children
.
length
))
{
var
i
=
-
1
,
n
,
children
;
while
(
++
i
<
n
)
nodes
.
push
(
children
[
i
]);
}
}
}
function
d3_layout_treeVisitAfter
(
node
,
callback
)
{
var
nodes
=
[];
d3_layout_treeVisitBefore
(
node
,
function
(
node
)
{
nodes
.
push
(
node
);
});
while
((
node
=
nodes
.
pop
())
!=
null
)
callback
(
node
);
}
function
d3_layout_treeLeft
(
v
)
{
var
children
=
v
.
children
;
return
children
.
length
?
children
[
0
]
:
v
.
thread
;
...
...
@@ -6890,165 +7043,11 @@
function
d3_layout_treeAncestor
(
vim
,
v
,
ancestor
)
{
return
vim
.
ancestor
.
parent
===
v
.
parent
?
vim
.
ancestor
:
ancestor
;
}
d3
.
layout
.
pack
=
function
()
{
var
hierarchy
=
d3
.
layout
.
hierarchy
().
sort
(
d3_layout_packSort
),
padding
=
0
,
size
=
[
1
,
1
],
radius
;
function
pack
(
d
,
i
)
{
var
nodes
=
hierarchy
.
call
(
this
,
d
,
i
),
root
=
nodes
[
0
],
w
=
size
[
0
],
h
=
size
[
1
],
r
=
radius
==
null
?
Math
.
sqrt
:
typeof
radius
===
"
function
"
?
radius
:
function
()
{
return
radius
;
};
root
.
x
=
root
.
y
=
0
;
d3_layout_treeVisitAfter
(
root
,
function
(
d
)
{
d
.
r
=
+
r
(
d
.
value
);
});
d3_layout_treeVisitAfter
(
root
,
d3_layout_packSiblings
);
if
(
padding
)
{
var
dr
=
padding
*
(
radius
?
1
:
Math
.
max
(
2
*
root
.
r
/
w
,
2
*
root
.
r
/
h
))
/
2
;
d3_layout_treeVisitAfter
(
root
,
function
(
d
)
{
d
.
r
+=
dr
;
});
d3_layout_treeVisitAfter
(
root
,
d3_layout_packSiblings
);
d3_layout_treeVisitAfter
(
root
,
function
(
d
)
{
d
.
r
-=
dr
;
});
}
d3_layout_packTransform
(
root
,
w
/
2
,
h
/
2
,
radius
?
1
:
1
/
Math
.
max
(
2
*
root
.
r
/
w
,
2
*
root
.
r
/
h
));
return
nodes
;
}
pack
.
size
=
function
(
_
)
{
if
(
!
arguments
.
length
)
return
size
;
size
=
_
;
return
pack
;
};
pack
.
radius
=
function
(
_
)
{
if
(
!
arguments
.
length
)
return
radius
;
radius
=
_
==
null
||
typeof
_
===
"
function
"
?
_
:
+
_
;
return
pack
;
};
pack
.
padding
=
function
(
_
)
{
if
(
!
arguments
.
length
)
return
padding
;
padding
=
+
_
;
return
pack
;
};
return
d3_layout_hierarchyRebind
(
pack
,
hierarchy
);
};
function
d3_layout_packSort
(
a
,
b
)
{
return
a
.
value
-
b
.
value
;
}
function
d3_layout_packInsert
(
a
,
b
)
{
var
c
=
a
.
_pack_next
;
a
.
_pack_next
=
b
;
b
.
_pack_prev
=
a
;
b
.
_pack_next
=
c
;
c
.
_pack_prev
=
b
;
}
function
d3_layout_packSplice
(
a
,
b
)
{
a
.
_pack_next
=
b
;
b
.
_pack_prev
=
a
;
}
function
d3_layout_packIntersects
(
a
,
b
)
{
var
dx
=
b
.
x
-
a
.
x
,
dy
=
b
.
y
-
a
.
y
,
dr
=
a
.
r
+
b
.
r
;
return
.
999
*
dr
*
dr
>
dx
*
dx
+
dy
*
dy
;
}
function
d3_layout_packSiblings
(
node
)
{
if
(
!
(
nodes
=
node
.
children
)
||
!
(
n
=
nodes
.
length
))
return
;
var
nodes
,
xMin
=
Infinity
,
xMax
=
-
Infinity
,
yMin
=
Infinity
,
yMax
=
-
Infinity
,
a
,
b
,
c
,
i
,
j
,
k
,
n
;
function
bound
(
node
)
{
xMin
=
Math
.
min
(
node
.
x
-
node
.
r
,
xMin
);
xMax
=
Math
.
max
(
node
.
x
+
node
.
r
,
xMax
);
yMin
=
Math
.
min
(
node
.
y
-
node
.
r
,
yMin
);
yMax
=
Math
.
max
(
node
.
y
+
node
.
r
,
yMax
);
}
nodes
.
forEach
(
d3_layout_packLink
);
a
=
nodes
[
0
];
a
.
x
=
-
a
.
r
;
a
.
y
=
0
;
bound
(
a
);
if
(
n
>
1
)
{
b
=
nodes
[
1
];
b
.
x
=
b
.
r
;
b
.
y
=
0
;
bound
(
b
);
if
(
n
>
2
)
{
c
=
nodes
[
2
];
d3_layout_packPlace
(
a
,
b
,
c
);
bound
(
c
);
d3_layout_packInsert
(
a
,
c
);
a
.
_pack_prev
=
c
;
d3_layout_packInsert
(
c
,
b
);
b
=
a
.
_pack_next
;
for
(
i
=
3
;
i
<
n
;
i
++
)
{
d3_layout_packPlace
(
a
,
b
,
c
=
nodes
[
i
]);
var
isect
=
0
,
s1
=
1
,
s2
=
1
;
for
(
j
=
b
.
_pack_next
;
j
!==
b
;
j
=
j
.
_pack_next
,
s1
++
)
{
if
(
d3_layout_packIntersects
(
j
,
c
))
{
isect
=
1
;
break
;
}
}
if
(
isect
==
1
)
{
for
(
k
=
a
.
_pack_prev
;
k
!==
j
.
_pack_prev
;
k
=
k
.
_pack_prev
,
s2
++
)
{
if
(
d3_layout_packIntersects
(
k
,
c
))
{
break
;
}
}
}
if
(
isect
)
{
if
(
s1
<
s2
||
s1
==
s2
&&
b
.
r
<
a
.
r
)
d3_layout_packSplice
(
a
,
b
=
j
);
else
d3_layout_packSplice
(
a
=
k
,
b
);
i
--
;
}
else
{
d3_layout_packInsert
(
a
,
c
);
b
=
c
;
bound
(
c
);
}
}
}
}
var
cx
=
(
xMin
+
xMax
)
/
2
,
cy
=
(
yMin
+
yMax
)
/
2
,
cr
=
0
;
for
(
i
=
0
;
i
<
n
;
i
++
)
{
c
=
nodes
[
i
];
c
.
x
-=
cx
;
c
.
y
-=
cy
;
cr
=
Math
.
max
(
cr
,
c
.
r
+
Math
.
sqrt
(
c
.
x
*
c
.
x
+
c
.
y
*
c
.
y
));
}
node
.
r
=
cr
;
nodes
.
forEach
(
d3_layout_packUnlink
);
}
function
d3_layout_packLink
(
node
)
{
node
.
_pack_next
=
node
.
_pack_prev
=
node
;
}
function
d3_layout_packUnlink
(
node
)
{
delete
node
.
_pack_next
;
delete
node
.
_pack_prev
;
}
function
d3_layout_packTransform
(
node
,
x
,
y
,
k
)
{
var
children
=
node
.
children
;
node
.
x
=
x
+=
k
*
node
.
x
;
node
.
y
=
y
+=
k
*
node
.
y
;
node
.
r
*=
k
;
if
(
children
)
{
var
i
=
-
1
,
n
=
children
.
length
;
while
(
++
i
<
n
)
d3_layout_packTransform
(
children
[
i
],
x
,
y
,
k
);
}
}
function
d3_layout_packPlace
(
a
,
b
,
c
)
{
var
db
=
a
.
r
+
c
.
r
,
dx
=
b
.
x
-
a
.
x
,
dy
=
b
.
y
-
a
.
y
;
if
(
db
&&
(
dx
||
dy
))
{
var
da
=
b
.
r
+
c
.
r
,
dc
=
dx
*
dx
+
dy
*
dy
;
da
*=
da
;
db
*=
db
;
var
x
=
.
5
+
(
db
-
da
)
/
(
2
*
dc
),
y
=
Math
.
sqrt
(
Math
.
max
(
0
,
2
*
da
*
(
db
+
dc
)
-
(
db
-=
dc
)
*
db
-
da
*
da
))
/
(
2
*
dc
);
c
.
x
=
a
.
x
+
x
*
dx
+
y
*
dy
;
c
.
y
=
a
.
y
+
x
*
dy
-
y
*
dx
;
}
else
{
c
.
x
=
a
.
x
+
db
;
c
.
y
=
a
.
y
;
}
}
d3
.
layout
.
cluster
=
function
()
{
var
hierarchy
=
d3
.
layout
.
hierarchy
().
sort
(
null
).
value
(
null
),
separation
=
d3_layout_treeSeparation
,
size
=
[
1
,
1
],
nodeSize
=
false
;
function
cluster
(
d
,
i
)
{
var
nodes
=
hierarchy
.
call
(
this
,
d
,
i
),
root
=
nodes
[
0
],
previousNode
,
x
=
0
;
d3_layout_
tree
VisitAfter
(
root
,
function
(
node
)
{
d3_layout_
hierarchy
VisitAfter
(
root
,
function
(
node
)
{
var
children
=
node
.
children
;
if
(
children
&&
children
.
length
)
{
node
.
x
=
d3_layout_clusterX
(
children
);
...
...
@@ -7060,7 +7059,7 @@
}
});
var
left
=
d3_layout_clusterLeft
(
root
),
right
=
d3_layout_clusterRight
(
root
),
x0
=
left
.
x
-
separation
(
left
,
right
)
/
2
,
x1
=
right
.
x
+
separation
(
right
,
left
)
/
2
;
d3_layout_
tree
VisitAfter
(
root
,
nodeSize
?
function
(
node
)
{
d3_layout_
hierarchy
VisitAfter
(
root
,
nodeSize
?
function
(
node
)
{
node
.
x
=
(
node
.
x
-
root
.
x
)
*
size
[
0
];
node
.
y
=
(
root
.
y
-
node
.
y
)
*
size
[
1
];
}
:
function
(
node
)
{
...
...
d3.min.js
View file @
b567b5d1
This source diff could not be displayed because it is too large. You can
view the blob
instead.
src/layout/cluster.js
View file @
b567b5d1
...
...
@@ -18,7 +18,7 @@ d3.layout.cluster = function() {
x
=
0
;
// First walk, computing the initial x & y values.
d3_layout_
tree
VisitAfter
(
root
,
function
(
node
)
{
d3_layout_
hierarchy
VisitAfter
(
root
,
function
(
node
)
{
var
children
=
node
.
children
;
if
(
children
&&
children
.
length
)
{
node
.
x
=
d3_layout_clusterX
(
children
);
...
...
@@ -37,7 +37,7 @@ d3.layout.cluster = function() {
x1
=
right
.
x
+
separation
(
right
,
left
)
/
2
;
// Second walk, normalizing x & y to the desired size.
d3_layout_
tree
VisitAfter
(
root
,
nodeSize
?
function
(
node
)
{
d3_layout_
hierarchy
VisitAfter
(
root
,
nodeSize
?
function
(
node
)
{
node
.
x
=
(
node
.
x
-
root
.
x
)
*
size
[
0
];
node
.
y
=
(
root
.
y
-
node
.
y
)
*
size
[
1
];
}
:
function
(
node
)
{
...
...
src/layout/hierarchy.js
View file @
b567b5d1
...
...
@@ -7,54 +7,36 @@ d3.layout.hierarchy = function() {
children
=
d3_layout_hierarchyChildren
,
value
=
d3_layout_hierarchyValue
;
// Recursively compute the node depth and value.
// Also converts to a standard hierarchy structure.
function
recurse
(
node
,
depth
,
nodes
)
{
var
childs
=
children
.
call
(
hierarchy
,
node
,
depth
);
node
.
depth
=
depth
;
function
hierarchy
(
root
)
{
var
stack
=
[
root
],
nodes
=
[],
node
;
root
.
depth
=
0
;
while
((
node
=
stack
.
pop
())
!=
null
)
{
nodes
.
push
(
node
);
if
(
childs
&&
(
n
=
childs
.
length
))
{
var
i
=
-
1
,
n
,
c
=
node
.
children
=
new
Array
(
n
),
v
=
0
,
j
=
depth
+
1
,
d
;
while
(
++
i
<
n
)
{
d
=
c
[
i
]
=
recurse
(
childs
[
i
],
j
,
nodes
);
d
.
parent
=
node
;
v
+=
d
.
value
;
if
((
childs
=
children
.
call
(
hierarchy
,
node
,
node
.
depth
))
&&
(
n
=
childs
.
length
))
{
var
n
,
childs
,
child
;
while
(
--
n
>=
0
)
{
stack
.
push
(
child
=
childs
[
n
]);
child
.
parent
=
node
;
child
.
depth
=
node
.
depth
+
1
;
}
if
(
sort
)
c
.
sort
(
sort
)
;
if
(
value
)
node
.
value
=
v
;
if
(
value
)
node
.
value
=
0
;
node
.
children
=
childs
;
}
else
{
if
(
value
)
node
.
value
=
+
value
.
call
(
hierarchy
,
node
,
node
.
depth
)
||
0
;
delete
node
.
children
;
if
(
value
)
{
node
.
value
=
+
value
.
call
(
hierarchy
,
node
,
depth
)
||
0
;
}
}
return
node
;
}
// Recursively re-evaluates the node value.
function
revalue
(
node
,
depth
)
{
var
children
=
node
.
children
,
v
=
0
;
if
(
children
&&
(
n
=
children
.
length
))
{
var
i
=
-
1
,
n
,
j
=
depth
+
1
;
while
(
++
i
<
n
)
v
+=
revalue
(
children
[
i
],
j
);
}
else
if
(
value
)
{
v
=
+
value
.
call
(
hierarchy
,
node
,
depth
)
||
0
;
}
if
(
value
)
node
.
value
=
v
;
return
v
;
}
d3_layout_hierarchyVisitAfter
(
root
,
function
(
node
)
{
var
childs
,
parent
;
if
(
sort
&&
(
childs
=
node
.
children
))
childs
.
sort
(
sort
);
if
(
value
&&
(
parent
=
node
.
parent
))
parent
.
value
+=
node
.
value
;
});
function
hierarchy
(
d
)
{
var
nodes
=
[];
recurse
(
d
,
0
,
nodes
);
return
nodes
;
}
...
...
@@ -78,7 +60,11 @@ d3.layout.hierarchy = function() {
// Re-evaluates the `value` property for the specified hierarchy.
hierarchy
.
revalue
=
function
(
root
)
{
revalue
(
root
,
0
);
if
(
value
)
d3_layout_hierarchyVisitAfter
(
root
,
function
(
node
)
{
var
parent
;
node
.
value
=
node
.
children
?
0
:
+
value
.
call
(
hierarchy
,
node
,
node
.
depth
)
||
0
;
if
(
parent
=
node
.
parent
)
parent
.
value
+=
node
.
value
;
});