Jump To …

thalamus.js

Copyright 2013 Allen Institute for Brain Science Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Visualize the projection volume of several experiments summarized at a structural level in a heatmap using the D3 JavaScript library.

$(function() { initialize(); });

function initialize() {
  $("#chart").addClass("loading");

  var width = $("#chart").width();
    var height = $("#chart").height();
  var cell_size = 25;
  var label_size = 100;
  var color = d3.scale.linear().domain([0,0.06,0.12,0.18]).range(["black","red","yellow","white"]);

Initialize the SVG diagram.

  var svg = d3.select("#chart").append("svg")
    .attr("width", width)
    .attr("height", height)
    .append("g");
  

This container will display detailed meta information as you mouseover the heatmap.

  var meta_container = $("<div>").attr("class","meta").appendTo($("#chart"));

Build the D3 components that display the heatmap color legend.

  function build_legend(chart_width, chart_height) {

Make an array of values, one for each pixel in the width of the legend.

    var legend_data = [];
    var num_elems = chart_width;
    for (var i = 0; i < num_elems; i++) { legend_data.push(i / num_elems * 0.18); }

This scale handles interpolation between projection volume values and legend position.

    var legend_scale = d3.scale.linear()
      .domain([0,0.18])
      .range([0,chart_width]);

This object will generate the tick values along the bottom of the legend.

    var legend_axis = d3.svg.axis()
      .scale(legend_scale)
      .orient("bottom")
      .tickValues(color.domain());
    

Append the group that will hold all of the legend components. A set of single-pixel rectangles are drawn across the legend and colored by their interpolated color value.

    svg.append("g")
      .attr("class", "legend axis")
      .attr("transform", "translate(0,-70)")
      .call(legend_axis)
      .selectAll(".legend_cell")
      .data(legend_data)
      .enter().append("rect")
      .attr("x", function(d,i) { return i; })
      .attr("y", -cell_size)
      .attr("width", 1)
      .attr("height", cell_size)
      .attr("fill", function(d) { return color(d); });

A title for the legend.

    svg.append("text")
      .attr("x", chart_width / 2)
      .attr("y", -105)
      .attr("text-anchor", "middle")
      .text("projection volume colors");
    
  }

Construct the heatmap and its axes. The data supplied to this method is an array of source-target volume values.

  function build_heatmap(data, chart_width, chart_height) {

This group will hold all of the rectangles within the heatmap.

    var cell_group = svg.append("g");

Make a rectangle for each source-target projection volume value.

    var rects = cell_group.selectAll(".cell")
      .data(data.both_data)
      .enter().append("rect")
      .attr("x", function(d) { return d.target_index * cell_size; })
      .attr("y", function(d) { return d.source_index * cell_size; })
      .style("fill", function(d) { return color(d.value); })
      .attr("width", cell_size)
      .attr("height", cell_size)
      .on("mouseover", function(d) {
        meta_container.html("<div><div class='label'>Primary Injection Structure:</div><div class='value'>" + d.source_structure.name + "</div></div>" + 
                  "<div><div class='label'>Target Structure:</div><div class='value'>" + d.target_structure.name + "</div></div>" +
                  "<div><div class='label'>Projection Volume:</div><div class='value'>" + d.value + "</div></div>");
      });

Construct text labels for the y axis (primary injection structures).

    svg.append("g")
      .attr("class", "y axis")
      .selectAll("text")
      .data(data.source_structures)
      .enter().append("text")
      .attr("y", function(d,i) { return i * cell_size + 17.5; })
      .attr("x", -5)
      .attr("text-anchor", "end")
      .text(function(d) { return d.acronym; });

Construct text labels for the x axis (target structures).

    svg.append("g")
      .attr("class", "x axis")
      .attr("transform", "translate(0,"+chart_height+")")
      .selectAll("text")
      .data(data.target_structures)
      .enter().append("text")
      .attr("transform", function(d,i) { 
        var x = (i * cell_size);
        var y = 0;
        return "translate("+ (x + 8) + "," + (y + 5) + ") rotate(90)" ; 
      })
      .text(function(d) { return d.acronym; });

A title for the x axis.

    svg.append("text")
      .attr("x", chart_width / 2)
      .attr("y", chart_height + 50)
      .attr("text-anchor", "middle")
      .text("target structure");

A title for the y axis.

    svg.append("text")
      .attr("text-anchor", "middle")
      .attr("transform","translate(-70," + (chart_height / 2) +") rotate(90)")
      .text("primary injection structure");
  }

Download the data. Once finished, call the heatmap initialization methods.

  download_data(function(data) {
    $("#chart").removeClass("loading");

    var chart_width = cell_size * data.target_structures.length;
    var chart_height = cell_size * data.source_structures.length;

    svg.attr("transform", "translate(" + 
         + ((width / 2) - (chart_width / 2)) + "," 
         + ((height / 2) - (chart_height / 2)) + 
         ")");

    build_heatmap(data, chart_width, chart_height);

    build_legend(chart_width, chart_height);
  });
};