d3 创建换行符/选择父节点

问题描述 投票:0回答:1

我想实现一个 line

break. Therefore I created two 
tspan
s in a text element. However, I can't get access to the first 
tspan` 元素,而不干扰第二个元素,甚至删除它。

我的代码如下所示:

svg.selectAll("text")
        .append("tspan")
        .append("tspan")
            .attr("dy","1.2em")
            .text("unten")
        .select(function() {return this.parentNode;})
        .text("oben");  
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>

HTML 中生成的树是: Tree

当我不包含最后两行时,第二个

tspan
将使用正确的文本进行实例化。那么我该如何做到让文本和
tspan
都存在呢?除了换行偏移之外,我需要让
tspan
具有相同的位置。

我尝试了各种不同的顺序,但似乎都不起作用。

一个可行的例子就是我想做的事情。我想在图中的某些节点上加双线。

function drawSunburst() {

    let data = {
        name: "Root",
        children: [
            {
                name: "Category 1",
                children: [
                    { 
                        name: "Subcategory 1A", 
                        children: [
                            { name: "SubSubcategory 1Ac", size: 10 }
                        ]
                    },
                    { 
                        name: "Subcategory 1B",  
                        children: [
                            { name: "SubSubcategory 1Ba", size: 10 },
                            { name: "SubSubcategory 1Bb", size: 10 },
                            { name: "SubSubcategory 1Bc", size: 10 }
                        ]
                    },
                    { 
                        name: "Subcategory 1C", 
                        children: [
                            { name: "SubSubcategory 1Ca", size: 10 },
                            { name: "SubSubcategory 1Cc", size: 10 }
                        ]
                    }
                ]
            },
            {
                name: "Category 2",
                children: [
                    { 
                        name: "Subcategory 2A",
                        children: [
                            { name: "SubSubcategory 2Aa", size: 10 },
                            { name: "SubSubcategory 2Ab", size: 10 },
                            { name: "SubSubcategory 2Ac", size: 10 }
                        ]
                    },
                    { 
                        name: "Subcategory 2B",
                        children: [
                            { name: "SubSubcategory 2Ba", size: 10 },
                            { name: "SubSubcategory 2Bc", size: 10 }
                        ]
                    },
                    {   
                        name: "Subcategory 2C",
                        children: [
                            { name: "SubSubcategory 2Ca", size: 10 },
                            { name: "SubSubcategory 2Cb", size: 10 },
                            { name: "SubSubcategory 2Cc", size: 10 }
                        ]
                    }
                ]
            },
            {
                name: "Category 3",
                children: [
                    { 
                        name: "Subcategory 3A",
                        children: [
                            { name: "SubSubcategory 3Aa", size: 10 },
                            { name: "SubSubcategory 3Ab", size: 10 },
                            { name: "SubSubcategory 3Ac", size: 10 }
                        ]
                    },
                    { 
                        name: "Subcategory 3B",
                        children: [
                            { name: "SubSubcategory 3Ba", size: 10 },
                            { name: "SubSubcategory 3Bb", size: 10 },
                            { name: "SubSubcategory 3Bc", size: 10 }
                        ]
                    },
                    { 
                        name: "Subcategory 3C",
                        children: [
                            { name: "SubSubcategory 3Ca", size: 10 },
                            { name: "SubSubcategory 3Cb", size: 10 }
                        ]
                    }
                ]
            }
        ]
    };

    let width = 1000;
    let height = 1000;
    let radius = Math.min(width, height) / 2;

    let svg = d3.select("#chart-svg")
    .attr("width", width)
    .attr("height", height)
        .append("g")
        .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

    let partition = d3.partition()
        .size([2 * Math.PI, radius]);

    let root = d3.hierarchy(data)
        .sum(function(d) { return d.size; });

    let arc = d3.arc()
        .startAngle(function(d) { return d.x0; })
        .endAngle(function(d) { return d.x1; })
        .innerRadius(function(d) { return Math.max(0, d.y0); })
        .outerRadius(function(d) { return Math.max(0, d.y1); });

    let node = svg.datum(root).selectAll("path")
        .data(partition(root).descendants())
        .enter().append("g")
        .attr("class", "node")
        .append("path")
        .attr("class", "arc")
        .attr("d", arc)
        .style("stroke", "#fff")
        .style("fill", "red");

    svg.append("g")
        .attr("pointer-events", "none")
        .attr("text-anchor", "middle")
        .attr("font-size", 10)
        .attr("font-family", "sans-serif")
        .selectAll("text")
        .data(root.descendants().filter(d => d.depth && (d.y0 + d.y1) / 2 * (d.x1 - d.x0) > 10))
        .join("text")
        .attr("transform", function(d, i) {
            let x = (d.x0 + d.x1) / 2 * 180 / Math.PI;
            let y = (d.y0 + d.y1) / 2;
            return `rotate(${x - 90}) translate(${y},0) rotate(${x < 180 ? 0 : 180})`;
        })
        .attr("dy", "0.35em")

    svg.selectAll("text")
        .append("tspan")
        .append("tspan")
            .attr("dy","1.2em")
            .text("bottom")
        .select(function() {return this.parentNode;})
        .text("top");   

}

window.onload = function() {
    drawSunburst();
};
<!DOCTYPE html>

<head>

  <title>Sunburst-Diagramm</title>
  <!-- D3.js -->
  <script src="https://d3js.org/d3.v7.min.js"></script>


</head>
<body>
  <!-- Container für das Diagramm -->
  <div id="chart-container">
    <svg id="chart-svg"></svg>
  </div>
  <script src="sunburst_short.js" defer></script>
</body>
</html>

javascript d3.js
1个回答
0
投票

您生成的 SVG 将无效。您不能让一个

tspan
成为另一个
tspan
的父级,它们都必须是
text
的子级。

所以,你只需这样写:

<html>
  <html>
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
    </head>

    <body>
      <svg width="100" height="100"></svg>
      <script>
        const t = d3.select('svg').append('text');

        t.append('tspan')
          .attr('x', 0)
          .attr('y', 10)
          .text('oben');

        t.append('tspan')
          .attr('x', 0)
          .attr('y', 10)
          .attr('dy', '1.2em')
          .text('unten');
      </script>
    </body>
  </html>
</html>

您还可以使包装数据驱动:

<html>
  <html>
    <head>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
    </head>

    <body>
      <svg width="100" height="100"></svg>
      <script>
        const d = ["oben", "mitte", "unten"]
        const t = d3.select('svg').append('text');

        t.selectAll("tspan")
          .data(d)
          .enter()
          .append('tspan')
          .attr('x', 0)
          .attr('y', 10)
          .attr('dy', (d,i) => (1.2 * i) + 'em')
          .text(d => d);
      </script>
    </body>
  </html>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.