代码之家  ›  专栏  ›  技术社区  ›  Jakeeln

带滑块的D3图形也需要添加标签

  •  0
  • Jakeeln  · 技术社区  · 8 年前

    我有一个D3脚本,它创建了一个侧面有一个滑块的图形。此滑块将仅显示具有滑块指示的度数的链接节点。所有其他节点都将断开连接并移到一边。

    我想包括所有这些节点的标签,将这些节点归纳到一边。我希望标签在节点内。我一直在尝试解决这个网站上的其他类似问题,但我似乎无法将其与我当前的代码正确集成。

    欢迎任何帮助!

    下面是我的脚本

    <!DOCTYPE html>
    <meta charset="utf-8">
    <title>Slider Graph</title>
    <style>
    
    .node {
      stroke: #fff;
      stroke-width: 1.5px;
    }
    
    .link {
      stroke: #999;
      stroke-opacity: .6;
    }
    
    .axis {
      opacity: 0.5;
      font: 10px sans-serif;
      -webkit-user-select: none;
      -moz-user-select: none;
      user-select: none;
    }
    
    .axis .domain {
      fill: none;
      stroke: #000;
      stroke-opacity: .3;
      stroke-width: 4px;
      stroke-linecap: round;
    }
    
    .axis .halo {
      fill: none;
      stroke: #ddd;
      stroke-width: 3px;
      stroke-linecap: round;
    }
    
    .slider .handle {
      fill: #fff;
      stroke: #000;
      stroke-opacity: .5;
      stroke-width: 1.25px;
      cursor: grab;
    }
    
    </style>
    <body>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <script>
    
    var width = 960,
        height = 500;
    
    var color = d3.scale.category20();
    
    var force = d3.layout.force()
        .charge(-120)
        .linkDistance(30)
        .size([width, height]);
    
    var x = d3.scale.linear()
        .domain([0, 20])
        .range([250, 80])
        .clamp(true);
    
    var brush = d3.svg.brush()
        .y(x)
        .extent([0, 0]);
    
    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);
    
    var links_g = svg.append("g");
    
    var nodes_g = svg.append("g");
    
    svg.append("g")
        .attr("class", "x axis")
        .attr("transform", "translate(" + (width - 20)  + ",0)")
        .call(d3.svg.axis()
          .scale(x)
          .orient("left")
          .tickFormat(function(d) { return d; })
          .tickSize(0)
          .tickPadding(12))
      .select(".domain")
      .select(function() { return this.parentNode.appendChild(this.cloneNode(true)); })
        .attr("class", "halo");
    
    var slider = svg.append("g")
        .attr("class", "slider")
        .call(brush);
    
    slider.selectAll(".extent,.resize")
        .remove();
    
    var handle = slider.append("circle")
        .attr("class", "handle")
        .attr("transform", "translate(" + (width - 20) + ",0)")
        .attr("r", 5);
    
    svg.append("text")
        .attr("x", width - 15)
        .attr("y", 60)
        .attr("text-anchor", "end")
        .attr("font-size", "12px")
        .style("opacity", 0.5)
        .text("degree threshold")
    
    d3.json("test4.json", function(error, graph) {
      if (error) throw error;
    
      graph.links.forEach(function(d,i){ d.i = i; });
      graph.nodes.forEach(function(d,i){ d.i = i; });
    
      function brushed() {
        var value = brush.extent()[0];
    
        if (d3.event.sourceEvent) {
          value = x.invert(d3.mouse(this)[1]);
          brush.extent([value, value]);
        }
        handle.attr("cy", x(value));
        var threshold = value;
        console.log(graph.nodes);
        var thresholded_nodes = graph.nodes.filter(function(d){ return (d.degree > threshold);});
        var thresholded_links = graph.links.filter(function(d){ return (d.min_degree > threshold);});
        console.log(thresholded_nodes);
    
        force
            .links(thresholded_links);
    
        var link = links_g.selectAll(".link")
            .data(thresholded_links, function(d){ return d.i; });
    
        link.enter().append("line")
            .attr("class", "link")
            .style("stroke-width", function(d) { return Math.sqrt(d.value); });
    
        link.exit().remove();
    
    
        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("cx", function(d) { return d.x; })
              .attr("cy", function(d) { return d.y; });
        });
    
        force.start();
    
      }
    
      force
          .nodes(graph.nodes);
    
      var node = nodes_g.selectAll(".node")
          .data(graph.nodes)
        .enter().append("circle")
          .attr("class", "node")
          .attr("r", 5)
          // .style("fill", function(d) { return color(1); })
          .style("fill", function(d) { return color(1); })
          .call(force.drag);
    
      node.append("title")
          .text(function(d) { return d.name; });
    
      brush.on("brush", brushed);
    
      slider
        .call(brush.extent([5, 5]))
        .call(brush.event);
    
    });
    
    </script>
    

    Test data here

    1 回复  |  直到 8 年前
        1
  •  1
  •   Mikhail Shabrikov    8 年前

    我重写了你的代码。请查收。这是你需要的吗?

    var jobject = `{"nodes":[
    {"name":"ADH1A","degree":9},
    {"name":"ADH1B","degree":10},
    {"name":"ADH1C","degree":9},
    {"name":"ADH4","degree":10},
    {"name":"ADH5","degree":9},
    {"name":"ADH7","degree":9},
    {"name":"ALDH1A1","degree":11},
    {"name":"ALDH2","degree":9},
    {"name":"BDNF","degree":5},
    {"name":"CHRNA5","degree":1},
    {"name":"CHRNB4","degree":2},
    {"name":"CNR1","degree":1},
    {"name":"COMT","degree":13},
    {"name":"CRHR1","degree":1},
    {"name":"CYP2E1","degree":9},
    {"name":"DRD1","degree":7},
    {"name":"DRD2","degree":9},
    {"name":"DRD3","degree":4},
    {"name":"DRD4","degree":6},
    {"name":"GABRA1","degree":9},
    {"name":"GABRA2","degree":8},
    {"name":"GABRA6","degree":7},
    {"name":"GABRB1","degree":8},
    {"name":"GABRB2","degree":8},
    {"name":"GABRB3","degree":7},
    {"name":"GABRG1","degree":5},
    {"name":"GABRG2","degree":8},
    {"name":"GAL","degree":5},
    {"name":"GRIK3","degree":1},
    {"name":"GRIN2B","degree":3},
    {"name":"GRM8","degree":4},
    {"name":"HTR1A","degree":2},
    {"name":"HTR1B","degree":5},
    {"name":"HTR2A","degree":5},
    {"name":"MAOA","degree":17},
    {"name":"NPY","degree":7},
    {"name":"OPRD1","degree":4},
    {"name":"OPRK1","degree":6},
    {"name":"OPRM1","degree":3},
    {"name":"PDYN","degree":6},
    {"name":"POMC","degree":10},
    {"name":"SLC6A3","degree":8},
    {"name":"SLC6A4","degree":13},
    {"name":"TPH1","degree":3}
    ],
    "links":[
    {"source":0,"target":1,"min_degree":9},
    {"source":0,"target":2,"min_degree":9},
    {"source":0,"target":3,"min_degree":9},
    {"source":0,"target":4,"min_degree":9},
    {"source":0,"target":5,"min_degree":9},
    {"source":0,"target":6,"min_degree":9},
    {"source":0,"target":7,"min_degree":9},
    {"source":0,"target":8,"min_degree":9},
    {"source":0,"target":11,"min_degree":9},
    {"source":1,"target":2,"min_degree":9},
    {"source":1,"target":3,"min_degree":10},
    {"source":1,"target":4,"min_degree":9},
    {"source":1,"target":5,"min_degree":9},
    {"source":1,"target":6,"min_degree":10},
    {"source":1,"target":7,"min_degree":10},
    {"source":1,"target":8,"min_degree":9},
    {"source":1,"target":9,"min_degree":9},
    {"source":1,"target":11,"min_degree":10},
    {"source":2,"target":3,"min_degree":9},
    {"source":2,"target":4,"min_degree":9},
    {"source":2,"target":5,"min_degree":9},
    {"source":2,"target":6,"min_degree":9},
    {"source":2,"target":8,"min_degree":9},
    {"source":2,"target":9,"min_degree":9},
    {"source":2,"target":11,"min_degree":9},
    {"source":3,"target":4,"min_degree":9},
    {"source":3,"target":5,"min_degree":9},
    {"source":3,"target":6,"min_degree":10},
    {"source":3,"target":7,"min_degree":10},
    {"source":3,"target":8,"min_degree":9},
    {"source":3,"target":9,"min_degree":9},
    {"source":3,"target":11,"min_degree":10},
    {"source":4,"target":5,"min_degree":9},
    {"source":4,"target":6,"min_degree":9},
    {"source":4,"target":8,"min_degree":9},
    {"source":4,"target":9,"min_degree":9},
    {"source":4,"target":11,"min_degree":9},
    {"source":5,"target":6,"min_degree":9},
    {"source":5,"target":8,"min_degree":9},
    {"source":5,"target":9,"min_degree":9},
    {"source":5,"target":11,"min_degree":9},
    {"source":6,"target":8,"min_degree":9},
    {"source":6,"target":9,"min_degree":9},
    {"source":6,"target":10,"min_degree":9},
    {"source":6,"target":11,"min_degree":11},
    {"source":6,"target":24,"min_degree":10},
    {"source":7,"target":8,"min_degree":9},
    {"source":7,"target":9,"min_degree":9},
    {"source":7,"target":11,"min_degree":13},
    {"source":7,"target":13,"min_degree":7},
    {"source":7,"target":18,"min_degree":2},
    {"source":7,"target":21,"min_degree":2},
    {"source":7,"target":23,"min_degree":7},
    {"source":7,"target":25,"min_degree":8},
    {"source":7,"target":39,"min_degree":6},
    {"source":7,"target":41,"min_degree":6},
    {"source":8,"target":9,"min_degree":9},
    {"source":9,"target":11,"min_degree":9},
    {"source":10,"target":12,"min_degree":5},
    {"source":10,"target":15,"min_degree":6},
    {"source":10,"target":22,"min_degree":5},
    {"source":10,"target":23,"min_degree":7},
    {"source":10,"target":24,"min_degree":9},
    {"source":10,"target":25,"min_degree":8},
    {"source":10,"target":39,"min_degree":6},
    {"source":10,"target":41,"min_degree":6},
    {"source":11,"target":13,"min_degree":7},
    {"source":11,"target":20,"min_degree":5},
    {"source":11,"target":23,"min_degree":7},
    {"source":11,"target":25,"min_degree":8},
    {"source":11,"target":34,"min_degree":13},
    {"source":11,"target":37,"min_degree":5},
    {"source":11,"target":39,"min_degree":6},
    {"source":11,"target":41,"min_degree":6},
    {"source":12,"target":13,"min_degree":5},
    {"source":12,"target":14,"min_degree":4},
    {"source":12,"target":15,"min_degree":5},
    {"source":12,"target":16,"min_degree":4},
    {"source":13,"target":22,"min_degree":5},
    {"source":13,"target":23,"min_degree":7},
    {"source":13,"target":24,"min_degree":7},
    {"source":13,"target":25,"min_degree":7},
    {"source":14,"target":22,"min_degree":4},
    {"source":14,"target":23,"min_degree":4},
    {"source":14,"target":24,"min_degree":4},
    {"source":15,"target":22,"min_degree":5},
    {"source":15,"target":23,"min_degree":6},
    {"source":15,"target":24,"min_degree":6},
    {"source":15,"target":26,"min_degree":6},
    {"source":16,"target":22,"min_degree":4},
    {"source":16,"target":23,"min_degree":4},
    {"source":16,"target":24,"min_degree":4},
    {"source":17,"target":18,"min_degree":1},
    {"source":19,"target":20,"min_degree":1},
    {"source":20,"target":25,"min_degree":5},
    {"source":20,"target":34,"min_degree":5},
    {"source":20,"target":43,"min_degree":3},
    {"source":21,"target":37,"min_degree":2},
    {"source":24,"target":38,"min_degree":4},
    {"source":24,"target":39,"min_degree":6},
    {"source":24,"target":40,"min_degree":3},
    {"source":24,"target":42,"min_degree":1},
    {"source":25,"target":34,"min_degree":8},
    {"source":25,"target":36,"min_degree":3},
    {"source":25,"target":37,"min_degree":5},
    {"source":26,"target":27,"min_degree":8},
    {"source":26,"target":28,"min_degree":7},
    {"source":26,"target":29,"min_degree":8},
    {"source":26,"target":30,"min_degree":8},
    {"source":26,"target":31,"min_degree":7},
    {"source":26,"target":32,"min_degree":5},
    {"source":26,"target":33,"min_degree":8},
    {"source":26,"target":34,"min_degree":9},
    {"source":27,"target":28,"min_degree":7},
    {"source":27,"target":29,"min_degree":8},
    {"source":27,"target":30,"min_degree":8},
    {"source":27,"target":31,"min_degree":7},
    {"source":27,"target":32,"min_degree":5},
    {"source":27,"target":33,"min_degree":8},
    {"source":27,"target":34,"min_degree":8},
    {"source":28,"target":29,"min_degree":7},
    {"source":28,"target":30,"min_degree":7},
    {"source":28,"target":31,"min_degree":7},
    {"source":28,"target":33,"min_degree":7},
    {"source":28,"target":34,"min_degree":7},
    {"source":29,"target":30,"min_degree":8},
    {"source":29,"target":31,"min_degree":7},
    {"source":29,"target":32,"min_degree":5},
    {"source":29,"target":33,"min_degree":8},
    {"source":29,"target":34,"min_degree":8},
    {"source":30,"target":31,"min_degree":7},
    {"source":30,"target":32,"min_degree":5},
    {"source":30,"target":33,"min_degree":8},
    {"source":30,"target":34,"min_degree":8},
    {"source":31,"target":33,"min_degree":7},
    {"source":31,"target":34,"min_degree":7},
    {"source":32,"target":33,"min_degree":5},
    {"source":33,"target":34,"min_degree":8},
    {"source":34,"target":36,"min_degree":3},
    {"source":34,"target":37,"min_degree":5},
    {"source":34,"target":43,"min_degree":3},
    {"source":35,"target":36,"min_degree":1},
    {"source":37,"target":43,"min_degree":3},
    {"source":38,"target":39,"min_degree":4},
    {"source":38,"target":40,"min_degree":3},
    {"source":38,"target":41,"min_degree":4},
    {"source":39,"target":41,"min_degree":6},
    {"source":40,"target":41,"min_degree":3}
    ]}`
    var graph = JSON.parse(jobject);
    
    var width = 960,
      height = 500;
    
    var color = d3.scale.category20();
    
    var force = d3.layout.force()
      .charge(-120)
      .linkDistance(30)
      .size([width, height]);
    
    var x = d3.scale.linear()
      .domain([0, 20])
      .range([250, 80])
      .clamp(true);
    
    var brush = d3.svg.brush()
      .y(x)
      .extent([0, 0]);
    
    var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height);
    
    var links_g = svg.append("g");
    
    var nodes_g = svg.append("g");
    
    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(" + (width - 20) + ",0)")
      .call(d3.svg.axis()
        .scale(x)
        .orient("left")
        .tickFormat(function(d) {
          return d;
        })
        .tickSize(0)
        .tickPadding(12))
      .select(".domain")
      .select(function() {
        return this.parentNode.appendChild(this.cloneNode(true));
      })
      .attr("class", "halo");
    
    var slider = svg.append("g")
      .attr("class", "slider")
      .call(brush);
    
    slider.selectAll(".extent,.resize")
      .remove();
    
    var handle = slider.append("circle")
      .attr("class", "handle")
      .attr("transform", "translate(" + (width - 20) + ",0)")
      .attr("r", 5);
    
    svg.append("text")
      .attr("x", width - 15)
      .attr("y", 60)
      .attr("text-anchor", "end")
      .attr("font-size", "12px")
      .style("opacity", 0.5)
      .text("degree threshold")
    
    
    graph.links.forEach(function(d, i) {
      d.i = i;
    });
    graph.nodes.forEach(function(d, i) {
      d.i = i;
    });
    
    function brushed() {
      var value = brush.extent()[0];
    
      if (d3.event.sourceEvent) {
        value = x.invert(d3.mouse(this)[1]);
        brush.extent([value, value]);
      }
      handle.attr("cy", x(value));
      var threshold = value;
    
      var thresholded_nodes = graph.nodes.filter(function(d) {
        return (d.degree > threshold);
      });
      var thresholded_links = graph.links.filter(function(d) {
        return (d.min_degree > threshold);
      });
    
    
      force
        .links(thresholded_links);
    
      var link = links_g.selectAll(".link")
        .data(thresholded_links, function(d) {
          return d.i;
        });
    
      link.enter().append("line")
        .attr("class", "link")
        .style("stroke-width", function(d) {
          return Math.sqrt(d.value);
        });
    
      link.exit().remove();
    
    
      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 + ")"; });
      });
    
      force.start();
    
    }
    
    force
      .nodes(graph.nodes);
    
    var node = nodes_g.selectAll(".node")
      .data(graph.nodes)
      .enter()
      .append('g')
      .attr("class", "node")
      .call(force.drag);
      
      node.append("circle")
      .attr("r", 5)
      // .style("fill", function(d) { return color(1); })
      .style("fill", function(d) {
        return color(1);
      })
      
     node.append("text")
          .attr("dx", 4)
          .attr("dy", ".35em")
          .text(function(d) { return d.name });
          
    node.append("title")
      .text(function(d) {
        return d.name;
      });
    
    brush.on("brush", brushed);
    
    slider
      .call(brush.extent([5, 5]))
      .call(brush.event);
    .node {
      stroke: #fff;
      stroke-width: 1.5px;
    }
    
    .link {
      stroke: #999;
      stroke-opacity: .6;
    }
    
    .axis {
      opacity: 0.5;
      font: 10px sans-serif;
      -webkit-user-select: none;
      -moz-user-select: none;
      user-select: none;
    }
    
    .axis .domain {
      fill: none;
      stroke: #000;
      stroke-opacity: .3;
      stroke-width: 4px;
      stroke-linecap: round;
    }
    
    .axis .halo {
      fill: none;
      stroke: #ddd;
      stroke-width: 3px;
      stroke-linecap: round;
    }
    
    
    text {
      pointer-events: none;
      font: 8px sans-serif;
      stroke: none;
      fill: red;
    }
    
    .slider .handle {
      fill: #fff;
      stroke: #000;
      stroke-opacity: .5;
      stroke-width: 1.25px;
      cursor: grab;
    }
    <script src="https://d3js.org/d3.v3.min.js"></script>