2015-03-25 71 views
0

我试图根据此示例创建垂直层次条形图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

我能够移动酒吧,所以他们现在开始在底部,但仍然有一些动画问题。钻取不起作用,我也想将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; 
     }; 
    }