如何在d3.js中正确放置文本标签?

时间:2017-10-25 20:57:06

标签: javascript d3.js

我已经绘制了一个描述专业自行车赛中使用兴奋剂的数据集的散点图,而我的绘图点目前是朝向的,我没有正确地在点旁边标记它们,标签只显示几个点,任何暗示我在哪里在标记点时做错了会很有用

link to codepen

// get data from the server
$.getJSON(
  "https://raw.githubusercontent.com/FreeCodeCamp/ProjectReferenceData/master/cyclist-data.json",
  function(x) {
    var margin = { top: 40, right: 20, bottom: 30, left: 40 },
        width = 960 - margin.left - margin.right,
        height = 500 - margin.top - margin.bottom;

    var svg = d3
    .select("body")
    .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 + ")");

    var data = x;
    var rankings = [];
    var values = [];

    //populate rankings and values variable with data
    for (var i in data) {
      rankings.push(data[i]["Place"]);
      values.push(data[i]["Seconds"] - 2210);
    }

    //function to format label on x-axis
    var formatMinutes = function(d) {
      var hours = Math.floor(d / 3600),
          minutes = Math.floor((d - hours * 3600) / 60),
          seconds = d - minutes * 60;
      var output = seconds + "s";
      if (minutes) {
        output = minutes + "m " + output;
      }
      if (hours) {
        output = hours + "h " + output;
      }
      return output;
    };

    var x = d3
    .scaleLinear()
    .domain([d3.max(values), 0])
    .range([0, width - 300]);

    var xAxis = d3
    .axisBottom()
    .scale(x)
    .ticks(6)
    .tickFormat(formatMinutes);

    //define yscale
    var y = d3
    .scaleLinear()
    .range([height, 0])
    .domain([d3.max(rankings), 0]);

    var yaxis = d3.axisLeft().scale(y);

    //define chart div
    var chart = d3
    .select(".chart")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom)
    .append("g")
    .attr(
      "transform",
      "translate(" + margin.left + 500 + "," + margin.top + 100 + ")"
    );

    //     draw x axis
    svg
      .append("g")
      .call(xAxis)
      .attr("transform", "translate(0," + height + ")");

    // draw yaxis
    svg
      .append("g")
      .attr("class", "y axis")
      .call(yaxis)
      .append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 6)
      .attr("dy", ".71em");

    // draw dots on the graph
    svg
      .selectAll(".dot")
      .data(data)
      .enter()
      .append("circle")
      .attr("class", "dot")
      .attr("r", 3.5)
      .attr("fill", function(d) {
      if (d.Doping.length == 0) {
        return "black";
      } else {
        return "red";
      }
    })
      .attr("cx", function(d) {
      return x(d.Seconds - 2210);
    })
      .attr("cy", function(d) {
      return y(d.Place);
    });

    //add text labels to the dots
    svg
      .selectAll("text")
      .data(data)
      .enter()
      .append("text")
      .style("text-anchor", "left")
      .attr("x", function(d) {

      return x(d.Seconds - 2210);
    })
      .attr("y", function(d) {
      return y(d.Place);
    })
      .text(function(d) {
      return d.Name;
    })
      .attr("transform", "translate(15,+4)");
  }
);

1 个答案:

答案 0 :(得分:1)

你几乎得到了它,但很少有一些细微的变化有助于获得理想的结果。

  1. 我认为你的意思是使用" y"而不是" yscale" (未定义yscale)

  2. 最好使用<g>并在其中包装点。这是一个片段: svg.append("g").classed('dots', true);

  3. 现在将所有点和文本附加到(组)即

    svg.select('g.dots').selectAll(".dot").data(data).enter().....
    
    svg.select('g.dots').selectAll("text").data(data).enter()....
    
  4. 那就是它。这是DEMO。您现在可以根据要求将字体样式应用于文本。

  5. 希望这会有所帮助。 :)