Circle Pack & Force 布局在同一页上?

Circle Pack & Force layout on same page?

我是 d3 和 svg 的新手,这听起来可能很天真。 我有一个力布局图和一个圆包,想在一页上并排显示它们。我去了 "Multiple layouts on same page (multiple force layouts same page)" 问题,但无法理解如何将这些布局放在 div 元素中。

这是强制布局 -

<!DOCTYPE html>
<meta charset="utf-8">
<body> 

 <style>
 h3{
 border: 1px solid green ;
 }
 .link {
stroke: #666;
stroke-opacity: 0.1;
stroke-width: 1.5px;

}
.node circle {
stroke: #fff;
opacity: 0.9;
stroke-width: 1.5px;
}
.node:not(:hover) .nodetext {
display: none;
}
text {
font: 17px serif;
opacity: 0.9;
pointer-events: none;
fill : red;
}
</style>

<script src=http://d3js.org/d3.v3.min.js></script>

<script> 
var links= [];
var nodes= [];

var width = 800
height = 400;

var color = d3.scale.category20();

var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkStrength(0.1)
.linkDistance(150)
.charge(-150)
.friction(0.6)
.gravity(0.5);

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

d3.json("sample1.json", function(error, data) {

  nodes = data.nodes;
  links = data.links;   

  force
      .nodes(nodes)
      .links(links)
      .on("tick", tick)
      .start();

 var link = svg.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(1); });


var node = svg.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.style("fill", "#7a85ec")
.style("opacity", 0.9)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click",clickf)
.call(force.drag);

node.append("circle")
.attr("r", function(d) { return Math.sqrt(3*d.weight); })

node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", "1.35em")
.attr("dy", "-1.35em")
.text(function(d) { return d.name });  

function tick() {
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 + ")"; });
}

function mouseover(d) {
var circle = d3.select(this);

  node
    .transition(500)
      .style("opacity", function(o) {
        return isConnected(o, d) ? 1.0 : 0.1 ;
      })
    .style("fill", function(o){
      if (isEqual(o, d)){
        return "red"  
        }
      else return "#7a85ec"
        })
    ;

  link
    .transition(500)
      .style("stroke-opacity", function(o) {
        return o.source === d || o.target === d ? 1 : 0.1;
      })
      ;

}

function mouseout() {
 var circle = d3.select(this);

  node
    .transition(500)
     .style("opacity", "1.0")
    .style("fill", "#7a85ec")
    ;

  link
    .transition(500)
    .style("stroke-opacity", "0.1");

}

function clickf(d){

}

var linkedByIndex = {};
links.forEach(function(d) {
  linkedByIndex[d.source.index + "," + d.target.index] = true;
});

function isConnected(a, b) {
    return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) || a.index == b.index;
}

function isConnectedAsSource(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}

function isConnectedAsTarget(a, b) {
    return linkedByIndex[b.index + "," + a.index];
}

function isEqual(a, b) {
    return a.index == b.index;
}

});



</script>
 </body>

这是我的圆包(样本来自 mbostock)-

<!DOCTYPE html>
<meta charset="utf-8">
<style>

circle {
  fill: rgb(31, 119, 180);
  fill-opacity: .25;
  stroke: rgb(31, 119, 180);
  stroke-width: 1px;
}

.leaf circle {
  fill: #ff7f0e;
  fill-opacity: 1;
}

text {
  font: 10px sans-serif;
}

</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>

var diameter = 560,
    format = d3.format(",d");

var pack = d3.layout.pack()
    .size([diameter - 4, diameter - 4])
    .value(function(d) { return d.size; });

var svg = d3.select("body").append("svg")
    .attr("width", diameter)
    .attr("height", diameter)
  .append("g")
    .attr("transform", "translate(2,2)");

d3.json("flare.json", function(error, root) {
  var node = svg.datum(root).selectAll(".node")
      .data(pack.nodes)
    .enter().append("g")
      .attr("class", function(d) { return d.children ? "node" : "leaf node"; })
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

  node.append("title")
      .text(function(d) { return d.name + (d.children ? "" : ": " + format(d.size)); });

  node.append("circle")
      .attr("r", function(d) { return d.r; });

  node.filter(function(d) { return !d.children; }).append("text")
      .attr("dy", ".3em")
      .style("text-anchor", "middle")
      .text(function(d) { return d.name.substring(0, d.r / 3); });
});

d3.select(self.frameElement).style("height", diameter + "px");

</script>

请帮我用div把这些放在一页上。

通过以下更改,这对我有用。希望这有帮助。

<!DOCTYPE html>
<meta charset="utf-8">
<style>

    #left-div
    {
        width:560px;
        height:560px;
        border:1px solid red;
        margin:10px;
        display:table-cell;
    }

    #right-div
    {
        width:560px;
        height:560px;
        border:1px solid red;
        margin:10px;
        display:table-cell;
    }

circle {
  fill: rgb(31, 119, 180);
  fill-opacity: .25;
  stroke: rgb(31, 119, 180);
  stroke-width: 1px;

}

.leaf circle {
  fill: #ff7f0e;
  fill-opacity: 1;
}

text {
  font: 10px sans-serif;
}

</style>

<div id="left-div"></div>
<div id="right-div"></div>

<script src="http://d3js.org/d3.v3.min.js"></script>

<body>  

<script>

var diameter = 560,
    format = d3.format(",d");

var pack = d3.layout.pack()
    .size([diameter - 4, diameter - 4])
    .value(function(d) { return d.size; });

var svg = d3.select("#left-div").append("svg")
    .attr("width", diameter)
    .attr("height", diameter)
  .append("g")
    .attr("transform", "translate(2,2)");

d3.json("flare.json", function(error, root) {
  var node = svg.datum(root).selectAll(".node")
      .data(pack.nodes)
    .enter().append("g")
      .attr("class", function(d) { return d.children ? "node" : "leaf node"; })
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; });

  node.append("title")
      .text(function(d) { return d.name + (d.children ? "" : ": " + format(d.size)); });

  node.append("circle")
      .attr("r", function(d) { return d.r; });

  node.filter(function(d) { return !d.children; }).append("text")
      .attr("dy", ".3em")
      .style("text-anchor", "middle")
      .text(function(d) { return d.name.substring(0, d.r / 3); });
});

d3.select(self.frameElement).style("height", diameter + "px");

</script>


<script> 
var links= [];
var nodes= [];

var width = 500
height = 500;

var color = d3.scale.category20();

var force = d3.layout.force()
.nodes(d3.values(nodes))
.links(links)
.size([width, height])
.linkStrength(0.1)
.linkDistance(150)
.charge(-150)
.friction(0.6)
.gravity(0.5);

var svg2 = d3.select("#right-div").append("svg")
.attr("width", width)
.attr("height", height);

d3.json("sample1.json", function(error, data) {

  nodes = data.nodes;
  links = data.links;   

  force
      .nodes(nodes)
      .links(links)
      .on("tick", tick)
      .start();

 var link = svg2.selectAll(".link")
.data(links)
.enter().append("line")
.attr("class", "link")
.style("stroke-width", function(d) { return Math.sqrt(1); });


var node = svg2.selectAll(".node")
.data(nodes)
.enter().append("g")
.attr("class", "node")
.style("fill", "#7a85ec")
.style("opacity", 0.9)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click",clickf)
.call(force.drag);

node.append("circle")
.attr("r", function(d) { return Math.sqrt(3*d.weight); })

node.append("svg:text")
.attr("class", "nodetext")
.attr("dx", "1.35em")
.attr("dy", "-1.35em")
.text(function(d) { return d.name });  

function tick() {
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 + ")"; });
}

function mouseover(d) {
var circle = d3.select(this);

  node
    .transition(500)
      .style("opacity", function(o) {
        return isConnected(o, d) ? 1.0 : 0.1 ;
      })
    .style("fill", function(o){
      if (isEqual(o, d)){
        return "red"  
        }
      else return "#7a85ec"
        })
    ;

  link
    .transition(500)
      .style("stroke-opacity", function(o) {
        return o.source === d || o.target === d ? 1 : 0.1;
      })
      ;

}

function mouseout() {
 var circle = d3.select(this);

  node
    .transition(500)
     .style("opacity", "1.0")
    .style("fill", "#7a85ec")
    ;

  link
    .transition(500)
    .style("stroke-opacity", "0.1");

}

function clickf(d){

}

var linkedByIndex = {};
links.forEach(function(d) {
  linkedByIndex[d.source.index + "," + d.target.index] = true;
});

function isConnected(a, b) {
    return isConnectedAsTarget(a, b) || isConnectedAsSource(a, b) || a.index == b.index;
}

function isConnectedAsSource(a, b) {
    return linkedByIndex[a.index + "," + b.index];
}

function isConnectedAsTarget(a, b) {
    return linkedByIndex[b.index + "," + a.index];
}

function isEqual(a, b) {
    return a.index == b.index;
}

});

</script>

请注意,其中一个图表遗漏了一些 CSS。根据需要进行调整。将 d3 图加载到 div 的关键是通过下面的代码。注意 div id 的字符串名称中的 #。

var svg = d3.select("#left-div").append("svg")

而不是下面的代码。

var svg = d3.select("body").append("svg")

我 运行 进入的下一个问题是由于两个脚本之间有一个名为 "svg" 的重复变量,所以我将其中一个重命名为 svg2。