Conflicts:
	d3.min.js
This commit is contained in:
Nelson Minar 2011-04-12 02:02:48 +00:00
Родитель 26030821a9 9f71e4e211
Коммит 2548d4fa32
18 изменённых файлов: 943 добавлений и 26 удалений

Просмотреть файл

@ -105,6 +105,7 @@ d3.layout.js: \
src/layout/pie.js \
src/layout/stack.js \
src/layout/hierarchy.js \
src/layout/tree.js \
src/layout/treemap.js \
src/end.js

15
d3.js поставляемый
Просмотреть файл

@ -1,4 +1,4 @@
(function(){d3 = {version: "1.9.1"}; // semver
(function(){d3 = {version: "1.10.1"}; // semver
if (!Date.now) Date.now = function() {
return +new Date();
};
@ -2573,7 +2573,7 @@ function d3_svg_lineStepAfter(points) {
function d3_svg_lineCardinalClosed(points, tension) {
return points.length < 3
? d3_svg_lineLinear(points)
: points[0] + d3_svg_lineHermite(points,
: points[0] + d3_svg_lineHermite((points.push(points[0]), points),
d3_svg_lineCardinalTangents([points[points.length - 2]]
.concat(points, [points[1]]), tension));
}
@ -2637,18 +2637,17 @@ function d3_svg_lineHermite(points, tangents) {
function d3_svg_lineCardinalTangents(points, tension) {
var tangents = [],
a = (1 - tension) / 2,
p0 = points[0],
p1 = points[1],
p2 = points[2],
i = 2,
p0,
p1 = points[0],
p2 = points[1],
i = 1,
n = points.length;
while (++i < n) {
tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
p0 = p1;
p1 = p2;
p2 = points[i];
}
tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
}
return tangents;
}

Просмотреть файл

@ -739,6 +739,244 @@ function d3_layout_hierarchyValue(d) {
function d3_layout_hierarchySort(a, b) {
return b.value - a.value;
}
// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
d3.layout.tree = function() {
var hierarchy = d3.layout.hierarchy(),
separation = d3_layout_treeSeparation,
size = [1, 1]; // width, height
function tree(d, i) {
var nodes = hierarchy.call(this, d, i),
root = nodes[0];
function firstWalk(node, previousSibling) {
var children = node.children,
layout = node._tree;
if (children) {
var n = children.length,
firstChild = children[0],
previousChild,
ancestor = firstChild,
child,
i = -1;
while (++i < n) {
child = children[i];
firstWalk(child, previousChild);
ancestor = apportion(child, previousChild, ancestor);
previousChild = child;
}
d3_layout_treeShift(node);
var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
if (previousSibling) {
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
layout.mod = layout.prelim - midpoint;
} else {
layout.prelim = midpoint;
}
} else {
if (previousSibling) {
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
}
}
}
function secondWalk(node, x) {
node.x = node._tree.prelim + x;
var children = node.children;
if (children) {
var i = -1,
n = children.length;
x += node._tree.mod;
while (++i < n) {
secondWalk(children[i], x);
}
}
}
function apportion(node, previousSibling, ancestor) {
if (previousSibling) {
var vip = node,
vop = node,
vim = previousSibling,
vom = node.parent.children[0],
sip = vip._tree.mod,
sop = vop._tree.mod,
sim = vim._tree.mod,
som = vom._tree.mod,
shift;
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
vom = d3_layout_treeLeft(vom);
vop = d3_layout_treeRight(vop);
vop._tree.ancestor = node;
shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
if (shift > 0) {
d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
sip += shift;
sop += shift;
}
sim += vim._tree.mod;
sip += vip._tree.mod;
som += vom._tree.mod;
sop += vop._tree.mod;
}
if (vim && !d3_layout_treeRight(vop)) {
vop._tree.thread = vim;
vop._tree.mod += sim - sop;
}
if (vip && !d3_layout_treeLeft(vom)) {
vom._tree.thread = vip;
vom._tree.mod += sip - som;
ancestor = node;
}
}
return ancestor;
}
// Initialize temporary layout variables.
d3_layout_treeVisitAfter(root, function(node, previousSibling) {
node._tree = {
ancestor: node,
prelim: 0,
mod: 0,
change: 0,
shift: 0,
number: previousSibling ? previousSibling._tree.number + 1 : 0
};
});
// Compute the layout using Buchheim et al.'s algorithm.
firstWalk(root);
secondWalk(root, -root._tree.prelim);
// Compute the left-most, right-most, and depth-most nodes for extents.
var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost),
right = d3_layout_treeSearch(root, d3_layout_treeRightmost),
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;
// Clear temporary layout variables; transform x and y.
d3_layout_treeVisitAfter(root, function(node) {
node.x = (node.x - x0) / (x1 - x0) * size[0];
node.y = node.depth / y1 * size[1];
delete node._tree;
});
return nodes;
}
tree.sort = d3.rebind(tree, hierarchy.sort);
tree.children = d3.rebind(tree, hierarchy.children);
tree.value = d3.rebind(tree, hierarchy.value);
tree.separation = function(x) {
if (!arguments.length) return separation;
separation = x;
return tree;
};
tree.size = function(x) {
if (!arguments.length) return size;
size = x;
return tree;
};
return tree;
};
function d3_layout_treeSeparation(a, b) {
return a.parent == b.parent ? 1 : 2;
}
// function d3_layout_treeSeparationRadial(a, b) {
// return (a.parent == b.parent ? 1 : 2) / a.depth;
// }
function d3_layout_treeLeft(node) {
return node.children ? node.children[0] : node._tree.thread;
}
function d3_layout_treeRight(node) {
return node.children ? node.children[node.children.length - 1] : node._tree.thread;
}
function d3_layout_treeSearch(node, compare) {
var children = node.children;
if (children) {
var child,
n = children.length,
i = -1;
while (++i < n) {
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
node = child;
}
}
}
return node;
}
function d3_layout_treeRightmost(a, b) {
return a.x - b.x;
}
function d3_layout_treeLeftmost(a, b) {
return b.x - a.x;
}
function d3_layout_treeDeepest(a, b) {
return a.depth - b.depth;
}
function d3_layout_treeVisitAfter(node, callback) {
function visit(node, previousSibling) {
var children = node.children;
if (children) {
var child,
previousChild = null,
i = -1,
n = children.length;
while (++i < n) {
child = children[i];
visit(child, previousChild);
previousChild = child;
}
}
callback(node, previousSibling);
}
visit(node, null);
}
function d3_layout_treeShift(node) {
var shift = 0,
change = 0,
children = node.children,
i = children.length,
child;
while (--i >= 0) {
child = children[i]._tree;
child.prelim += shift;
child.mod += shift;
shift += child.shift + (change += child.change);
}
}
function d3_layout_treeMove(ancestor, node, shift) {
ancestor = ancestor._tree;
node = node._tree;
var change = shift / (node.number - ancestor.number);
ancestor.change += change;
node.change -= change;
node.shift += shift;
node.prelim += shift;
node.mod += shift;
}
function d3_layout_treeAncestor(vim, node, ancestor) {
return vim._tree.ancestor.parent == node.parent
? vim._tree.ancestor
: ancestor;
}
// Squarified Treemaps by Mark Bruls, Kees Huizing, and Jarke J. van Wijk
d3.layout.treemap = function() {
var hierarchy = d3.layout.hierarchy(),

2
d3.layout.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

2
d3.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -19,11 +19,12 @@ circle.node {
}
path.hull {
fill: lightsteelblue;
opacity: 0.3;
fill-opacity: 0.3;
}
line.link {
stroke: #333;
opacity: 0.5;
stroke-opacity: 0.5;
pointer-events: none;
}
</style>
</head>
@ -144,9 +145,7 @@ function convexHulls(nodes, index, offset) {
// create convex hulls
var hulls = [];
for (i in h) {
var p = d3.geom.hull(h[i]);
p.push(p[0]); // close the loop
hulls.push({group: i, path: p});
hulls.push({group: i, path: d3.geom.hull(h[i])});
}
return hulls;

Просмотреть файл

@ -35,6 +35,8 @@
<li><a href="stream/stream.html">stream</a></li>
<li><a href="stream/stack.html">stack</a></li>
<li><a href="symbol-map/symbol-map.html">symbol-map</a></li>
<li><a href="tree/tree.html">tree</a></li>
<li><a href="tree/tree-radial.html">tree-radial</a></li>
<li><a href="treemap/treemap.html">treemap</a></li>
<li><a href="voronoi/voronoi.html">voronoi</a></li>
<li><a href="zoom/zoom.html">zoom</a></li>

286
examples/tree/flare.json Normal file
Просмотреть файл

@ -0,0 +1,286 @@
{
"flare": {
"analytics": {
"cluster": {
"AgglomerativeCluster": 3938,
"CommunityStructure": 3812,
"HierarchicalCluster": 6714,
"MergeEdge": 743
},
"graph": {
"BetweennessCentrality": 3534,
"LinkDistance": 5731,
"MaxFlowMinCut": 7840,
"ShortestPaths": 5914,
"SpanningTree": 3416
},
"optimization": {
"AspectRatioBanker": 7074
}
},
"animate": {
"Easing": 17010,
"FunctionSequence": 5842,
"interpolate": {
"ArrayInterpolator": 1983,
"ColorInterpolator": 2047,
"DateInterpolator": 1375,
"Interpolator": 8746,
"MatrixInterpolator": 2202,
"NumberInterpolator": 1382,
"ObjectInterpolator": 1629,
"PointInterpolator": 1675,
"RectangleInterpolator": 2042
},
"ISchedulable": 1041,
"Parallel": 5176,
"Pause": 449,
"Scheduler": 5593,
"Sequence": 5534,
"Transition": 9201,
"Transitioner": 19975,
"TransitionEvent": 1116,
"Tween": 6006
},
"data": {
"converters": {
"Converters": 721,
"DelimitedTextConverter": 4294,
"GraphMLConverter": 9800,
"IDataConverter": 1314,
"JSONConverter": 2220
},
"DataField": 1759,
"DataSchema": 2165,
"DataSet": 586,
"DataSource": 3331,
"DataTable": 772,
"DataUtil": 3322
},
"display": {
"DirtySprite": 8833,
"LineSprite": 1732,
"RectSprite": 3623,
"TextSprite": 10066
},
"flex": {
"FlareVis": 4116
},
"physics": {
"DragForce": 1082,
"GravityForce": 1336,
"IForce": 319,
"NBodyForce": 10498,
"Particle": 2822,
"Simulation": 9983,
"Spring": 2213,
"SpringForce": 1681
},
"query": {
"AggregateExpression": 1616,
"And": 1027,
"Arithmetic": 3891,
"Average": 891,
"BinaryExpression": 2893,
"Comparison": 5103,
"CompositeExpression": 3677,
"Count": 781,
"DateUtil": 4141,
"Distinct": 933,
"Expression": 5130,
"ExpressionIterator": 3617,
"Fn": 3240,
"If": 2732,
"IsA": 2039,
"Literal": 1214,
"Match": 3748,
"Maximum": 843,
"methods": {
"add": 593,
"and": 330,
"average": 287,
"count": 277,
"distinct": 292,
"div": 595,
"eq": 594,
"fn": 460,
"gt": 603,
"gte": 625,
"iff": 748,
"isa": 461,
"lt": 597,
"lte": 619,
"max": 283,
"min": 283,
"mod": 591,
"mul": 603,
"neq": 599,
"not": 386,
"or": 323,
"orderby": 307,
"range": 772,
"select": 296,
"stddev": 363,
"sub": 600,
"sum": 280,
"update": 307,
"variance": 335,
"where": 299,
"xor": 354,
"_": 264
},
"Minimum": 843,
"Not": 1554,
"Or": 970,
"Query": 13896,
"Range": 1594,
"StringUtil": 4130,
"Sum": 791,
"Variable": 1124,
"Variance": 1876,
"Xor": 1101
},
"scale": {
"IScaleMap": 2105,
"LinearScale": 1316,
"LogScale": 3151,
"OrdinalScale": 3770,
"QuantileScale": 2435,
"QuantitativeScale": 4839,
"RootScale": 1756,
"Scale": 4268,
"ScaleType": 1821,
"TimeScale": 5833
},
"util": {
"Arrays": 8258,
"Colors": 10001,
"Dates": 8217,
"Displays": 12555,
"Filter": 2324,
"Geometry": 10993,
"heap": {
"FibonacciHeap": 9354,
"HeapNode": 1233
},
"IEvaluable": 335,
"IPredicate": 383,
"IValueProxy": 874,
"math": {
"DenseMatrix": 3165,
"IMatrix": 2815,
"SparseMatrix": 3366
},
"Maths": 17705,
"Orientation": 1486,
"palette": {
"ColorPalette": 6367,
"Palette": 1229,
"ShapePalette": 2059,
"SizePalette": 2291
},
"Property": 5559,
"Shapes": 19118,
"Sort": 6887,
"Stats": 6557,
"Strings": 22026
},
"vis": {
"axis": {
"Axes": 1302,
"Axis": 24593,
"AxisGridLine": 652,
"AxisLabel": 636,
"CartesianAxes": 6703
},
"controls": {
"AnchorControl": 2138,
"ClickControl": 3824,
"Control": 1353,
"ControlList": 4665,
"DragControl": 2649,
"ExpandControl": 2832,
"HoverControl": 4896,
"IControl": 763,
"PanZoomControl": 5222,
"SelectionControl": 7862,
"TooltipControl": 8435
},
"data": {
"Data": 20544,
"DataList": 19788,
"DataSprite": 10349,
"EdgeSprite": 3301,
"NodeSprite": 19382,
"render": {
"ArrowType": 698,
"EdgeRenderer": 5569,
"IRenderer": 353,
"ShapeRenderer": 2247
},
"ScaleBinding": 11275,
"Tree": 7147,
"TreeBuilder": 9930
},
"events": {
"DataEvent": 2313,
"SelectionEvent": 1880,
"TooltipEvent": 1701,
"VisualizationEvent": 1117
},
"legend": {
"Legend": 20859,
"LegendItem": 4614,
"LegendRange": 10530
},
"operator": {
"distortion": {
"BifocalDistortion": 4461,
"Distortion": 6314,
"FisheyeDistortion": 3444
},
"encoder": {
"ColorEncoder": 3179,
"Encoder": 4060,
"PropertyEncoder": 4138,
"ShapeEncoder": 1690,
"SizeEncoder": 1830
},
"filter": {
"FisheyeTreeFilter": 5219,
"GraphDistanceFilter": 3165,
"VisibilityFilter": 3509
},
"IOperator": 1286,
"label": {
"Labeler": 9956,
"RadialLabeler": 3899,
"StackedAreaLabeler": 3202
},
"layout": {
"AxisLayout": 6725,
"BundledEdgeRouter": 3727,
"CircleLayout": 9317,
"CirclePackingLayout": 12003,
"DendrogramLayout": 4853,
"ForceDirectedLayout": 8411,
"IcicleTreeLayout": 4864,
"IndentedTreeLayout": 3174,
"Layout": 7881,
"NodeLinkTreeLayout": 12870,
"PieLayout": 2728,
"RadialTreeLayout": 12348,
"RandomLayout": 870,
"StackedAreaLayout": 9121,
"TreeMapLayout": 9191
},
"Operator": 2490,
"OperatorList": 5248,
"OperatorSequence": 4190,
"OperatorSwitch": 2581,
"SortOperator": 2023
},
"Visualization": 16540
}
}
}

Просмотреть файл

@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<title>Node-Link Tree (Radial)</title>
<script type="text/javascript" src="../../d3.js"></script>
<script type="text/javascript" src="../../d3.layout.js"></script>
<link type="text/css" rel="stylesheet" href="tree.css"/>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript" src="tree-radial.js"></script>
</body>
</html>

Просмотреть файл

@ -0,0 +1,60 @@
var r = 960 / 2;
var tree = d3.layout.tree()
.size([360, r - 120])
.sort(null)
.children(function(d) { return isNaN(d.value) ? d3.entries(d.value) : null; })
.separation(function(a, b) { return (a.parent == b.parent ? 1 : 2) / a.depth; });
var vis = d3.select("#chart").append("svg:svg")
.attr("width", r * 2)
.attr("height", r * 2 - 150)
.append("svg:g")
.attr("transform", "translate(" + r + "," + r + ")");
d3.json("flare.json", function(json) {
var nodes = tree(d3.entries(json)[0]);
var link = vis.selectAll("g.link")
.data(nodes)
.enter().append("svg:g")
.attr("class", "link");
link.selectAll("line")
.data(children)
.enter().append("svg:line")
.attr("x1", function(d) { return x(d.parent); })
.attr("y1", function(d) { return y(d.parent); })
.attr("x2", function(d) { return x(d.child); })
.attr("y2", function(d) { return y(d.child); });
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; })
node.append("svg:circle")
.attr("r", 5);
node.append("svg:text")
.attr("dx", function(d) { return d.x < 180 ? 8 : -8; })
.attr("dy", ".31em")
.attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; })
.attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; })
.text(function(d) { return d.data.key; });
// Returns parent+child objects for any children of `d`.
function children(d) {
return (d.children || []).map(function(v) {
return {
parent: d,
child: v
};
});
}
// Radial scales for x and y.
function x(d) { return d.y * Math.cos((d.x - 90) / 180 * Math.PI); }
function y(d) { return d.y * Math.sin((d.x - 90) / 180 * Math.PI); }
});

14
examples/tree/tree.css Normal file
Просмотреть файл

@ -0,0 +1,14 @@
.node circle {
fill: #fff;
stroke: steelblue;
stroke-width: 1.5px;
}
.node {
font: 10px sans-serif;
}
.link {
stroke: #ccc;
stroke-width: 1.5px;
}

14
examples/tree/tree.html Normal file
Просмотреть файл

@ -0,0 +1,14 @@
<!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>
<link type="text/css" rel="stylesheet" href="tree.css"/>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript" src="tree.js"></script>
</body>
</html>

55
examples/tree/tree.js Normal file
Просмотреть файл

@ -0,0 +1,55 @@
var w = 960,
h = 2000;
var tree = d3.layout.tree()
.size([h, w - 160])
.sort(null)
.children(function(d) { return isNaN(d.value) ? d3.entries(d.value) : null; });
var vis = d3.select("#chart").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.attr("transform", "translate(40, 0)");
d3.json("flare.json", function(json) {
var nodes = tree(d3.entries(json)[0]);
var link = vis.selectAll("g.link")
.data(nodes)
.enter().append("svg:g")
.attr("class", "link");
link.selectAll("line")
.data(children)
.enter().append("svg:line")
.attr("x1", function(d) { return d.parent.y; })
.attr("y1", function(d) { return d.parent.x; })
.attr("x2", function(d) { return d.child.y; })
.attr("y2", function(d) { return d.child.x; });
var node = vis.selectAll("g.node")
.data(nodes)
.enter().append("svg:g")
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")"; })
node.append("svg:circle")
.attr("r", 5);
node.append("svg:text")
.attr("dx", function(d) { return d.children ? -8 : 8; })
.attr("dy", 3)
.attr("text-anchor", function(d) { return d.children ? "end" : "start"; })
.text(function(d) { return d.data.key; });
// Returns parent+child objects for any children of `d`.
function children(d) {
return (d.children || []).map(function(v) {
return {
parent: d,
child: v
};
});
}
});

Просмотреть файл

@ -1 +1 @@
d3 = {version: "1.9.1"}; // semver
d3 = {version: "1.10.1"}; // semver

238
src/layout/tree.js Normal file
Просмотреть файл

@ -0,0 +1,238 @@
// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm
d3.layout.tree = function() {
var hierarchy = d3.layout.hierarchy(),
separation = d3_layout_treeSeparation,
size = [1, 1]; // width, height
function tree(d, i) {
var nodes = hierarchy.call(this, d, i),
root = nodes[0];
function firstWalk(node, previousSibling) {
var children = node.children,
layout = node._tree;
if (children) {
var n = children.length,
firstChild = children[0],
previousChild,
ancestor = firstChild,
child,
i = -1;
while (++i < n) {
child = children[i];
firstWalk(child, previousChild);
ancestor = apportion(child, previousChild, ancestor);
previousChild = child;
}
d3_layout_treeShift(node);
var midpoint = .5 * (firstChild._tree.prelim + child._tree.prelim);
if (previousSibling) {
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
layout.mod = layout.prelim - midpoint;
} else {
layout.prelim = midpoint;
}
} else {
if (previousSibling) {
layout.prelim = previousSibling._tree.prelim + separation(node, previousSibling);
}
}
}
function secondWalk(node, x) {
node.x = node._tree.prelim + x;
var children = node.children;
if (children) {
var i = -1,
n = children.length;
x += node._tree.mod;
while (++i < n) {
secondWalk(children[i], x);
}
}
}
function apportion(node, previousSibling, ancestor) {
if (previousSibling) {
var vip = node,
vop = node,
vim = previousSibling,
vom = node.parent.children[0],
sip = vip._tree.mod,
sop = vop._tree.mod,
sim = vim._tree.mod,
som = vom._tree.mod,
shift;
while (vim = d3_layout_treeRight(vim), vip = d3_layout_treeLeft(vip), vim && vip) {
vom = d3_layout_treeLeft(vom);
vop = d3_layout_treeRight(vop);
vop._tree.ancestor = node;
shift = vim._tree.prelim + sim - vip._tree.prelim - sip + separation(vim, vip);
if (shift > 0) {
d3_layout_treeMove(d3_layout_treeAncestor(vim, node, ancestor), node, shift);
sip += shift;
sop += shift;
}
sim += vim._tree.mod;
sip += vip._tree.mod;
som += vom._tree.mod;
sop += vop._tree.mod;
}
if (vim && !d3_layout_treeRight(vop)) {
vop._tree.thread = vim;
vop._tree.mod += sim - sop;
}
if (vip && !d3_layout_treeLeft(vom)) {
vom._tree.thread = vip;
vom._tree.mod += sip - som;
ancestor = node;
}
}
return ancestor;
}
// Initialize temporary layout variables.
d3_layout_treeVisitAfter(root, function(node, previousSibling) {
node._tree = {
ancestor: node,
prelim: 0,
mod: 0,
change: 0,
shift: 0,
number: previousSibling ? previousSibling._tree.number + 1 : 0
};
});
// Compute the layout using Buchheim et al.'s algorithm.
firstWalk(root);
secondWalk(root, -root._tree.prelim);
// Compute the left-most, right-most, and depth-most nodes for extents.
var left = d3_layout_treeSearch(root, d3_layout_treeLeftmost),
right = d3_layout_treeSearch(root, d3_layout_treeRightmost),
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;
// Clear temporary layout variables; transform x and y.
d3_layout_treeVisitAfter(root, function(node) {
node.x = (node.x - x0) / (x1 - x0) * size[0];
node.y = node.depth / y1 * size[1];
delete node._tree;
});
return nodes;
}
tree.sort = d3.rebind(tree, hierarchy.sort);
tree.children = d3.rebind(tree, hierarchy.children);
tree.value = d3.rebind(tree, hierarchy.value);
tree.separation = function(x) {
if (!arguments.length) return separation;
separation = x;
return tree;
};
tree.size = function(x) {
if (!arguments.length) return size;
size = x;
return tree;
};
return tree;
};
function d3_layout_treeSeparation(a, b) {
return a.parent == b.parent ? 1 : 2;
}
// function d3_layout_treeSeparationRadial(a, b) {
// return (a.parent == b.parent ? 1 : 2) / a.depth;
// }
function d3_layout_treeLeft(node) {
return node.children ? node.children[0] : node._tree.thread;
}
function d3_layout_treeRight(node) {
return node.children ? node.children[node.children.length - 1] : node._tree.thread;
}
function d3_layout_treeSearch(node, compare) {
var children = node.children;
if (children) {
var child,
n = children.length,
i = -1;
while (++i < n) {
if (compare(child = d3_layout_treeSearch(children[i], compare), node) > 0) {
node = child;
}
}
}
return node;
}
function d3_layout_treeRightmost(a, b) {
return a.x - b.x;
}
function d3_layout_treeLeftmost(a, b) {
return b.x - a.x;
}
function d3_layout_treeDeepest(a, b) {
return a.depth - b.depth;
}
function d3_layout_treeVisitAfter(node, callback) {
function visit(node, previousSibling) {
var children = node.children;
if (children) {
var child,
previousChild = null,
i = -1,
n = children.length;
while (++i < n) {
child = children[i];
visit(child, previousChild);
previousChild = child;
}
}
callback(node, previousSibling);
}
visit(node, null);
}
function d3_layout_treeShift(node) {
var shift = 0,
change = 0,
children = node.children,
i = children.length,
child;
while (--i >= 0) {
child = children[i]._tree;
child.prelim += shift;
child.mod += shift;
shift += child.shift + (change += child.change);
}
}
function d3_layout_treeMove(ancestor, node, shift) {
ancestor = ancestor._tree;
node = node._tree;
var change = shift / (node.number - ancestor.number);
ancestor.change += change;
node.change -= change;
node.shift += shift;
node.prelim += shift;
node.mod += shift;
}
function d3_layout_treeAncestor(vim, node, ancestor) {
return vim._tree.ancestor.parent == node.parent
? vim._tree.ancestor
: ancestor;
}

Просмотреть файл

@ -121,7 +121,7 @@ function d3_svg_lineStepAfter(points) {
function d3_svg_lineCardinalClosed(points, tension) {
return points.length < 3
? d3_svg_lineLinear(points)
: points[0] + d3_svg_lineHermite(points,
: points[0] + d3_svg_lineHermite((points.push(points[0]), points),
d3_svg_lineCardinalTangents([points[points.length - 2]]
.concat(points, [points[1]]), tension));
}
@ -185,18 +185,17 @@ function d3_svg_lineHermite(points, tangents) {
function d3_svg_lineCardinalTangents(points, tension) {
var tangents = [],
a = (1 - tension) / 2,
p0 = points[0],
p1 = points[1],
p2 = points[2],
i = 2,
p0,
p1 = points[0],
p2 = points[1],
i = 1,
n = points.length;
while (++i < n) {
tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
p0 = p1;
p1 = p2;
p2 = points[i];
}
tangents.push([a * (p2[0] - p0[0]), a * (p2[1] - p0[1])]);
}
return tangents;
}

Просмотреть файл

@ -46,5 +46,5 @@ interpolate(cardinal):
interpolate(cardinal-closed):
[[0, 0]]: M0,0L0,0Z
[[0, 0], [5, 5]]: M0,0L5,5L5,0L0,0Z
[[0, 0], [5, 5], [10, 0]]: M0,0C0,0,3.5,5,5,5S10,0,10,0L10,0C10,0,6.5,0,5,0S0,0,0,0Z
[[0, 0], [5, 5], [10, 0]]: M0,0C-0.7500000000000001,0.7500000000000001,3.5,5,5,5S10.75,0.7500000000000001,10,0S0.7500000000000001,-0.7500000000000001,0,0L10,0C10.75,0,6.5,0,5,0S-0.7500000000000001,0,0,0S9.25,0,10,0Z

Просмотреть файл

@ -41,5 +41,5 @@ interpolate(cardinal):
interpolate(cardinal-closed):
[[0, 0]]: M0,0
[[0, 0], [5, 5]]: M0,0L5,5
[[0, 0], [5, 5], [10, 0]]: M0,0C0,0,3.5,5,5,5S10,0,10,0
[[0, 0], [5, 5], [10, 0]]: M0,0C-0.7500000000000001,0.7500000000000001,3.5,5,5,5S10.75,0.7500000000000001,10,0S0.7500000000000001,-0.7500000000000001,0,0