2015-12-21 131 views
1

可以使用D3在一個圖形中用一條線繪製一個堆積柱形圖嗎?使用d3.js在一個圖形中用一條線堆積柱形圖

這裏是例如:

stacked bar plot with a line

任何幫助理解。

+0

你是什麼意思,按行在一個圖中? – Cyril

+0

說有三個屬性:其中兩個是學生人口(男性和女性)在一個班級,這些是由堆積列表示。並且說,還有另一個屬性,稱爲班級中學生的平均分數,我想用圖中所示的一條線來表示。 – Artiga

+1

那麼右側軸將顯示人口和左側軸標記? – Cyril

回答

3

我已經合併下列實現可視化文件:

使秤和軸:

//x axis is ordinal 
var x = d3.scale.ordinal() 
    .rangeRoundBands([0, width-150], .1); 
//y left axis is linear for head count 
var y = d3.scale.linear() 
    .rangeRound([height, 0]); 
//this scale is for the average 
y1 = d3.scale.linear().range([height, 0]).domain([0,100]);//marks can have min 0 and max 100 
// y axis right for average marks. 
var yAxisRight = d3.svg.axis().scale(y1) 
    .orient("right").ticks(5); 

然後作出這樣的矩形和折線圖此(評論加入):

//filter out name and average 
    color.domain(d3.keys(data[0]).filter(function(key) { return key !== "Name" && key !=="Average"; })); 
    data.forEach(function(d) { 
    var y0 = 0; 
    d.group = color.domain().map(function(name) { return {name: name, y0: y0, y1: y0 += +d[name]}; }); 
    d.total = d.group[d.group.length - 1].y1; 
    }); 


    x.domain(data.map(function(d) { return d.Name; })); 
    //stores toltal headcount 
    y.domain([0, d3.max(data, function(d) { return d.total; })]); 

    //line function for averageLine 
    var averageline = d3.svg.line() 
     .x(function(d) { return x(d.Name) + x.rangeBand()/2; }) 
     .y(function(d) { return y1(d.Average); }); 

    //this will make the y axis to the right 
    svg.append("g")    
     .attr("class", "y axis")  
     .attr("transform", "translate(" + (width-100) + " ,0)") 
     .style("fill", "red")  
     .call(yAxisRight); 

    svg.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    svg.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
    .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Population"); 

    var state = svg.selectAll(".state") 
     .data(data) 
    .enter().append("g") 
     .attr("class", "g") 
     .attr("transform", function(d) { return "translate(" + x(d.Name) + ",0)"; }); 
    //adding the rect for group chart 
    state.selectAll("rect") 
     .data(function(d) { return d.group; }) 
    .enter().append("rect") 
     .attr("width", x.rangeBand()) 
     .attr("y", function(d) { return y(d.y1); }) 
     .attr("height", function(d) { return y(d.y0) - y(d.y1); }) 
     .style("fill", function(d) { return color(d.name); }); 

    svg.append("path")  // Add the valueline path. 
     .attr("d", averageline(data)); 
    //add the legend 
    var legend = svg.selectAll(".legend") 
     .data(color.domain().slice().reverse()) 
    .enter().append("g") 
     .attr("class", "legend") 
     .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); 

    legend.append("rect") 
     .attr("x", width - 18) 
     .attr("width", 18) 
     .attr("height", 18) 
     .style("fill", color); 

    legend.append("text") 
     .attr("x", width - 24) 
     .attr("y", 9) 
     .attr("dy", ".35em") 
     .style("text-anchor", "end") 
     .text(function(d) { return d; }); 

編輯

是的,你可以使線通過插值彎曲:

var averageline = d3.svg.line() 
     .x(function(d) { return x(d.Name) + x.rangeBand()/2; }) 
     .y(function(d) { return y1(d.Average); }).interpolate("basis"); 

this

工作代碼here

希望這有助於!

+0

謝謝你的迴應Cyril。我可以將曲線作爲曲線嗎?如果是的我怎麼能?通過曲率我的意思是沒有尖銳的邊緣。並在圖片上顯示某些圖像,如圖片/圖形所示。 – Artiga

+0

我們如何使用d3.js在問題的圖片中添加圖片的頂部? – Artiga

+1

更新的小提琴圖像http://plnkr.co/edit/Ye0zL9IUNgnieCTlN8Xr?p=preview – Cyril