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

标签 javascript d3.js svg data-visualization

这里是 D3 的新手,使用以下代码处理图表。当用户将鼠标悬停在其中一个文本标签上时,我有一个名为“提示”的 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)

})

最佳答案

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

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

#svgwrapper {
    position: relative;
}

...并且,对于工具提示 div,绝对位置,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);
		
d3.select("circle").on("mouseover", function(){
    tip.html("Hello!")
		.style("opacity", 1)
}).on("mouseout", function(){
    tip.style("opacity", 0)
});
#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;
}
<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>

关于javascript - 在 D3 JS 中将 div 放置在图表的左上角,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41803847/

相关文章:

javascript - 如何从此对象中检索 Constituency_Name

javascript - 从 Javascript 访问 SVG 对象时收到 Uncaught SecurityError

javascript - 在 d3js styleTween 中使用 CSS calc 时发生意外转换

javascript - 启动 svg 动画 onclick 事件

html - 如何让 SVG 元素扩展以填充容器的宽度,同时保持纵横比

javascript - 如何在 Javascript 函数之外检索数据?

javascript - 如果模型是基于 Ruby on Rails 4 上的单表继承创建的,如何制作下拉列表

javascript - Javascript 中的或运算符 (|) 与 parseInt 的作用相同吗?

javascript - 对文本元素进行条件操作?

javascript - 如何使复选框显示/隐藏 SVG 内容