繁体   English   中英

D3分层条形图 - 旋转X轴和Y轴

[英]D3 hierarchical bar chart - Rotate X and Y Axes

我看到了一个分层条形图的例子,并且它也适用于我的数据集。

http://d3-example.herokuapp.com/examples/bar/bar-hierarchy.html

但是,我希望切换x和Y轴。 基本上,我希望看到一个带有分层数据的垂直条形图。 请帮忙!

干杯,阿琼

在这里,我已经解决了您的问题,请仔细检查我的代码,您将获得解决方案。

 <!DOCTYPE html> <meta charset="utf-8"> <style> text { font: 10px sans-serif; } rect.background { fill: white; } .axis { shape-rendering: crispEdges; } .axis path, .axis line { fill: none; stroke: #000; } </style> <body> <script src="//d3js.org/d3.v3.min.js"></script> <script> var margin = {top: 10, right: 120, bottom: 120, left: 120}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var y = d3.scale.linear() .range([height, 0]); var barHeight = 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 svg = d3.select("body").append("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", "x axis") .attr("transform", "translate(0, " + height + ")") .append("line") .attr("x1", "100%"); svg.append("g") .attr("class", "y axis"); d3.json("https://jsonblob.com/api/f577d19c-0f2b-11e7-a0ba-09040711ce47", function(error, root) { if (error) throw error; 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(" + barHeight * i * 2.5 + "," + 0 + ")"; }); // Transition entering text. enterTransition.select("text") .style("fill-opacity", 1); // Transition entering rects to the new y-scale. enterTransition.select("rect") .attr("y", function(d) { return y(d.value); }) .attr("height", function(d) { return height - 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 y-scale. exitTransition.selectAll("rect") .attr("height", function(d) { return height - 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(" + barHeight * i * 2.5 + "," + 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 y-scale domain. y.domain([0, d3.max(d.parent.children, function(d) { return d.value; })]).nice(); // Update the y-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 y-scale. // When the entering parent rect is done, make it visible! enterTransition.select("rect") .attr("height", function(d) { return height - y(d.value); }) .attr("y", 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 height - y(d.value); }) .attr("y", 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(15,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("x", barHeight / 2) .attr("y", height + 10) .attr("dy", ".35em") .style("text-anchor", "start") .text(function(d) { return d.name; }) .attr("transform", "rotate(45 " + (barHeight / 2) + " " + (height + 10) + ")") bar.append("rect") .attr("width", barHeight) .attr("height", function(d) { return height - y(d.value); }) .attr("y", function(d) { return y(d.value); }); return bar; } // A stateful closure for stacking bars horizontally. function stack(i) { var y0 = 0; return function(d) { var tx = "translate(" + barHeight * i * 1.5 + "," + y0 + ")"; y0 += y(d.value); return tx; }; } </script> 

这不是很正确..但它已经到了一半..动画并没有真正像水平条那样工作,而且钻取完全不起作用..希望有人可以帮助添加它..

var m = [40, 50, 5, 70], // top right bottom left
w = 550 - m[1] - m[3], // width
h = 384 - m[0] - m[2], // height
y = d3.scale.linear().range([h,0]),
x = 70, // bar width
z = d3.scale.ordinal().range(["steelblue", "#aaa"]); // bar color

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

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

var xAxis = d3.svg.axis()
    .scale(x)
    .orient("bottom");


var svg = d3.select(".sales-pipeline-chart").append("svg:svg")
    .attr("width", w + m[1] + m[3])
    .attr("height", h + m[0] + m[2])
  .append("svg:g")
    .attr("transform", "translate(" + m[3] + "," + m[0] + ")");

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

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

svg.append("svg:g")
    .attr("class", "y axis");
  /*.append("svg:line")
    .attr("y1", "100%");*/

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

function down(d, i) {

  if (!d.children || this.__transition__) return;
  var duration = d3.event && d3.event.altKey ? 7500 : 750,
      delay = duration / d.children.length;

  // 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 barWidth = 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", z(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(" + x * i * 1.3 + "," + (h - y(d.value)) + ")"; });
      /*.call(xAxis);*/

  // 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 z(!!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 duration = d3.event && d3.event.altKey ? 7500 : 750,
      delay = duration / d.children.length;

  // 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(" + x * i * 1.3 + "," + (h - 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 z(!!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 * 2)
      .call(yAxis);

  // Transition entering bars to fade in over the full duration.
  var enterTransition = enter.transition()
      .duration(duration * 2)
      .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", z(true));

  // Remove exiting nodes when the last child has finished transitioning.
  exit.transition().duration(duration * 2).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("svg:g", ".x.axis")
      .attr("class", "enter")
      .attr("transform", "translate(10,0)")
    .selectAll("g")
      .data(d.children)
    .enter().append("svg:g")
      .style("cursor", function(d) { return !d.children ? null : "pointer"; })
      .on("click", down);

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

  /*var barWidth = w / d.children.length;*/

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

  return bar;
}

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM