2017-02-11 121 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