利用Mike Bostock’s Wrapping Long Labels function我能够在D3.js中包装长文本标签。但是我发现当我需要将特定文本包装成两行以上时,我的D3图表会插入额外的新行。没有这些额外的新线路,请你帮我装一下吗?
这是我的标签数据和Mike Bostock的代码。
treeData = {
'name': 'Good Short Label',
'parent': 'null',
'_children': [
{'name': 'Very Very Long Good Wapped Label'},
{'name': 'Very Very Very Very Very Very Very Very Very Long Label With Extra New Line'},
{'name': 'Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Long Label With Extra New Lines'}
]
};
function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
x = text.attr('x'),
y = text.attr('y'),
dy = 0, //parseFloat(text.attr('dy')),
tspan = text.text(null)
.append('tspan')
.attr('x', x)
.attr('y', y)
.attr('dy', dy + 'em');
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(' '));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(' '));
line = [word];
tspan = text.append('tspan')
.attr('x', x)
.attr('y', y)
.attr('dy', ++lineNumber * lineHeight + dy + 'em')
.text(word);
}
}
});
}
以下是复制此内容的jsfiddle link。
答案 0 :(得分:2)
不要增加lineHeight变量
.attr('dy', ++lineNumber * lineHeight + dy + 'em') // add a newline multiple times
.attr('dy', lineHeight + dy + 'em') // adds only one new line
var treeData = {
'name': 'Good Short Label',
'parent': 'null',
'_children': [
{'name': 'Very Very Long Good Wapped Label'},
{'name': 'Very Very Very Very Very Very Very Very Very Long Label With Extra New Line'},
{'name': 'Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Very Long Label With Extra New Lines'}
]
};
var margin = {top: 20, right: 120, bottom: 20, left: 200};
var width = 950 - margin.right - margin.left;
var height = 800 - margin.top - margin.bottom;
var i = 0;
var duration = 750;
var root;
var tree = d3.layout.tree().size([height, width]);
var diagonal = d3.svg.diagonal()
.projection(function (d) {
return [d.y, d.x];
});
var svg = d3.select('#tree').append('svg')
.attr('width', width + margin.right + margin.left)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
root = treeData;
root.x0 = height / 2;
root.y0 = 0;
update(root);
d3.select(self.frameElement).style('height', '800px');
function update(source) {
// Compute the new tree layout.
var nodes = tree.nodes(root).reverse();
var links = tree.links(nodes);
// Normalize for fixed-depth.
nodes.forEach(function (d) {
d.y = d.depth * 180;
});
// Update the nodes…
var node = svg.selectAll('g.node')
.data(nodes, function (d) {
return d.id || (d.id = ++i);
});
// Enter any new nodes at the parent's previous position.
var nodeEnter = node.enter().append('g')
.attr('class', 'node')
.attr('transform', function (d) {
return 'translate(' + source.y0 + ',' + source.x0 + ')';
})
.on('click', click);
nodeEnter.append('circle')
.attr('r', 1e-6)
.style('fill', function (d) {
return d._children ? '#ccff99' : '#fff';
});
nodeEnter.append('text')
.attr('x', function (d) {
return d.children || d._children ? -13 : 13;
})
.attr('dy', '.35em')
.attr('text-anchor', function (d) {
return d.children || d._children ? 'end' : 'start';
})
.text(function (d) {
return d.name;
})
.call(wrap, 150)
.style('fill-opacitsy', 1e-6)
.attr('class', function (d) {
if (d.url != null) {
return 'hyper';
}
})
.on('click', function (d) {
$('.hyper').attr('style', 'font-weight:normal');
d3.select(this).attr('style', 'font-weight:bold');
})
;
// Transition nodes to their new position.
var nodeUpdate = node.transition()
.duration(duration)
.attr('transform', function (d) {
return 'translate(' + d.y + ',' + d.x + ')';
});
nodeUpdate.select('circle')
.attr('r', 10)
.style('fill', function (d) {
return d._children ? '#ccff99' : '#fff';
});
nodeUpdate.select('text')
.style('fill-opacity', 1);
// Transition exiting nodes to the parent's new position.
var nodeExit = node.exit().transition()
.duration(duration)
.attr('transform', function (d) {
return 'translate(' + source.y + ',' + source.x + ')';
})
.remove();
nodeExit.select('circle')
.attr('r', 1e-6);
nodeExit.select('text')
.style('fill-opacity', 1e-6);
// Update the links…
var link = svg.selectAll('path.link')
.data(links, function (d) {
return d.target.id;
});
// Enter any new links at the parent's previous position.
link.enter().insert('path', 'g')
.attr('class', 'link')
.attr('d', function (d) {
var o = {x: source.x0, y: source.y0};
return diagonal({source: o, target: o});
});
// Transition links to their new position.
link.transition()
.duration(duration)
.attr('d', diagonal);
// Transition exiting nodes to the parent's new position.
link.exit().transition()
.duration(duration)
.attr('d', function (d) {
var o = {x: source.x, y: source.y};
return diagonal({source: o, target: o});
})
.remove();
// Stash the old positions for transition.
nodes.forEach(function (d) {
d.x0 = d.x;
d.y0 = d.y;
});
}
// Toggle children on click.
function click(d) {
if (d.children) {
d._children = d.children;
d.children = null;
} else {
d.children = d._children;
d._children = null;
}
update(d);
}
function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
x = text.attr('x'),
y = text.attr('y'),
dy = 0, //parseFloat(text.attr('dy')),
tspan = text.text(null)
.append('tspan')
.attr('x', x)
.attr('y', y)
.attr('dy', dy + 'em');
while (word = words.pop()) {
line.push(word);
tspan.text(line.join(' '));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(' '));
line = [word];
tspan = text.append('tspan')
.attr('x', x)
.attr('y', y)
.attr('dy', lineHeight + dy + 'em')
.text(word);
}
}
});
}

#vid-container {
width: 100%;
height: 100%;
width: 820px;
height: 461.25px;
float: none;
clear: both;
margin: 2px auto;
}
svg {
border-radius: 3px;
}
.node {
cursor: pointer;
}
.node circle {
fill: #fff;
stroke: #99ccff;;
stroke-width: 3px;
}
.node text {
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #99ccff;
stroke-width: 2px;
}
.hyper {
color: red;
text-decoration: underline;
}
.hyper:hover {
color: yellow;
text-decoration: none;
}
.selected {
font-weight: bold;
}
.not-selected {
font-weight: normtal;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id='tree'></div>
&#13;