Popup Form To Edit Shape Position And Label?
Solution 1:
In D3 it's quite simple to override the datum. Inside the listener where d
is the first parameter, just do:
d.foo = bar;
In your example, let's use prompt
to get the new values. This is just a demo to show you how to do it: you can easily change the ugly prompts for fancy popup divs.
So, inside the listener, we get the new values...
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: ");
... and use them to reposition the rectangles, overriding the datum at the same time:
d3.select(this)
.attr("x", d.x = +newX)
.attr("y", d.y = +newY);
The only problem is getting the labels. As you have to go up and down in the DOM, I suggest you to give them (unique) ids...
rects.append("text")
.attr("id", function(d, i) {
return"label" + i;
})
... and them getting them:
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;
});
Here is your code with those changes only:
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
});
<scriptsrc="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Have in mind that this is a very, very simple demo: I'm neither checking the type of the input (string, integer, float...) nor their values.
PS: If you were using D3 v4 (that, with your code, requires no change at all!), you could avoid the new-positioned rectangle going behind the other ones with a simple selection.raise()
.
Post a Comment for "Popup Form To Edit Shape Position And Label?"