view moztree.js @ 11:dc89fb1726b4

fixed fade bug
author Atul Varma <varmaa@toolness.com>
date Sun, 13 Dec 2009 00:42:21 -0800
parents c4f96938c259
children 279bee726817
line wrap: on
line source

const SVG_NS = "http://www.w3.org/2000/svg";

function getJSON(filename, cb) {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', filename);
  xhr.overrideMimeType('text/plain');
  xhr.addEventListener("load",
                       function() { cb(JSON.parse(xhr.responseText)); },
                       false);
  xhr.send(null);
}

function SVGElement(name, attribs, options) {
  var element = document.createElementNS(SVG_NS, name);
  for (name in attribs)
    element.setAttribute(name, attribs[name]);
  if (options) {
    if (options.content)
      element.textContent = options.content;
    if (options.className)
      element.setAttribute("class", options.className);
  }
  return element;
}

function drawDir(svg, dir, depth, options) {
  if (depth == 0 || !dir.subdirs)
    return;

  var currY = options.y + options.height;
  dir.subdirs.forEach(
    function(subdir) {
      var heightScale = subdir.size / dir.size;
      var height = options.height * heightScale;
      var y = currY - height;

      if (height < options.minHeight)
        return;

      svg.appendChild(SVGElement("rect", {x: options.x,
                                          y: y,
                                          width: options.width,
                                          height: height}));

      var text = SVGElement("text",
                            {x: options.x + options.textPadding,
                             y: y + height - options.textPadding});
      text.appendChild(SVGElement("tspan", {},
                                  {content: subdir.name}));
      text.appendChild(SVGElement("tspan",
                                  {x: (options.x + options.width -
                                       options.textPadding)},
                                  {content: subdir.changes,
                                   className: "changes"}));
      svg.appendChild(text);

      drawDir(svg, subdir, depth - 1, {x: options.x + options.width,
                                       y: y,
                                       width: options.width,
                                       height: height,
                                       minHeight: options.minHeight,
                                       textPadding: options.textPadding});
      currY = y;
    });
}

function makeTree(tree, options) {
  var svg = document.createElementNS(SVG_NS, "svg");
  var group = document.createElementNS(SVG_NS, "g");
  var svgHeight = options.height;
  var svgWidth = options.dirWidth * options.dirDepth;

  if (options.landscape) {
    var temp = svgWidth;
    group.setAttribute("transform",
                       "translate(" + svgHeight + ", 0) rotate(90)");
    svgWidth = svgHeight;
    svgHeight = temp;
  }

  svg.setAttribute("width", svgWidth);
  svg.setAttribute("height", svgHeight);
  svg.appendChild(group);

  drawDir(group, tree, options.dirDepth,
          {x: 0,
           y: 0,
           width: options.dirWidth,
           height: options.height,
           textPadding: options.textPadding,
           minHeight: options.minHeight});
  return svg;
}

function getTreePath(tree, path) {
  var pathParts = path.split("/");
  pathParts.reverse();
  while (pathParts.length > 0) {
    var dirName = pathParts.pop();
    tree.subdirs.forEach(
      function(subdir) {
        if (subdir.name == dirName)
          tree = subdir;
      });
  }
  return tree;
}

var App = {
  tree: null,
  lastHash: null,
  onIdle: function onIdle() {
    if (window.location.hash != this.lastHash)
      this.updateTree();
  },
  updateTree: function updateTree() {
    var dir = this.tree;
    if (window.location.hash && window.location.hash.length > 1)
      dir = getTreePath(dir, window.location.hash.slice(1));
    this.lastHash = window.location.hash;

    var svg = makeTree(dir,
                       {height: 2800,
                        dirWidth: 120,
                        dirDepth: 6,
                        landscape: false,
                        textPadding: 4,
                        minHeight: 16});
    $("#tree").empty().append(svg).hide().fadeIn("fast");
  },
  start: function start() {
    var self = this;
    getJSON(
      'moztree.json',
      function(tree) {
        self.tree = tree;
        self.updateTree();
        window.setInterval(function() { self.onIdle(); }, 500);
      });
  }
};

$(window).ready(function() { App.start(); });