• Stars
    star
    154
  • Rank 242,095 (Top 5 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created almost 11 years ago
  • Updated almost 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

painless cross-browser line wrapping for text passages in SVG projects built with D3.js

d3-textwrap

wrap long lines of text in SVG images

demonstration

Overview

Astonishingly, SVG does not natively provide a way to wrap long lines of text. However, it does provide two mechanisms by which text wrapping can be very tediously implemented.

  1. the long text can be split into substrings which are inserted into tspan elements, each of which is then positioned individually

  2. the text can be added to a foreignObject which uses HTML instead of SVG to wrap long lines

The first approach can be buggy in Safari, and the second does not work at all in Internet Explorer 10 or below. This plugin implements both solutions, and can switch between them depending on browser support.

Quick Start

The d3.textwrap method is a factory which returns functions which can then have their wrapping behavior configured, and are then run on a set of text nodes using selection.call.

// create a text wrapping function
var wrap = d3.textwrap().bounds({height: 480, width: 960});
// wrap all text
d3.selectAll('text').call(wrap);

Install

Install with npm or yarn, or download the latest release.

npm install d3-textwrap

Import

You can import with ESM import syntax and then attach it to your d3 object:

import { textwrap } from 'd3-textwrap';
d3.textwrap = textwrap;

Or do the same with CJS require():

var textwrap = require('d3-textwrap').textwrap;
d3.textwrap = textwrap;

You can also load directly in the browser without a build tool or package manager. Add the plugin script to your HTML page after you've loaded d3.js and the textwrap() function will be automatically added to the d3 object:

<html>
  <head>
    <script type="text/javascript" src="https://d3js.org/d3.v5.min.js"></script>
    <script type="text/javascript" src="/path/to/textwrap.js"></script>
  </head>

API Reference

Creating Text Wrapping Functions

# d3.textwrap

Creates a function that can then be configured and used to wrap text. This allows for varying configurations within the same project.

var wrap = d3.textwrap();

Configuration

# textwrap.bounds(bounds)

Gets or sets the boundaries within which text will be wrapped. Takes one argument, which can be a DOM node, an object with "height" and "width" properties, or a function which returns an object with "height" and "width" properties. To wrap to a 480×960 pixel rectangle:

var wrap;
// create a text wrapping function
wrap = d3.textwrap()
    // wrap to 480 x 960 pixels
    .bounds({height: 480, width: 960});

# textwrap.padding(padding)

Gets or sets optional additional padding which will be calculated on top of the bounds before the text wrapping is performed. Takes one argument, which can be a number or a function which returns a number. Note that this does not support CSS units. To pad by 10 pixels, thus bringing the effective dimensions to 460×940:

var wrap;
// create a text wrapping function
wrap = d3.textwrap()
    // wrap to 480 x 960 pixels
    .bounds({height: 480, width: 960})
    // pad by an additional 10 pixels
    .padding(10);

# textwrap.method(method)

Gets or sets the name of the text wrapping method to be used, which can be either "foreignobject" or "tspans". If this is not specified, the default behavior is to use foreignobject wrapping for most browsers, but fall back to using tspan elements when that is not an available option. With that said, in some scenarios it may also make sense to always use the tspan method in pursuit of consistent behavior.

var wrap;
// create a text wrapping function
wrap = d3.textwrap()
    // wrap to 480 x 960 pixels
    .bounds({height: 480, width: 960})
    // wrap with tspans in all browsers
    .method('tspans');

Running

After configuring a text wrapping function, run it using selection.call():

var wrap,
    text;
// create a text wrapping function
wrap = d3.textwrap()
    // wrap to 480 x 960 pixels
    .bounds({height: 480, width: 960});
// select all text nodes
text = d3.selectAll('text');
// run the text wrapping function on all text nodes
text.call(wrap);

Alternatives

Gregor Aisch's handy d3-jetpack toolkit also provides a text wrapping routine which works by counting the number of characters on each line instead of measuring the amount of horizontal space they occupy.

More Repositories

1

lit

a little preprocessor for literate programming
Shell
119
star
2

d3-history

proper URL bar history for D3.js
JavaScript
49
star
3

memento

dynamic data binding along a timeline with HTML5 media elements
JavaScript
49
star
4

d3-xray

view the data bound to a D3.js project simply by mousing over elements
26
star
5

rollup-plugin-markdown

import JavaScript from Markdown code blocks
JavaScript
17
star
6

genius-defender

prevent genius.com annotations
PHP
15
star
7

bisonica

accessible data visualizations with Vega Lite
JavaScript
15
star
8

d3-parent

inverted DOM traversal for nested data binds
JavaScript
12
star
9

pingkiller

disable the HTML ping attribute
JavaScript
12
star
10

lit-web

client-side parsing of JavaScript literate programming in Markdown documents
JavaScript
10
star
11

genius-blender

remove Genius web annotations
JavaScript
8
star
12

multiverse-json

a lightweight specification for storing alternate versions of a document using JSON
Python
8
star
13

object-iteration

hashmap implementations of map, filter, reduce and other array iteration methods
JavaScript
7
star
14

microlens

easy functional getter/setters for nested data structures in JavaScript
JavaScript
6
star
15

wp-professionals

Turn WordPress posts into professional listings
PHP
5
star
16

d3-rect

draw rectangles using path elements
JavaScript
4
star
17

literate-webassembly

artisanal WebAssembly math
JavaScript
3
star
18

genius-defender-js

node module to prevent genius.com annotations
JavaScript
2
star
19

cryptopals-literate-python

solutions to the CryptoPals challenges implemented with "literate programming" style
Shell
2
star
20

rerandom

repeatable randomization for JavaScript
JavaScript
1
star
21

diversitymatrix

data visualization for longitudinal display of demographics
CSS
1
star
22

css-zen-garden-api

a ridiculous fake API created with CSS
CSS
1
star