d3不向绑定的rect显示初始数据 [英] d3 not displaying initial data to bound rects
问题描述
我有一个初始的对象数组,即我的数据.调用一个名为render()
的函数,该函数应首先显示绑定到该数据的矩形.但是我没有看到任何矩形.
然后,如果单击这些矩形中的任何一个,则会调用函数removeElement
,该函数将从数组中删除该矩形的数据,然后调用render()
并使用新数据执行该函数.
如果在任意位置单击svg,则将新数据元素添加到数据中,然后再次调用render,该渲染应根据新数据再次显示矩形.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/*.active {
stroke: #000;
stroke-width: 2px;
}*/
svg {
border: 1px solid black;
}
</style>
<svg width="800" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {
top: 20,
right: 20,
bottom: 20,
left: 20
},
width = 840 - margin.left - margin.right,
height = 640 - margin.top - margin.bottom;
var svg = d3.select("svg");
var data = [{
x: 100
}, {
x: 300
}, {
x: 400
}, {
x: 600
}];
var ind = 0;
var groove = svg.append("g")
.attr("class", "groove_group");
groove.append("rect")
.attr("x", 0)
.attr("y", 150)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", width)
.style("fill", "grey");
groove.append("rect")
.attr("x", 2)
.attr("y", 152)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
render();
function render() {
// create group
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
group.exit().remove();
group.enter().append("g")
.attr("class", "group")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
group.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 100)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'handle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black");
group.append("text")
.attr("x", function(d, i) {
if (i == 0) { // first element
return ((data[i].x / 2));
} else {
return (data[i].x - (data[i].x - data[i - 1].x) / 2);
}
})
.attr("y", 100)
.attr("text-anchor", "middle")
.style("fill", "black")
.attr('id', function(d, i) {
return 'text_' + i;
})
.text(function(d, i) {
if (i == 0) { // first set
return i + ": " + (data[i].x) + "m";
} else {
return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
}
});
}
svg.on("click", function() {
var coords = d3.mouse(this);
getPosition(ind, coords[0]);
render();
});
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d, i) {
if (i == 0) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x / 2))
.text(function(d) {
return i + " " + d3.event.x
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else if (i == data.length - 1) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
.text(function(d) {
return (i + 1) + ": " + (width - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else {
d3.select("#text_" + i)
.attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
}
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d, i) {
d3.event.stopPropagation();
data = data.filter(function(e) {
return e != d;
});
d3.select(this)
.remove();
render();
}
function getPosition(ind, coords) {
if (coords[0] > data[ind].x) {
getPosition(++ind);
} else {
data.splice(1, 0, {
x: coords
});
}
}
</script>
任何帮助将不胜感激,
如果您查看group
...
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
...您将看到它只是一个更新"选择.此处没有没有 SVG <g>
元素.因此,这...
group.append("rect")
//etc...
没有效果.
解决方案:使用merge()
功能或适当的回车选择:
var groupEnter = group.enter()
.append("g")
.attr("class", "group");
groupEnter.append("rect")
//etc...
这是更新的代码:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/*.active {
stroke: #000;
stroke-width: 2px;
}*/
svg {
border: 1px solid black;
}
</style>
<svg width="800" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {
top: 20,
right: 20,
bottom: 20,
left: 20
},
width = 840 - margin.left - margin.right,
height = 640 - margin.top - margin.bottom;
var svg = d3.select("svg");
var data = [{
x: 100
}, {
x: 300
}, {
x: 400
}, {
x: 600
}];
var ind = 0;
var groove = svg.append("g")
.attr("class", "groove_group");
groove.append("rect")
.attr("x", 0)
.attr("y", 150)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", width)
.style("fill", "grey");
groove.append("rect")
.attr("x", 2)
.attr("y", 152)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
render();
function render() {
// create group
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
group.exit().remove();
var groupEnter = group.enter().append("g")
.attr("class", "group");
groupEnter.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
groupEnter.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 100)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'handle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black");
groupEnter.append("text")
.attr("x", function(d, i) {
if (i == 0) { // first element
return ((data[i].x / 2));
} else {
return (data[i].x - (data[i].x - data[i - 1].x) / 2);
}
})
.attr("y", 100)
.attr("text-anchor", "middle")
.style("fill", "black")
.attr('id', function(d, i) {
return 'text_' + i;
})
.text(function(d, i) {
if (i == 0) { // first set
return i + ": " + (data[i].x) + "m";
} else {
return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
}
});
}
svg.on("click", function() {
var coords = d3.mouse(this);
getPosition(ind, coords[0]);
render();
});
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d, i) {
if (i == 0) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x / 2))
.text(function(d) {
return i + " " + d3.event.x
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else if (i == data.length - 1) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
.text(function(d) {
return (i + 1) + ": " + (width - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else {
d3.select("#text_" + i)
.attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
}
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d, i) {
d3.event.stopPropagation();
data = data.filter(function(e) {
return e != d;
});
d3.select(this)
.remove();
render();
}
function getPosition(ind, coords) {
if (coords[0] > data[ind].x) {
getPosition(++ind);
} else {
data.splice(1, 0, {
x: coords
});
}
}
</script>
PS:您的代码仍然有很多问题(我可以在这里预见未来的问题)...这个答案仅在仅处理有关输入"选择的主要问题. >
I have an initial array of object which is my data. A function called render()
is called which should first display rectangles bound to this data. But I am not seeing any rectangles.
Then if any of these rectangles is clicked a function removeElement
is called, which removes that rectangle's data from the array and then calls render()
and executes it using the new data.
If the svg is clicked on anywhere a new data element is added to the data, and again render is called which should display the rectangles again according to the new data.
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/*.active {
stroke: #000;
stroke-width: 2px;
}*/
svg {
border: 1px solid black;
}
</style>
<svg width="800" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {
top: 20,
right: 20,
bottom: 20,
left: 20
},
width = 840 - margin.left - margin.right,
height = 640 - margin.top - margin.bottom;
var svg = d3.select("svg");
var data = [{
x: 100
}, {
x: 300
}, {
x: 400
}, {
x: 600
}];
var ind = 0;
var groove = svg.append("g")
.attr("class", "groove_group");
groove.append("rect")
.attr("x", 0)
.attr("y", 150)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", width)
.style("fill", "grey");
groove.append("rect")
.attr("x", 2)
.attr("y", 152)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
render();
function render() {
// create group
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
group.exit().remove();
group.enter().append("g")
.attr("class", "group")
.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
group.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 100)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'handle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black");
group.append("text")
.attr("x", function(d, i) {
if (i == 0) { // first element
return ((data[i].x / 2));
} else {
return (data[i].x - (data[i].x - data[i - 1].x) / 2);
}
})
.attr("y", 100)
.attr("text-anchor", "middle")
.style("fill", "black")
.attr('id', function(d, i) {
return 'text_' + i;
})
.text(function(d, i) {
if (i == 0) { // first set
return i + ": " + (data[i].x) + "m";
} else {
return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
}
});
}
svg.on("click", function() {
var coords = d3.mouse(this);
getPosition(ind, coords[0]);
render();
});
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d, i) {
if (i == 0) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x / 2))
.text(function(d) {
return i + " " + d3.event.x
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else if (i == data.length - 1) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
.text(function(d) {
return (i + 1) + ": " + (width - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else {
d3.select("#text_" + i)
.attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
}
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d, i) {
d3.event.stopPropagation();
data = data.filter(function(e) {
return e != d;
});
d3.select(this)
.remove();
render();
}
function getPosition(ind, coords) {
if (coords[0] > data[ind].x) {
getPosition(++ind);
} else {
data.splice(1, 0, {
x: coords
});
}
}
</script>
Any help would be greatly appreciated,
If you look at group
...
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
... you'll see that it is just an "update" selection. There is no SVG <g>
element being appended here. Thus, this...
group.append("rect")
//etc...
Has no effect.
Solution: Use a merge()
function or a proper enter selection:
var groupEnter = group.enter()
.append("g")
.attr("class", "group");
groupEnter.append("rect")
//etc...
Here is the updated code:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
/*.active {
stroke: #000;
stroke-width: 2px;
}*/
svg {
border: 1px solid black;
}
</style>
<svg width="800" height="300"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
var margin = {
top: 20,
right: 20,
bottom: 20,
left: 20
},
width = 840 - margin.left - margin.right,
height = 640 - margin.top - margin.bottom;
var svg = d3.select("svg");
var data = [{
x: 100
}, {
x: 300
}, {
x: 400
}, {
x: 600
}];
var ind = 0;
var groove = svg.append("g")
.attr("class", "groove_group");
groove.append("rect")
.attr("x", 0)
.attr("y", 150)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 6)
.attr("width", width)
.style("fill", "grey");
groove.append("rect")
.attr("x", 2)
.attr("y", 152)
.attr("rx", 2)
.attr("ry", 2)
.attr("height", 2)
.attr("width", 796)
.style("fill", "black");
render();
function render() {
// create group
var group = svg.selectAll(null)
.data(data, function(d) {
return d.x
});
group.exit().remove();
var groupEnter = group.enter().append("g")
.attr("class", "group");
groupEnter.call(d3.drag()
.on("start", dragstarted)
.on("drag", dragged)
.on("end", dragended))
.on("click", removeElement);
groupEnter.append("rect")
.attr("x", function(d) {
return d.x;
})
.attr("y", 100)
.attr("height", 100)
.attr("width", 15)
.style("fill", "lightblue")
.attr('id', function(d, i) {
return 'handle_' + i;
})
.attr("rx", 6)
.attr("ry", 6)
.attr("stroke-width", 2)
.attr("stroke", "black");
groupEnter.append("text")
.attr("x", function(d, i) {
if (i == 0) { // first element
return ((data[i].x / 2));
} else {
return (data[i].x - (data[i].x - data[i - 1].x) / 2);
}
})
.attr("y", 100)
.attr("text-anchor", "middle")
.style("fill", "black")
.attr('id', function(d, i) {
return 'text_' + i;
})
.text(function(d, i) {
if (i == 0) { // first set
return i + ": " + (data[i].x) + "m";
} else {
return i + ": " + ((data[i].x - data[i - 1].x)) + "m";
}
});
}
svg.on("click", function() {
var coords = d3.mouse(this);
getPosition(ind, coords[0]);
render();
});
function dragstarted(d) {
d3.select(this).raise().classed("active", true);
}
function dragged(d, i) {
if (i == 0) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x / 2))
.text(function(d) {
return i + " " + d3.event.x
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + " " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else if (i == data.length - 1) {
d3.select("#text_" + i)
.attr("x", d.x = (d3.event.x - data[i - 1].x) / 2 + data[i - 1].x)
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + (width - d3.event.x) / 2)
.text(function(d) {
return (i + 1) + ": " + (width - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
} else {
d3.select("#text_" + i)
.attr("x", d.x = d3.event.x - ((d3.event.x - data[i - 1].x) / 2))
.text(function(d) {
return i + ": " + (d3.event.x - data[i - 1].x) + "m"
});
d3.select("#text_" + (i + 1))
.attr("x", d.x = d3.event.x + ((data[i + 1].x - d3.event.x) / 2))
.text(function(d) {
return (i + 1) + ": " + (data[i + 1].x - d3.event.x) + "m"
});
d3.select(this).select("rect")
.attr("x", d.x = d3.event.x);
}
}
function dragended(d) {
d3.select(this)
.classed("active", false);
}
function removeElement(d, i) {
d3.event.stopPropagation();
data = data.filter(function(e) {
return e != d;
});
d3.select(this)
.remove();
render();
}
function getPosition(ind, coords) {
if (coords[0] > data[ind].x) {
getPosition(++ind);
} else {
data.splice(1, 0, {
x: coords
});
}
}
</script>
PS: Your code still have a lot of problems (and I can foresee future questions here)... This answer is dealing only with the main issue regarding the "enter" selection.
这篇关于d3不向绑定的rect显示初始数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!