我想实现一个 line
break. Therefore I created two
tspans 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 中生成的树是:
当我不包含最后两行时,第二个
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>
您生成的 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>