//
//     Copyright © 2011-2025 Cambridge Intelligence Limited.
//     All rights reserved.
//
//     Sample Code
//!    Customise nodes and glyphs with images and font icons.
import KeyLines from "keylines";
import { data } from "./fonticons-data.js";

let chart;

function getImageAlignment() {
  // Images are added to to the imageAlignment object
  // using their path as the key and an object describing the
  // adjustments to their position and scale as the value.
  const imageAlignmentDefinition = {
    "/images/icons/person4.png": { e: 0.9 },
    "/images/icons/car.png": { dy: -6, e: 0.9 },
    "/images/icons/laptop1.png": { dy: -20, dx: 20 },
    "/images/icons/facebook.svg": { dx: 10, e: 1.2 },
  };

  // For font icons, instead of a path as the key,
  // we need to pass in the same value as used in fi's t property.
  const fontIconAlignmentDefinitions = {
    "fas fa-user": { dy: -10 },
    "far fa-user": { dy: -10 },
    "far fa-building": { dy: 2, e: 0.9 },
    "fas fa-phone-square": { dx: 20, dy: -20, e: 1.3 },
    "fas fa-home": { e: 1.05 },
    "fas fa-at": { e: 1.2, dy: -40, dx: 40 },
    "fas fa-info-circle": { e: 1.2, dy: -40, dx: 40 },
  };

  return {
    ...imageAlignmentDefinition,
    ...fontIconAlignmentDefinitions,
  };
}

async function startKeyLines() {
  chart = await KeyLines.create({
    container: "klchart",
    options: {
      handMode: true,
      // Font icons and images can often be poorly aligned.
      // Set offsets to the icons to ensure they are centred correctly.
      imageAlignment: getImageAlignment(),
      logo: {
        u: "/images/Logo.png",
      },
      // Set the name of the font we want to use for icons
      // (a font must be loaded in the browser with exactly this name)
      iconFontFamily: "Font Awesome 5 Free",
    },
  });

  // To see how images and font icons are included within the data, see fonticons-data.js
  chart.load(data);
  chart.layout();
}

function loadFontsAndStart() {
  Promise.all([
    document.fonts.load('900 24px "Font Awesome 5 Free"'),
    document.fonts.load('400 24px "Font Awesome 5 Free"'),
  ]).then(startKeyLines);
}

window.addEventListener("DOMContentLoaded", loadFontsAndStart);
<!DOCTYPE html>
<html lang="en" style="background-color: #2d383f;">
  <head>
    <meta charset="UTF-8">
    <title>Icons and Images</title>
    <link rel="stylesheet" type="text/css" href="/css/keylines.css">
    <link rel="stylesheet" type="text/css" href="/css/minimalsdk.css">
    <link rel="stylesheet" type="text/css" href="/css/sdk-layout.css">
    <link rel="stylesheet" type="text/css" href="/css/demo.css">
    <link rel="stylesheet" type="text/css" href="/css/fontawesome5/all.css">
    <script src="/vendor/jquery.js" defer type="text/javascript"></script>
    <script id="keylines" src="/public/keylines.umd.cjs" defer type="text/javascript"></script>
    <script src="/fonticons.js" crossorigin="use-credentials" defer type="module"></script>
  </head>
  <body>
    <div class="chart-wrapper demo-cols">
      <div class="tab-content-panel flex1" id="lhs" data-tab-group="rhs">
        <div class="toggle-content is-visible" id="lhsVisual" style="width:100%; height: 100%;">
          <div class="klchart" id="klchart">
          </div>
        </div>
      </div>
      <div class="rhs citext closed" id="demorhscontent">
        <div class="title-bar">
          <svg viewBox="0 0 360 60" style="max-width: 360px; max-height: 60px; font-size: 24px; font-family: Raleway; flex: 1;">
            <text x="0" y="38" style="width: 100%;">Icons and Images</text>
          </svg>
        </div>
        <div class="tab-content-panel" data-tab-group="rhs">
          <div class="toggle-content is-visible tabcontent" id="controlsTab">
            <form autocomplete="off" onsubmit="return false" id="rhsForm">
              <div class="cicontent"></div>
              <p>Using images on nodes and glyphs is a powerful way to customise charts. </p>
            </form>
          </div>
        </div>
      </div>
    </div>
    <div id="moreParent">
      <div id="moreContainer">
      </div>
    </div>
    <div id="lazyScripts">
    </div>
  </body>
</html>
Loading source