繁体   English   中英

如何在散点图中的点内添加标签?

[英]How can I add labels inside the points in a scatterplot?

我试图像这样在散点图中添加状态缩写: 带有标签的散点图

这是我正在使用的CSV文件的代码段:

id   abbr healthcare  poverty
 1   AL   13.9        19.3
 2   AK   15          11.2      
 3   AZ   14.4        18.2
 4   AR   16.3        18.9
 5   CA   14.8        16.4
 6   CO   12.8        12
 7   CT   8.7         10.8
 8   DE   8.7         12.5

这是我的JavaScript代码:

// @TODO: YOUR CODE HERE!
var svgWidth = 750;
var svgHeight = 500;

var margin = {
    top: 20,
    right: 40,
    bottom: 60, 
    left: 100
};

var width = svgWidth - margin.left - margin.right;
var height = svgHeight - margin.top - margin.bottom;

// Create an SVG wrapper, append an SVG group that will hold our chart and shift the latter by left and top margins
var svg = d3.select("#scatter")
  .append("svg")
  .attr("width", svgWidth)
  .attr("height", svgHeight);

var chartGroup = svg.append("g")
  .attr("transform", `translate(${margin.left}, ${margin.top})`);

// Import Data
d3.csv("data.csv").then(function(censusData) {

    // Parse Data & Cast as numbers
    censusData.forEach(function(data) {
        data.healthcare = +data.healthcare;
        data.poverty = +data.poverty;
    });

    // Create scale functions
    var xLinearScale = d3.scaleLinear()
      .domain(d3.extent(censusData, d => d.poverty))
      .range([0, width]);

    var yLinearScale = d3.scaleLinear()
      .domain([0, d3.max(censusData, d => d.healthcare)])
      .range([height, 0]);

    // Create axis functions
    var bottomAxis = d3.axisBottom(xLinearScale);
    var leftAxis = d3.axisLeft(yLinearScale);

    // Append axes to the chart
    chartGroup.append("g")
      .attr("transform", `translate(0, ${height})`)
      .call(bottomAxis);

    chartGroup.append("g")
      .call(leftAxis);

    // Create circles
    var circlesGroup = chartGroup.selectAll("Circle")
      .data(censusData)
      .enter()
      .append("circle")
      .attr("cx", d => xLinearScale(d.poverty))
      .attr("cy", d => yLinearScale(d.healthcare))
      .attr("r", "15")
      .attr("fill", "rgb(117, 145, 197)") 
      .attr("opacity", "0.5");

    // Add state labels to the points
    var circleLabels = circlesGroup.selectAll("text").data(censusData).enter().append("text");

    circleLabels
      .attr("x", function(d) { return d.poverty; })
      .attr("y", function(d) { return d.healthcare; })
      .text(function(d) { return d.abbr; })
      .attr("font-family", "sans-serif")
      .attr("font-size", "5px")
      .attr("fill", "white");

    // Create axes labels
    chartGroup.append("text")
      .attr("transform", "rotate(-90)")
      .attr("y", 0 - margin.left + 40)
      .attr("x", 0 - (height / 2))
      .attr("dy", "1em")
      .attr("class", "axisText")
      .style("text-anchor", "middle")
      .text("Lacks Healthcare (%)");

    chartGroup.append("text")
      .attr("transform", `translate(${width / 2}, ${height + margin.top + 30})`)
      .attr("class", "axisText")
      .style("text-anchor", "middle")
      .text("In Poverty (%)");

    // Initialize tooltip
    var toolTip = d3.tip() 
      .attr("class", "tooltip")
      .offset([80, -60])
      .html(function(d) {
        return  `${d.state}<br>Poverty: ${d.poverty}<br>Healthcare: ${d.healthcare}<br>`; 
    });

    // Create tooltip in the chart
    chartGroup.call(toolTip);

    // Create event listeners to display and hide the tooltip
    circlesGroup.on("mouseover", function(data) {
      toolTip.show(data, this);
    })
      // onmouseout event
      .on("mouseout", function(data, index) {
        toolTip.hide(data);
      });

});

我试图将它们添加到代码的circleLabels部分中,但无济于事。 谁能告诉我这部分我做错了什么:

// Add state labels to the points
    var circleLabels = circlesGroup.selectAll("text").data(censusData).enter().append("text");

    circleLabels
      .attr("x", function(d) { return d.poverty; })
      .attr("y", function(d) { return d.healthcare; })
      .text(function(d) { return d.abbr; })
      .attr("font-family", "sans-serif")
      .attr("font-size", "5px")
      .attr("fill", "white");

欢迎提出任何建议或更改。

您有三个问题:

  1. circlesGroup是圈子的选择。 您不能将<text>元素附加到<circle>元素。 因此,将其更改为chartGroup

     var circleLabels = chartGroup.selectAll("text")//etc... 

    这给我们带来了第二个问题:

  2. 该选择中包含文本元素。 因此,为避免将数据绑定到现有元素(这会减小enter选择的大小),请使用selectAll(null

     var circleLabels = chartGroup.selectAll(null)//etc... 

    要了解有关selectAll(null)更多信息,请在这里阅读我的问答: 选择null:D3.js中“ selectAll(null)”背后的原因是什么?

  3. 您没有使用刻度来定位文本。

最后,使用text-anchor: middle输入文本。

这是您所做的更改的代码:

 var csv = `id,abbr,healthcare,poverty 1,AL,13.9,19.3 2,AK,15,11.2, 3,AZ,14.4,18.2 4,AR,16.3,18.9 5,CA,14.8,16.4 6,CO,12.8,12 7,CT,8.7,10.8 8,DE,8.7,12.5`; const censusData = d3.csvParse(csv) var svgWidth = 960; var svgHeight = 500; var margin = { top: 20, right: 40, bottom: 60, left: 100 }; var width = svgWidth - margin.left - margin.right; var height = svgHeight - margin.top - margin.bottom; // Create an SVG wrapper, append an SVG group that will hold our chart and shift the latter by left and top margins var svg = d3.select("#scatter") .append("svg") .attr("width", svgWidth) .attr("height", svgHeight); var chartGroup = svg.append("g") .attr("transform", `translate(${margin.left}, ${margin.top})`); // Parse Data & Cast as numbers censusData.forEach(function(data) { data.healthcare = +data.healthcare; data.poverty = +data.poverty; }); // Create scale functions var xLinearScale = d3.scaleLinear() .domain(d3.extent(censusData, d => d.poverty)) .range([0, width]); var yLinearScale = d3.scaleLinear() .domain([0, d3.max(censusData, d => d.healthcare)]) .range([height, 0]); // Create axis functions var bottomAxis = d3.axisBottom(xLinearScale); var leftAxis = d3.axisLeft(yLinearScale); // Append axes to the chart chartGroup.append("g") .attr("transform", `translate(0, ${height})`) .call(bottomAxis); chartGroup.append("g") .call(leftAxis); // Create circles var circlesGroup = chartGroup.selectAll("Circle") .data(censusData) .enter() .append("circle") .attr("cx", d => xLinearScale(d.poverty)) .attr("cy", d => yLinearScale(d.healthcare)) .attr("r", "15") .attr("fill", "blue") .attr("opacity", "0.5"); var circleLabels = chartGroup.selectAll(null).data(censusData).enter().append("text"); circleLabels .attr("x", function(d) { return xLinearScale(d.poverty); }) .attr("y", function(d) { return yLinearScale(d.healthcare); }) .text(function(d) { return d.abbr; }) .attr("font-family", "sans-serif") .attr("font-size", "10px") .attr("text-anchor", "middle") .attr("fill", "white"); // Create axes labels chartGroup.append("text") .attr("transform", "rotate(-90)") .attr("y", 0 - margin.left + 40) .attr("x", 0 - (height / 2)) .attr("dy", "1em") .attr("class", "axisText") .text("Lacks Healthcare (%)"); chartGroup.append("text") .attr("transform", `translate(${width / 2}, ${height + margin.top + 30})`) .attr("class", "axisText") .text("In Poverty (%)"); 
 <head> <meta charset="UTF-8"> <title>D3Times</title> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"> <link rel="stylesheet" href="assets/css/style.css"> <link rel="stylesheet" href="assets/css/d3Style.css"> </head> <body> <div class="container"> <div class="row"> <div class="col-xs-12 col-md-12"> <h1>D3Times</h1> </div> </div> <div class="row"> <div class="col-xs-12 col-md-9"> <div id="scatter"> <!-- We append our chart here. --> </div> </div> </div> </div> <!-- Footer--> <div id="footer"> <p>The Coding Boot Camp&copy;2016</p> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.5.0/d3.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/d3-tip/0.9.1/d3-tip.js"></script> <script type="text/javascript" src="assets/js/app.js"></script> </body> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM