我正在使用CodePen的代码作为基础,根据我的需求构建甘特图。但是,我试图修改代码,以便实际的Rectangle高度适应给予它们的文本。在所示的示例中,所有任务文本都是一个字长,因此它们适合矩形。但是,如果任务长度为几个字且矩形宽度较短,则文本不会换行并溢出。
我如何修改代码以便绘制矩形高度以适合其中的文本,或者使用文本换行并使矩形增长(高度)以容纳文本?
现在,CodePen示例中的矩形高度是硬编码的:
var barHeight = 20;
该示例还以如下方式将文本添加到矩形(参见下文)。我试图将html放在矩形而不是文本中无效:
var rectText = rectangles.append("text")
.text(function(d){
return d.task;
})
答案 0 :(得分:1)
你真的在问两个问题。一,如何包装文本然后两个,如何将矩形高度缩放到包装文本。
1。)M. Bostock here提供了包装文本的规范示例。
2。)要将rect的高度缩放到文本,可以使用.getBBox()
作为@BenLyall提示。首先包装文本,然后在文本节点上调用.getBBox()
并将高度应用于矩形。
这是一个完整的例子:
var someWidth = Math.random() * 250;
var longText = "Now is the time for all good men to come to the aid of their country";
var rect = g.append('rect')
.style('fill','steelblue')
.attr('width', someWidth) //<-- random width we don't know it
.attr('height', 1); // <-- start with arbitrary height
var txt = g.append('text')
.text(longText) //<-- our super long text
.attr('x', 4)
.attr('y', 10)
.attr('dy', '.71em')
.style('fill', 'white')
.call(wrap, someWidth); //<-- wrap it according to our width
var height = txt.node().getBBox().height + 15; //<-- get our height plus a margin
rect.attr('height', height); //<-- change our rect
这是一个有效的example。
答案 1 :(得分:0)
以下是您链接到的示例的修改版本。
http://codepen.io/anon/pen/JdyGGp
有趣的一点:
var innerRects = rectangles.append("g")
.attr("class", "rectangle");
innerRects.append("rect")
.attr("rx", 3)
.attr("ry", 3)
.attr("x", function(d){
return timeScale(dateFormat.parse(d.startTime)) + theSidePad;
})
.attr("y", function(d, i){
return i*theGap + theTopPad;
})
.attr("width", function(d){
return (timeScale(dateFormat.parse(d.endTime))-timeScale(dateFormat.parse(d.startTime)));
})
//.attr("height", theBarHeight)
.attr("stroke", "none")
.attr("fill", function(d){
for (var i = 0; i < categories.length; i++){
if (d.type == categories[i]){
return d3.rgb(theColorScale(i));
}
}
})
var rectText = innerRects.append("text")
.text(function(d){
return d.task;
})
.attr("x", function(d){
return (timeScale(dateFormat.parse(d.endTime))-timeScale(dateFormat.parse(d.startTime)))/2 + timeScale(dateFormat.parse(d.startTime)) + theSidePad;
})
.attr("y", function(d, i){
return i*theGap + 14+ theTopPad;
})
.attr("font-size", 11)
.attr("text-anchor", "middle")
.attr("text-height", theBarHeight)
.attr("fill", "#fff");
innerRects.each(function(r) {
var bBox = d3.select(this).select("text").node().getBBox();
d3.select(this).select("rect").attr("height", function(d) {
return bBox.height;
}).attr("y", function(d) {
return bBox.y;
});
});
我没有直接将rect
和text
元素直接添加到单个组中,而是为每个元素创建了一个新组,以便它们可以链接在一起,因为每个组都可以rect
我们需要找出height
对应的text
元素。
创建rect
和text
元素之后,我然后循环遍历我创建的g
元素并获取边界框({{1}}函数调用)并将关联的getBBox()
元素的height
设置为从边界框返回的rect
值。我还要设置height
的{{1}}元素以匹配。
此外,将y
和rect
元素组合在一起的新g
元素会破坏工具提示定位代码,因此会相应更新:
rect
这里的变化是:
text
以前,这是使用innerRects.on('mouseover', function(e) {
var tag = "";
if (d3.select(this).data()[0].details != undefined){
tag = "Task: " + d3.select(this).data()[0].task + "<br/>" +
"Type: " + d3.select(this).data()[0].type + "<br/>" +
"Starts: " + d3.select(this).data()[0].startTime + "<br/>" +
"Ends: " + d3.select(this).data()[0].endTime + "<br/>" +
"Details: " + d3.select(this).data()[0].details;
} else {
tag = "Task: " + d3.select(this).data()[0].task + "<br/>" +
"Type: " + d3.select(this).data()[0].type + "<br/>" +
"Starts: " + d3.select(this).data()[0].startTime + "<br/>" +
"Ends: " + d3.select(this).data()[0].endTime;
}
var output = document.getElementById("tag");
var item = d3.select(this).select("rect").node();
var x = (item.x.animVal.value + item.width.animVal.value/2) + "px";
var y = item.y.animVal.value + 25 + "px";
output.innerHTML = tag;
output.style.top = y;
output.style.left = x;
output.style.display = "block";
}).on('mouseout', function() {
var output = document.getElementById("tag");
output.style.display = "none";
});
来抓取 var item = d3.select(this).select("rect").node();
var x = (item.x.animVal.value + item.width.animVal.value/2) + "px";
var y = item.y.animVal.value + 25 + "px";
元素的this
和x
位置。由于这些代码现在与y
分组,因此需要更新代码以引用组中的rect
子元素。这段代码就是这样。
当你开始包装文本时,还有很多问题。背景矩形也需要动态增长以包含它们。我建议重构一下这个例子来解决这个问题。
您需要执行以下操作:
为所有text
添加占位符元素。对于背景和任务rect
,您应该能够提前设置rect
(背景rect
宽度只是包含元素的宽度。任务的宽度{ {1}}由任务的开始和结束日期设置。
使用任务width
的{{1}},您可以添加文本元素并以适当的宽度换行。 (此示例可能有助于执行http://bl.ocks.org/mbostock/7555321)
根据所有子rect
元素的计算rect
,返回并设置所有背景和任务width
的{{1}} s