我在尝试创建悬停效果的d3.js v4堆积条形图时遇到了一些麻烦
目标是在整个堆栈突出显示并在悬停时显示工具提示。我想我正在寻找获取矩形的位置坐标和大小来绘制整个堆栈
我正在使用这个经过修改的d3-tip库为v4提供工具提示 https://github.com/VACLab/d3-tip
这个问题的图片说了千言万语: http://nicholasmahoney.com/gj/ex.jpg - 在那里,我可以非常接近x位置,我可以通过使用x(d.fellow)和x.bandwith获得宽度,但不能找出y分量。我希望此示例中的黑条与堆叠条的位置和大小相同
EDIt:添加jsfiddle代码和数据,
这里是确切的代码: http://jsfiddle.net/nickmahoney/ddjbumrx/6/
<svg width="500" height="500">
</svg>
<script>
var svg = d3.select("svg"),
margin = {
top: 40,
right: 20,
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])
.paddingInner(0.05)
.align(0.1);
var y = d3.scaleLinear()
.rangeRound([height, 0]);
var z = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var data = [ { "fellow": "demo", "primary": 1, "assistant": 1, "observer": 0, "instructor": 0 }, { "fellow": "alpha", "primary": 22, "assistant": 8, "observer": 0, "instructor": 0 }, { "fellow": "betta", "primary": 0, "assistant": 4, "observer": 0, "instructor": 0 }, { "fellow": "gamma", "primary": 4, "assistant": 2, "observer": 0, "instructor": 0 }, { "fellow": "donkey", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 },{ "fellow": "donkey", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 } , { "fellow": "eeee", "primary": 22, "assistant": 8, "observer": 0, "instructor": 0 }, { "fellow": "ffff", "primary": 0, "assistant": 4, "observer": 0, "instructor": 0 }, { "fellow": "gaggggmma", "primary": 4, "assistant": 2, "observer": 0, "instructor": 0 }, { "fellow": "aaaa", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 },{ "fellow": "ddddddefef", "primary": 44, "assistant": 149, "observer": 20, "instructor": 0 }];
// fix pre-processing
var keys = [];
for (key in data[0]){
if (key != "fellow")
keys.push(key);}
data.forEach(function(d){
d.total = 0;
keys.forEach(function(k){
d.total += d[k];
})
});
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return "<strong>Name:</strong> <span style='color:red'>" + d.fellow + "<br><strong>Primary:</strong>" + d.primary + "</span>";
})
svg.call(tip);
//data.sort(function(a, b) { return b.total - a.total; });
x.domain(data.map(function(d) { return d.fellow; }));
y.domain([0, d3.max(data, function(d) { return d.total; })]).nice();
z.domain(keys);
g.append("g")
.selectAll("g")
.data(d3.stack().keys(keys)(data))
.enter().append("g")
.attr("fill", function(d) { return z(d.key); })
.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr("x", function(d) { return x(d.data.fellow); })
.attr("y", function(d) { return y(d[1]); })
.attr("height", function(d) { return y(d[0]) - y(d[1]); })
.attr("width", x.bandwidth())
;
//tooltip bars
svg.selectAll(".bar")
.data(data)
.enter().append("rect")
.attr("class", "bar")
.attr("x", function(d) { return 40+ x(d.fellow) ; })
.attr("width", x.bandwidth())
.attr("y", function(d) { return y(d.primary) ; })
.attr("height", function(d) { return y(d.primary) ; })
.on('mouseover', tip.show)
.on('mouseout', tip.hide)
g.append("g")
.attr("class", "axis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x))
;
g.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y).ticks(null, "s"))
.append("text")
.attr("x", 2)
.attr("y", y(y.ticks().pop()) + 0.5)
.attr("dy", "0.32em")
.attr("fill", "#000")
.attr("font-weight", "bold")
.attr("text-anchor", "start")
;
var legend = g.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.selectAll("g")
.data(keys.slice().reverse())
.enter().append("g")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; });
legend.append("rect")
.attr("x", width - 19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", z);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9.5)
.attr("dy", "0.32em")
.text(function(d) {return d;});
</script>
答案 0 :(得分:1)
这是你小提琴的一个分支:http://jsfiddle.net/s54tbyxb/
您已根据所需键计算total
值。我只是使用该值来确定y
组件和height
。
代码中的相关更改:
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("x", function(d) { return x(d.fellow) ; })
.attr("width", x.bandwidth())
.attr("y", function(d) {
return y(d.total) ;
})
.attr("height", function(d) { return height-y(d.total) ; })
希望这有帮助。