2017-01-23 68 views
1

這裏是D3的新手,並使用下面的代碼處理圖表。我有一個叫做「tip」的div,當用戶懸停在其中一個文本標籤上時,它顯示出來(通過改變不透明度)。我無法正確定位它。在D3中的圖表左上角放置一個div JS

我想要的是將它放在圖表的左上角,假設x,y座標爲10,10。但我不知道如何獲得這個座標,因爲它是一個div。任何人都可以幫助我?

var url = "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json"; 
d3.json(url, function(json) { 

    var data = json; 

    //Dimensions of the SVG container 
    var margin = { 
    top: 40, 
    right: 100, 
    bottom: 60, 
    left: 60 
    }; 
    //inner width for the chart, within SVG element 
    var w = 1000 - margin.left - margin.right; 
    //inner height for the chart, within SVG element 
    var h = 800 - margin.top - margin.bottom; 
    var padding = 20; 

    //create SVG conratiner and append to DOM 
    var svg = d3.select("#chart") 
    .append("svg") 
    .attr("width", w + margin.left + margin.right) 
    .attr("height", h + margin.top + margin.bottom) 
    .append("g") 
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 

    var maxRank = d3.max(data, function(d) { 

    return d.Place; 

    }); 

    var minSeconds = d3.min(data, function(d) { 

    return d.Seconds; 

    }); 

    var maxSeconds = d3.max(data, function(d) { 

    return d.Seconds; 

    }); 

    var formatTime = d3.timeFormat("%M:%S"); 
    var formatSeconds = formatMinutes = function(d) { 
    return formatTime(new Date(2016, 0, 0, 0, 1, d)); 
    }; 

    var xScale = d3.scaleLinear() 
    .domain([maxSeconds + 5, minSeconds]) 
    .range([0, w]); 

    var yScale = d3.scaleLinear() 
    .domain([0, maxRank + 2]) 
    .range([0, h]); 

    var xAxis = d3.axisBottom() 
    .scale(xScale) 
    .ticks(10) 
    .tickFormat(formatMinutes) 

    var yAxis = d3.axisLeft() 
    .scale(yScale) 
    .ticks(10); 

    var tip = d3.select("#chart").append("div") 
    .attr("class", "tooltip") 
    .style("opacity", 0); 

    var circles = svg.selectAll("circle") 
    .data(data) 
    .enter() 
    .append("circle"); 


    var circleAttributes = circles 
    .attr("cx", function(d) { 

     return xScale(d.Seconds); 

    }) 
    .attr("cy", function(d) { 

     return yScale(d.Place); 

    }) 
    .attr("r", 6) 
    .attr("class", "circles") 
    .attr("fill", function(d) { 

     if (d.Doping === "") { 

     return "#2c3e50"; 

     } else { 

     return "#e74c3c"; 

     } 

    }); 

    var labels = svg.selectAll("text") 
    .data(data) 
    .enter() 
    .append("text") 
    .text(function(d) { 

     return d.Name; 

    }) 
    .attr("x", function(d) { 

     return xScale(d.Seconds) + 7; 

    }) 
    .attr("y", function(d) { 

     return yScale(d.Place) + 4; 

    }) 
    .attr("class", "labels") 
    .attr("font-family", "roboto slab") 
    .attr("font-size", "12px") 
    .attr("fill", "#2c3e50") 
    .on("mouseover", function(d) { 

     tip.transition() 
     .duration(200) 
     .style("opacity", 0.7); 
     tip.html("<span><strong>" + d.Name + "</strong><br/><i>Place: </i>" + d.Place + "<br/><i>Time: </i>" + d.Time + "<br/><i>Year: </i>" + d.Year + "<br/><i>Nationality: </i>" + d.Nationality + "<br/><i>Doping: </i>" + d.Doping + "</span>") 
     .style("left", (d3.event.pageX + 48) + "px") 
     .style("top", (d3.event.pageY + 48) + "px"); 

    }) 
    .on("mouseout", function(d) { 

     tip.transition() 
     .duration(200) 
     .style("opacity", 0); 

    }); 

    svg.append("g") 
    .attr("class", "axis") 
    .attr("transform", "translate(0," + h + ")") 
    .call(xAxis); 

    svg.append("g") 
    .attr("class", "axis") 
    .call(yAxis) 

}) 
+0

你能提供工作的jsfiddle? – Elfayer

回答

3

在我看來,這個問題有(幾乎)與D3.js無關。相反,這是一個CSS問題。

有一些不同的解決方案,在一個我認爲這裏很簡單:只需設置div容器的相對位置(ID爲chart股利)...

#svgwrapper { 
    position: relative; 
} 

...和,以工具提示格,絕對位置,以零topleft

.tooltip { 
    position: absolute; 
    top: 0 px; 
    left: 0 px; 
} 

而且,不要忘了丟棄這些d3.event.pageXd3.event.pageY,因爲你的提示將始終在露面相同的位置。

這裏是一個演示(懸停在圈子):

var tip = d3.select("#svgwrapper").append("div") 
 
    .attr("class", "tooltip") 
 
    .style("opacity", 0); 
 
\t \t 
 
d3.select("circle").on("mouseover", function(){ 
 
    tip.html("Hello!") 
 
\t \t .style("opacity", 1) 
 
}).on("mouseout", function(){ 
 
    tip.style("opacity", 0) 
 
});
#svgwrapper { 
 
\t border: 1px solid gray; 
 
\t position: relative; 
 
} 
 

 
.tooltip { 
 
\t position: absolute; 
 
\t top: 0px; 
 
\t left: 0px; 
 
\t border: 1px solid gray; 
 
\t border-radius: 2px; 
 
\t padding: 4px; 
 
\t background-color: tan; 
 
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> 
 
<div>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.</div> 
 
<div id="svgwrapper"> 
 
<svg> 
 
\t <circle cx="100" cy="100" r="20" fill="teal"></circle> 
 
</svg> 
 
</div>

+0

工作,謝謝! – chemook78

+0

現在好了!再次感謝 – chemook78