我尝试根据此示例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;
};
}
答案 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;
};
}