D3 bubble chart toggle buttons

405
December 10, 2016, at 3:16 PM

I am new to D3.js and trying to create a bubble chart with a toggle button to switch different candidates of the presidential campaign. I managed to create the chart for one candidate only, but am having trouble doing the toggle with D3.js. I am trying to do something like this, but less sophisticated and with lesser animation. How do I do this?

My HTML is as follows:

 <link rel = "stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel = "stylesheet" href = "style.css">
<link rel="stylesheet" href="//rawgithub.com/Caged/d3-tip/master/examples/example-styles.css">
<script src= "http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src= "http://d3js.org/d3.v3.min.js"></script>
<script src= "d3-tip.js"></script>

<div class="container">
    <h1> Who's Giving Them Money? </h1>
    <div class="row">
      <div class="col-sm-6">
        <p> A look at the individual contributions to prominent candidates in the 2016 presidential campaign. The visualization below looks at the amount per 1,000 persons in each state of the US. Data has been sourced from the <strong> Federal Election Commission </strong> website, and is from April 1, 2015 to September 30, 2015. </p>
      </div>
    </div>
    <div class="btn-group-lg" role="group" aria-label="...">
        <button type="button" class="btn btn-default hillary dem">Hillary Clinton</button>
        <button type="button" class="btn btn-default rubio rep">Marco Rubio</button>
        <button type="button" class="btn btn-default sanders dem">Bernie Sanders</button>
        <button type="button" class="btn btn-default bush rep">Jeb Bush</button>
        <button type="button" class="btn btn-default cruz rep">Ted Cruz</button>
        <button type="button" class="btn btn-default trump rep">Donald Trump</button>
    </div>
    <div id ="viz">
    </div>
    <script src= "script.js"></script>

</div>

Here is my javascript:

    var tooltip = d3.tip().attr('class', 'd3-tip').html(
function(d) { return d['Name'] + ': $' + d['Amount'];
});

    var diameter = 500
    var color = d3.scale.ordinal()
                  .domain(['R','D'])
                  .range(['#B2182B','#2166AC']);

    var bubble = d3.layout.pack()
                   .sort(null)
                   .size([diameter, diameter])
                   .padding(3.5);
    var svg = d3.select("#viz")
        .append("svg")
        .attr("width", diameter)
        .attr("height", diameter)
        .attr("class", "bubble");

    /* modified d3-tip boilerplate */
    /* Invoke the tip in the context of your visualization */
    svg.call(tooltip);
    d3.csv("Candidates.csv", function(error, data) {
        var nest = d3.nest()
                     .key(function(d){return d['Candidate'] })
                     .entries(data);
var button = d3.select("")

data = data.map(function(d) {
    d.value = +d["Amount"];
    return d;
});
var nodes = bubble.nodes({children: data }).filter(function(d) {
    return !d.children;
});

var bubbles = svg.append("g")
    .attr("transform", "translate(0,0)")
    .selectAll(".bubble")
    .data(nodes)
    .enter();
bubbles.append("circle")
    .attr("r", function(d) { return d.r; })
    .attr("cx", function(d) {return d.x; })
    .attr("cy", function(d) { return d.y; })
    .style("fill", function(d) {
        return color(d["Past"]);
    })

//format the text for each bubble
bubbles.append("text")
    .attr("x", function(d) {
        return d.x;
    })
    .attr("y", function(d) {
        return d.y + 5;
    })
    .attr("text-anchor", "middle")
    //.text(function(d){ return d["State"] ; })
    .text(function(d) {
        return d["State"];
    });
bubbles.append("circle")
    .attr("r", function(d) { return d.r; })
    .attr("cx", function(d) {return d.x; })
    .attr("cy", function(d) { return d.y; })
    .style("fill", function(d) {
        return "rgba(0,0,0,0)";
    })
    .on('mouseover', tooltip.show)
    .on('mouseout', tooltip.hide);

});

And here's my CSV file sample. The full file can be seen here:

    Candidate,State,Name,Past,Amount
    Marco Rubio,AK,Alaska,R,10.5
    Hillary Clinton,AL,Alabama,R,10.47
    Jeb Bush,AR,Arkansas,R,4.55
    Donald Trump,AZ,Arizona,R,46.13
    Ted Cruz,CA,California,D,82.55

Just for clarification, the 'Past' field shows how the states have voted in the past (Republican/Democrat), Sorry if I made any mistakes in the post. This is my first ever post! I'd really appreciate if you could help me out. Thank you!

Answer 1

// d3.tip 
// Copyright (c) 2013 Justin Palmer 
// 
// Tooltips for d3.js SVG visualizations 
 
(function (root, factory) { 
  if (typeof define === 'function' && define.amd) { 
    // AMD. Register as an anonymous module with d3 as a dependency. 
    define(['d3'], factory) 
  } else if (typeof module === 'object' && module.exports) { 
    // CommonJS 
    module.exports = function(d3) { 
      d3.tip = factory(d3) 
      return d3.tip 
    } 
  } else { 
    // Browser global. 
    root.d3.tip = factory(root.d3) 
  } 
}(this, function (d3) { 
 
  // Public - contructs a new tooltip 
  // 
  // Returns a tip 
  return function() { 
    var direction = d3_tip_direction, 
        offset    = d3_tip_offset, 
        html      = d3_tip_html, 
        node      = initNode(), 
        svg       = null, 
        point     = null, 
        target    = null 
 
    function tip(vis) { 
      svg = getSVGNode(vis) 
      point = svg.createSVGPoint() 
      document.body.appendChild(node) 
    } 
 
    // Public - show the tooltip on the screen 
    // 
    // Returns a tip 
    tip.show = function() { 
      var args = Array.prototype.slice.call(arguments) 
      if(args[args.length - 1] instanceof SVGElement) target = args.pop() 
 
      var content = html.apply(this, args), 
          poffset = offset.apply(this, args), 
          dir     = direction.apply(this, args), 
          nodel   = getNodeEl(), 
          i       = directions.length, 
          coords, 
          scrollTop  = document.documentElement.scrollTop || document.body.scrollTop, 
          scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft 
 
      nodel.html(content) 
        .style({ opacity: 1, 'pointer-events': 'all' }) 
 
      while(i--) nodel.classed(directions[i], false) 
      coords = direction_callbacks.get(dir).apply(this) 
      nodel.classed(dir, true).style({ 
        top: (coords.top +  poffset[0]) + scrollTop + 'px', 
        left: (coords.left + poffset[1]) + scrollLeft + 'px' 
      }) 
 
      return tip 
    } 
 
    // Public - hide the tooltip 
    // 
    // Returns a tip 
    tip.hide = function() { 
      var nodel = getNodeEl() 
      nodel.style({ opacity: 0, 'pointer-events': 'none' }) 
      return tip 
    } 
 
    // Public: Proxy attr calls to the d3 tip container.  Sets or gets attribute value. 
    // 
    // n - name of the attribute 
    // v - value of the attribute 
    // 
    // Returns tip or attribute value 
    tip.attr = function(n, v) { 
      if (arguments.length < 2 && typeof n === 'string') { 
        return getNodeEl().attr(n) 
      } else { 
        var args =  Array.prototype.slice.call(arguments) 
        d3.selection.prototype.attr.apply(getNodeEl(), args) 
      } 
 
      return tip 
    } 
 
    // Public: Proxy style calls to the d3 tip container.  Sets or gets a style value. 
    // 
    // n - name of the property 
    // v - value of the property 
    // 
    // Returns tip or style property value 
    tip.style = function(n, v) { 
      if (arguments.length < 2 && typeof n === 'string') { 
        return getNodeEl().style(n) 
      } else { 
        var args =  Array.prototype.slice.call(arguments) 
        d3.selection.prototype.style.apply(getNodeEl(), args) 
      } 
 
      return tip 
    } 
 
    // Public: Set or get the direction of the tooltip 
    // 
    // v - One of n(north), s(south), e(east), or w(west), nw(northwest), 
    //     sw(southwest), ne(northeast) or se(southeast) 
    // 
    // Returns tip or direction 
    tip.direction = function(v) { 
      if (!arguments.length) return direction 
      direction = v == null ? v : d3.functor(v) 
 
      return tip 
    } 
 
    // Public: Sets or gets the offset of the tip 
    // 
    // v - Array of [x, y] offset 
    // 
    // Returns offset or 
    tip.offset = function(v) { 
      if (!arguments.length) return offset 
      offset = v == null ? v : d3.functor(v) 
 
      return tip 
    } 
 
    // Public: sets or gets the html value of the tooltip 
    // 
    // v - String value of the tip 
    // 
    // Returns html value or tip 
    tip.html = function(v) { 
      if (!arguments.length) return html 
      html = v == null ? v : d3.functor(v) 
 
      return tip 
    } 
 
    // Public: destroys the tooltip and removes it from the DOM 
    // 
    // Returns a tip 
    tip.destroy = function() { 
      if(node) { 
        getNodeEl().remove(); 
        node = null; 
      } 
      return tip; 
    } 
 
    function d3_tip_direction() { return 'n' } 
    function d3_tip_offset() { return [0, 0] } 
    function d3_tip_html() { return ' ' } 
 
    var direction_callbacks = d3.map({ 
      n:  direction_n, 
      s:  direction_s, 
      e:  direction_e, 
      w:  direction_w, 
      nw: direction_nw, 
      ne: direction_ne, 
      sw: direction_sw, 
      se: direction_se 
    }), 
 
    directions = direction_callbacks.keys() 
 
    function direction_n() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.n.y - node.offsetHeight, 
        left: bbox.n.x - node.offsetWidth / 2 
      } 
    } 
 
    function direction_s() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.s.y, 
        left: bbox.s.x - node.offsetWidth / 2 
      } 
    } 
 
    function direction_e() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.e.y - node.offsetHeight / 2, 
        left: bbox.e.x 
      } 
    } 
 
    function direction_w() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.w.y - node.offsetHeight / 2, 
        left: bbox.w.x - node.offsetWidth 
      } 
    } 
 
    function direction_nw() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.nw.y - node.offsetHeight, 
        left: bbox.nw.x - node.offsetWidth 
      } 
    } 
 
    function direction_ne() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.ne.y - node.offsetHeight, 
        left: bbox.ne.x 
      } 
    } 
 
    function direction_sw() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.sw.y, 
        left: bbox.sw.x - node.offsetWidth 
      } 
    } 
 
    function direction_se() { 
      var bbox = getScreenBBox() 
      return { 
        top:  bbox.se.y, 
        left: bbox.e.x 
      } 
    } 
 
    function initNode() { 
      var node = d3.select(document.createElement('div')) 
      node.style({ 
        position: 'absolute', 
        top: 0, 
        opacity: 0, 
        'pointer-events': 'none', 
        'box-sizing': 'border-box' 
      }) 
 
      return node.node() 
    } 
 
    function getSVGNode(el) { 
      el = el.node() 
      if(el.tagName.toLowerCase() === 'svg') 
        return el 
 
      return el.ownerSVGElement 
    } 
 
    function getNodeEl() { 
      if(node === null) { 
        node = initNode(); 
        // re-add node to DOM 
        document.body.appendChild(node); 
      }; 
      return d3.select(node); 
    } 
 
    // Private - gets the screen coordinates of a shape 
    // 
    // Given a shape on the screen, will return an SVGPoint for the directions 
    // n(north), s(south), e(east), w(west), ne(northeast), se(southeast), nw(northwest), 
    // sw(southwest). 
    // 
    //    +-+-+ 
    //    |   | 
    //    +   + 
    //    |   | 
    //    +-+-+ 
    // 
    // Returns an Object {n, s, e, w, nw, sw, ne, se} 
    function getScreenBBox() { 
      var targetel   = target || d3.event.target; 
 
      while ('undefined' === typeof targetel.getScreenCTM && 'undefined' === targetel.parentNode) { 
          targetel = targetel.parentNode; 
      } 
 
      var bbox       = {}, 
          matrix     = targetel.getScreenCTM(), 
          tbbox      = targetel.getBBox(), 
          width      = tbbox.width, 
          height     = tbbox.height, 
          x          = tbbox.x, 
          y          = tbbox.y 
 
      point.x = x 
      point.y = y 
      bbox.nw = point.matrixTransform(matrix) 
      point.x += width 
      bbox.ne = point.matrixTransform(matrix) 
      point.y += height 
      bbox.se = point.matrixTransform(matrix) 
      point.x -= width 
      bbox.sw = point.matrixTransform(matrix) 
      point.y -= height / 2 
      bbox.w  = point.matrixTransform(matrix) 
      point.x += width 
      bbox.e = point.matrixTransform(matrix) 
      point.x -= width / 2 
      point.y -= height / 2 
      bbox.n = point.matrixTransform(matrix) 
      point.y += height 
      bbox.s = point.matrixTransform(matrix) 
 
      return bbox 
    } 
 
    return tip 
  }; 
 
})); 
 
 
var tooltip = d3.tip().attr('class', 'd3-tip').html( 
function(d) { return d['Name'] + ': $' + d['Amount']; 
}); 
 
 
    var diameter = 500 
    var color = d3.scale.ordinal() 
                  .domain(['R','D']) 
                  .range(['#B2182B','#2166AC']); 
 
 
    var bubble = d3.layout.pack() 
                   .sort(null) 
                   .size([diameter, diameter]) 
                   .padding(3.5); 
 
    var svg = d3.select("#viz") 
        .append("svg") 
        .attr("width", diameter) 
        .attr("height", diameter) 
        .attr("class", "bubble"); 
 
 
    /* modified d3-tip boilerplate */ 
    /* Invoke the tip in the context of your visualization */ 
    svg.call(tooltip); 
var data=[ 
{Candidate:"Marco",State:"AK",Name:"Alaska",Past:"R",Amount:10.5}, 
{Candidate:"Hillary Clinton",State:"AL",Name:"Alabama",Past:"R",Amount:10.47}, 
{Candidate:"Jeb Bush",State:"AR",Name:"Arkansas",Past:"R",Amount:4.55}, 
{Candidate:"Donald Trump",State:"AZ",Name:"Arizona",Past:"R",Amount:46.13}, 
{Candidate:"Ted Cruz",State:"CA",Name:"California",Past:"D",Amount:82.55} 
]; 
draw(data); 
    //d3.csv("Candidates.csv", function(error, data) { 
function draw(data){ 
        var nest = d3.nest() 
                     .key(function(d){return d['Candidate'] }) 
                     .entries(data); 
 
//var button = d3.select("") 
 
 
data = data.map(function(d) { 
    d.value = +d["Amount"]; 
    return d; 
}); 
 
var nodes = bubble.nodes({children: data }).filter(function(d) { 
    return !d.children; 
}); 
 
console.log(nodes); 
var bubbles = svg.append("g") 
    .attr("transform", "translate(0,0)") 
    .selectAll(".bubble") 
    .data(nodes) 
    .enter(); 
 
bubbles.append("circle") 
    .attr("r", function(d) { return d.r; }) 
    .attr("cx", function(d) {return d.x; }) 
    .attr("cy", function(d) { return d.y; }) 
    .style("fill", function(d) { 
        return color(d["Past"]); 
    }) 
 
 
//format the text for each bubble 
bubbles.append("text") 
    .attr("x", function(d) { 
        return d.x; 
    }) 
    .attr("y", function(d) { 
        return d.y + 5; 
    }) 
    .attr("text-anchor", "middle") 
    //.text(function(d){ return d["State"] ; }) 
    .text(function(d) { 
        return d["State"]; 
    }); 
 
bubbles.append("circle") 
    .attr("r", function(d) { return d.r; }) 
    .attr("cx", function(d) {return d.x; }) 
    .attr("cy", function(d) { return d.y; }) 
    .style("fill", function(d) { 
        return "rgba(0,0,0,0)"; 
    }) 
    .on('mouseover', tooltip.show) 
    .on('mouseout', tooltip.hide); 
    //}); 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css" type="text/css" rel="stylesheet"/> 
 
 
<link href="https://rawgithub.com/Caged/d3-tip/master/examples/example-styles.css" type="text/css" rel="stylesheet"/> 
<script src="http://vallandingham.me/vis/gates/js/CustomTooltip.js" type="text/javascript"></script> 
 
<div class="container"> 
    <h1> Who's Giving Them Money? </h1> 
 
    <div class="row"> 
      <div class="col-sm-6"> 
        <p> A look at the individual contributions to prominent candidates in the 2016 presidential campaign. The visualization below looks at the amount per 1,000 persons in each state of the US. Data has been sourced from the <strong> Federal Election Commission </strong> website, and is from April 1, 2015 to September 30, 2015. </p> 
      </div> 
    </div> 
 
    <div class="btn-group-lg" role="group" aria-label="..."> 
        <button type="button" class="btn btn-default hillary dem">Hillary Clinton</button> 
        <button type="button" class="btn btn-default rubio rep">Marco Rubio</button> 
        <button type="button" class="btn btn-default sanders dem">Bernie Sanders</button> 
        <button type="button" class="btn btn-default bush rep">Jeb Bush</button> 
        <button type="button" class="btn btn-default cruz rep">Ted Cruz</button> 
        <button type="button" class="btn btn-default trump rep">Donald Trump</button> 
    </div> 
 
    <div id ="viz"> 
 
    </div> 
     
 
 
</div>

I've done up to here, And you are looking for whenever we press on buttons like Hillary Clinton, Marco Rubio, Bernie Sanders etc what do you want to show.... Describe a little so that we can achieve it. Hope you understood.

Rent Charter Buses Company
READ ALSO
jQuery insert div into td

jQuery insert div into td

I want to add div into a table when I click the alert button, and the div should insert after class "name2", but when I clicked the button, the original text were gone, and the test() function can't work, how to fix it?

781
jquery input value undefined

jquery input value undefined

Javascript value and jQuery val() returns undefined on keyup eventVariable currency is a select input which I want the value of in the convertCash function

653
node get the source code from url and display

node get the source code from url and display

I am using node-webkit to create an applicationI need to get the webpage from the url and display it

329