我是一名新手程序员,d3 经验有限。我希望创建一个交互式分层布局,用户可以在其中钻入每个对象并在原始对象的“框”内打开嵌套对象。例如,单击某个矩形将显示该父矩形的子矩形,而单独留下未单击的父矩形(或最终将它们暂时淡出等)。我们的想法是遵循与可缩放冰柱示例类似的逻辑,但最初仅在加载时显示最高级别的层次结构,然后在单击父级时打开较低级别。 这里到目前为止,单击矩形“One”应该会在矩形“One”的框中显示其他矩形(例如,“One_A”和“One_B”)(现在,单击只会将矩形变为紫色)。如果我错过了一些基本的东西,请提前道歉。我想可能有比使用 d3 更简单的方法(可能是 jquery),但我希望最终将嵌套的数据驱动元素进一步合并到层次结构的下方,这就是为什么我尝试使用 d3 来完成这一切的原因。我应该在每个最高级别的矩形中添加 SVG 组并使用事件侦听器“激活”子组吗?还是使用分层布局方法?还是两者的某种组合?任何帮助将不胜感激!
这是到目前为止的代码:
//Make the overall SVG Container
var svgContainer = d3.select("body").append("svg")
.attr("width", 1200)
.attr("height", 1200);
//Make group for the highest level of rectangles
var rectsGroup = svgContainer.append("g");
//Data for the highest level of rectangles
var rectData = [
{ "x": 10, "y": 10, "width": 0, "height": 0, "fill": "blue", "label": "One" },
{ "x": 310, "y": 10, "width": 0, "height": 0, "fill": "red", "label": "Two" },
{ "x": 10, "y": 310, "width": 0, "height": 0, "fill": "green", "label": "Three" },
{ "x": 310, "y": 310, "width": 0, "height": 0, "fill": "orange", "label": "Four" }];
//Data for the second-highest level of rectangles within one rectangle?
var rectOneData = [
{ "x": 10, "y": 10, "width": 150, "height": 150, "fill": "purple", "label": "One_A" }];
//Creating the 4 highest-level rectangles in the group within the main SVG container
var rects = rectsGroup.selectAll("rect")
.data(rectData)
.enter()
.append("rect");
var rectOne = rectsGroup.select('[id="One"]')
.append("g");
//Add the attributes
var rectAttributes = rects
.attr("x", function (d) { return d.x - 155; })
.attr("y", function (d) { return d.y - 155; })
.attr("width", function (d) { return d.width; })
.attr("height", function (d) { return d.height; })
.style("fill", function (d) { return d.fill; })
.attr("id", function (d) { return d.label; })
.on("mouseover", function() {
console.log(this);
console.log(d3.select.this);
d3.select(this).transition().style("fill", "yellow");
})
.on("mouseout", function() {
console.log(this);
console.log(d3.select.this);
d3.select(this).transition().style("fill", function (d) { return d.fill; });
})
.transition()
.attr("x", function (d) { return d.x ; })
.attr("y", function (d) { return d.y ; })
.attr("width",300)
.attr("height",300)
.duration(1500)
.delay(10);
//Acting on a particular SVG object on click...
var rectReceivingAttributes = d3.select('[id="One"]')
.attr("id", function (d) { return d.label; })
.attr("x", function (d) { return d.x ; })
.attr("y", function (d) { return d.y ;})
.attr("width", function (d) { return d.width ; })
.attr("height", function (d) { return d.height ; })
.on("click", function() {
rectsGroup.select('[id="One"]').transition().style("fill", "purple")});
var text = rectsGroup.selectAll("text")
.data(rectData)
.enter()
.append("text");
var textLabels = text
.attr("x", function(d) { return d.x + 155; })
.attr("y", function(d) { return d.y + 155; })
.text( function (d) { return d.label;})
.attr("font-family", "sans-serif")
.attr("font-size", "20px")
.attr("fill", "black")
.attr("text-anchor", "middle")
.attr("opacity", 0)
.transition()
.attr("opacity", 100)
.duration(3000)
.delay(1000);