SVG Text Wrapping
A modification from the D3Plus library to allow SVG text wrapping.
HTML
<svg>
<!-- Text that will use the D3plus default wrapping. -->
<text class="type" dy="15px" x="75px">Wrapped</text>
<rect class="shape" height="150px" width="150px" y="50px"></rect>
<text id="rectWrap" class="wrap" y="50px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.aaaaaaaaaaaaaaaaaa</text>
<circle class="shape" r="75px" cx="75px" cy="300px"></circle>
<text id="circleWrap" class="wrap" y="225px" x="0px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>
<!-- Text that D3plus will resize to fit the available space. -->
<text class="type" dy="15px" x="275px">Resized + Wrapped</text>
<rect class="shape" height="150px" width="150px" y="50px" x="200px"></rect>
<text id="rectResizeWrap" class="wrap" y="50px" x="200px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.aaaaaaaaaaa</text>
<circle class="shape" r="75px" cx="275px" cy="300px"></circle>
<text id="circleResizeWrap" class="wrap" y="225px" x="200px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>
<!-- Text that D3plus will resize to fit the available space. -->
<text class="type" dy="15px" x="475px">Resized </text>
<rect class="shape" height="150px" width="150px" y="50px" x="400px"></rect>
<text id="rectResize" class="wrap" y="50px" x="400px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>
<circle class="shape" r="75px" cx="475px" cy="300px"></circle>
<text id="circleResize" class="wrap" y="225px" x="400px" font-size="12">Here is a long text string that SVG should wrap by default, but it does not.</text>
<!-- For comparison, how SVG would display the text without D3plus. -->
<text class="type" dy="15px"...
CSS
svg {
font-family:"Helvetica", "Arial", sans-serif;
height: 400px;
margin: 25px;
width: 1300px;
border: thin solid red;
}
.type {
fill: #888;
text-anchor: middle;
}
.shape {
fill: #eee;
stroke: #ccc;
}
JavaScript
var d3plus = {};
d3plus.textwrap = function() {
var _resize = false; // Should the text be resized in the container?
var _wrap = false; // Should the text be wrapped in the container?
var _textElement; // Represents the text element that will have the wrapping applied
var _x; // The offset x-position
var _y; // The offset y-position
var _width; // The maximum width that should be afforded for text rendering
var _height; // The maximum height that should be afforded for text rendering
var _alignment = "center";
var _rotate = 0;
var _size;
var _valign = null;
var _innerHeight;
var _innerWidth;
var _padding = null;
// Calculates the sizes of the words that we need to render when put into SVG
function fontSizes(vars, maxSize) {
var sizes = [];
var svg = d3.select("body").append("svg");
// Create some spans such that we can work out the length of the various words
var tspans = svg.append("text")
.selectAll("tspan")
.data(vars.words)
.enter()
.append("tspan")
.attr("left", "0px")
.attr("position", "absolute")
.attr("top", "0px")
.attr("x", 0)
.attr("y", 0)
.style("font-size", maxSize + "px")
.text(function(d) {
return d;
})
.each(function(d) {
var width = this.getComputedTextLength();
var height = this.offsetHeight || this.getBoundingClientRect().height || this.parentNode.getBBox().height;
var children = d3.select(this).selectAll("tspan");
if (children.size()) {
alert("didn't expect to get here");
...