d3.js将图像显示为圆圈

时间:2017-07-03 05:08:49

标签: javascript image d3.js svg

代码:

// some colour variables
var tcBlack = "#130C0E";

// rest of vars
var w = 1255,
h = 925,
maxNodeSize = 50,
x_browser = 10,
y_browser = 15,
root;

var vis;
var force = d3.layout.force(); 

vis = d3.select("#vis").append("svg").attr("width", w).attr("height", h);

d3.json("marvel.json", function(json) {

root = json;
root.fixed = true;
root.x = w / 2;
root.y = h / 4;


    // Build the path
var defs = vis.insert("svg:defs")
  .data(["end"]);


defs.enter().append("svg:path")
  .attr("d", "M0,-5L10,0L0,5");

 update();
});



function update() {
  var nodes = flatten(root),
  links = d3.layout.tree().links(nodes);

 // Restart the force layout.
 force.nodes(nodes)
    .links(links)
    .gravity(0.05)
.charge(-1500)
.linkDistance(100)
.friction(0.5)
.linkStrength(function(l, i) {return 1; })
.size([w, h])
.on("tick", tick)
    .start();

var path = vis.selectAll("path.link")
  .data(links, function(d) { return d.target.id; });

path.enter().insert("svg:path")
  .attr("class", "link")
  // .attr("marker-end", "url(#end)")
  .style("stroke", "#eee");


// Exit any old paths.
path.exit().remove();



// Update the nodes…
var node = vis.selectAll("g.node")
  .data(nodes, function(d) { return d.id; });


// Enter any new nodes.
var nodeEnter = node.enter().append("svg:g")
  .attr("class", "node")
  .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
  .on("click", click)
  .call(force.drag);

// Append a circle
nodeEnter.append("svg:circle")
  .attr("r", function(d) { return Math.sqrt(40000) / 10 || 30; })
  .style("fill", "#ffffff");

// Append images
var images = nodeEnter.append("svg:image")
    .attr("xlink:href",  function(d) { return d.img;})
    .attr("x", function(d) { return -25;})
    .attr("y", function(d) { return -25;})
    .attr("height", 50)
    .attr("width", 50);

// make the image grow a little on mouse over and add the text details on click
var setEvents = images
      // Append hero text
      .on( 'click', function (d) {
          // d3.select("h1").html(d.hero); 
          d3.select("h3").html(d.name); 
          // d3.select("h3").html ("Take me to " + "<a href='" + d.link + "' >"  + d.hero + " web page ⇢"+ "</a>" ); 
       })

      .on( 'mouseenter', function() {
        // select element in current context
        d3.select( this )
          .transition()
          .attr("x", function(d) { return -60;})
          .attr("y", function(d) { return -60;})
          .attr("height", 100)
          .attr("width", 100);
      })
      // set back
      .on( 'mouseleave', function() {
        d3.select( this )
          .transition()
          .attr("x", function(d) { return -25;})
          .attr("y", function(d) { return -25;})
          .attr("height", 50)
          .attr("width", 50);
      });

 // Append hero name on roll over next to the node as well
 nodeEnter.append("text")
    .attr("class", "nodetext")
    .attr("x", x_browser)
    .attr("y", y_browser +15)
    .attr("fill", "red")
    .text(function(d) { return d.name; });


 // Exit any old nodes.
 node.exit().remove();


 // Re-select for update.
 path = vis.selectAll("path.link");
 node = vis.selectAll("g.node");

function tick() {


path.attr("d", function(d) {

 var dx = d.target.x - d.source.x,
       dy = d.target.y - d.source.y,
       dr = Math.sqrt(dx * dx + dy * dy);
       return   "M" + d.source.x + "," 
        + d.source.y 
        + "A" + dr + "," 
        + dr + " 0 0,1 " 
        + d.target.x + "," 
        + d.target.y;
});
node.attr("transform", nodeTransform);    
}
}



function nodeTransform(d) {
 d.x =  Math.max(maxNodeSize, Math.min(w - (d.imgwidth/2 || 16), d.x));
 d.y =  Math.max(maxNodeSize, Math.min(h - (d.imgheight/2 || 16), d.y));
 return "translate(" + d.x + "," + d.y + ")";
}


function click(d) {
 if (d.children) {
 d._children = d.children;
 d.children = null;
} else {
 d.children = d._children;
 d._children = null;
}

 update();
}


/**
 * Returns a list of all nodes under the root.
*/ 
function flatten(root) {
  var nodes = []; 
  var i = 0;

  function recurse(node) {
   if (node.children) 
   node.children.forEach(recurse);
   if (!node.id) 
   node.id = ++i;
   nodes.push(node);
  }

recurse(root);
return nodes;
}   

我正在使用上面的代码使用d3.js显示图片。但是图像没有显示为圆圈。我希望子节点图像正确填充圆圈。

所以请帮助解决这个问题。答案将不胜感激。由于
Image

这是我使用的示例:d3 | Force layout with images

1 个答案:

答案 0 :(得分:1)

var marvelJson={
 "name": "marvel",
 "img": "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/marvel.png",
 "children": [
  {
   "name": "Heroes",
   "children": [
    {
      "hero": "Spider-Man",
      "name": "Peter Benjamin Parker", 
      "link": "http://marvel.com/characters/54/spider-man",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_spiderman.png",
      "size": 40000
    },
    {
      "hero": "CAPTAIN MARVEL",
      "name": "Carol Danvers", 
      "link": "http://marvel.com/characters/9/captain_marvel",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_captainmarvel.png",
      "size": 40000
    },
    {
      "hero": "HULK", 
      "name": "Robert Bruce Banner",
      "link": "http://marvel.com/characters/25/hulk",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_hulk.png",
      "size": 40000
    },
    {
      "hero": "Black Widow", 
      "name": "Natalia 'Natasha' Alianovna Romanova",
      "link": "http://marvel.com/characters/6/black_widow",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_blackwidow.png",
      "size": 40000
    },
    {
      "hero": "Daredevil", 
      "name": "Matthew Michael Murdock",
      "link": "http://marvel.com/characters/11/daredevil",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_daredevil.png",
      "size": 40000
    },
    {
      "hero": "Wolverine", 
      "name": "James Howlett",
      "link": "http://marvel.com/characters/66/wolverine",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_wolverine.png",
      "size": 40000
    },
    {
      "hero": "Captain America", 
      "name": "Steven Rogers",
      "link": "http://marvel.com/characters/8/captain_america",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_captainamerica.png",
      "size": 40000
    },
    {
      "hero": "Iron Man", 
      "name": "Anthony Edward 'Tony' Stark",
      "link": "http://marvel.com/characters/29/iron_man",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_ironman.png",
      "size": 40000
    },
    {
      "hero": "THOR", 
      "name": "Thor Odinson",
      "link": "http://marvel.com/characters/60/thor",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/top_thor.png",
      "size": 40000
    }
  ]
  },
  {
   "name": "Villains",
   "children": [
    {
      "hero": "Dr. Doom",
      "name": "Victor von Doom", 
      "link": "http://marvel.com/characters/13/dr_doom",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/drdoom.png",
      "size": 40000
    },
    {
      "hero": "Mystique",
      "name": "Unrevealed", 
      "link": "http://marvel.com/characters/1552/mystique",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/mystique.png",
      "size": 40000
    },
    {
      "hero": "Red Skull",
      "name": "Johann Shmidt", 
      "link": "http://marvel.com/characters/1901/red_skull",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/redskull.png",
      "size": 40000
    },
    {
      "hero": "Ronan",
      "name": "Ronan", 
      "link": "http://marvel.com/characters/49/ronan",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/ronan.png",
      "size": 40000
    },
    {
      "hero": "Magneto",
      "name": "Max Eisenhardt", 
      "link": "http://marvel.com/characters/35/magneto",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/magneto.png",
      "size": 40000
    },
    {
      "hero": "Thanos",
      "name": "Thanos", 
      "link": "http://marvel.com/characters/58/thanos",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/thanos.png",
      "size": 40000
    },
    {
      "hero": "Black Cat",
      "name": "Felicia Hardy", 
      "link": "http://marvel.com/characters/271/black_cat",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/blackcat.png",
      "size": 40000
    }
   ]
  },
  {
   "name": "Teams",
   "children": [
    {
      "hero": "Avengers",
      "name": "", 
      "link": "http://marvel.com/characters/68/avengers",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/avengers.png",
      "size": 40000
    },
    {
      "hero": "Guardians of the Galaxy",
      "name": "", 
      "link": "http://marvel.com/characters/70/guardians_of_the_galaxy",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/gofgalaxy.png",
      "size": 40000
    },
    {
      "hero": "Defenders",
      "name": "", 
      "link": "http://marvel.com/characters/534/defenders",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/defenders.png",
      "size": 40000
    },
    {
      "hero": "X-Men",
      "name": "", 
      "link": "http://marvel.com/characters/71/x-men",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/xmen.png",
      "size": 40000
    },
    {
      "hero": "Fantastic Four",
      "name": "", 
      "link": "http://marvel.com/characters/69/fantastic_four",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/fantasticfour.png",
      "size": 40000
    },
    {
      "hero": "Inhumans",
      "name": "", 
      "link": "http://marvel.com/characters/1040/inhumans",
      "img":  "https://dl.dropboxusercontent.com/u/19954023/marvel_force_chart_img/inhumans.png",
      "size": 40000
    }
   ]
  }  
 ]
}

/*
var imgurl = "http://wallpapers.androlib.com/wallicons/wallpaper.big-pqC.cs.png"

var margin = {top: 20, right: 10, bottom: 20, left: 10};


var width = 960 - margin.left - margin.right,
    height = 500 - margin.top - margin.bottom;


var svg = d3.select("body").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
  .append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");


var defs = svg.append("defs").attr("id", "imgdefs")

var catpattern = defs.append("pattern")
                        .attr("id", "catpattern")
                        .attr("height", 1)
                        .attr("width", 1)
                        .attr("x", "0")
                        .attr("y", "0")


catpattern.append("image")
     .attr("x", -130)
     .attr("y", -220)
     .attr("height", 640)
     .attr("width", 480)
     .attr("xlink:href", imgurl)

svg.append("circle")
    .attr("r", 100)
    .attr("cy", 80)
    .attr("cx", 120)
    .attr("fill", "url(#catpattern)")
    */
    
    
    // some colour variables
  var tcBlack = "#130C0E";

// rest of vars
var w = 960,
    h = 800,
    maxNodeSize = 50,
    x_browser = 20,
    y_browser = 25,
    root;
 
var vis;
var force = d3.layout.force(); 

vis = d3.select("#vis").append("svg").attr("width", w).attr("height", h);
 
//d3.json("marvel.json", function(json) {
 var json = marvelJson;
 
  root = json;
  root.fixed = true;
  root.x = w / 2;
  root.y = h / 4;
 
 
        // Build the path
  var defs = vis.insert("svg:defs")
      .data(["end"]);
 
 
  defs.enter().append("svg:path")
      .attr("d", "M0,-5L10,0L0,5");
 try{
     update();
     }catch(e){
     console.log(e);
     }
//});
 
 
/**
 *   
 */
function update() {
  var nodes = flatten(root),
      links = d3.layout.tree().links(nodes);
 
  // Restart the force layout.
  force.nodes(nodes)
        .links(links)
        .gravity(0.05)
    .charge(-1500)
    .linkDistance(100)
    .friction(0.5)
    .linkStrength(function(l, i) {return 1; })
    .size([w, h])
    .on("tick", tick)
        .start();
 
   var path = vis.selectAll("path.link")
      .data(links, function(d) { return d.target.id; });
 
    path.enter().insert("svg:path")
      .attr("class", "link")
      // .attr("marker-end", "url(#end)")
      .style("stroke", "#eee");
 
 
  // Exit any old paths.
  path.exit().remove();
 
 
 
  // Update the nodes…
  var node = vis.selectAll("g.node")
      .data(nodes, function(d) { return d.id; });
 
 
  // Enter any new nodes.
  var nodeEnter = node.enter().append("svg:g")
      .attr("class", "node")
      .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
      .on("click", click)
      .call(force.drag);
 
 
 /*Dinesh Code*/
 /*
 
 var defs = svg.append("defs").attr("id", "imgdefs")

var catpattern = defs.append("pattern")
                        .attr("id", "catpattern")
                        .attr("height", 1)
                        .attr("width", 1)
                        .attr("x", "0")
                        .attr("y", "0")


catpattern.append("image")
     .attr("x", -130)
     .attr("y", -220)
     .attr("height", 640)
     .attr("width", 480)
     .attr("xlink:href", imgurl)

svg.append("circle")
    .attr("r", 100)
    .attr("cy", 80)
    .attr("cx", 120)
    .attr("fill", "url(#catpattern)")
    */
 
 /******* Dinesh Code End******/
 
 nodeEnter.append("defs").attr("id", "imgdefs")
 .append("pattern")
   .attr("id", function(d){ if(d.img)return d.img.replace(/[/|.|:]/g, ""); else null; })
   .attr("height", 1)
   .attr("width", 1)
   .attr("x", "0")
   .attr("y", "0")
   .append("image")
     .attr("height",  function(d) { return 2* Math.sqrt(d.size) / 10 || 4.5; })
     .attr("width",  function(d) { return 2* Math.sqrt(d.size) / 10 || 4.5; })
     .attr("xlink:href",  function(d){if(d.img)return d.img+""; else null; })
 
  // Append a circle
 var images = nodeEnter.append("svg:circle")
      .attr("r", function(d) { return Math.sqrt(d.size) / 10 || 4.5; })
      .attr("fill", function(d){ if(d.img)return "url(#"+d.img.replace(/[/|.|:]/g, "")+")" ; else null; });
 
   
  // Append images
 /* var images = nodeEnter.append("svg:image")
        .attr("xlink:href",  function(d) { return d.img;})
        .attr("x", function(d) { return -25;})
        .attr("y", function(d) { return -25;})
        .attr("height", 50)
        .attr("width", 50);*/
  
  // make the image grow a little on mouse over and add the text details on click
  var setEvents = images
          // Append hero text
          .on( 'click', function (d) {
              d3.select("h1").html(d.hero); 
              d3.select("h2").html(d.name); 
              d3.select("h3").html ("Take me to " + "<a href='" + d.link + "' >"  + d.hero + " web page ⇢"+ "</a>" ); 
           })

          .on( 'mouseenter', function(d) {
          if(d.img){
          //console.log(d3.select(this).parent);
          d3.select("pattern#"+d.img.replace(/[/|.|:]/g, "")).select("image").attr("width","100").attr("height","100");
            // select element in current context
            d3.select( this )
              .transition()
              .attr("x", function(d) { return -60;})
              .attr("y", function(d) { return -60;})
              .attr("r", "50")
              //.attr("height", 100)
              //.attr("width", 100);
              }
          })
          // set back
          .on( 'mouseleave', function(d) {
          if(d.img){
          d3.select("pattern#"+d.img.replace(/[/|.|:]/g, "")).select("image").attr("width","40").attr("height","40");
          
            d3.select( this )
              .transition()
              .attr("x", function(d) { return -25;})
              .attr("y", function(d) { return -25;})
              .attr("r", "20")
              //.attr("height", 50)
              //.attr("width", 50);
              }
          });

  // Append hero name on roll over next to the node as well
  nodeEnter.append("text")
      .attr("class", "nodetext")
      .attr("x", x_browser)
      .attr("y", y_browser +15)
      .attr("fill", tcBlack)
      .text(function(d) { return d.hero; });
 
 
  // Exit any old nodes.
  node.exit().remove();
 
 
  // Re-select for update.
  path = vis.selectAll("path.link");
  node = vis.selectAll("g.node");
 
function tick() {
 
 
    path.attr("d", function(d) {
 
     var dx = d.target.x - d.source.x,
           dy = d.target.y - d.source.y,
           dr = Math.sqrt(dx * dx + dy * dy);
           return   "M" + d.source.x + "," 
            + d.source.y 
            + "A" + dr + "," 
            + dr + " 0 0,1 " 
            + d.target.x + "," 
            + d.target.y;
  });
    node.attr("transform", nodeTransform);    
  }
}

 
/**
 * Gives the coordinates of the border for keeping the nodes inside a frame
 * http://bl.ocks.org/mbostock/1129492
 */ 
function nodeTransform(d) {
  d.x =  Math.max(maxNodeSize, Math.min(w - (d.imgwidth/2 || 16), d.x));
    d.y =  Math.max(maxNodeSize, Math.min(h - (d.imgheight/2 || 16), d.y));
    return "translate(" + d.x + "," + d.y + ")";
   }
 
/**
 * Toggle children on click.
 */ 
function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
 
  update();
}
 
 
/**
 * Returns a list of all nodes under the root.
 */ 
function flatten(root) {
  var nodes = []; 
  var i = 0;
 
  function recurse(node) {
    if (node.children) 
      node.children.forEach(recurse);
    if (!node.id) 
      node.id = ++i;
    nodes.push(node);
  }
 
  recurse(root);
  return nodes;
}
@import url(http://fonts.googleapis.com/css?family=Source+Code+Pro:400,600);
      body {font-family: "Source Code Pro", Consolas, monaco, monospace; line-height: 160%; font-size: 16px;  margin: 0; }
      path.link {
        fill: none;
        stroke-width: 2px;
      }
      .node:not(:hover) .nodetext {
        display: none;
      }
      h1 { font-size: 36px; margin: 10px 0; text-transform: uppercase; font-weight: normal;}
      h2, h3 { font-size: 18px; margin: 5px 0 ; font-weight: normal;}
      header {padding: 20px; position: absolute; top: 0; left: 0;}
      a:link { color: #EE3124; text-decoration: none;}
      a:visited { color: #EE3124; }
      a:hover { color: #A4CD39; text-decoration: underline;}
      a:active { color: #EE3124; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.0/d3.min.js"></script>
<section id="vis"></section>

工作了几个小时之后,我做了一些事情,请注意我所做的代码更改,如果你无法弄明白,请在下面评论,我将编辑我的答案并提供完整的解释。 :d