text: var width = 960,
      height = 700,
      radius = Math.min(width, height) / 2;
  
  var x = d3.scale.linear()
      .range([0, 2 * Math.PI]);
  
  var y = d3.scale.sqrt()
      .range([0, radius]);
  
  var color = d3.scale.category20c();
  
  var svg = d3.select("body").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + (height / 2 + 10) + ")");
  
  var partition = d3.layout.partition()
      .sort(null)
      .value(function(d) { return 1; });
  
  var arc = d3.svg.arc()
      .startAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x))); })
      .endAngle(function(d) { return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx))); })
      .innerRadius(function(d) { return Math.max(0, y(d.y)); })
      .outerRadius(function(d) { return Math.max(0, y(d.y + d.dy)); });
  
  
  
  function loadSet(jData) {
      var json = null;
      $.ajax({
  	async: false,
  	global: false,
  	url: jData,
  	dataType: "json",
  	success: function (data) {
              json = data;
  	},
  	failure: function() {alert("problem with the file" + jData); }
      });
      return json;
  };
  //var root = loadSet('data/flare.json');
  var root = loadSet('data/audience_demo.json');
  //console.log(root);
  
  
  
  var g = svg.selectAll("g")
      .data(partition.nodes(root))
      .enter().append("g");
  
  var path = g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color((d.children ? d : d.parent).name); })
      .on("click", click)
  //    .on("mouseover", mouseover);
  
  //d3.select("#container").on("mouseleave", mouseleave);
  var totalSize = path.node().__data__.value;
  
  d3.selectAll("input").on("change", function change() {
      var value = this.value === "count"
          ? function() { return 1; }
          : function(d) { return d.size; };
      path
          .data(partition.value(value).nodes)
  	.transition()
          .duration(1000)
          .attrTween("d", arcTweenData);
  });
  
  
  var text = g.append("text")
      .attr("transform", function(d) { return "rotate(" + computeTextRotation(d) + ")"; })
      .attr("x", function(d) { return y(d.y); })
      .attr("dx", "6") // margin
      .attr("dy", ".35em") // vertical-align
      .text(function(d) { return d.name; });
  
  function click(d) {
      // fade out all text elements
      text.transition().attr("opacity", 0);
      
      path.transition()
  	.duration(750)
  	.attrTween("d", arcTween(d))
  	.each("end", function(e, i) {
              // check if the animated element's data e lies within the visible angle span given in d
              if (e.x >= d.x && e.x < (d.x + d.dx)) {
  		// get a selection of the associated text element
  		var arcText = d3.select(this.parentNode).select("text");
  		// fade in the text element and recalculate positions
  		arcText.transition().duration(750)
  		    .attr("opacity", 1)
  		    .attr("transform", function() { return "rotate(" + computeTextRotation(e) + ")" })
  		    .attr("x", function(d) { return y(d.y); });
              }
  	});
  }
  
  d3.select(self.frameElement).style("height", height + "px");
  
  // Interpolate the scales!
  function arcTween(d) {
      var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
  	yd = d3.interpolate(y.domain(), [d.y, 1]),
  	yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
      return function(d, i) {
  	return i
              ? function(t) { return arc(d); }
          : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
      };
  }
  
  function computeTextRotation(d) {
      return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
  }
  // Setup for switching data: stash the old values for transition.
  function stash(d) {
    d.x0 = d.x;
    d.dx0 = d.dx;
  }
  
  // When switching data: interpolate the arcs in data space.
  function arcTweenData(a, i) {
    var oi = d3.interpolate({x: a.x0, dx: a.dx0}, a);
    function tween(t) {
      var b = oi(t);
      a.x0 = b.x;
      a.dx0 = b.dx;
      return arc(b);
    }
    if (i == 0) {
     // If we are on the first arc, adjust the x domain to match the root node
     // at the current zoom level. (We only need to do this once.)
      var xd = d3.interpolate(x.domain(), [node.x, node.x + node.dx]);
      return function(t) {
        x.domain(xd(t));
        return tween(t);
      };
    } else {
      return tween;
    }
  }
  
  // When zooming: interpolate the scales.
  function arcTweenZoom(d) {
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
        yd = d3.interpolate(y.domain(), [d.y, 1]),
        yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
    return function(d, i) {
      return i
          ? function(t) { return arc(d); }
          : function(t) { x.domain(xd(t)); y.domain(yd(t)).range(yr(t)); return arc(d); };
    };
  }
  
  // Fade all but the current sequence, and show it in the breadcrumb trail.
  function mouseover(d) {
  
    var percentage = (100 * d.value / totalSize).toPrecision(3);
    var percentageString = percentage + "%";
    if (percentage < 0.1) {
      percentageString = "< 0.1%";
    }
  
    d3.select("#percentage")
        .text(percentageString);
  
    d3.select("#explanation")
        .style("visibility", "");
  
    var sequenceArray = getAncestors(d);
    updateBreadcrumbs(sequenceArray, percentageString);
  
    // Fade all the segments.
    d3.selectAll("path")
        .style("opacity", 0.3);
  
    // Then highlight only those that are an ancestor of the current segment.
    vis.selectAll("path")
        .filter(function(node) {
                  return (sequenceArray.indexOf(node) >= 0);
                })
        .style("opacity", 1);
  }
  
  // Restore everything to full opacity when moving off the visualization.
  function mouseleave(d) {
  
    // Hide the breadcrumb trail
    d3.select("#trail")
        .style("visibility", "hidden");
  
    // Deactivate all segments during transition.
    d3.selectAll("path").on("mouseover", null);
  
    // Transition each segment to full opacity and then reactivate it.
    d3.selectAll("path")
        .transition()
        .duration(1000)
        .style("opacity", 1)
        .each("end", function() {
                d3.select(this).on("mouseover", mouseover);
              });
  
    d3.select("#explanation")
        .style("visibility", "hidden");
  }
  
  // Given a node in a partition layout, return an array of all of its ancestor
  // nodes, highest first, but excluding the root.
  function getAncestors(node) {
    var path = [];
    var current = node;
    while (current.parent) {
      path.unshift(current);
      current = current.parent;
    }
    return path;
  }
  
  function initializeBreadcrumbTrail() {
    // Add the svg area.
    var trail = d3.select("#sequence").append("svg:svg")
        .attr("width", width)
        .attr("height", 50)
        .attr("id", "trail");
    // Add the label at the end, for the percentage.
    trail.append("svg:text")
      .attr("id", "endlabel")
      .style("fill", "#000");
  }
  
  // Generate a string that describes the points of a breadcrumb polygon.
  function breadcrumbPoints(d, i) {
    var points = [];
    points.push("0,0");
    points.push(b.w + ",0");
    points.push(b.w + b.t + "," + (b.h / 2));
    points.push(b.w + "," + b.h);
    points.push("0," + b.h);
    if (i > 0) { // Leftmost breadcrumb; don't include 6th vertex.
      points.push(b.t + "," + (b.h / 2));
    }
    return points.join(" ");
  }
  
  