在力向图中,D3从饼图过渡到简单圆,反之亦然

时间:2018-07-19 21:20:56

标签: javascript d3.js graph transitions

我正在使用强制控制的布局,并根据我在节点上编码的属性将每个节点定制为饼图。

现在,我还有其他属性和一个选择要编码的属性的选项。基于选定的属性,我想更改节点的显示样式。例如here,如果选择了“ bin”单选按钮,我想将节点的编码从饼图更改为简单圆,反之亦然,如果选择了“比例”单选按钮,则相反。

<!DOCTYPE html>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>

<style>
  .main {
    float: left;
    width: 100%;
    height: 90%;
  }
  
  .top {
    background-color: #e8e8e8;
    float: left;
    width: 100%;
    height: 10%;
  }
  
  .link {
    fill: none;
    stroke: #000000;
    stroke-width: 1.5px;
    stroke-opacity: 0.8;
  }
  
  div.tooltip {
    position: absolute;
    text-align: center;
    min-width: 100;
    width: auto;
    min-height: 25;
    height: auto;
    padding: 2px;
    font: 10px sans-serif;
    background: rgba(0, 0, 0, 0.8);
    color: #fff;
    border: 0px;
    border-radius: 8px;
    pointer-events: none;
  }
</style>

<body>
  <div class="top">
    <input type="radio" name="attributes" value="0" checked> <label>Proportions</label><br>
    <input type="radio" name="attributes" value="1"> <label>Bin</label><br>

  </div>
  <div class="main"></div>
</body>

<script type="text/javascript">
  graph = {
    "nodes": [{
      "proportions": [{
        "group": 1,
        "value": 1
      }, {
        "group": 2,
        "value": 2
      }, {
        "group": 3,
        "value": 3
      }],
      "Weight": "2",
      "name": "abc1",
      "bin": 1
    }, {
      "proportions": [{
        "group": 1,
        "value": 2
      }, {
        "group": 2,
        "value": 1
      }, {
        "group": 3,
        "value": 5
      }],
      "Weight": "3",
      "name": "abc2",
      "bin": 1
    }, {
      "proportions": [{
        "group": 1,
        "value": 7
      }, {
        "group": 2,
        "value": 1
      }, {
        "group": 3,
        "value": 3
      }],
      "Weight": "4",
      "name": "abc3",
      "bin": 2
    }, {
      "proportions": [{
        "group": 1,
        "value": 5
      }, {
        "group": 2,
        "value": 3
      }, {
        "group": 3,
        "value": 4
      }],
      "Weight": "2",
      "name": "abc4",
      "bin": 1
    }, {
      "proportions": [{
        "group": 1,
        "value": 2
      }, {
        "group": 2,
        "value": 7
      }, {
        "group": 3,
        "value": 3
      }],
      "Weight": "1",
      "name": "abc5",
      "bin": 2
    }],
    "links": [{
      "source": 0,
      "target": 1,
      "width": 1
    }, {
      "source": 1,
      "target": 2,
      "width": 1
    }, {
      "source": 1,
      "target": 3,
      "width": 1
    }, {
      "source": 2,
      "target": 3,
      "width": 1
    }, {
      "source": 0,
      "target": 2,
      "width": 1
    }, {
      "source": 4,
      "target": 2,
      "width": 1
    }]
  }

  var width = 300,
    height = 500,
    radius = 25,
    color = d3.scale.category10(),
    rscale = d3.scale.linear().range([5, 20]);

  var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) {
      return d.value;
    });

  var arc = d3.svg.arc()
    .outerRadius(radius)
    .innerRadius(0);

  var svg = d3.select("div.main").append("svg")
    .attr("width", width)
    .attr("height", height);

  var force = d3.layout.force()
    .charge(-90)
    .gravity(0.09)
    .distance(100)
    .size([width, height]);

  force
    .nodes(graph.nodes)
    .links(graph.links)
    .start();

  rscale.domain(d3.extent(graph.nodes, function(d) {
    return d.Weight;
  }))

  var div = d3.select("div.main")
    .append("div")
    .attr("class", "tooltip")
    .style("opacity", 0);

  var link = svg.selectAll(".link")
    .data(graph.links)
    .enter().append("line")
    .attr("class", "link");

  var node = svg.selectAll(".node")
    .data(graph.nodes)
    .enter().append("g")
    .attr("class", "node")
    .on("mouseover", function(d) {
      var hoverArc = d3.svg.arc()
        .outerRadius(40)
        .innerRadius(0);

      d3.select(this).selectAll("path").transition()
        .duration(250)
        .attr("d", hoverArc);

      div.transition()
        .duration(200)
        .style("opacity", .9);
      div.html(d.name)
        .style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY - 28) + "px");
    })
    .on("mouseout", function(d) {
      var hoverArcOut = d3.svg.arc()
        .outerRadius(rscale(d.Weight))
        .innerRadius(0);

      d3.select(this).selectAll("path").transition()
        .duration(250)
        .attr("d", hoverArcOut);

      div.transition()
        .duration(500)
        .style("opacity", 0);
    })
    .call(force.drag);

  node.each(function(d) {
    arc = arc.outerRadius(rscale(d.Weight));

    d3.select(this)
      .selectAll("path")
      .data(function(d) {
        return pie(d.proportions);
      })
      .enter().append("path")
      .attr("d", arc)
      .style("fill", function(d, i) {
        return color(d.data.group);
      })
      .on("mouseover", function(d) {
        var hoverArc = d3.svg.arc()
          .outerRadius(70)
          .innerRadius(0);

        d3.select(this).transition()
          .duration(250)
          .attr("d", hoverArc);
      })
      .on("mouseout", function(d) {
        var hoverArcOut = d3.svg.arc()
          .outerRadius(40)
          .innerRadius(0);

        d3.select(this).transition()
          .duration(250)
          .attr("d", hoverArcOut);
      });
  });

  force.on("tick", function() {
    link.attr("x1", function(d) {
        return d.source.x;
      })
      .attr("y1", function(d) {
        return d.source.y;
      })
      .attr("x2", function(d) {
        return d.target.x;
      })
      .attr("y2", function(d) {
        return d.target.y;
      });

    node.attr('transform', function(d) {
      return 'translate(' + d.x + ',' + d.y + ')';
    });
  });

  d3.selectAll("div.top").on("change", function() {

  });
</script>

有人能帮助我提出这样的转变吗?

谢谢!

0 个答案:

没有答案