Circle Pack&在同一页面上强制布局?

时间:2015-01-28 11:18:36

标签: javascript html css svg d3.js

我对d3和svg很新,听起来很天真。 我有一个力布局图和一个Circle pack,并希望在一个页面上并排显示它们。我去了同一页面上的多个布局(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放在一页上。

1 个答案:

答案 0 :(得分:1)

这对我来说有以下变化。希望这会有所帮助。

<!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”的重复var,因此我将其中一个重命名为svg2。