D3气泡图切换按钮

时间:2015-11-13 08:33:08

标签: javascript jquery html css d3.js

我是D3.js的新手,并试图创建一个带有切换按钮的气泡图,以切换总统竞选的不同候选人。我设法只为一个候选人创建了图表,但是在使用D3.js进行切换时遇到了麻烦。我正在尝试做this这样的事情,但不太复杂,动画也较少。我该怎么做呢?

我的HTML如下:

 <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>

这是我的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);

});

这是我的CSV文件示例。可以看到完整文件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

为了澄清,“过去”字段显示了各州过去的投票方式(共和党/民主党人),如果我在帖子中犯了任何错误,我很抱歉。这是我的第一篇文章!如果你能帮助我,我真的很感激。谢谢!

1 个答案:

答案 0 :(得分:0)

&#13;
&#13;
// 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);
    //});
}
&#13;
<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>
&#13;
&#13;
&#13;

我已经到了这里, 当你按下希拉里克林顿,马可卢比奥,伯尼桑德斯等按钮时,你正在寻找什么......你想要展示什么...... 描述一下,以便我们能够实现它。 希望你能理解。