D3 Voronoi边缘条件

时间:2013-12-31 18:08:09

标签: d3.js force-layout delaunay voronoi

我正在使用force directed voronoi graph的D3示例文件...但是,我主要只需要一个只有三个顶点的简化版...所以我简化了文件并包含了{{3我文件当前所在的位置。我的问题是如何处理边缘条件。现在,voronoi边缘延伸到容器div的边缘。但是,我想用圆边界剪切每个voronoi单元格。我已经包含两张图片来帮助解释我的问题。第一张图片显示现在存在的脚本,而第二张图片用photoshop制作 - 显示圆形剪裁边界。好像JSFiddle example似乎是最好的选择,但我真的不知道如何在我的脚本中实现剪切方法。任何建议都将不胜感激。

Voronoi without edge boundary Voronoi with circle boundary

<!DOCTYPE html>
<html>
<head>
    <title>Voronoi Diagram with Force Directed Nodes and Delaunay Links</title>
    <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <style type="text/css">
      path
        {
            stroke: #EFEDF5;
            stroke-width: 4px;
        }
    </style>
</head>
<body>
<div id="chart">
</div>
<script type="text/javascript">
    var w = window.innerWidth > 960 ? 960 : (window.innerWidth || 960),
        h = window.innerHeight > 500 ? 500 : (window.innerHeight || 500),
        radius = 5.25,
        links = [],
        simulate = true,
        zoomToAdd = true,
        cc = ["#FFA94A","#F58A3A","#F85A19"]

    var numVertices = (w*h) / 200000;
    var vertices = d3.range(numVertices).map(function(i) {
        angle = radius * (i+10);
        return {x: angle*Math.cos(angle)+(w/2), y: angle*Math.sin(angle)+(h/2)};
    });
    var d3_geom_voronoi = d3.geom.voronoi().x(function(d) { return d.x;}).y(function(d) { return d.y; })
    var prevEventScale = 1;
    var zoom = d3.behavior.zoom().on("zoom", function(d,i) {
        if (zoomToAdd){
          if (d3.event.scale > prevEventScale) {
            angle = radius * vertices.length;
          } 
          force.nodes(vertices).start()
        } else {
          if (d3.event.scale > prevEventScale) {
            radius+= .01
          } else {
            radius -= .01
          }
          vertices.forEach(function(d, i) {
            angle = radius * (i+10);
            vertices[i] = {x: angle*Math.cos(angle)+(w/2), y: angle*Math.sin(angle)+(h/2)};
          });
          force.nodes(vertices).start()
        }
        prevEventScale = d3.event.scale;
    });

    d3.select(window)
      .on("keydown", function() {
        // shift
        if(d3.event.keyCode == 16) {
          zoomToAdd = false
        }
      })
      .on("keyup", function() {
        zoomToAdd = true
      })

    var svg = d3.select("#chart")
        .append("svg")
        .attr("width", w)
        .attr("height", h)
        .call(zoom)

    var force = d3.layout.force()
        .charge(-300)
        .size([w, h])
        .on("tick", update);

    force.nodes(vertices).start();

    var path = svg.selectAll("path");

    function update(e) {
        path = path.data(d3_geom_voronoi(vertices))
        path.enter().append("path")
            // drag node by dragging cell
            .call(d3.behavior.drag()
              .on("drag", function(d, i) {
              vertices[i] = {x: vertices[i].x + d3.event.dx, y: vertices[i].y + d3.event.dy}
          })
        )
        .style("fill", function(d, i) { return cc[0] })
    path.attr("d", function(d) { return "M" + d.join("L") + "Z"; })
        .transition().duration(150)
        .style("fill", function(d, i) { return cc[i] })
    path.exit().remove();

    if(!simulate) force.stop()
}

0 个答案:

没有答案