在D3 JS中将div放在图表的左上角

che*_*k78 2 javascript svg data-visualization d3.js

这里是D3的新手,并使用下面的代码在图表上工作.当用户将鼠标悬停在其中一个文本标签上时,我有一个名为"tip"的div显示(通过改变不透明度).我无法正确定位.

我想要的是将它放在图表的左上角,让我们说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)

})
Run Code Online (Sandbox Code Playgroud)

Ger*_*ado 5

在我看来,这个问题(几乎)与D3.js无关.相反,这是一个CSS问题.

有一些不同的解决方案,我在这里建议的非常简单:只需设置容器div(带有Id的div chart)的相对位置......

#svgwrapper {
    position: relative;
}
Run Code Online (Sandbox Code Playgroud)

...并且,对于工具提示div,一个绝对位置,零top和for left:

.tooltip {
    position: absolute;
    top: 0 px;
    left: 0 px;
}
Run Code Online (Sandbox Code Playgroud)

另外,不要忘了丢弃这些d3.event.pageXd3.event.pageY,因为你的提示将始终在同一位置显示出来.

这是一个演示(悬停在圆圈上):

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

.tooltip {
	position: absolute;
	top: 0px;
	left: 0px;
	border: 1px solid gray;
	border-radius: 2px;
	padding: 4px;
	background-color: tan;
}
Run Code Online (Sandbox Code Playgroud)
<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>
	<circle cx="100" cy="100" r="20" fill="teal"></circle>
</svg>
</div>
Run Code Online (Sandbox Code Playgroud)