Heatmap

by ramnathv

HTML

<script src="//rawgit.com/ramnathv/8263e4ef88a293185e96/raw/de85372d953630eac280f4fa82ab6336100844c7/testdata.js"></script>
<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/gka/d3-jetpack/master/d3-jetpack.js"></script>
<script src="//rawgit.com/Caged/d3-tip/master/index.js"></script>
<link rel="stylesheet" href="//rawgit.com/Caged/d3-tip/master/examples/example-styles.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css">
<script src="//rawgit.com/ramnathv/a5a3199538f86817ec1b/raw/f6627fc544e65d8e6186ba87556f743caa3f2730/visutils.js"></script>
<link rel="stylesheet" href="//keen.github.io/dashboards/assets/css/keen-dashboards.css">
<div class="container-fluid">
    <div id="chart"></div>
</div>

CSS

.d3-tip table{
  line-height: 1.2em;
  font-weight: normal;
  font-size: 11px;
}
.d3-tip.n:after{
  margin-top: -2px;
}
.container-fluid{
  margin-top: 40px;
}
#chart .y-axis-layer path,
#chart .y-axis-layer line{
  fill: none;
  stroke: #bbb;
}
#chart .x-axis-layer path,
#chart .x-axis-layer line{
  fill: none;
  stroke: #bbb;
}
#chart .y-axis-layer text,
#chart .x-axis-layer text{
  font-size: 11px;
  fill-opacity: 0.6;
}
#chart2 .x-axis-layer path,
#chart2 .x-axis-layer line {
  fill: none;
}
#chart2 .y-axis-layer path,
#chart2 .y-axis-layer line {
  fill: none;
}
#chart2 .x-axis-layer text,
#chart2 .y-axis-layer text{
  font-size: 11px;
  opacity: 0.6
}
path.voronoi{
  fill: none;
  stroke: none;
  pointer-events: all;
}
#chart2 .circle{
  pointer-events: none;
}
#chart2 rect{
  pointer-events: none;
}
.d3-tip{
  pointer-events: none !important;
}

CoffeeScript

defaults = 
  margin: {left: 30, right: 10, top: 10, bottom: 30}
  initialHeight: 300
  initialWidth: 300
    
heatMapConstructor = (skeleton) ->
  layers = skeleton.getLayerOrganizer()
  S =
    x: d3.scale.linear()
    y: d3.scale.linear()
    c: d3.scale.linear()
  A =
    x: (d) -> d.x
    y: (d) -> d.y
    c: (d) -> d.z
  layers.create(['overlay', 'cells', 'y-axis', 'x-axis', ])
  rect = layers.get("overlay").append('rect')
  visualize = ->
    D = skeleton.data()
    d = D.z.map (row, i) ->
      row.map (z, j) ->
        {x: D.x[i], y: D.y[j], z: z, i: i, j: j}
    
    data = d3.merge(d)

    x = Math.min(
      skeleton.getInnerWidth(),    
      skeleton.getInnerHeight()
    )
    W_ = x; H_ = x;
    dx = W_/(D.x.length + 1)
    dy = H_/(D.y.length  + 1)
    S.x.range([0, W_]).domain d3.extent(data, A.x)
    S.y.range([H_, 0]).domain d3.extent(data, A.y)
    S.c.range(['crimson', 'lightyellow', 'slateblue'])
      .domain([-0.015, 0, 0.015])
    cells = layers.get('cells').selectAll('.cell')
      .data(data)
    cells.enter().append('rect.cell')
    cells.attr
      x: (d) -> S.x(A.x(d))
      y: (d) -> S.y(A.y(d)) - dy
      width: dx
      height: dy
      fill: (d) -> S.c A.c(d)
    cells.exit().remove()
    cells.call attachTooltip, {html: d3.table}
    
    yAxis = d3.svg.axis()
      .scale(S.y)
      .orient('left')
      .outerTickSize(0)
    layers.get('y-axis')
      .call(yAxis)
    xAxis = d3.svg.axis()
      .scale(S.x)
      .orient('bottom')
      .outerTickSize(0)
    layers.get('x-axis')
      .attr("transform", "translate(0, #{H_})")
      .call(xAxis)
    rect.attr
      width: W_
      height: H_
      fill: "none"
  skeleton
    .resizeToFitContainer()
    .on("data", visualize)
    .on("resize", visualize)
    .autoResize(true)
    #.autoResizeToAspectRatio(1)
    
    
heatMap = d3Kit.factory.createChart(
  defaults, [], heatMapConstructor                                   
)

new heatMap("#chart").data(data)