Skip to content

Instantly share code, notes, and snippets.

@davelandry
Last active October 10, 2023 10:30
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 4 You must be signed in to fork a gist
  • Save davelandry/a39f0c3fc52804ee859a to your computer and use it in GitHub Desktop.
Save davelandry/a39f0c3fc52804ee859a to your computer and use it in GitHub Desktop.
SVG Text Wrapping

Using d3plus.textwrap, SVG <text> elements can be broken into separate <tspan> lines, as HTML does with <div> elements. In this example, the first column shows normal wrapped text, the second column shows text that is resized to fill the available space, and the third column shows the default SVG behavior.

D3plus automatically detects if there is a <rect> or <circle> element placed directly before the <text> container element in DOM, and uses that element's shape and dimensions to wrap the text. If it can't find one, or that behavior needs to be overridden, they can manually be specified using .shape( ), .width( ), and .height( ).

Featured on D3plus.org

<!DOCTYPE html>
<meta charset="utf-8">
<script src="//d3plus.org/js/d3.js"></script>
<script src="//d3plus.org/js/d3plus.js"></script>
<style>
svg {
font-family: "Helvetica", "Arial", sans-serif;
height: 425px;
margin: 25px;
width: 900px;
}
.type {
fill: #888;
text-anchor: middle;
}
.shape {
fill: #eee;
stroke: #ccc;
}
</style>
<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.
</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</text>
<rect class="shape" height="150px" width="150px" y="50px" x="200px"></rect>
<text id="rectResize" 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.
</text>
<circle class="shape" r="75px" cx="275px" cy="300px"></circle>
<text id="circleResize" 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>
<!-- For comparison, how SVG would display the text without D3plus. -->
<text class="type" dy="15px" x="475px">Default Behavior</text>
<rect class="shape" height="150px" width="150px" y="50px" x="400px"></rect>
<text 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 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>
</svg>
<script>
// Wrap text in a rectangle.
d3plus.textwrap()
.container(d3.select("#rectWrap"))
.draw();
// Wrap text in a rectangle, and size the text to fit.
d3plus.textwrap()
.container(d3.select("#rectResize"))
.resize(true)
.draw();
// Wrap text in a circle.
d3plus.textwrap()
.container(d3.select("#circleWrap"))
.draw();
// Wrap text in a circle, and size the text to fit.
d3plus.textwrap()
.container(d3.select("#circleResize"))
.resize(true)
.draw();
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment