在上一个问题中,我问过如何为生成的矩形here
生成唯一ID现在,我一直在尝试在这些矩形内绘制小矩形。但是,id="rectup0"
只能有4个具有唯一xlink:href
属性的小型矩形
其余的可以在里面有2个矩形。
<body>
<div id="chart">
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.3.0/d3.js"></script>
<script type="text/javascript">
var width = 1000,
height = 250,
margin = 7,
nRect = 11,
rectWidth = (width - (nRect - 1) * margin) / nRect,
svgContainer = d3.select('#chart').append('svg')
.attr('width', width)
.attr('height', height),
svgWalkway = d3.select('#chart').append('svg')
.attr('width', '1000')
.attr('height', '150'),
svgContainer2 = d3.select('#chart').append('svg')
.attr('width', width)
.attr('height', height);
// Rectangles scaling
var firstRow = d3.range(nRect),
posxScale = d3.scaleLinear()
.domain(d3.extent(firstRow))
.range([0, width - rectWidth]);
var middleRow = d3.range(1),
posxScale3 = d3.scaleLinear()
.domain(d3.extent(middleRow))
.range([0, width - rectWidth]);
var secondRow = d3.range(nRect),
posxScale2 = d3.scaleLinear()
.domain(d3.extent(secondRow))
.range([0, width - rectWidth]);
//Drawing the actual objects HTML rects
svgContainer.selectAll('rect.up')
.data(firstRow)
.enter()
.append('rect')
.attr("id", function(d,i){ return "rectup" + i })
.attr('x', posxScale)
.attr('width', rectWidth)
.attr('height', height)
.attr('class','up');
svgWalkway.selectAll('rect.middle')
.data(middleRow)
.enter()
.append('rect')
.attr('x', posxScale3)
.attr('width','1000')
.attr('height','150')
.attr('class', 'middle');
svgContainer2.selectAll('rect.down')
.data(secondRow)
.enter()
.append('rect')
.attr('id', function (d,i) { return "rectdown" + i })
.attr('x', posxScale2)
.attr('width', rectWidth)
.attr('height', height)
.attr('class', 'down')
.attr('y', 0);
</script>
</div>
</body>
我尝试绘制类似前面的矩形(使用.append()
),但到目前为止只是将它们放在svgContainer
旁边。我一直在阅读一些关于使用分组的帖子,试过但没有用。提前致谢
更新
所以基本上,整个问题可以恢复为在 rect
之后向添加rect id="rectup0"
标记,以便我可以
<rect id="rectup0"></rect>
<rect id="redrect" x="0" width="20" height="40"></rect>
我知道JQuery
允许您将类属性添加到其他类,但不确定D3,这将类似于以编程方式添加新的rect
标记。甚至可能吗?
更新2
我想可以d3.insert
使用以下内容:
d3.select('#rectup0').insert('rect')
.attr('id', 'redrect')
.attr('x', 0)
.attr('width', '20')
.attr('height', '40');
然而,它会在开头的中间得到它并关闭rect
标签,如此
<rect id="rectup0">
<rect id="redrect" x="0" width="20" height="40"></rect>
</rect>
毋庸置疑,由于结束rect
代码
答案 0 :(得分:0)
您可以使用each
包装器为所选数据执行此操作。它接受3个参数:当前数据d
,当前索引i
和整个数据数组arr
。所以如果你需要某种检查,你是否应该附加小rect
,你可以创建一个辅助函数:
var testIndex = function(d, i, arr) {
return
// test index
i == 5 ||
// test current data
d == 10 ||
// test other array members, which would be an EnterNode here
(i > 0 && arr[i - 1]['__data__'] == 7);
}
// do checks in one line:
var testIndex = function (d, i, arr) { return i == 4 || i == 10 || i == 7; }
var data = svgContainer.selectAll('rect.up')
.data(firstRow);
data
.enter()
.each(function (d, i, arr) {
// select DOM element to add the rects
t = d3.select(this);
t
.append('rect')
// note that here we use empty the parameters list
.attr('id', 'rectup' + i)
.attr('x', posxScale)
.attr('width', rectWidth)
.attr('height', height)
.attr('class','up');
if (!testIndex(d, i, arr)) {
return;
}
t
.append('rect')
.attr('id', 'redrect' + i)
// note that we need to define x-coord similar to first rect
.attr('x', posxScale)
.attr('class', 'redrect');
});
// remove your data before redraw
data
.exit()
.remove();
输出:
<svg width="1000" height="250">
<rect id="rectup0" x="0" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup1" x="91.54545454545456" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup2" x="183.09090909090912" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup3" x="274.6363636363636" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup4" x="366.18181818181824" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup5" x="457.72727272727275" width="84.54545454545455" height="250" class="up"></rect>
<rect id="redrect5" x="457.72727272727275" class="redrect"></rect>
<rect id="rectup6" x="549.2727272727273" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup7" x="640.8181818181818" width="84.54545454545455" height="250" class="up"></rect>
<rect id="redrect7" x="732.3636363636365" class="redrect"></rect>
<rect id="rectup8" x="732.3636363636365" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup9" x="823.909090909091" width="84.54545454545455" height="250" class="up"></rect>
<rect id="rectup10" x="915.4545454545455" width="84.54545454545455" height="250" class="up"></rect>
<rect id="redrect10" x="915.4545454545455" class="redrect"></rect>
</svg>
此方法的缺点是您无法提供attr
参数作为JSON:
// wouldn't work
.attr({
id: 'redrect',
x: posxScale,
width: '20',
height: '40'
});