我想点击形状以使用弹出窗体编辑其文本标签和x,y坐标,当提交时,更新该形状的数据,然后形状移动到新的x,y坐标。我一直无法在网上或通常的书中找到这样的例子。
页面上所有形状的数据存储在JSON数组中。一些在线示例显示如何“就地”编辑文本或编辑单个值。这对我来说不起作用,因为只有标签应该显示在形状上,我想编辑多个通常在页面上看不到的形状参数。
如果可能,我想将解决方案保留为D3或基本JavaScript。
这里显示了一个显示三个可点击矩形的简单示例: https://jsfiddle.net/NovasTaylor/oyL0hj3d/
当前"click"
事件将标签,x和y值写入控制台。此事件应触发可编辑表单的显示。
rects.append("rect")
.attr("x", function (d) { return d.x; })
.attr("y", function (d) { return d.y; })
.attr("height", function (d) { return d.height; })
.attr("width", function (d) { return d.width; })
.style("fill", function(d) { return d.color; })
.on("click", function(d){
console.log("You clicked rectangle: " + d.label)
console.log ("X position: " + d.x)
console.log ("Y position: " + d.y)
});
所有建议都非常感谢,并且更加努力地展示了这个例子!
答案 0 :(得分:2)
在D3中,覆盖基准非常简单。在d
是第一个参数的监听器内部,只需执行:
d.foo = bar;
在您的示例中,我们使用prompt
来获取新值。这只是一个演示,向您展示如何做到这一点:您可以轻松地更改丑陋的弹出式div的提示。
所以,在听众中,我们得到了新的值......
var newLabel = prompt("Please enter the new label: ");
var newX = prompt("Please enter the new x position: ");
var newY = prompt("Please enter the new y position: ");
...并使用它们重新定位矩形,同时覆盖原点:
d3.select(this)
.attr("x", d.x = +newX)
.attr("y", d.y = +newY);
唯一的问题是获得标签。因为你必须在DOM中上下,我建议你给它们(独特的)ID ...
rects.append("text")
.attr("id", function(d, i) {
return "label" + i;
})
......他们得到了他们:
d3.select(this.parentNode)
.select("#label" + i)
.text(newLabel)
.attr("x", function(d) {
return d.x + 10;
})
.attr("y", function(d) {
return d.y + 10;
});
以下是仅包含这些更改的代码:
var rectData = [{
"label": "one",
"x": 100,
"y": 50,
"height": 100,
"width": 120,
"color": "green"
}, {
"label": "two",
"x": 250,
"y": 50,
"height": 100,
"width": 120,
"color": "purple"
}, {
"label": "three",
"x": 400,
"y": 50,
"height": 100,
"width": 120,
"color": "red"
}];
var svg = d3.select("body").append("svg")
.attr("width", 600)
.attr("height", 200);
var rects = svg.selectAll("rect")
.data(rectData)
.enter();
rects.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", function(d) {
return d.y;
})
.attr("height", function(d) {
return d.height;
})
.attr("width", function(d) {
return d.width;
})
.style("fill", function(d) {
return d.color;
})
.on('mouseover', function(d) {
var rectSelection = d3.select(this)
.style({
opacity: '0.5'
})
})
.on('mouseout', function(d) {
var rectSelection = d3.select(this)
.style({
opacity: '1'
})
})
.on("click", function(d, i) {
var newLabel = prompt("Please enter the new label: ")
var newX = prompt("Please enter the new x position: ")
var newY = prompt("Please enter the new y position: ")
d3.select(this).attr("x", d.x = +newX).attr("y", d.y = +newY);
d3.select(this.parentNode).select("#label" + i).text(newLabel).attr("x", function(d) {
return d.x + 10;
})
.attr("y", function(d) {
return d.y + 10;
})
});
// Rectangle Label
rects.append("text")
.attr("id", function(d, i) {
return "label" + i;
})
.style("fill", "black")
.attr("dy", ".35em")
.attr("x", function(d) {
return d.x + 10;
})
.attr("y", function(d) {
return d.y + 10;
})
.text(function(d) {
return "Label: " + d.label
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
请记住,这是一个非常非常简单的演示:我既不检查输入的类型(字符串,整数,浮点...),也不检查它们的值。
PS:如果您使用的是D3 v4(根据您的代码,需要无需更改!),您可以避免新定位的矩形落后于其他的矩形{ {1}}。