Simplify subclassing of hierarchy layout.
The subclasses can't use the same object as the parent class, because they are functions. But, there's no reason to duplicate the code that rebinds the methods onto the subclass.
This commit is contained in:
Родитель
953bebb17c
Коммит
d756caa0d8
61
d3.layout.js
61
d3.layout.js
|
@ -529,17 +529,13 @@ d3.layout.partition = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
partition.sort = d3.rebind(partition, hierarchy.sort);
|
||||
partition.children = d3.rebind(partition, hierarchy.children);
|
||||
partition.value = d3.rebind(partition, hierarchy.value);
|
||||
|
||||
partition.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
return partition;
|
||||
};
|
||||
|
||||
return partition;
|
||||
return d3_layout_hierarchyRebind(partition, hierarchy);
|
||||
};
|
||||
d3.layout.pie = function() {
|
||||
var value = Number,
|
||||
|
@ -1054,6 +1050,15 @@ d3.layout.hierarchy = function() {
|
|||
return hierarchy;
|
||||
}
|
||||
|
||||
// A method assignment helper for hierarchy subclasses.
|
||||
function d3_layout_hierarchyRebind(object, hierarchy) {
|
||||
object.sort = d3.rebind(object, hierarchy.sort);
|
||||
object.children = d3.rebind(object, hierarchy.children);
|
||||
object.links = d3_layout_hierarchyLinks;
|
||||
object.value = d3.rebind(object, hierarchy.value);
|
||||
return object;
|
||||
}
|
||||
|
||||
function d3_layout_hierarchyChildren(d) {
|
||||
return d.children;
|
||||
}
|
||||
|
@ -1065,8 +1070,17 @@ function d3_layout_hierarchyValue(d) {
|
|||
function d3_layout_hierarchySort(a, b) {
|
||||
return b.value - a.value;
|
||||
}
|
||||
|
||||
// Returns an array source+target objects for the specified nodes.
|
||||
function d3_layout_hierarchyLinks(nodes) {
|
||||
return d3.merge(nodes.map(function(parent) {
|
||||
return (parent.children || []).map(function(child) {
|
||||
return {source: parent, target: child};
|
||||
});
|
||||
}));
|
||||
}
|
||||
d3.layout.pack = function() {
|
||||
var hierarchy = d3.layout.hierarchy(),
|
||||
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
|
||||
size = [1, 1];
|
||||
|
||||
function pack(d, i) {
|
||||
|
@ -1087,17 +1101,13 @@ d3.layout.pack = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
pack.sort = d3.rebind(pack, hierarchy.sort);
|
||||
pack.children = d3.rebind(pack, hierarchy.children);
|
||||
pack.value = d3.rebind(pack, hierarchy.value);
|
||||
|
||||
pack.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
return pack;
|
||||
};
|
||||
|
||||
return pack.sort(d3_layout_packSort);
|
||||
return d3_layout_hierarchyRebind(pack, hierarchy);
|
||||
};
|
||||
|
||||
function d3_layout_packSort(a, b) {
|
||||
|
@ -1310,10 +1320,6 @@ d3.layout.cluster = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
cluster.sort = d3.rebind(cluster, hierarchy.sort);
|
||||
cluster.children = d3.rebind(cluster, hierarchy.children);
|
||||
cluster.links = d3_layout_treeLinks;
|
||||
|
||||
cluster.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
|
@ -1326,7 +1332,7 @@ d3.layout.cluster = function() {
|
|||
return cluster;
|
||||
};
|
||||
|
||||
return cluster;
|
||||
return d3_layout_hierarchyRebind(cluster, hierarchy);
|
||||
};
|
||||
|
||||
function d3_layout_clusterY(children) {
|
||||
|
@ -1465,7 +1471,7 @@ d3.layout.tree = function() {
|
|||
deep = d3_layout_treeSearch(root, d3_layout_treeDeepest),
|
||||
x0 = left.x - separation(left, right) / 2,
|
||||
x1 = right.x + separation(right, left) / 2,
|
||||
y1 = deep.depth;
|
||||
y1 = deep.depth || 1;
|
||||
|
||||
// Clear temporary layout variables; transform x and y.
|
||||
d3_layout_treeVisitAfter(root, function(node) {
|
||||
|
@ -1477,10 +1483,6 @@ d3.layout.tree = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
tree.sort = d3.rebind(tree, hierarchy.sort);
|
||||
tree.children = d3.rebind(tree, hierarchy.children);
|
||||
tree.links = d3_layout_treeLinks;
|
||||
|
||||
tree.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
|
@ -1493,18 +1495,9 @@ d3.layout.tree = function() {
|
|||
return tree;
|
||||
};
|
||||
|
||||
return tree;
|
||||
return d3_layout_hierarchyRebind(tree, hierarchy);
|
||||
};
|
||||
|
||||
// Returns an array source+target objects for the specified nodes.
|
||||
function d3_layout_treeLinks(nodes) {
|
||||
return d3.merge(nodes.map(function(parent) {
|
||||
return (parent.children || []).map(function(child) {
|
||||
return {source: parent, target: child};
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function d3_layout_treeSeparation(a, b) {
|
||||
return a.parent == b.parent ? 1 : 2;
|
||||
}
|
||||
|
@ -1740,10 +1733,6 @@ d3.layout.treemap = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
treemap.sort = d3.rebind(treemap, hierarchy.sort);
|
||||
treemap.children = d3.rebind(treemap, hierarchy.children);
|
||||
treemap.value = d3.rebind(treemap, hierarchy.value);
|
||||
|
||||
treemap.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
|
@ -1769,6 +1758,6 @@ d3.layout.treemap = function() {
|
|||
return treemap;
|
||||
};
|
||||
|
||||
return treemap;
|
||||
return d3_layout_hierarchyRebind(treemap, hierarchy);
|
||||
};
|
||||
})()
|
Различия файлов скрыты, потому что одна или несколько строк слишком длинны
|
@ -0,0 +1,119 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<title>Node-Link Tree</title>
|
||||
<script type="text/javascript" src="../../d3.js"></script>
|
||||
<script type="text/javascript" src="../../d3.layout.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
.node {
|
||||
stroke: #fff;
|
||||
stroke-width: 2px;
|
||||
}
|
||||
|
||||
.link {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
var w = 960,
|
||||
h = 500,
|
||||
root = {},
|
||||
data = [root],
|
||||
tree = d3.layout.tree().size([w - 20, h - 20]),
|
||||
diagonal = d3.svg.diagonal(),
|
||||
duration = 750,
|
||||
timer = setInterval(update, duration);
|
||||
|
||||
var vis = d3.select("body").append("svg:svg")
|
||||
.attr("width", w)
|
||||
.attr("height", h)
|
||||
.append("svg:g")
|
||||
.attr("transform", "translate(10, 10)");
|
||||
|
||||
vis.selectAll("circle")
|
||||
.data(tree(root))
|
||||
.enter().append("svg:circle")
|
||||
.attr("class", "node")
|
||||
.attr("r", 3.5)
|
||||
.attr("cx", x)
|
||||
.attr("cy", y);
|
||||
|
||||
function update() {
|
||||
if (data.length >= 500) return clearInterval(timer);
|
||||
|
||||
// Add a new datum to a random parent.
|
||||
var d = {id: data.length}, parent = data[~~(Math.random() * data.length)];
|
||||
if (parent.children) parent.children.push(d); else parent.children = [d];
|
||||
data.push(d);
|
||||
|
||||
// Compute the new tree layout. We'll stash the old layout in the data.
|
||||
var nodes = tree(root);
|
||||
|
||||
// Update the nodes…
|
||||
var node = vis.selectAll("circle.node")
|
||||
.data(nodes, nodeId);
|
||||
|
||||
// Enter any new nodes at the parent's previous position.
|
||||
node.enter().append("svg:circle")
|
||||
.attr("class", "node")
|
||||
.attr("r", 3.5)
|
||||
.attr("cx", function(d) { return d.parent.data.x0; })
|
||||
.attr("cy", function(d) { return d.parent.data.y0; })
|
||||
.transition()
|
||||
.duration(duration)
|
||||
.attr("cx", x)
|
||||
.attr("cy", y);
|
||||
|
||||
// Transition nodes to their new position.
|
||||
node.transition()
|
||||
.duration(duration)
|
||||
.attr("cx", x)
|
||||
.attr("cy", y);
|
||||
|
||||
// Update the links…
|
||||
var link = vis.selectAll("path.link")
|
||||
.data(tree.links(nodes), linkId);
|
||||
|
||||
// Enter any new links at the parent's previous position.
|
||||
link.enter().insert("svg:path", "circle")
|
||||
.attr("class", "link")
|
||||
.attr("d", function(d) {
|
||||
var o = {x: d.source.data.x0, y: d.source.data.y0};
|
||||
return diagonal({source: o, target: o});
|
||||
})
|
||||
.transition()
|
||||
.duration(duration)
|
||||
.attr("d", diagonal);
|
||||
|
||||
// Transition links to their new position.
|
||||
link.transition()
|
||||
.duration(duration)
|
||||
.attr("d", diagonal);
|
||||
}
|
||||
|
||||
function linkId(d) {
|
||||
return d.source.data.id + "-" + d.target.data.id;
|
||||
}
|
||||
|
||||
function nodeId(d) {
|
||||
return d.data.id;
|
||||
}
|
||||
|
||||
function x(d) {
|
||||
return d.data.x0 = d.x;
|
||||
}
|
||||
|
||||
function y(d) {
|
||||
return d.data.y0 = d.y;
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -39,10 +39,6 @@ d3.layout.cluster = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
cluster.sort = d3.rebind(cluster, hierarchy.sort);
|
||||
cluster.children = d3.rebind(cluster, hierarchy.children);
|
||||
cluster.links = d3_layout_treeLinks;
|
||||
|
||||
cluster.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
|
@ -55,7 +51,7 @@ d3.layout.cluster = function() {
|
|||
return cluster;
|
||||
};
|
||||
|
||||
return cluster;
|
||||
return d3_layout_hierarchyRebind(cluster, hierarchy);
|
||||
};
|
||||
|
||||
function d3_layout_clusterY(children) {
|
||||
|
|
|
@ -78,6 +78,15 @@ d3.layout.hierarchy = function() {
|
|||
return hierarchy;
|
||||
}
|
||||
|
||||
// A method assignment helper for hierarchy subclasses.
|
||||
function d3_layout_hierarchyRebind(object, hierarchy) {
|
||||
object.sort = d3.rebind(object, hierarchy.sort);
|
||||
object.children = d3.rebind(object, hierarchy.children);
|
||||
object.links = d3_layout_hierarchyLinks;
|
||||
object.value = d3.rebind(object, hierarchy.value);
|
||||
return object;
|
||||
}
|
||||
|
||||
function d3_layout_hierarchyChildren(d) {
|
||||
return d.children;
|
||||
}
|
||||
|
@ -89,3 +98,12 @@ function d3_layout_hierarchyValue(d) {
|
|||
function d3_layout_hierarchySort(a, b) {
|
||||
return b.value - a.value;
|
||||
}
|
||||
|
||||
// Returns an array source+target objects for the specified nodes.
|
||||
function d3_layout_hierarchyLinks(nodes) {
|
||||
return d3.merge(nodes.map(function(parent) {
|
||||
return (parent.children || []).map(function(child) {
|
||||
return {source: parent, target: child};
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
d3.layout.pack = function() {
|
||||
var hierarchy = d3.layout.hierarchy(),
|
||||
var hierarchy = d3.layout.hierarchy().sort(d3_layout_packSort),
|
||||
size = [1, 1];
|
||||
|
||||
function pack(d, i) {
|
||||
|
@ -20,17 +20,13 @@ d3.layout.pack = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
pack.sort = d3.rebind(pack, hierarchy.sort);
|
||||
pack.children = d3.rebind(pack, hierarchy.children);
|
||||
pack.value = d3.rebind(pack, hierarchy.value);
|
||||
|
||||
pack.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
return pack;
|
||||
};
|
||||
|
||||
return pack.sort(d3_layout_packSort);
|
||||
return d3_layout_hierarchyRebind(pack, hierarchy);
|
||||
};
|
||||
|
||||
function d3_layout_packSort(a, b) {
|
||||
|
|
|
@ -38,15 +38,11 @@ d3.layout.partition = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
partition.sort = d3.rebind(partition, hierarchy.sort);
|
||||
partition.children = d3.rebind(partition, hierarchy.children);
|
||||
partition.value = d3.rebind(partition, hierarchy.value);
|
||||
|
||||
partition.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
return partition;
|
||||
};
|
||||
|
||||
return partition;
|
||||
return d3_layout_hierarchyRebind(partition, hierarchy);
|
||||
};
|
||||
|
|
|
@ -113,7 +113,7 @@ d3.layout.tree = function() {
|
|||
deep = d3_layout_treeSearch(root, d3_layout_treeDeepest),
|
||||
x0 = left.x - separation(left, right) / 2,
|
||||
x1 = right.x + separation(right, left) / 2,
|
||||
y1 = deep.depth;
|
||||
y1 = deep.depth || 1;
|
||||
|
||||
// Clear temporary layout variables; transform x and y.
|
||||
d3_layout_treeVisitAfter(root, function(node) {
|
||||
|
@ -125,10 +125,6 @@ d3.layout.tree = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
tree.sort = d3.rebind(tree, hierarchy.sort);
|
||||
tree.children = d3.rebind(tree, hierarchy.children);
|
||||
tree.links = d3_layout_treeLinks;
|
||||
|
||||
tree.separation = function(x) {
|
||||
if (!arguments.length) return separation;
|
||||
separation = x;
|
||||
|
@ -141,18 +137,9 @@ d3.layout.tree = function() {
|
|||
return tree;
|
||||
};
|
||||
|
||||
return tree;
|
||||
return d3_layout_hierarchyRebind(tree, hierarchy);
|
||||
};
|
||||
|
||||
// Returns an array source+target objects for the specified nodes.
|
||||
function d3_layout_treeLinks(nodes) {
|
||||
return d3.merge(nodes.map(function(parent) {
|
||||
return (parent.children || []).map(function(child) {
|
||||
return {source: parent, target: child};
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
function d3_layout_treeSeparation(a, b) {
|
||||
return a.parent == b.parent ? 1 : 2;
|
||||
}
|
||||
|
|
|
@ -141,10 +141,6 @@ d3.layout.treemap = function() {
|
|||
return nodes;
|
||||
}
|
||||
|
||||
treemap.sort = d3.rebind(treemap, hierarchy.sort);
|
||||
treemap.children = d3.rebind(treemap, hierarchy.children);
|
||||
treemap.value = d3.rebind(treemap, hierarchy.value);
|
||||
|
||||
treemap.size = function(x) {
|
||||
if (!arguments.length) return size;
|
||||
size = x;
|
||||
|
@ -170,5 +166,5 @@ d3.layout.treemap = function() {
|
|||
return treemap;
|
||||
};
|
||||
|
||||
return treemap;
|
||||
return d3_layout_hierarchyRebind(treemap, hierarchy);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче