我希望在单击形状时更新<div>
中显示的形状标签,x位置和y位置值。
https://jsfiddle.net/NovasTaylor/q8cLhw9b/
用户编辑表单字段以根据需要更改值,然后单击“提交”将更改(如果有)写回JSON数组。
我在矩形的"click"
事件中构建了表单,该事件也会触发不透明度以在页面顶部的<div>
中显示表单:
.on("click", function(d){
d3.select("#rectInfo").style("opacity", 1);
var infoForm = d3.select("#rectInfo").append("form")
.attr("id", "foo")
.attr("action", "javascript:submitForm();")
.attr("method", "post")
.attr("class", "formEle");
显示按需工作。但是,我不知道如何将表单中的值推回到JSON数组。 submitForm()函数只清除div convent。
function submitForm(){
d3.selectAll(".formEle").remove();
d3.select("#rectInfo").style("opacity", 0);
}
如何将表单中的值恢复为JSON数组?
答案 0 :(得分:3)
根据your comment,您不会将此信息发送到任何地方。因此,您不需要表格。
所以,只需将常规文本输入附加到该div ...
var div = d3.select("#rectInfo")
var labelText = div.append("p")
.text("Label: ");
var labelInput = labelText.append("input")
.attr("size", "15")
.attr("type", "text")
.attr("value", d.label);
var xPosText = div.append("p")
.text("X pos: ");
var xPosInput = xPosText.append("input")
.attr("size", "15")
.attr("type", "text")
.attr("value", d.x);
var yPosText = div.append("p")
.text("Y pos: ");
var yPosInput = yPosText.append("input")
.attr("size", "15")
.attr("type", "text")
.attr("value", d.y);
...并创建一个按钮,在“点击”时,获取输入的值并更改x
,y
和label
属性:
var button = div.append("button")
.text("Submit/Hide")
.on("click", function() {
d3.select(self).attr("x", function(d) {
return d.x = +xPosInput.node().value
}).attr("y", function(d) {
return d.y = +yPosInput.node().value
});
d3.select("#text" + i).text(function(d) {
return "Label: " + (d.label = labelInput.node().value);
})
.attr("x", function(d) {
return d.x = +xPosInput.node().value + 10
}).attr("y", function(d) {
return d.y = +yPosInput.node().value + 10
});
})
注意这种模式:
return d.x = +xPosInput.node().value
它做了两件事:
+xPosInput.node().value
); d.x
,从而更改我们的数据。此外,输入返回字符串,即使用户键入数字......这就是为什么在上面的示例中xPosInput.node().value
之前存在一元加号运算符的原因。
作为最后一点,我不是删除/重新附加元素的粉丝(我在谈论div)。你可以简单地更新它们。但是,正如我在其他答案中告诉你的那样,这是一个不同的问题,并且在S.O.我们试图在每个问题中只保留一个问题(所以,我在这个答案中没有处理它)。
以下是包含这些更改的代码:
var rectInfoActive = false;
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()
.append("g");
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 self = this;
if (rectInfoActive == true) {
// clicked a node while previous info block displayed
d3.selectAll("input").remove();
d3.selectAll(".formEle").remove();
d3.select("#rectInfo").selectAll("*").remove();
d3.select("#rectInfo").style("opacity", 0);
}
d3.select("#rectInfo").style("opacity", 1);
// Form displayed in /div becomes visible onclick of a rect.
// submit button clears the form. No data update yet.
var div = d3.select("#rectInfo")
var labelText = div.append("p")
.text("Label: ");
var labelInput = labelText.append("input")
.attr("size", "15")
.attr("type", "text")
.attr("value", d.label);
var xPosText = div.append("p")
.text("X pos: ");
var xPosInput = xPosText.append("input")
.attr("size", "15")
.attr("type", "text")
.attr("value", d.x);
var yPosText = div.append("p")
.text("Y pos: ");
var yPosInput = yPosText.append("input")
.attr("size", "15")
.attr("type", "text")
.attr("value", d.y);
var button = div.append("button")
.text("Submit/Hide")
.on("click", function() {
d3.select(self).attr("x", function(d) {
return d.x = +xPosInput.node().value
}).attr("y", function(d) {
return d.y = +yPosInput.node().value
});
d3.select("#text" + i).text(function(d) {
return "Label: " + (d.label = labelInput.node().value);
})
.attr("x", function(d) {
return d.x = +xPosInput.node().value + 10
}).attr("y", function(d) {
return d.y = +yPosInput.node().value + 10
});
d3.select("#rectInfo").selectAll("*").remove();
d3.select("#rectInfo").style("opacity", 0);
})
rectInfoActive = true;
});
// END OF FORM
// Rectangle Label
rects.append("text")
.attr("id", function(d, i) {
return "text" + 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
});
// Misc functions -------------------------------------------------------------
// clearTheForm ----
// Clear the form and input values. This will later become the Update function
// that will update changed values back into the JSON array.
#rectInfo {
background-color: white;
position: relative;
padding: 10px;
width: 230px;
height: 100px;
border: 2px;
outline: grey solid thin;
}
#rectInfo p {
margin: 4px;
}
.formLabel {
font-family: courier;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- Click on a shape to see its label, x, y pos.
Submit button clears the div (not working here in fiddle)
but should be changed to instead call a fnt that updates the data with values changed in the form.
-->
<div id="rectInfo" style="opacity:0">
<!-- Rect info will appear here -->
</div>