Javascript CSS基本多面板图形布局D3.js
我正在尝试为D3中的多面板图创建自定义布局。布局应为3列宽,前2列拆分为两行。最终结果应该是左侧有4个大小相等的矩形,右侧有一个从上到下的柱(右侧栏)。我已尝试使用以下代码执行此操作:Javascript CSS基本多面板图形布局D3.js,javascript,html,css,d3.js,Javascript,Html,Css,D3.js,我正在尝试为D3中的多面板图创建自定义布局。布局应为3列宽,前2列拆分为两行。最终结果应该是左侧有4个大小相等的矩形,右侧有一个从上到下的柱(右侧栏)。我已尝试使用以下代码执行此操作: <!DOCTYPE html> var数据集; var quadhight=“289”; var quadwidth=“450”; var maincontainer=d3.选择(“主体”) .附加(“div”) .attr(“类”、“主容器”) .attr(“id”,“主控”);
<!DOCTYPE html>
var数据集;
var quadhight=“289”;
var quadwidth=“450”;
var maincontainer=d3.选择(“主体”)
.附加(“div”)
.attr(“类”、“主容器”)
.attr(“id”,“主控”);
var ltq=maincontainer
.append(“svg”)
.attr(“id”,“左上象限”)
.attr(“宽度”,四倍宽度)
.attr(“高度”,四倍高度)
.attr(“类”、“象限”);
var rtq=maincontainer
.append(“svg”)
.attr(“id”,“右上象限”)
.attr(“宽度”,四倍宽度)
.attr(“高度”,四倍高度)
.attr(“类”、“象限”);
变量菜单=d3。选择(“主体”)
.附加(“div”)
.attr(“id”,“菜单div”);
var lbq=主容器
.append(“svg”)
.attr(“id”,“左下象限”)
.attr(“宽度”,四倍宽度)
.attr(“高度”,四倍高度)
.attr(“类”、“象限”);
var rbq=主容器
.append(“svg”)
.attr(“id”,“右下象限”)
.attr(“宽度”,四倍宽度)
.attr(“高度”,四倍高度)
.attr(“类”、“象限”);
但是,我无法了解如何将侧栏(最后一列)放置在右侧。任何帮助都将不胜感激。由于我在前端开发方面缺乏经验,我意识到这可能不是实现相同结果的最佳解决方案,因此任何其他更好的解决方案都是不错的,包括简单的CSS/HTML解决方案(无需在D3.js中动态构建布局)
提前感谢,,
Tumaini使用当前代码,您可以正确构造象限元素,但没有将它们放置在任何位置。您可以使用代码并手动将每个象限放置在您想要的位置;然后再加上一个额外的a列,手动计算应该放在哪里。。。或者您可以使用D3布局的强大功能来帮助您: 设置布局 这是设置,在这里我强制布局以固定高度600px填充整个主体元素的宽度。简单地说,D3布局只是一组预先构建的行为,它们以特定的方式作用于您提供的数据,我选择使用分区布局,因为这与您想要实现的大致匹配
var body = d3.select('body'),
w = body[0][0].offsetWidth,
h = 600,
x = d3.scale.linear().range([0, w]),
y = d3.scale.linear().range([0, h]);
上面的设置非常直接,唯一奇怪的是我使用了d3.scale.linear()
来给我两个函数x
和y
。您可以很容易地计算要在这里使用的数学表达式,但是使用D3这样的库的目的是减少您自己的工作量。基本上,随后调用的结果函数x()
将把0
和1
之间传递的任何值转换为沿0
到w
比例的值(其中w
是body[0][0]点处的body宽度。计算了offsetWidth
)。除了范围在0
和h
之间之外,y
也是如此。因此,如果我执行x(0.5)
,返回的结果值将是w
的一半。这些函数也将在0和1之外工作(因此名称刻度,如数字刻度),因此如果我调用y(2)
,返回值将等于2*h
,即1200
本节的其余部分只是附加和设置一些包装元素的样式,除了.value(函数(d){return d.size;})
部分。如果您实际使用分区布局来显示值之间的视觉差异,则会使用此位,但实际情况并非如此,因此它实际上对该代码没有影响。它存在的唯一原因是分区布局需要为其每个矩形/项定义一个值,没有它就无法正确显示
var partition = d3.layout.partition()
.value(function(d) { return d.size; }),
visual = body
.append("div")
.attr("class", "chart")
.style("width", w + "px")
.style("height", h + "px")
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("g")
.classed("container", true);
为什么是分区,是什么?
基本上,我有点滥用分区布局来实现您的要求。分区布局以分层顺序用均匀宽度的单元填充可用空间;这些单元的高度受每个单元“值”和父单元拥有的兄弟单元数的影响。这里的解释更加雄辩:
分区布局生成邻接图:节点链接树图的空间填充变体。节点不是在层次中的父节点和子节点之间绘制链接,而是绘制为实体区域(圆弧或矩形),它们相对于其他节点的位置显示了它们在层次中的位置。节点的大小编码了一个在节点链接图中很难显示的量化维度
深入了解分区布局超出了这个问题的范围,真正最好的学习方法是自己动手制作一个示例或教程——D3网站上有几个不同可用布局的示例
您需要从上面了解的是,分区布局负责以比其父分区更小的垂直大小(通常以水平顺序)显示子分区
上述情况可以想象为:
+--------++--------++--------+
| || Child || Child |
| || A || of A |
| parent |+--------++--------+
| || Child || Child |
| || B || of B |
+--------++--------++--------+
一旦有了数据结构,就需要将其输入D3。下面的visual
对象是对外部包装SVG元素的引用,我们的所有其他元素都将添加到该元素中
在D3中,就像.attr
和.style
方法一样,您可以将.data()
绑定到选定的SVG元素组。如果给.data()
一个数组/项目列表,它会将每个数组项目应用于每个
var partition = d3.layout.partition()
.value(function(d) { return d.size; }),
visual = body
.append("div")
.attr("class", "chart")
.style("width", w + "px")
.style("height", h + "px")
.append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("g")
.classed("container", true);
------> working direction is left to right by default.
+--------++--------++--------+
| || Child |+--------+ <-- even smaller children
| || One |+--------+
| parent |+--------++--------+
| || Child |+--------+
| || Two |+--------+
+--------++--------++--------+
var root = {
"name": "full column",
"class": "full-col",
"children": [
{
"name": "top right quad",
"class": "quad",
"size": 1,
"children": [{
"name": "top left quad",
"size": 1,
"class": "quad"
}]
},
{
"name": "bottom right quad",
"class": "quad",
"size": 1,
"children": [{
"name": "top left quad",
"size": 1,
"class": "quad"
}]
}
]
};
+--------++--------++--------+
| || Child || Child |
| || A || of A |
| parent |+--------++--------+
| || Child || Child |
| || B || of B |
+--------++--------++--------+
/// must run this first to prep the root object with .dx and .dy
var g = visual.selectAll("g").data(partition.nodes(root)),
kx = w / root.dx,
ky = h / 1;
/// for each data item, append a g element
var ge = g.enter()
.append("svg:g")
.attr("transform", function(d) {
/// calculate the cells position in our layout
return "translate(" + (-x(d.y)) + "," + y(d.x) + ")";
});
/// for each item append a rectangle
ge.append("svg:rect")
.attr("width", root.dy * kx)
.attr("height", function(d) { return d.dx * ky; })
.attr("class", function(d) { return d["class"]; });
/// for each item append some text
ge.append("svg:text")
.attr("transform", function(d) {
return "translate(8," + d.dx * ky / 2 + ")";
})
.attr("dy", ".35em")
.text(function(d) { return d.name; });
/// force the layout to work from the right side to left
visual.attr("transform", "translate("+(w - root.dy * kx)+",0)")
+----------------------+
| svg +----------------------+
| | visual container |
| +------+------+|+------+ |
| |Cell |Cell |||Cell | |
| | | ||| | |
| +------+------+|| | |
| |Cell |Cell ||| | |
| | | ||| | |
| +------+------+|+------+ |
| +----------------------+
+----------------------+
+----------------------+
| svg +----------------------+
| | visual container |
|+------+------+|+------+ |
||Cell |Cell |||Cell | |
|| | ||| | |
|+------+------+|| | |
||Cell |Cell ||| | |
|| | ||| | |
|+------+------+|+------+ |
| +----------------------+
+----------------------+