2016-06-10 97 views
1

我是D3新世界的新手。試圖將此example轉換爲水平分組條形圖時,我面臨着一個複雜的情況。我正在按照this post中描述的要點進行轉換。這是我的code版本。D3 JS:將垂直分組的條形圖轉換爲水平分組的條形圖

我已經轉換了水平組圖表的所有域和範圍,但不可能成功。

var xScale = d3.scale.linear().range([innerHeight, 0]); 
var yScale = d3.scale.ordinal().rangeBands([innerWidth, 0], barPadding); 




    bars.attr("y", function(d, i, j) { 
     return yScale(d[yColumn]) + barWidth * j; 
    }) 
    .attr("x", 0) 
    .attr("height", barWidth) 
    .attr("width", function(d) { 
     return xScale(d.y); 
    }) 

任何幫助將不勝感激!

回答

1

這個轉換比起先假設的有點棘手。在你分享的片段中,yScale範圍是[innerWidth, 0],它應該是[0, innerHeight]。以下是相關部分。你可以看到它現場運行here

請注意,我使用堆棧的佈局d.x作爲y軸的輸入,d.y作爲x軸的輸入。這是因爲d3.layout.stack沒有方向作爲參數。

var yColumn = "country"; 
var xColumn = "population"; 

var xScale = d3.scale.linear().range([0, innerWidth]); 
var yScale = d3.scale.ordinal().rangeBands([0, innerHeight], barPadding); 
var colorScale = d3.scale.category10(); 

var xAxis = d3.svg.axis().scale(xScale).orient("bottom") 
    .ticks(5) 
    .tickFormat(d3.format("s")) 
    .outerTickSize(0); 
var yAxis = d3.svg.axis().scale(yScale).orient("left") 
    .outerTickSize(0); 

function render(data) { 

    var nested = d3.nest() 
    .key(function(d) { 
     return d[layerColumn]; 
    }) 
    .entries(data); 

    var stack = d3.layout.stack() 
    .y(function(d) { return d[xColumn];}) 
    .values(function(d) {return d.values;}); 

    var layers = stack(nested); 

    yScale.domain(layers[0].values.map(function(d) { 
    return d[yColumn]; 
    })); 

    xScale.domain([ 
    0, 
    d3.max(layers, function(layer) { 
     return d3.max(layer.values, function(d) { 
     return d.y; 
     }); 
    }) 
    ]); 

    colorScale.domain(layers.map(function(layer) { 
    return layer.key; 
    })); 

    xAxisG.call(xAxis); 
    yAxisG.call(yAxis); 

    var layers = g.selectAll(".layer").data(layers); 
    layers.enter().append("g").attr("class", "layer"); 
    layers.exit().remove(); 
    layers.style("fill", function(d) { 
    return colorScale(d.key); 
    }); 

    var bars = layers.selectAll("rect").data(function(d) { 
    return d.values; 
    }); 
    var barWidth = yScale.rangeBand()/colorScale.domain().length; 
    bars.enter().append("rect") 
    bars.exit().remove(); 
    bars 
    .attr("y", function(d, i, j) { 
     return yScale(d[yColumn]) + barWidth * j; 
    }) 
    .attr("x", function(d) { 
     return xScale(d.x); 
    }) 
    .attr("height", barWidth) 
    .attr("width", function(d) { 
     return xScale(d.y); 
    }) 

    colorLegendG.call(colorLegend); 
}