D3 Statemap

by ramnathv

HTML

<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-tip/0.6.3/d3-tip.min.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootswatch/3.3.4/yeti/bootstrap.min.css">
<script src="//rawgit.com/ramnathv/1340327235b5f71cca82/raw/64dbd16863f45a845eeb63e87cc45b95639b0e96/state_issues.js"></script>
<script src="//eyeseast.github.io/visible-data/components/colorbrewer/colorbrewer.js"></script>
<script src="//rawgit.com/emeeks/d3-svg-legend/master/legend.js"></script>
<script src="//rawgit.com/gka/d3-jetpack/master/d3-jetpack.js"></script>
<script src="//rawgit.com/ramnathv/0fbcd07caace0173ee63/raw/f868d785e57a6dd3d24a988e04893444700a000c/state_taxes.js"></script>
<div class="container" style='margin-top:30px;'>
  <div class="col-md-8">
      <div id="mypanel" class='PANEL'></div>
      <div id="mypanel2" class='PANEL'></div> 
      <!-- <input type="range" min=3 max=8 value=5 id='bins'> -->
 <!--      <button class='btn btn-info' id="update">More Breaks!</button> -->
  </div>
</div>

<!-- <div id="annotation" style='float:left;'></div> -->
<!-- <div id="notes" class='d3-tip light' style='float:left;'>Note</div> -->

CSS

.axis line {
  fill: none;
  stroke: black;
  shape-rendering: crispEdges;
}

.axis path{
  display: none;
}

.y.axis text {
    font-size: 6px;
}
.y.axis text:hover {
    font-size: 24px;
}

.axis text {
  font-family: sans-serif;
  font-size: 11px;
}

.d3-tip {
  line-height: 1;
  font-weight: normal;
  font-size: 14px;
  padding: 8px; /* 12px */
  background: rgba(0, 0, 0, 0.8);
  color: #fff;
  border-radius: 2px;
  pointer-events: none;
}

.d3-tip.light {
  padding: 10px;
  background-color: white;
  color: black;
  -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
  -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
  box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4);
}

/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
  box-sizing: border-box;
  display: inline;
  font-size: 10px;
  width: 100%;
  line-height: 1;
  color: rgba(0, 0, 0, 0.8);
  position: absolute;
  pointer-events: none;
}

.d3-tip.light:after{
  color: #fff;
}

/* Northward tooltips */
.d3-tip.n:after {
  content: "\25BC";
  margin: -2px 0 0 0;
  top: 100%;
  left: 0;
  text-align: center;
}

/* Eastward tooltips */
.d3-tip.e:after {
  content: "\25C0";
  margin: -4px 0 0 0;
  top: 50%;
  left: -8px;
}

/* Southward tooltips */
.d3-tip.s:after {
  content: "\25B2";
  margin: 0 0 1px 0;
  top: -5px;
  left: 0;
  text-align: center;
}

/* Westward tooltips */
.d3-tip.w:after {
  content: "\25B6";
  margin: -4px 0 0 -1px;
  top: 50%;
  left: 100%;
}

#annotation {
  margin: 50px;
  padding: 15px;
  min-width: 100px;
  min-height: 50px;
  background: whitesmoke;
}

svg text {
  font-family: "Helvetica";
  font-size: 12px;
  text-anchor: middle;
  alignment-baseline: middle;
  pointer-events: none;
}

.legend rect {
  stroke: none;
}

CoffeeScript

createAccessors = (visExport) ->
  for n of visExport.opts
    continue  unless visExport.opts.hasOwnProperty(n)
    visExport[n] = ((n) ->
      (v) ->
        (if arguments.length then (visExport.opts[n] = v
        this
        ) else visExport.opts[n])
    )(n)
  return

# http://gomakethings.com/vanilla-javascript-version-of-jquery-extend/
extend = (defaults, options) ->
  extended = {}
  prop = undefined
  for prop of defaults
    `prop = prop`
    if Object::hasOwnProperty.call(defaults, prop)
      extended[prop] = defaults[prop]
  for prop of options
    `prop = prop`
    if Object::hasOwnProperty.call(options, prop)
      extended[prop] = options[prop]
  extended
        

        
d3.table = (data) ->
  table = ["<b id='tooltip-title'>", data.state, "</b>", "<table style='line-height:2em;'>"]
  d3.entries(data).forEach (d) ->
    table.push("<tr><td>" + d.key + "</td><td>&nbsp</td><td>" + d.value + "</td></tr>")
  table.join("") + "</table>"
    

d3.uniq = (data, fun) ->
  if typeof fun is 'function'
    v_ = data.map(fun)
  else
    v_ = data.map (d) -> d[fun]
  d3.set(v_).values()


d3.selection.prototype.appendOnce = (name) ->
   that = this.selectAll(name).data([{}])
   that.enter().append(name)
   return that

d3.selection.prototype.dataAppend = (data, name) ->
   that = this.selectAll(name).data(data)
   that.enter().append(name)

d3.ui = d3.ui || {}
d3.ui.panel = () ->
  defaults = {panels: ["heading", "body"], type: "default"}
  opts = arguments[0] || defaults
  exports = (selection) ->
    selection.each (data) ->
      d3.select(@)
        .appendOnce("div.panel.panel-#{opts.type}")
        .dataAppend(opts.panels, "div")
        .attr
           class: (d) -> "panel-#{d}"     
  exports.opts = opts; createAccessors(exports)
  exports
                
d3.ui.select = ->
  opts = {text: "text", value: "value"}
  event_handlers = {}
  exports = (selection) ->
    selection.each (data) ->
       
      # Start of body
      select =...