动态更改附加 D3
Dynamically Change the Append D3
var data = [
{"name": "Lincoln", "pid":1, "sex": "M"},
{"name": "Tad", "pid":2, "sex":"M"},
{"name": "Mary", "pid":3, "sex": "F"},
];
var nodes = svg.append("g")
.selectAll("rect")
.selectAll("circle")
.data(information.descendants())
.enter()
.append(function(d){
getPerson(d.data.child).sex === "M" ? "rect" : "circle"
})
我想根据人物的性别设置圆形或矩形。我不知道是否有适当的约定来设置这些条件。我不知道如何在两者之间正确切换,因为如果它是男性和“矩形”,则需要设置 .attr("x") 和 .attr("y")。如果是“圆圈”,则还需要设置 .attr("cx") 和 .attr("cy") 以及 .attr("r")。
information.descendants() 基于传递到树结构中的 d3.stratify() (d3.tree())。
有很多方法可以实现这一点。下面的第一个选项仅使用矩形,第二个和第三个选项使用 svg 路径(所有三个选项都简化了定位、选择修改、从一个到另一个更改形状。)
第四个选项是追加,其中元素在矩形和圆形之间变化。
圆一些矩形
如果您的形状是圆形和方形,也许最简单的方法是使用具有 rx, ry 属性的矩形,这样一些矩形看起来像矩形,而另一些像圆形:
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("x",d=>d.x)
.attr("y",d=>d.y)
.attr("rx",d=>d.circle?width/2:0)
.attr("ry",d=>d.circle?width/2:0)
.attr("width", width)
.attr("height",width);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
使用D3.symbol
我们可以使用路径而不是矩形或圆,d3.symbol returns 路径数据并且有一个圆和一个矩形,d3.symbol 如果我们想改变,有一个大小方法大小(符号以其中心坐标为中心,如圆圈):
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("transform",d=>"translate("+[d.x,d.y]+")")
.attr("d", function(d) {
var symbol = d.circle ? d3.symbolCircle : d3.symbolSquare;
return d3.symbol().type(symbol).size(300)();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
创建自己的路径
我们可以只使用一个函数来代替符号 returns 圆形或矩形的路径数据,比 d3.symbol 给你更多的灵活性,但失去了它的一些简单性(例如符号的简单重新缩放):
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("transform",d=>"translate("+[d.x,d.y]+")")
.attr("d", pather)
function pather(d) {
if(d.circle) {
return "M10,10m-10,0a10,10 0 1,0 20,0a 10,10 0 1,0 -20,0"
}
else {
return "M0,0L0,20L20,20L20,0Z";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
一次追加同时创建矩形和圆形
selection.append() 可以接受一个函数——函数返回的任何元素都会附加到 DOM。为了制作我们的节点,我们将创建一个分离的 SVG 元素并向其添加一个圆圈。
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append(makeShape)
function makeShape(d) {
// create a temporary svg
let svg = document.createElementNS(d3.namespaces.svg, "svg")
// create an element:
if(d.circle) {
return d3.select(svg)
.append("circle")
.attr("cx",d.x)
.attr("cy",d.y)
.attr("r", 10)
.node() // return node, not selection.
}
else {
return d3.select(svg)
.append("rect")
.attr("x",d.x)
.attr("y",d.y)
.attr("width", 20)
.attr("height", 20)
.node();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
但是现在您可以选择圆形和矩形 - 以后处理起来会更麻烦。
var data = [
{"name": "Lincoln", "pid":1, "sex": "M"},
{"name": "Tad", "pid":2, "sex":"M"},
{"name": "Mary", "pid":3, "sex": "F"},
];
var nodes = svg.append("g")
.selectAll("rect")
.selectAll("circle")
.data(information.descendants())
.enter()
.append(function(d){
getPerson(d.data.child).sex === "M" ? "rect" : "circle"
})
我想根据人物的性别设置圆形或矩形。我不知道是否有适当的约定来设置这些条件。我不知道如何在两者之间正确切换,因为如果它是男性和“矩形”,则需要设置 .attr("x") 和 .attr("y")。如果是“圆圈”,则还需要设置 .attr("cx") 和 .attr("cy") 以及 .attr("r")。
information.descendants() 基于传递到树结构中的 d3.stratify() (d3.tree())。
有很多方法可以实现这一点。下面的第一个选项仅使用矩形,第二个和第三个选项使用 svg 路径(所有三个选项都简化了定位、选择修改、从一个到另一个更改形状。)
第四个选项是追加,其中元素在矩形和圆形之间变化。
圆一些矩形
如果您的形状是圆形和方形,也许最简单的方法是使用具有 rx, ry 属性的矩形,这样一些矩形看起来像矩形,而另一些像圆形:
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("x",d=>d.x)
.attr("y",d=>d.y)
.attr("rx",d=>d.circle?width/2:0)
.attr("ry",d=>d.circle?width/2:0)
.attr("width", width)
.attr("height",width);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
使用D3.symbol
我们可以使用路径而不是矩形或圆,d3.symbol returns 路径数据并且有一个圆和一个矩形,d3.symbol 如果我们想改变,有一个大小方法大小(符号以其中心坐标为中心,如圆圈):
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("transform",d=>"translate("+[d.x,d.y]+")")
.attr("d", function(d) {
var symbol = d.circle ? d3.symbolCircle : d3.symbolSquare;
return d3.symbol().type(symbol).size(300)();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
创建自己的路径
我们可以只使用一个函数来代替符号 returns 圆形或矩形的路径数据,比 d3.symbol 给你更多的灵活性,但失去了它的一些简单性(例如符号的简单重新缩放):
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append("path")
.attr("transform",d=>"translate("+[d.x,d.y]+")")
.attr("d", pather)
function pather(d) {
if(d.circle) {
return "M10,10m-10,0a10,10 0 1,0 20,0a 10,10 0 1,0 -20,0"
}
else {
return "M0,0L0,20L20,20L20,0Z";
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
一次追加同时创建矩形和圆形
selection.append() 可以接受一个函数——函数返回的任何元素都会附加到 DOM。为了制作我们的节点,我们将创建一个分离的 SVG 元素并向其添加一个圆圈。
var data = [
{x: 100, y: 100, circle: true},
{x: 200, y: 100, circle: false}
]
var width = 20;
d3.select("body")
.append("svg")
.selectAll(null)
.data(data)
.enter()
.append(makeShape)
function makeShape(d) {
// create a temporary svg
let svg = document.createElementNS(d3.namespaces.svg, "svg")
// create an element:
if(d.circle) {
return d3.select(svg)
.append("circle")
.attr("cx",d.x)
.attr("cy",d.y)
.attr("r", 10)
.node() // return node, not selection.
}
else {
return d3.select(svg)
.append("rect")
.attr("x",d.x)
.attr("y",d.y)
.attr("width", 20)
.attr("height", 20)
.node();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
但是现在您可以选择圆形和矩形 - 以后处理起来会更麻烦。