我是d3的经验丰富的新手程序员。我希望创建一个交互式分层布局,用户可以在其中钻取到每个对象,并在原始对象的“框”内打开嵌套对象。例如,单击某个矩形将显示该父矩形的子项,而单独保留未单击的父矩形(或最终将它们暂时淡出,等等)。我们的想法是遵循与zoomable icicle example类似的逻辑,但最初只显示加载时的最高级别,然后在单击父级时打开较低级别。 Here是我到目前为止,点击矩形“一”应该在矩形“一”的框内显示其他矩形(例如,“One_A”和“One_B”)(现在,点击只是转动矩形紫色)。如果我遗漏了一些基本的东西,请提前道歉。我想可能有更简单的方法(可能是jquery)而不是d3,但我希望最终在层次结构中进一步包含嵌套的数据驱动元素,这就是为什么我要尝试用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);