Add d3.layout.voronoi.{links,triangles}.

This commit is contained in:
Jason Davies 2013-03-15 23:30:20 +00:00
Родитель 78a30bae0a
Коммит fa6ef52de9
6 изменённых файлов: 99 добавлений и 19 удалений

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

@ -3794,7 +3794,7 @@ d3 = function() {
var polygons = vertices.map(function() {
return [];
}), Z = 1e6;
d3_voronoi_tessellate(vertices, function(e) {
d3_geom_voronoiTessellate(vertices, function(e) {
var s1, s2, x1, x2, y1, y2;
if (e.a === 1 && e.b >= 0) {
s1 = e.ep.r;
@ -3853,11 +3853,11 @@ d3 = function() {
});
return polygons;
};
var d3_voronoi_opposite = {
var d3_geom_voronoiOpposite = {
l: "r",
r: "l"
};
function d3_voronoi_tessellate(vertices, callback) {
function d3_geom_voronoiTessellate(vertices, callback) {
var Sites = {
list: vertices.map(function(v, i) {
return {
@ -3919,7 +3919,7 @@ d3 = function() {
return he.edge == null ? Sites.bottomSite : he.edge.region[he.side];
},
rightRegion: function(he) {
return he.edge == null ? Sites.bottomSite : he.edge.region[d3_voronoi_opposite[he.side]];
return he.edge == null ? Sites.bottomSite : he.edge.region[d3_geom_voronoiOpposite[he.side]];
}
};
var Geom = {
@ -4009,7 +4009,7 @@ d3 = function() {
},
endPoint: function(edge, side, site) {
edge.ep[side] = site;
if (!edge.ep[d3_voronoi_opposite[side]]) return;
if (!edge.ep[d3_geom_voronoiOpposite[side]]) return;
callback(edge);
},
distance: function(s, t) {
@ -4109,7 +4109,7 @@ d3 = function() {
e = Geom.bisect(bot, top);
bisector = EdgeList.createHalfEdge(e, pm);
EdgeList.insert(llbnd, bisector);
Geom.endPoint(e, d3_voronoi_opposite[pm], v);
Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v);
p = Geom.intersect(llbnd, bisector);
if (p) {
EventQueue.del(llbnd);
@ -4131,7 +4131,7 @@ d3 = function() {
var edges = vertices.map(function() {
return [];
}), triangles = [];
d3_voronoi_tessellate(vertices, function(e) {
d3_geom_voronoiTessellate(vertices, function(e) {
edges[e.region.l.index].push(vertices[e.region.r.index]);
});
edges.forEach(function(edge, i) {
@ -6204,6 +6204,30 @@ d3 = function() {
}
return voronoi;
};
voronoi.links = function(data) {
var points = [], graph = [], links = [], fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length;
for (i = 0; i < n; ++i) points.push([ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ]),
graph.push([]);
d3_geom_voronoiTessellate(points, function(e) {
var l = e.region.l.index, r = e.region.r.index;
if (graph[l][r]) return;
graph[l][r] = graph[r][l] = true;
links.push({
source: points[l],
target: points[r]
});
});
return links;
};
voronoi.triangles = function(data) {
var points = [], point, fx = d3_functor(x), fy = d3_functor(y), d, i, n = data.length;
for (i = 0; i < n; ++i) {
point = [ +fx.call(this, d = data[i], i), +fy.call(this, d, i) ];
point.data = d;
points.push(point);
}
return d3.geom.delaunay(points);
};
return voronoi;
};
d3.random = {

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

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

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

@ -10,7 +10,7 @@ d3.geom.delaunay = function(vertices) {
triangles = [];
// Use the Voronoi tessellation to determine Delaunay edges.
d3_voronoi_tessellate(vertices, function(e) {
d3_geom_voronoiTessellate(vertices, function(e) {
edges[e.region.l.index].push(vertices[e.region.r.index]);
});

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

@ -26,7 +26,7 @@ d3.geom.voronoi = function(vertices) {
var polygons = vertices.map(function() { return []; }),
Z = 1e6;
d3_voronoi_tessellate(vertices, function(e) {
d3_geom_voronoiTessellate(vertices, function(e) {
var s1,
s2,
x1,
@ -103,9 +103,9 @@ d3.geom.voronoi = function(vertices) {
return polygons;
};
var d3_voronoi_opposite = {l: "r", r: "l"};
var d3_geom_voronoiOpposite = {l: "r", r: "l"};
function d3_voronoi_tessellate(vertices, callback) {
function d3_geom_voronoiTessellate(vertices, callback) {
var Sites = {
list: vertices
@ -188,7 +188,7 @@ function d3_voronoi_tessellate(vertices, callback) {
rightRegion: function(he) {
return he.edge == null
? Sites.bottomSite
: he.edge.region[d3_voronoi_opposite[he.side]];
: he.edge.region[d3_geom_voronoiOpposite[he.side]];
}
};
@ -307,7 +307,7 @@ function d3_voronoi_tessellate(vertices, callback) {
endPoint: function(edge, side, site) {
edge.ep[side] = site;
if (!edge.ep[d3_voronoi_opposite[side]]) return;
if (!edge.ep[d3_geom_voronoiOpposite[side]]) return;
callback(edge);
},
@ -422,7 +422,7 @@ function d3_voronoi_tessellate(vertices, callback) {
e = Geom.bisect(bot, top);
bisector = EdgeList.createHalfEdge(e, pm);
EdgeList.insert(llbnd, bisector);
Geom.endPoint(e, d3_voronoi_opposite[pm], v);
Geom.endPoint(e, d3_geom_voronoiOpposite[pm], v);
p = Geom.intersect(llbnd, bisector);
if (p) {
EventQueue.del(llbnd);

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

@ -1,4 +1,5 @@
import "../core/functor";
import "../geom/delaunay";
import "../geom/polygon";
import "../geom/voronoi";
import "../svg/line";
@ -44,5 +45,41 @@ d3.layout.voronoi = function() {
return voronoi;
};
voronoi.links = function(data) {
var points = [],
graph = [],
links = [],
fx = d3_functor(x),
fy = d3_functor(y),
d,
i,
n = data.length;
for (i = 0; i < n; ++i) points.push([+fx.call(this, d = data[i], i), +fy.call(this, d, i)]), graph.push([]);
d3_geom_voronoiTessellate(points, function(e) {
var l = e.region.l.index,
r = e.region.r.index;
if (graph[l][r]) return;
graph[l][r] = graph[r][l] = true;
links.push({source: points[l], target: points[r]});
});
return links;
};
voronoi.triangles = function(data) {
var points = [],
point,
fx = d3_functor(x),
fy = d3_functor(y),
d,
i,
n = data.length;
for (i = 0; i < n; ++i) {
point = [+fx.call(this, d = data[i], i), +fy.call(this, d, i)];
point.data = d;
points.push(point);
}
return d3.geom.delaunay(points);
};
return voronoi;
};

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

@ -60,6 +60,25 @@ suite.addBatch({
"the returned cells' data points back to the input data": function(cells) {
assert.deepEqual(cells.map(function(cell) { return cell.data; }), [[200, 200], [760, 300]]);
}
},
"links": {
"for two points": function(v) {
assert.deepEqual(v.links([[200, 200], [760, 300]]), [
{source: [200, 200], target: [760, 300]}]);
},
"for three points": function(v) {
assert.deepEqual(v.links([[200, 200], [500, 250], [760, 300]]), [
{source: [200, 200], target: [760, 300]},
{source: [500, 250], target: [760, 300]},
{source: [200, 200], target: [500, 250]}]);
}
},
"triangles": {
"for three points": function(v) {
assert.deepEqual(v.triangles([[200, 200], [500, 250], [760, 300]]).map(function(d) {
return d.map(function(d) { return d.data; });
}), [[ [200, 200], [760, 300], [500, 250]]]);
}
}
},