0

我是一名新手程序员,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);
4

0 回答 0