Insert text inside Circle in D3 chart

谁说我不能喝 提交于 2019-12-02 04:07:17

When you do this:

var text = vis.selectAll("text")
    .data(sampleData)
    .enter()
    .insert("text");

You are selecting <text> elements that already exist in that SVG (in your case, the axes' ticks). Because of that, your "enter" selection is empty.

Solution: select something that doesn't exist, like null:

var text = vis.selectAll(null)
    .data(sampleData)
    .enter()
    .insert("text");

Here is the updated code:

var sampleData = [{
  "x": 8,
  "y": 1
}, {
  "x": 2,
  "y": 1
}, {
  "x": 4,
  "y": 1
}, {
  "x": 5,
  "y": 1
}];

var vis = d3.select("svg");
var xRange = d3.scale.linear().range([40, 400]).domain([0, 10]);
var yRange = d3.scale.linear().range([200, 40]).domain([0, 2]);

var xAxis = d3.svg.axis().scale(xRange).ticks(2);
var yAxis = d3.svg.axis().scale(yRange).ticks(2).orient("left");
vis.append("svg:g").call(xAxis).attr("transform", "translate(0,200)");
vis.append("svg:g").call(yAxis).attr("transform", "translate(40,0)");

var circles = vis.selectAll("circle").data(sampleData);

circles
  .enter()
  .append("circle")
  .attr("cx", function(d) {
    return xRange(d.x);
  })
  //.attr("cy", function(d) { return yRange (d.y); })
  .attr("cy", function(d) {
    return yRange(d.y);
  })
  .attr("r", function(d) {
    return Math.log(d.x) * 30;
  })
  .attr("stroke", "black")
  .style("fill", "yellow");

var text = vis.selectAll(null)
  .data(sampleData)
  .enter()
  .append("text");

var textLabels = text
  .attr("x", function(d) {
    return xRange(d.x);
  })
  .attr("text-anchor", "middle")
  .attr("y", function(d) {
    return yRange(d.y);
  })
  .text(function(d) {
    return "( " + d.x + ", " + d.y + " )";
  })
  .attr("font-family", "sans-serif")
  .attr("font-size", "10px")
  .attr("fill", "red");
line, path{
  fill: none;
  stroke: black;
}
<script src="https://d3js.org/d3.v3.min.js"></script>
<svg width="400" height="220"></svg>

PS: Don't use insert, use append instead.

A better way of doing this is to use svg groups, then you can position both the circles and the text together:

var join = vis.selectAll(".points").data(sampleData);

var groups = join
  .enter()
  .append("g")
  .attr("transform", function(d) { return "translate(" + [d.x, d.y] + ")"; });
  .attr("cx", function(d) { return xRange (d.x); })

groups.append("circle")
  .attr("r", function(d) { return Math.log(d.x) * 30; })
  .attr("stroke","black")
  .style("fill", "yellow");

groups.append("text")
      .data(sampleData)
      .text( function (d) { return "( " + d.cx + ", " + d.cy +" )"; })
      .attr("font-family", "sans-serif")
      .attr("font-size", "20px")
      .attr("fill", "red");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!