2014-12-19 118 views
1

我目前正在嘗試爲d3中的交互配對條形圖創建工具提示,但我無法獲取x位置以便找到svg上的工具提示。如何獲取工具提示更新的d3配對條形圖上的酒吧的x位置

下面是該問題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拉如下(我也有一個點擊功能,轉換到第二個配對圖,因此額外的數據列

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 

我很確定我需要訪問mouseover上的每個「矩形」的父元素,並檢索x位置,但我沒有任何運氣做這個...任何建議?

+0

您是不是要找'的xPosition = X1(d.name)+ x1.rangeBand()'?另外,當您調整窗口大小時,您的'x'和'y'比例將被重置爲純粹的整數。 –

+0

不,因爲當我這樣做:'console.log(x1(d.name));'它爲每個交替的條分別返回0和24。我認爲我需要的偏移量被附加到父元素'.bar',因爲'x(d.month)'在代碼中的轉換中使用了,但我不知道如何訪問它們...任何想法? – user1270657

+0

這裏是一個jsfiddle重現這個問題。 [jsFiddle](http://jsfiddle.net/w95y8qyz/)...請注意,當您將鼠標懸停在元素上時,y位置會發生變化,但我無法弄清楚如何讓x位置正確地居中在每個條上 – user1270657

回答

1

您可以訪問父的每個rectg

.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

+0

感謝您!這正是我正在尋找的。 – user1270657

0

另一種方法是使用d3.event.pageX/Y財產

d3.select("#tooltip") 
      .style("left", (d3.event.pageX + 20) + "px") 
      .style("top", (d3.event.pageY - 50)+ "px")**strong text** 
相關問題