使分层条形图垂直

时间:2015-03-25 12:57:03

标签: javascript d3.js charts hierarchical

我尝试根据此示例http://bl.ocks.org/mbostock/1283663创建垂直层次结构条形图。  我能够定位轴但我似乎无法移动条形图从图表底部而不是顶部开始。有人可以帮忙吗?

var margin = {top: 30, right: 120, bottom: 30, left: 120},
 width = 600 - margin.left - margin.right,
 height = 300 - margin.top - margin.bottom;

var y = d3.scale.linear()
  .range([height,0]);

var barWidth = 20;

var color = d3.scale.ordinal()
   .range(["steelblue", "#ccc"]);

var duration = 750,
  delay = 25;

var partition = d3.layout.partition()
  .value(function(d) { return d.size; });

var yAxis = d3.svg.axis()
   .scale(y)
   .orient("left");

 var xAxis = d3.svg.axis()
   .scale(barWidth)
   .orient("botom");

 var svg = d3.select(".sales-pipeline-chart").append("svg:svg")
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
.append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

 svg.append("rect")
  .attr("class", "background")
  .attr("width", width)
  .attr("height", height)
  .on("click", up);

svg.append("g")
 .attr("class", "y axis");

svg.append("g")
   .attr("class", "x axis")
 .append("line")
   .attr("x1", "100%")
   .attr("transform", "translate(0," + height + ")");     

  d3.json("/flare.json", function(root) {
     partition.nodes(root);
     y.domain([0, root.value]).nice();
     down(root, 0);
  });


  function down(d, i) {
    if (!d.children || this.__transition__) return;
    var end = duration + d.children.length * delay;

   // Mark any currently-displayed bars as exiting.
    var exit = svg.selectAll(".enter")
       .attr("class", "exit");

  // Entering nodes immediately obscure the clicked-on bar, so hide it.
    exit.selectAll("rect").filter(function(p) { return p === d; })
        .style("fill-opacity", 1e-6);

  // Enter the new bars for the clicked-on data.
  // Per above, entering bars are immediately visible.
   var enter = bar(d)
       .attr("transform", stack(i))
       .style("opacity", 1);

 // Have the text fade-in, even though the bars are visible.
 // Color the bars as parents; they will fade to children if appropriate.
   enter.select("text").style("fill-opacity", 1e-6);
   enter.select("rect").style("fill", color(true));

 // Update the x-scale domain.
  y.domain([0, d3.max(d.children, function(d) { return d.value; })]).nice();

 // Update the x-axis.
 svg.selectAll(".y.axis").transition()
    .duration(duration)
    .call(yAxis);

 // Transition entering bars to their new position.
 var enterTransition = enter.transition()
      .duration(duration)
      .delay(function(d, i) { return i * delay; })
      .attr("transform", function(d, i) { return "translate(" + barWidth *
  i * 1.2 + ",0)"; });

  // Transition entering text.
  enterTransition.select("text")
     .style("fill-opacity", 1);

 // Transition entering rects to the new x-scale.
 enterTransition.select("rect")
     .attr("height", function(d) { return y(d.value); })
     .style("fill", function(d) { return color(!!d.children); });

 // Transition exiting bars to fade out.
 var exitTransition = exit.transition()
     .duration(duration)
     .style("opacity", 1e-6)
     .remove();

  // Transition exiting bars to the new x-scale.
  exitTransition.selectAll("rect")
     .attr("height", function(d) { return y(d.value); });

 // Rebind the current node to the background.
  svg.select(".background")
      .datum(d)
    .transition()
      .duration(end);

  d.index = i;
 }

  function up(d) {
     if (!d.parent || this.__transition__) return;
     var end = duration + d.children.length * delay;

  // Mark any currently-displayed bars as exiting.
  var exit = svg.selectAll(".enter")
      .attr("class", "exit");

  // Enter the new bars for the clicked-on data's parent.
  var enter = bar(d.parent)
      .attr("transform", function(d, i) { return "translate(" + barWidth *
 i * 1.2 + ",0)"; })
      .style("opacity", 1e-6);

  // Color the bars as appropriate.
  // Exiting nodes will obscure the parent bar, so hide it.
   enter.select("rect")
       .style("fill", function(d) { return color(!!d.children); })
      .filter(function(p) { return p === d; })
       .style("fill-opacity", 1e-6);

   // Update the x-scale domain.
     y.domain([0, d3.max(d.parent.children, function(d) { return d.value;
  })]).nice();

   // Update the x-axis.
  svg.selectAll(".y.axis").transition()
     .duration(duration)
     .call(yAxis);

  // Transition entering bars to fade in over the full duration.
   var enterTransition = enter.transition()
      .duration(end)
      .style("opacity", 1);

  // Transition entering rects to the new x-scale.
  // When the entering parent rect is done, make it visible!
   enterTransition.select("rect")
      .attr("height", function(d) { return y(d.value); })
      .each("end", function(p) { if (p === d)
   d3.select(this).style("fill-opacity", null); });

   // Transition exiting bars to the parent's position.
   var exitTransition = exit.selectAll("g").transition()
      .duration(duration)
      .delay(function(d, i) { return i * delay; })
      .attr("transform", stack(d.index));

   // Transition exiting text to fade out.
   exitTransition.select("text")
      .style("fill-opacity", 1e-6);

  // Transition exiting rects to the new scale and fade to parent color.
   exitTransition.select("rect")
      .attr("height", function(d) { return y(d.value); })
      .style("fill", color(true));

  // Remove exiting nodes when the last child has finished transitioning.
   exit.transition()
       .duration(end)
       .remove();

  // Rebind the current parent to the background.
  svg.select(".background")
      .datum(d.parent)
    .transition()
      .duration(end);
 }

 // Creates a set of bars for the given data node, at the specified index.
function bar(d) {
   var bar = svg.insert("g", ".x.axis")
      .attr("class", "enter")
      .attr("transform", "translate(5,0)")
     .selectAll("g")
      .data(d.children)
     .enter().append("g")
        .style("cursor", function(d) { return !d.children ? null : "pointer";
  })
   .on("click", down);

  bar.append("text")
      .attr("y", -6)
      .attr("x", barWidth / 2)
      .attr("dx", ".35em")
      .style("text-anchor", "end")
      .text(function(d) { return d.name; });

  bar.append("rect")
     .attr("height", function(d) { return y(d.value); })
     .attr("width", barWidth);

  return bar;
}

  // A stateful closure for stacking bars horizontally.
  function stack(i) {
      var y0 = 0;
      return function(d) {
         var tx = "translate(" + barWidth * i * 1.2 + "," + y0 + ")";
         y0 += y(d.value);
         return tx;
       };
    }

1 个答案:

答案 0 :(得分:0)

我能够移动条形,所以它们现在从底部开始,但动画仍然存在一些问题。钻取工作不起作用,我也希望将文本移到xAxis下面。

var margin = {top: 30, right: 120, bottom: 30, left: 120},
 width = 600 - margin.left - margin.right,
 height = 300 - margin.top - margin.bottom;

 var y = d3.scale.linear()
      .range([height,0]);

 var barHeight = 40;

 var color = d3.scale.ordinal()
    .range(["steelblue", "#ccc"]);

 var duration = 750,
   delay = 25;

 var partition = d3.layout.partition()
    .value(function(d) { return d.size; });

 var yAxis = d3.svg.axis()
    .scale(y)
    .orient("left");

 var xAxis = d3.svg.axis()
    .scale(barHeight)
    .orient("botom");

 var svg = d3.select(".sales-pipeline-chart").append("svg:svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
   .append("g")
    .attr("transform", "translate(" + margin.right + "," + margin.top + ")");

 svg.append("rect")
   .attr("class", "background")
   .attr("width", width)
   .attr("height", height)
   .on("click", up);

svg.append("g")
   .attr("class", "y axis");

 svg.append("g")
     .attr("class", "x axis")
   .append("line")
    .attr("x1", "100%")
    .attr("transform", "translate(0," + height + ")");


 d3.json("/flare.json", function(root) {
    partition.nodes(root);
    y.domain([0, root.value]).nice();
    down(root, 0);
 });

function down(d, i) {

    if (!d.children || this.__transition__) return;
    var end = duration + d.children.length * delay;

   // Mark any currently-displayed bars as exiting.
   var exit = svg.selectAll(".enter").attr("class", "exit");

  // Entering nodes immediately obscure the clicked-on bar, so hide it.
   exit.selectAll("rect").filter(function(p) { return p === d; })
      .style("fill-opacity", 1e-6);

 // Enter the new bars for the clicked-on data.
  // Per above, entering bars are immediately visible.
  //var barHeight = w / d.children.length;

  var enter = bar(d)
     .attr("transform", stack(i))
     .style("opacity", 1);

 // Have the text fade-in, even though the bars are visible.
 // Color the bars as parents; they will fade to children if appropriate.
  enter.select("text").style("fill-opacity", 1e-6);
  enter.select("rect").style("fill", color(true));

  // Update the y-scale domain.
  y.domain([0, d3.max(d.children, function(d) { return d.value; })]).nice();

 // Update the y-axis.
 svg.selectAll(".y.axis").transition()
      .duration(duration)
      .call(yAxis);  

 // Transition entering bars to their new position.
  var enterTransition = enter.transition()
       .duration(duration)
      .delay(function(d, i) { return i * delay; })
      .attr("transform", function(d, i) { return "translate(" + barHeight * i * 1.2 + "," + (height- y(d.value)) + ")"; });


   // Transition entering text.
   enterTransition.select("text").style("fill-opacity", 1);

  // Transition entering rects to the new x-scale.
   enterTransition.select("rect")
      .attr("height", function(d) { return y(d.value); })
     .style("fill", function(d) { return color(!!d.children); });

  // Transition exiting bars to fade out.
   var exitTransition = exit.transition()
      .duration(duration)
      .style("opacity", 1e-6)
      .remove();

  // Transition exiting bars to the new x-scale.
   exitTransition.selectAll("rect").attr("height", function(d) { return   y(d.value); });

 // Rebind the current node to the background.
   svg.select(".background").data(d).transition().duration(duration * 2); d.index = i;
}

function up(d) {
    if (!d.parent || this.__transition__) return;
   var end = duration + d.children.length * delay;

    // Mark any currently-displayed bars as exiting.
    var exit = svg.selectAll(".enter").attr("class", "exit");

  // Enter the new bars for the clicked-on data's parent.
   var enter = bar(d.parent)
      .attr("transform", function(d, i) { return "translate(" + barHeight * i * 1.2 + "," + (height - y(d.value)) + ")"; })
      .style("opacity", 1e-6);

  // Color the bars as appropriate.
  // Exiting nodes will obscure the parent bar, so hide it.
   enter.select("rect")
      .style("fill", function(d) { return color(!!d.children); })
     .filter(function(p) { return p === d; })
       .style("fill-opacity", 1e-6);

  // Update the x-scale domain.
     y.domain([0, d3.max(d.parent.children, function(d) { return d.value; })]).nice();

   // Update the x-axis.
    svg.selectAll(".y.axis").transition()
       .duration(duration)
       .call(yAxis);

  // Transition entering bars to fade in over the full duration.
  var enterTransition = enter.transition()
      .duration(end)
      .style("opacity", 1);

  // Transition entering rects to the new x-scale.
  // When the entering parent rect is done, make it visible!
   enterTransition.select("rect")
      .attr("height", function(d) { return y(d.value); })
      .each("end", function(p) { if (p === d) d3.select(this).style("fill-opacity", null); });

   // Transition exiting bars to the parent's position.
  var exitTransition = exit.selectAll("g").transition()
      .duration(duration)
      .delay(function(d, i) { return i * delay; })
      .attr("transform", stack(d.index));

  // Transition exiting text to fade out.
    exitTransition.select("text")
      .style("fill-opacity", 1e-6);

  // Transition exiting rects to the new scale and fade to parent color.
  exitTransition.select("rect")
     .attr("height", function(d) { return y(d.value); })
     .style("fill", color(true));

  // Remove exiting nodes when the last child has finished transitioning.
  exit.transition().duration(end).remove();

 // Rebind the current parent to the background.
   svg.select(".background").data(d.parent).transition().duration(duration * 2);
  }

  // Creates a set of bars for the given data node, at the specified index.
  function bar(d) {
     var bar = svg.insert("g", ".x.axis")
       .attr("class", "enter")
       .attr("transform", "translate(10,0)")//0.10
      .selectAll("g")
       .data(d.children)
       .enter().append("g")
       .style("cursor", function(d) { return !d.children ? null : "pointer"; })
        .on("click", down);

 bar.append("text")
    .attr("y", -6)
    .attr("x",barHeight/2)
    .attr("dx", ".35em")//
    .attr("text-anchor", "middle")
    .text(function(d) { return d.name; });

 bar.append("rect")
    .attr("height", function(d) { return y(d.value); })
    .attr("width", barHeight);

 return bar;
  }

 // A stateful closure for stacking bars horizontally.
 function stack(i) {
     var y0 = 0;
     return function(d) {
        var ty = "translate(" + barHeight * i * 1.2+ "," + y0  + ")";
        y0 += y(d.value);
       return ty;
      };
   }