D3 Kit Example Scatterplot

by ramnathv

HTML

<script src="//d3js.org/d3.v3.min.js"></script>
<script src="//rawgit.com/kristw/75b61f9beeab9b530612/raw/389e984e4041117a9185cf6edad9f6b85a38097a/d3kit.min.js"></script>
<script src="//rawgit.com/DarkMarmot/kodama/master/kodama.js"></script>
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<div class="container-fluid">
    <div class="row">
        <div class="col-xs-12">
            <div id="chart"></div>
        </div>
    </div>
</div>

CSS

div[name="kodama"]{
   pointer-events: none;
}
g.layer-circles{
  pointer-events: none;
}
path.voronoi {
  pointer-events: all;
}

CoffeeScript

voronoiLayer = (sel, data, S, A, O) ->
  voronoi = d3.geom.voronoi()
    .x((d) -> S.x A.x(d))
    .y((d) -> S.y A.y(d))
    .clipExtent([[0, 0], [O.W, O.H]])
        
  polygons = sel
     .selectAll(".voronoi")
     .data(voronoi(data))
        
  polygons.enter()
     .append("path")
     .classed("voronoi", true)
 
  polygons
    .attr
      d: (d, i) -> "M" + d.join("L") + "Z"
      fill: "none"
      stroke: "gray"
    .datum((d) -> d.point)
  
  polygons.call d3.kodama.tooltip().format (d, i) ->
    title: "Polygon #{i}"
    target: d3.select("#circle-#{i}")
    distance: 0

chartConstructor = (skeleton) ->
  S =
    x: d3.scale.linear()
    y: d3.scale.linear()
    r: d3.scale.sqrt()
    c: d3.scale.category10()
  A =
    x: (d) -> d.x
    y: (d) -> d.y
    r: (d) -> 25*d.r
  L = skeleton.getLayerOrganizer()
  L.create(['voronoi', 'circles'])
  visualize = ->
    dims =
      W: skeleton.getInnerWidth()
      H: skeleton.getInnerHeight()
    data = skeleton.data()
    S.x.range([0, dims.W]).domain d3.extent(data, A.x)
    S.y.range([dims.H, 0]).domain d3.extent(data, A.y)
    
    circles = L.get('circles').selectAll('circle').data(data)
    circles.enter().append('circle')
    circles.attr
      cx: (d) -> S.x A.x(d)
      cy: (d) -> S.y A.y(d)
      r: (d) -> S.r A.r(d)
      fill: (d, i) -> S.c(i)
      id: (d, i) -> "circle-#{i}"
    circles.exit().remove()
    voronoiLayer(L.get('voronoi'), data, S, A, dims)
   skeleton
    .autoResize(true)
    .on("data", visualize)
    .on("resize", visualize)
    
defaults = 
  margin: {left: 20, right: 20, bottom: 20, top: 20}
  initialHeight: 300
  initialWidth: "auto"
    
scatterChart = d3Kit.factory.createChart(
   defaults, [], chartConstructor                                            
)

makeData = (n) ->
  d3.range(n).map ->
    {x: Math.random(), y: Math.random(), r: Math.random()}

dat = makeData(100)

new scatterChart("#chart")
  .data(dat)