title: How do I replace a node with an image using D3 and CoffeeScript for a network visualization?
body: <p>I've been attempting to solve this problem for days, and am completely stumped. </p>
  
  <p>I'm using this network implementation walk-through:
  <a href="http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/" rel="nofollow noreferrer">http://flowingdata.com/2012/08/02/how-to-make-an-interactive-network-visualization/</a> </p>
  
  <p><img src="https://i.stack.imgur.com/b7ozw.png" alt="enter image description here"></p>
  
  <p>I have successfully created my visualization through this walk-through, and now would like to replace a node with a small picture, based on the node's value.</p>
  
  <p>This is a great example of code to work from, where every node was replaced with an image. 
  http: //bl.ocks .org/mbostock/950642</p>
  
  <p>Specifically:</p>
  
  <pre><code>node.append("image")
  .attr("xlink:href", "https://github.com/favicon.ico")
  .attr("x", -8)
  .attr("y", -8)
  .attr("width", 16)
  .attr("height", 16);
  </code></pre>
  
  <p>The only issue is that this code is in JavaScript, and my implementation of the network graph is written in CoffeeScript. </p>
  
  <p>I tried creating my own JavaScript file with the code above and linking to it, however this did not work for me, and quite frankly I don't know if that is the best approach to take anyway.  </p>
  
  <p>I tried converting the code from JavaScript into CoffeeScript through this JS to CoffeeScript tool, <a href="http://js2coffee.org/" rel="nofollow noreferrer">http://js2coffee.org/</a>, however I am not familiar with CoffeeScript enough to add the code in the correct location... and I feel like I've tried every spot with no luck. </p>
  
  <p>What I'm exactly trying to do is to put a specific picture in place of a node based on the data contained by the node.  I would prefer to have an if statement in the CoffeeScript itself to insert a picture based on the node selected, (could be the name or group or whatever.)   I would also like to have the text label for each node as well, displaying, say, "amount," however I still need to research more on how to do that one. </p>
  
  <p>Sample node:</p>
  
  <pre><code>"nodes" : [{
  "match" : "1.0",
  "name" : "Airplane",
  "virtualAmount" : "1000",
  "artist" : "Airplane",
  "amount" : "999.99",
  "id" : "a1234",
  "playcount" : "500",
  "group" : "airplanePic.jpg"
  }, {
  </code></pre>
  
  <p>Thanks! Any help would be very much appreciated! </p>
  
  <p>Edit: (with my code)</p>
  
  <p>Thank you Lars, I was unaware of the inability to use an image with an SVG.  Here is the code I am working with:</p>
  
  <p>This is the CoffeeScript section that I believe I need to edit to get my desired SVG file to replace what is currently a circle for a node. </p>
  
  <pre><code># enter/exit display for nodes
  updateNodes = () -&gt;
    node = nodesG.selectAll("circle.node")
      .data(curNodesData, (d) -&gt; d.id)
  
  node.enter().append("circle")
    .attr("class", "node")
    .attr("cx", (d) -&gt; d.x)
    .attr("cy", (d) -&gt; d.y)
    .attr("r", (d) -&gt; d.radius)
    .style("fill", (d) -&gt; nodeColors(d.artist))
    .style("stroke", (d) -&gt; strokeFor(d))
    .style("stroke-width", 1.0)
  </code></pre>
  
  <p>I have been trying to use an if statement, like this, however I'm new to CoffeeScript so be gentle.</p>
  
  <pre><code>if d.group is "airplane"     #comment: or whatever group name I'm looking for
  .attr("src", "tinyWhale.jpg")
  </code></pre>
  
  <p>However, I'm now aware that this won't work since I can't import an image to an SVG.  I'm still very confused as to how to replace the node with an SVG, even after reading Lar's comment and linked question. </p>
  
  <p>Would I be able to just create an if statement and replace the circle with a googled svg file?  </p>
  
  <p>Thanks again for the help.</p>
  
  <p>Update 2: 
  Thanks so much Lars, I am trying to add this to the vis.coffee file, however it breaks when I add any of the code.  Here is how I am adding the code: </p>
  
  <p>The 4th .attr is the code added. </p>
  
  <pre><code>node.enter().append("circle")
    .attr("class", "node")
    .attr("cx", (d) -&gt; d.x)
    .attr("cy", (d) -&gt; d.y)
    .attr("r", (d) -&gt; d.radius) #this is the code added
    .attr("fill", (d) -&gt; "url(#" + d.group + ")")
    .style("fill", (d) -&gt; nodeColors(d.artist))
    .style("stroke", (d) -&gt; strokeFor(d))
    .style("stroke-width", 1.0)
  </code></pre>
  
  <p>And I added this here, which also breaks the code. Am I putting this in the entirely wrong spot?</p>
  
  <pre><code># Starting point for network visualization
  # Initializes visualization and starts force layout
  network = (selection, data) -&gt;
  # format our data
  allData = setupData(data)
  
  # create our svg and groups
  vis = d3.select(selection).append("svg")
    .attr("width", width)
    .attr("height", height)
  linksG = vis.append("g").attr("id", "links")
  nodesG = vis.append("g").attr("id", "nodes")
  
  defs = svg.append("defs")
  
  defs.selectAll("pattern")
    .data(curNodesData)
    .append("pattern")
    .attr("id", (d) -&gt; d.group)
    .append("image")
    .attr("xlink:href", (d) -&gt; d.group)
  </code></pre>
  
  <p>Thanks for your help and patience! </p>
  
  <p>Here is my vis.coffee file: 
  https:// dl.dropboxusercontent .com/u/18496047/vis.coffee 
  Added spaces because it won't let me have more than one link in the question. </p>
  
  <p>Edit 3: 
  Using this to go off of, which I hope will help me figure out the CoffeeScript node implementation. </p>
  
  <pre><code># create node objects from original data
  # that will serve as the data behind each
  # bubble in the vis, then add each node
  # to @nodes to be used later
  create_nodes: () =&gt;
    @data.forEach (d) =&gt;
      node = {
        id: d.id
        radius: @radius_scale(d.total_amount)
        value: d.total_amount
        name: d.tweet_rate
        org: d.organization
        group: d.tweet_amount
        top_conv: d.top_conv
        x: Math.random() * 900
        y: Math.random() * 800
      }
      @nodes.push node
  
    @nodes.sort (a,b) -&gt; b.value - a.value
  
  
  # create svg at #vis and then 
  # create circle representation for each node
  create_vis: () =&gt;
    @vis = d3.select("#vis").append("svg")
      .attr("width", @width)
      .attr("height", @height)
      .attr("id", "svg_vis")
  
    @circles = @vis.selectAll("circle")
      .data(@nodes, (d) -&gt; d.id)
  
    # used because we need 'this' in the 
    # mouse callbacks
    that = this
  
    # radius will be set to 0 initially.
    # see transition below
    @circles.enter().append("circle")
      .attr("r", 0)
      .attr("fill", (d) =&gt; @fill_color(d.group))
      .attr("stroke-width", 2)
      .attr("stroke", (d) =&gt; d3.rgb(@fill_color(d.group)).brighter(5))
      .attr("id", (d) -&gt; "bubble_#{d.id}")
      .on("mouseover", (d,i) -&gt; that.show_details(d,i,this))
      .on("mouseout", (d,i) -&gt; that.hide_details(d,i,this))
  
    # Fancy transition to make bubbles appear, ending with the
    # correct radius
    @circles.transition().duration(2000).attr("r", (d) -&gt; d.radius)
  </code></pre>
  
  <p>Edit 4: </p>
  
  <p>I converted the CoffeeSctipt to JavaScript for readability and my own comfortability. </p>
  
  <p>Any answers can be contributed via JS or CoffeeScript.</p>
  
  <p>Thanks... this problem is killing me.</p>
  
  <p>Anyone who wants to help: 
  plnkr.co/edit/DeI4a0gjg0p8ypRS2HUn?p=preview</p>