|
|
1
Gerardo Furtado
6 年前
你的问题是
key function
绑定数据时。
如果您查看文档,您将看到:
可以指定一个键函数,通过计算
一串
每个基准和元素的标识符。(强调我的)
但是,在您的案例中,您不是使用字符串,而是返回整个对象:
var groups = content.selectAll("g")
.data(data, function (d) {
return d;
// ^--- this is an object
});
当然,这行不通。
因此,我们有你描述的行为:你的
exit
所选内容包含所有组,它们都将被删除。然后,输入选择包含所有元素,它们都会重新绘制。
让我们看看,单击元素并查看控制台:
var dataArray = [];
dataArray.push({ "label": 'red', "shape": "circle", "clickCnt": 0, x: 30, y: 100 });
dataArray.push({ "label": 'orange', "shape": "square", "clickCnt": 0, x: 110, y: 100 });
dataArray.push({ "label": 'yellow', "shape": "circle", "clickCnt": 0, x: 210, y: 100 });
dataArray.push({ "label": 'green', "shape": "square", "clickCnt": 0, x: 310, y: 100 });
dataArray.push({ "label": 'blue', "shape": "circle", "clickCnt": 0, x: 30, y: 200 });
dataArray.push({ "label": 'indigo', "shape": "square", "clickCnt": 0, x: 110, y: 200 });
dataArray.push({ "label": 'violet', "shape": "circle", "clickCnt": 0, x: 210, y: 200 });
dataArray.push({ "label": 'white', "shape": "square", "clickCnt": 0, x: 310, y: 200 });
var width = 400;
var height = 400;
d3.select("div#svg-container").select("svg").remove();
var svg = d3.select("#svg-container").append("svg")
.attr("width", width)
.attr("height", height);
var content = svg.append("g")
function create(data) {
var groups = content.selectAll("g")
.data(data, function (d) {
return d;
});
console.log("The exit selection size is: " + groups.exit().size())
groups.exit().remove();
groups.enter()
.append("g")
.attr('transform', function (d, i) {
return 'translate(' + d.x + ',' + d.y + ')'
})
.each(function (d) {
var e = d3.select(this);
e.append("text")
.classed("small-text", true)
.classed("label", true)
.text(function (d) {
return d.label;
})
.style("fill", function (d) {
return d.label;
});
e.append("text")
.classed("small-text", true)
.classed("clickCnt", true)
.attr("y", 20)
.text(function (d) {
return d.clickCnt;
})
.style("fill", function (d) {
return d.label;
})
if (d.shape == "circle") {
e.append("circle")
.attr("class", "circle")
.attr("r", 15)
.attr("cx", 10)
.attr("cy", -40)
.on("click", iconClicked)
.style("cursor", "pointer");
} else if (d.shape == "square") {
e.append("rect")
.attr("class", "square")
.attr("width", 30)
.attr("height", 30)
.attr("x", 0)
.attr("y", -55)
.on("click", iconClicked)
.style("cursor", "pointer");
}
});
}
create(dataArray);
function iconClicked(evt) {
if (evt.shape == "circle") {
evt.shape = "square"
} else if (evt.shape == "square") {
evt.shape = "circle"
}
evt.clickCnt++;
document.getElementById('output').innerHTML = "item clicked: " + evt.label + " " + evt.clickCnt;
create(dataArray);
}
.as-console-wrapper { max-height: 20% !important;}
.circle {
stroke: red;
stroke-width: 2px;
}
.square {
stroke: blue;
stroke-width: 2px;
}
#timeline-background {
background: slategray;
}
.label {
fill: blue;
}
.small-text {
font-size: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<body>
<label id="output">out</label>
<div id="timeline-background" style="width: 100%; height: 100%;">
<div id="svg-container"></div>
</div>
</body>
(部分)解
:使用唯一字符串作为返回值,例如
label
属性:
var groups = content.selectAll("g")
.data(data, function (d) {
return d.label;
});
看看:
var dataArray = [];
dataArray.push({ "label": 'red', "shape": "circle", "clickCnt": 0, x: 30, y: 100 });
dataArray.push({ "label": 'orange', "shape": "square", "clickCnt": 0, x: 110, y: 100 });
dataArray.push({ "label": 'yellow', "shape": "circle", "clickCnt": 0, x: 210, y: 100 });
dataArray.push({ "label": 'green', "shape": "square", "clickCnt": 0, x: 310, y: 100 });
dataArray.push({ "label": 'blue', "shape": "circle", "clickCnt": 0, x: 30, y: 200 });
dataArray.push({ "label": 'indigo', "shape": "square", "clickCnt": 0, x: 110, y: 200 });
dataArray.push({ "label": 'violet', "shape": "circle", "clickCnt": 0, x: 210, y: 200 });
dataArray.push({ "label": 'white', "shape": "square", "clickCnt": 0, x: 310, y: 200 });
var width = 400;
var height = 400;
d3.select("div#svg-container").select("svg").remove();
var svg = d3.select("#svg-container").append("svg")
.attr("width", width)
.attr("height", height);
var content = svg.append("g")
function create(data) {
var groups = content.selectAll("g")
.data(data, function (d) {
return d.label;
});
console.log("The exit selection size is: " + groups.exit().size())
groups.exit().remove();
groups.enter()
.append("g")
.attr('transform', function (d, i) {
return 'translate(' + d.x + ',' + d.y + ')'
})
.each(function (d) {
var e = d3.select(this);
e.append("text")
.classed("small-text", true)
.classed("label", true)
.text(function (d) {
return d.label;
})
.style("fill", function (d) {
return d.label;
});
e.append("text")
.classed("small-text", true)
.classed("clickCnt", true)
.attr("y", 20)
.text(function (d) {
return d.clickCnt;
})
.style("fill", function (d) {
return d.label;
})
if (d.shape == "circle") {
e.append("circle")
.attr("class", "circle")
.attr("r", 15)
.attr("cx", 10)
.attr("cy", -40)
.on("click", iconClicked)
.style("cursor", "pointer");
} else if (d.shape == "square") {
e.append("rect")
.attr("class", "square")
.attr("width", 30)
.attr("height", 30)
.attr("x", 0)
.attr("y", -55)
.on("click", iconClicked)
.style("cursor", "pointer");
}
});
}
create(dataArray);
function iconClicked(evt) {
if (evt.shape == "circle") {
evt.shape = "square"
} else if (evt.shape == "square") {
evt.shape = "circle"
}
evt.clickCnt++;
document.getElementById('output').innerHTML = "item clicked: " + evt.label + " " + evt.clickCnt;
create(dataArray);
}
.作为控制台包装最大高度:20%!重要;
.圆{
行程:红色;
行程宽度:2px;
}
.正方形{
笔画:蓝色;
行程宽度:2px;
}
#时间线背景{
背景:斯莱特雷;
}
.标签{
填充:蓝色;
}
.小文本{
字体大小:16px;
}
<script src=“https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js”></script>
<正文>
<label id=“output”>输出</label>
<div id=“Timeline Background”style=“width:100%;height:100%;”>
<DIV ID=“SVG容器”></DIV>
</DIV>
</body>
现在,如你所见,
出口
所选内容的大小始终为零。
然而,我写道
部分
原因:你不再改变元素了!原因是您没有正确的更新选择。由于退出选择不再有元素,因此输入选择的大小也为零。此处不更新任何内容。
创建这样的更新选择超出了这个答案的范围,我将把这项工作留给您。
|