代码之家  ›  专栏  ›  技术社区  ›  djangofan

如何将文本居中放置在D3.js SVG网格上?

  •  1
  • djangofan  · 技术社区  · 5 年前

    如何在D3.js SVG网格上水平和垂直居中放置文本?

    以下是我正在努力工作的示例:

    https://jsfiddle.net/djangofan/koc74p9x/4/

    var columnText = row.selectAll(".column")  // select .column val from data
        .data(function(d) { return d; })
        .enter().append("text")
        .text(function(d) { return d.chord; })
        .attr("x", function(d) { return d.x; })
        .attr("y", function(d) { return d.y; })
        .style("fill", "red");
    

    这就是它的样子。我希望'Gm'文本位于第一个单元格的中心。如果我试图向下调整,文本会在通过单元格的顶部边框时消失。

    enter image description here

    enter image description here

    0 回复  |  直到 5 年前
        1
  •  4
  •   Gerardo Furtado    5 年前

    移动 x y 按宽度/高度的一半定位:

    .attr("x", function(d) {
        return d.x + d.width / 2;
    })
    .attr("y", function(d) {
        return d.y + d.height / 2;
    })
    

    并设置两者 text-anchor dominant-baseline middle :

    .attr("text-anchor", "middle")
    .attr("dominant-baseline", "middle")
    

    最后,将文本移动到矩形的顶部(即稍后附加)。

    以下是您进行了这些更改的代码:

    function gridConfig() {
      var data = new Array();
      var xpos = 1; //starting xpos and ypos at 1 so the stroke will show when we make the grid below
      var ypos = 80;
      var width = 80;
      var height = 80;
      var click = 0;
    
      for (var row = 0; row < 8; row++) {
        data.push(new Array());
        for (var column = 0; column < 8; column++) {
          data[row].push({
            rowNum: row + 1,
            columnNum: column + 1,
            x: xpos,
            y: ypos,
            width: width,
            height: height,
            chord: randomChord()
          })
          // increment the x position. I.e. move it over by width variable
          xpos += width;
        }
        // reset the x position after a row is complete
        xpos = 1;
        // increment the y position for the next row. Move it down height variable
        ypos += height;
      }
      return data;
    }
    
    function randomChord() {
      var textArray = ['Cm', 'D7', 'Gm', 'Cdim', 'Am', 'Em'];
      return textArray[Math.floor(Math.random() * textArray.length)];
    }
    
    var gridData = gridConfig();
    
    var grid = d3.select("#grid")
      .append("svg")
      .attr("width", "810px")
      .attr("height", "890px");
    
    var row = grid.selectAll(".row") // select .row val from data
      .data(gridData)
      .enter().append("g")
      .attr("class", "row")
      .append("g")
      .attr("class", "column");
    
    var column = row.selectAll(".square")
      .data(function(d) {
        return d;
      })
      .enter()
      .append("rect")
      .attr("class", "square")
      .attr("x", function(d) {
        return d.x;
      })
      .attr("y", function(d) {
        return d.y;
      })
      .attr("width", function(d) {
        return d.width;
      })
      .attr("height", function(d) {
        return d.height;
      })
      .style("fill", "#fff")
      .style("stroke", "#222");
    
    var columnText = row.selectAll(".column") // select .column val from data
      .data(function(d) {
        return d;
      })
      .enter()
      .append("text")
      .text(function(d) {
        return d.chord;
      })
      .attr("rowNum", function(d) {
        return d.rowNum;
      })
      .attr("columnNum", function(d) {
        return d.columnNum;
      })
      .attr("x", function(d) {
        return d.x + d.width / 2;
      })
      .attr("y", function(d) {
        return d.y + d.height / 2;
      })
      .attr("text-anchor", "middle")
      .attr("dominant-baseline", "middle")
      .style("fill", "red")
      .style("font-weight", "bold")
      .style("font-size", "24");
    <html>
    <head>
        <script src="https://d3js.org/d3.v4.min.js"></script>
    </head>
    <body>
    <div id="grid"></div>
    <script src="grid.js" type="text/javascript"></script>
    </body>
    </html>