Add d3.layout.voronoi.{links,triangles}.
This commit is contained in:
Родитель
78a30bae0a
Коммит
fa6ef52de9
|
@ -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,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]]]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче