2017-02-11 119 views
3

我使用d3.stack()來創建規範化堆疊條形圖。
但是,我無法訪問mousover工具提示的inital數據集的相關值。D3v4堆疊條形圖工具提示

serie.selectAll("rect") 
    .data(function(d) { return d; }) 
    .enter().append("rect") 
     ... 
     .on("mousemove", function(d){ 
      let coords = d3.mouse(svg.node()); 
      tooltip.style("left", coords[0] + "px"); 
      tooltip.style("top", coords[1] - 70 + "px"); 
      tooltip.style("display", "inline-block"); 
      tooltip.html("HOW TO ACCESS DATA HERE?"); 
     }); 

dArray[2]在這一點上與定義基線/背線的值,d.data是完整的原始數據對象,但缺少了該系列目前,我正在徘徊的這堆的信息。
理想我想工具提示徘徊在foo矩形上方時顯示的數據集像{name:"item1", foo:10, bar:20}

value: 10 
percentage: 33% 


我發現的所有例子都是針對D3v3的,您可以簡單地使用d.y來訪問相關的值,但D3v4似乎不再適用。

+0

v4中的第一個參數('d')與v3完全相同。我建議你發佈[MCVE](http://stackoverflow.com/help/mcve)。 –

+0

然後,我認爲它是版本相關的假設是錯誤的,但問題仍然存在:我如何知道我正在盤旋的系列的哪個矩形?根據這個例子(http://bl.ocks.org/mstanaland/6100713)它應該只是'dy',但這裏是它不起作用的小提琴,因爲'd'是堆棧數組:https:// jsfiddle.net/vu624zrg/1/ – TommyF

回答

5

就可以得到元素訪問父的數據,並使用該名稱來獲取值的名稱:

.on('mouseover', function(d, i) { 
    var thisName = d3.select(this.parentNode).datum().key; 
    var thisValue = d.data[thisName]; 
    var total = d.data.foo + d.data.bar; 
    tooltip.html("Name: " + thisName + "<br>Value: " + thisValue + "<br>Percentage: " + thisValue/total + "%"); 
}); 

這裏是你的代碼與修改:

var svg = d3.select("svg"), 
 
    margin = { 
 
     top: 20, 
 
     right: 60, 
 
     bottom: 30, 
 
     left: 40 
 
    }, 
 
    width = +svg.attr("width") - margin.left - margin.right, 
 
    height = +svg.attr("height") - margin.top - margin.bottom, 
 
    g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
 

 
var x = d3.scaleBand() 
 
    .rangeRound([0, width]) 
 
    .padding(0.1) 
 
    .align(0.1); 
 

 
var y = d3.scaleLinear() 
 
    .rangeRound([height, 0]); 
 
var stack = d3.stack() 
 
    .offset(d3.stackOffsetExpand); 
 

 
var colors = ["#FF0000", "#00FF00", "#0000FF"]; 
 

 
var data = [{ 
 
    name: "item1", 
 
    foo: 10, 
 
    bar: 20 
 
}, { 
 
    name: "item2", 
 
    foo: 50, 
 
    bar: 50 
 
}]; 
 

 
x.domain(data.map(function(d) { 
 
    return d.name; 
 
})); 
 

 
var serie = g.selectAll(".serie") 
 
    .data(stack.keys(["foo", "bar"])(data)) 
 
    .enter().append("g") 
 
    .attr("class", "serie") 
 
    .attr("fill", function(d, i) { 
 
     return colors[i]; 
 
    }); 
 

 

 
var tooltip = d3.select('#tooltip'); 
 

 
var rects = serie.selectAll("rect") 
 
    .data(function(d) { 
 
     return d; 
 
    }) 
 
    .enter().append("rect") 
 

 
rects.attr("x", function(d) { 
 
     return x(d.data.name); 
 
    }) 
 
    .attr("y", function(d) { 
 
     return y(d[1]); 
 
    }) 
 
    .attr("height", function(d) { 
 
     return y(d[0]) - y(d[1]); 
 
    }) 
 
    .attr("width", x.bandwidth()) 
 
    .on('mouseover', function(d, i) { 
 
     var thisName = d3.select(this.parentNode).datum().key; 
 
     var thisValue = d.data[thisName]; 
 
     var total = d.data.foo + d.data.bar; 
 
     tooltip.html("Name: " + thisName + "<br>Value: " + thisValue + "<br>Percentage: " + thisValue/total + "%"); 
 
    }); 
 

 
g.append("g") 
 
    .attr("class", "axis axis--x") 
 
    .attr("transform", "translate(0," + height + ")") 
 
    .call(d3.axisBottom(x)); 
 

 
g.append("g") 
 
    .attr("class", "axis axis--y") 
 
    .call(d3.axisLeft(y).ticks(10, "%"));
<script src="https://d3js.org/d3.v4.min.js"></script> 
 

 
<div id="tooltip">tooltip</div> 
 
<svg width="500" height="300"></svg>

+0

非常感謝,'d3.select(this.parentNode).datum().key'是我找不到的部分! – TommyF