Introduction

KeyLines lets you use custom fonts for text inside glyphs and labels. Font icons can be used as node icons, glyph icons (on nodes, links, annotations and combos) and label icons (inside node and annotation labels).

You can use any web font library or create custom font families that fit your application design.

image of a network of nodes styled with various font icons

KeyLines lets you use fonts from a variety of sources including:

  • Using a content delivery network (CDN) link
  • Using a package manager to download a package
  • Hosting downloaded files (eg. CSS or .woff or .ttf files)

For all of these sources, we recommend using the document.fonts property from the CSS Font Loading API to ensure fonts are fully loaded before rendering. We use this approach throughout the guides below.

Fonts

Fonts are assets that define the look of characters including letters, numbers and symbols. Many font families offer multiple font variants with different font weights or styles. KeyLines fully supports custom fonts and renders them consistently across the chart.

KeyLines uses 'sans-serif' as the default font family.

See the Advanced Node Styles demo for an example using Raleway, Montserrat and Valera Round fonts.

Adding fonts

If you don't have a KeyLines project, follow the Step 1 and Step 2 of Using KeyLines with JavaScript to create a quick application with a single "Hello World" node.
  1. In your project's root folder, add the font to your HTML file.
  2. We're using the Google Raleway font and a CDN link from Google Fonts to generate a script for two different font weights, 400 and 800:

    <!-- weights 400 and 800 -->
    <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css2?family=Raleway:wght@400;800&display=swap"/>
  3. If you want to use multiple font weights or styles of the same font, you must update your application's CSS with a unique @font-face declaration for each variant.
  4. If you are using a CDN link, you can find the @font-face rules by clicking the link generated in the script.

    For the JavaScript tutorial application, add the CSS code in my-keylines-app/src/style.css:

    @font-face {
      font-family: 'Raleway';
      font-style: normal;
      font-weight: 400;
      font-display: swap;
      src: url('https://fonts.gstatic.com/s/raleway/v28/1Ptug8zYS_SKggPNyCMIT5lu.woff2') format('woff2');
    }
     
    @font-face {
      font-family: 'Raleway Bold';    /* creates a unique name for this font weight */
      font-style: normal;
      font-weight: 800;
      font-display: swap;
      src: url('https://fonts.gstatic.com/s/raleway/v28/1Ptug8zYS_SKggPNyCMIT4ttDfA.woff2') format('woff2');
    }

    If you are only using a single font weight or style, no CSS changes are needed.

  5. Next, set the default fontFamily in chart options.
  6. For the JavaScript tutorial application, this is in my-keylines-app/src/main.js:

    async function startKeyLines() {
      chart = await KeyLines.create({
        type: 'chart',
        container: 'kl',
        options: {
          fontFamily: 'Raleway',
        },
      });
      chart.load(data);
    }

    This text font will be used inside labels and glyphs unless a font family is explicitly set on the label/glyph in the ff property.

  7. Define and load the fonts and start your KeyLines application once the fonts have successfully loaded:
  8. Promise.all([
      document.fonts.load('24px "Raleway Bold"'),   // Raleway Bold specified in CSS in step 2
      document.fonts.load('24px "Raleway"'),
    ]).then(startKeyLines);
  9. Now that the fonts are loading into KeyLines, we can use them in our chart.
  10. This is what that looks like for a "Hello World" node from the JavaScript tutorial:

    items: [
      { 
        id: 'id1', 
        type: 'node',
        c: '#43976C',
        t: [
          { t: 'Hello world' },                         // font is set by fontFamily
          { t: 'Hello again!', ff: 'Raleway Bold' },    // font is set by ff
        ],
        x: 150, y: 150,
      },
    ],

    At the end of this step, you should see the custom font in your application.

Font icons

Font icons are vector-based glyphs embedded in font files, where specific character codes are mapped to icons instead of traditional letters or numbers. They are highly customisable as you can scale their size and dynamically change their colour.

See the Advanced Node Styles demo for an example using Font Awesome Free Icons and Material Design Icons.

Adding font icons

This guide assumes that you are using KeyLines 8.5 or newer. To use it with older versions, apply the change from the Font icons showing as a single letter section at the last step.
If you don't have a KeyLines project, follow the Step 1 and Step 2 of Using KeyLines with JavaScript to create a quick application with a single "Hello World" node.
  1. In the root folder of your project, install the latest version of your icons using your preferred package manager. We're using Font Awesome Free Icons.
  2. npm install --save @fortawesome/fontawesome-free
    yarn add @fortawesome/fontawesome-free
    pnpm install --save @fortawesome/fontawesome-free
  3. Import the font icon families into the component file where you are importing KeyLines. For the JavaScript tutorial application, this is in my-keylines-app/src/main.js:
  4. import "@fortawesome/fontawesome-free/css/all.css";
  5. Set the iconFontFamily in chart options:
  6. async function startKeyLines() {
      chart = await KeyLines.create({
        type: 'chart',
        container: 'kl',
        options: {
          iconFontFamily: 'Font Awesome 6 Free'
        }
      });
    chart.load(data);
    }

    This family is used to render the icon unless a font family is explicitly set on the item/sub-item in the ff option of the fi property.

  7. Define and load the fonts and start your KeyLines application once the fonts have successfully loaded:
  8. Promise.all([                                              // specify both styles as we imported all.css in step 2
      document.fonts.load('900 16px "Font Awesome 6 Free"'),   // fas (solid, weight 900)
      document.fonts.load('400 16px "Font Awesome 6 Free"'),   // far (regular, weight 400)
    ]).then(startKeyLines);
  9. Now that the fonts are loading into KeyLines, we can use them in our chart. Pass the icon's CSS class name to the t option of the fi property of the item/sub-item.
  10. This is what that looks like for a "Hello World" node from the JavaScript tutorial:

    items: [
      { 
        id: 'id1', 
        type: 'node',
        c: '#43976C',
        t: [
          { t: 'Hello World' },              // node label
          {
            fi: { t: 'far fa-handshake' },   // font icon inside a label, renders a regular weight (far) icon
          },
          {
            fi: { t: 'fas fa-globe', c: '#2B65EC' },   // renders a solid weight (fas) icon in blue
            position: { vertical: 'inherit' },
          },
        ],
        x: 150, y: 150,
      },
    ],

    At the end of this step, you should see font icons in your application.

Font icon weights

Some font icon providers have multiple font weights or styles as variants of the same font family.

For example, Font Awesome Free Icons are either Regular (far) or Solid (fas), which should be specified as part of the icon's CSS class name in the t property.

Others, such as Material Design Icons, include Filled, Outlined, Rounded or Sharp variants, where each variant must be imported separately. See Step 2 of the Adding fonts section for a similar example using @font-face rules. The interactive example in Styling font icons imports the variants as separate CDN links in the HTML tab.

Styling font icons

KeyLines lets you set the colour c as well as a custom font family ff for that particular item directly inside the item's fi property.

In addition, depending on the item where the font icon is used, KeyLines lets you customise its various properties:

  • Node icons - Use imageAlignment to position the icon within the node and scale the icon size.
  • Glyph icons (on nodes, links and annotations) - Use imageAlignment to position the icon within the glyph and scale the icon size.
  • Label icons (on nodes and annotations) - Use the properties available for node label and annotation label APIs including position or fs (font size, to scale the icon).

The example below uses Font Awesome Free Icons (Solid and Regular) and Material Design Icons (Sharp and Outlined). Click the Playground button to explore the chart and its source code:

items: [
  {
    id: 'bank',
    type: 'node',
    c: '#15803D',
    fi: { c: 'white', t: 'account_balance', ff: 'Material Icons' },
    g: [
      {
        p: 'ne',
        c: '#4ADE80',
        b: 'transparent',
        fi: { c: 'white', t: 'fas fa-dollar-sign' },
      },
    ],
  },
  {
    id: 'client',
    type: 'node',
    c: '#2563EB',
    fi: { c: 'white', t: 'person', ff: 'Material Icons Outlined' },
  },
  {
    id: 'an01',
    type: 'annotation',
    subject: 'client',
    t: [
      {
        t: 'Card Expired: 01/2025',
        fs: 16,
        margin: 5,
      },
      {
        fi: { t: 'fas fa-exclamation-triangle' },
        fs: 25,
        position: { vertical: 'inherit' },
        fc: '#991B1B',
      },
    ],
    connectorStyle: { c: '#991B1B' },
    b: '#991B1B',
    g: [
      {
        p: 's',
        c: '#991B1B',
        b: 'transparent',
        fi: { c: 'white', t: 'far fa-credit-card' },
      },
    ],
  },
  {
    id: 'link01',
    id1: 'bank',
    id2: 'client',
    type: 'link',
    c: '#F97316',
    a2: true,
    g: [
      {
        p: 'ne',
        c: '#F97316',
        b: 'transparent',
        fi: { c: 'white', t: 'far fa-envelope' },
      },
    ],
  },
],
a thumbnail of the example Playground

Troubleshooting

This section offers help with some of the most common issues with using fonts and font icons.

Cannot access fonts and font icons from another domain

When loaded from a different domain to your app, fonts and font icons can fail to appear in your chart or in the output of chart.export() or chart.toDataURL() (now deprecated). This is due to the CORS restrictions. See the Cross-Origin Images (CORS) page for more details.

Font icons showing as a single letter

node where a missing icon is replaced by a single letter

If you complete the Adding font icons guide and the font icons only show as the first letter of the string in the t property, you might be using an older version of KeyLines.

In KeyLines 8.4 or older, passing the CSS class name or icon name directly in the t option, such as fi: { t: 'fas fa-globe' }, was not supported. Instead, KeyLines.getFontIcon() was used to get the Unicode character.

We strongly recommend upgrading KeyLines to the latest version so that you can avoid using the getFontIcon() function which is now deprecated.

If you want to continue using an older version of KeyLines with the Adding font icons guide, set the CSS class name inside the getFontIcon() function:

let data = { id: 'user', type: 'node', fi: { t: KeyLines.getFontIcon('fas fa-user') } };

If you need help upgrading, see the Upgrading documentation or contact [email protected].

node where a missing icon is replaced by its full name

Font icons showing as a plain text

If you complete the Adding font icons guide but the font icons are only showing as the plain text specified in the t option, there's probably an issue with importing the font.

Review and repeat the steps in the tutorial and if the issue persists, contact [email protected].

Font files loaded via CSS @import showing as a plain text

If you are importing font files using @import inside a CSS file, the validations in point 4 of Adding Font Icons can sometimes be executed before the CSS is processed. As a result, icons can fail to load and instead show as the plain text specified in the t option.

To fix this, include document.fonts.ready at the top of the chain of promises:

document.fonts.ready                                        // resolves once the document has completed loading fonts
.then(() =>
  Promise.all([                                             // resolves when ALL the fonts are loaded
    document.fonts.load('1em "Material Icons"'),
    document.fonts.load('1em "Material Icons Outlined"'),
  ]).then(startKeyLines);                                   // starts KeyLines
)

Check the Advanced Node Styles demo for an example.

Rendering of font families with whitespace and number in name

If you use a font family whose name contains a whitespace and ends in a number, e.g. "Exo 2" or "Goudy Bookletter 1911", the text may not render correctly in the chart. This is due to certain CSS restrictions on acceptable characters and identifiers.

In addition to quoting the font family name, wrap the font family name into additional set of quotes:

{ id: 'n2', type: 'node', c: '#43976C', t: 'Text',  fs: 14, ff: "'Exo 2'" }           

Slow loading performance with multiple font families

If you have issues with slow loading performance when using multiple font families, you can use a tool such as Fontello to create a single font family containing the font icons you want to use. Loading a single family uses less bandwidth and avoids slow-running charts.