我目前正在尝试为d3中的交互式配对条形图创建工具提示,但是在获取x位置以便在svg上定位工具提示时遇到了麻烦。
这是显示问题的JSFiddle:注意yPosition更新,但是我不确定如何在鼠标悬停时为每个栏获得正确的xPosition
我的代码如下:
$(document).ready(function(){
//Graph
var e = $('#graph');
//Get width of graph div
var w = document.getElementById('graph').clientWidth;
//Set margins, width and height of graph
var margin = {top: 40, right: 20, bottom: 30, left: 40}, width = w - margin.left - margin.right -10, height = 500 - margin.top - margin.bottom;
//Sca;e amd ramge
var x = d3.scale.ordinal()
.rangeRoundBands([0, width], .1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
//Define x and y axis
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
//Generate svg element in graph div
var svg = d3.select("#graph").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
//Redraw graph on window resize
function updateWindow(){
x = w.innerWidth || e.clientWidth || g.clientWidth;
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
svg.attr("width", x).attr("height", y);
}
window.onresize = updateWindow;
//Access output data to populate graph
d3.csv("inputs/outputs/Milk_Month2.csv",type, function(error, data) {
//Graph colors
var color = d3.scale.ordinal().range(["#98abc5", "#8a89a6"]);
//data attributes for the two different graphs
var categoryNamesMilk = d3.keys(data[0]).filter(function(key) { return key !== "month" && key !== "water_current" && key !== "water_future" ; });
var categoryNamesWater = d3.keys(data[0]).filter(function(key) { return key !== "month" && key !== "milk_current" && key !== "milk_future" ; });
data.forEach(function(d) {
d.categoriesMilk = categoryNamesMilk.map(function(name) { return {name: name, value: +d[name]}; });
d.categoriesWater = categoryNamesWater.map(function(name) { return {name: name, value: +d[name]}; });
});
x.domain(data.map(function(d) { return d.month; }));
x1.domain(categoryNamesMilk).rangeRoundBands([0, x.rangeBand()]);
y.domain([0, d3.max(data, function(d) { return d3.max(d.categoriesMilk, function(d) { return d.value; }); })]);
//Generate X Axis
var axisX = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
//Generate Y Axis
var axisY = 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("Milk Production (KG/Day)").attr("class","yaxis-text");
var infoBars = svg.selectAll(".bar")
.data(data)
.enter().append("g")
.attr("class", "g")
.attr("transform", function(d,i) {console.log(x(d.month),i); return "translate(" + x(d.month) + ",0)"; });
infoBars.selectAll("rect")
.data(function(d) { return d.categoriesMilk; })
.enter().append("rect")
.attr("width", x1.rangeBand())
.attr("x", function(d) { return x1(d.name); })
.attr("y", function(d) { return y(d.value); })
.attr("height", function(d) { return height - y(d.value); })
.style("fill", function(d) { return color(d.name); })
.on("mouseover", function(d,i) {
//Where I'm having problems - getting the X attribute!
var xPosition = parseFloat(x(i) + x1.rangeBand());
var yPosition = parseFloat(d3.select(this).attr("y")) / 2 + height / 2;
//Update the tooltip position and value
d3.select("#tooltip")
.style("left", xPosition + "px")
.style("top", yPosition + "px")
.select("#value")
.text(d.value);
//Show the tooltip
d3.select("#tooltip").classed("hidden", false);
}).on("mouseout", function() {
//Hide the tooltip
d3.select("#tooltip").classed("hidden", true);
});
});
//Data type conversion
function type(d) {
d.milk_current = +d.milk_current;
d.water_current = +d.water_current;
d.milk_future = +d.milk_future;
d.water_future = +d.water_future;
return d;
}
});
它是从csv提取的,如下所示(我还有一个click函数,可转换为第二个配对图,因此还有其他数据列
month,water_current,milk_current,water_future,milk_future
1,2.259,1.955,2.4849,100
2,0.006,0,0.0066,0
3,14.443,11.795,15.8873,10.6155
4,2.87,21.538,3.157,19.3842
5,0,20.216,1,18.1944
6,0.973,18.37,1.0703,16.533
7,1.492,15.686,1.6412,14.1174
8,0,13.146,0.5,11.8314
9,0,12.087,0.4,10.8783
10,0,9.626,0.3,8.6634
11,7.434,8.19,8.1774,7.371
12,6.049,7.207,6.6539,6.4863
我很确定我需要在鼠标悬停时访问每个“矩形”的父元素并检索x位置,但是这样做没有任何运气...任何建议吗?
最佳答案
您可以像以下方式访问每个g
的父rect
:
.on("mouseover", function(d,i) {
var parentG = d3.select(this.parentNode);
要获得X值:
var barPos = parseFloat(parentG.attr('transform').split("(")[1]);
x位置变为:
var xPosition = barPos + x1(d.name);
小提琴here。