Search

Arrange Items

Layouts

Rearrange selected nodes to improve clarity.

Arrange Items
View live example →

This demo illustrates how selected nodes can be forced into patterns to improve intelligibility of a chart.

KeyLines layouts are typically curved and 'organic' to provide an attractive and easy-to-read chart. Sometimes, you might need to cluster a set of nodes together in a particular arrangement.

The demo shows the application of distinctive arrangements (grid, circle and radial) to clearly differentiate the selected and sorted nodes from their peers. The demo also illustrates various sorting options.

You could also think about using combos to group nodes. See the Combo Options demo to see combos in action.

Key functions used:

import KeyLines from "keylines";
import { data } from "./data.js";

let chart;
const tightValueSlider = document.getElementById("slider");

// Returns the selected radio button
// name should be : shape, criteria, or position
function getSelectedRadioButton(name) {
  return document.querySelector(`input[name=${name}]:checked`).value;
}

async function doArrange(items) {
  const idList = items.map((item) => item.id);
  const tightness = +tightValueSlider.value;
  const position = getSelectedRadioButton("position");
  const options = { tightness, position, fit: true };
  await chart.arrange(getSelectedRadioButton("shape"), idList, options);
}

function sortByLabel(items) {
  return items.sort((a, b) => a.t.localeCompare(b.t));
}

function sortByValues(items, sortValues) {
  return items.slice().sort((a, b) => sortValues[b.id] - sortValues[a.id]);
}

function isNode(item) {
  return item && item.type === "node";
}

async function startArrange() {
  // Filter nodes from the whole selection
  const selectedItems = chart.getItem(chart.selection());
  const selectedNodes = selectedItems.filter(isNode);

  // Change the selection only to nodes
  chart.selection(selectedNodes.map((item) => item.id));

  // Get the selected criteria from the right panel
  const criteria = getSelectedRadioButton("criteria");

  // sort items and arrange them
  let orderedList;
  switch (criteria) {
    case "alpha":
      orderedList = sortByLabel(selectedNodes);
      break;
    case "betweenness":
      {
        const betweennessValues = await chart.graph().betweenness({});
        orderedList = sortByValues(selectedNodes, betweennessValues);
      }
      break;
    case "degree":
      {
        const degreesValues = chart.graph().degrees();
        orderedList = sortByValues(selectedNodes, degreesValues);
      }
      break;
    default:
      break;
  }
  doArrange(orderedList);
}

function updateSliderValue() {
  const tightValue = tightValueSlider.value;
  document.getElementById("tighValueDisplayed").innerHTML = ` ${tightValue}`;
}

function createEventHandlers() {
  const arrangeButton = document.getElementById("arrangeButton");
  arrangeButton.addEventListener("click", startArrange);

  const layoutButton = document.getElementById("layoutButton");
  layoutButton.addEventListener("click", () => chart.layout());

  tightValueSlider.addEventListener("input", updateSliderValue);
}

async function loadKeyLines() {
  const options = {
    drag: {
      links: false,
    },
    logo: "/public/images/Logo.png",
    minZoom: 0.01,
  };

  chart = await KeyLines.create({
    id: "kl",
    container: "klchart",
    options,
  });

  chart.load(data);
  chart.layout();

  createEventHandlers();
}

window.addEventListener("DOMContentLoaded", loadKeyLines);
const defaultNodeColour = "rgb(253, 141, 60)";
const defaultLinkColour = "rgb(145, 146, 149)";

export const data = {
  type: "LinkChart",
  items: [
    {
      type: "node",
      id: "343111",
      t: "Tamara Williams",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343112",
      t: "Joshua Cervantes",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343113",
      t: "Larry Anderson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343114",
      t: "Michael Solis",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343115",
      t: "Maria Barker",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343116",
      t: "Justin Patel",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343117",
      t: "Richard Evans",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343118",
      t: "Julie Chavez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343119",
      t: "Denise Wheeler",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343120",
      t: "Tracy Fisher",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343121",
      t: "Alicia Smith",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343122",
      t: "Malik Powell",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343123",
      t: "Amy Brady",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343124",
      t: "Angela Campbell",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343125",
      t: "Kimberly Williams",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343126",
      t: "Tina Burton",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343127",
      t: "Michael Nicholson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343128",
      t: "John Becker",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343129",
      t: "Cindy Jenkins",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343130",
      t: "Debbie McConnell",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343131",
      t: "Robert Mckenzie",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343132",
      t: "Michael Osborn",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343133",
      t: "Sandra Bush",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343134",
      t: "Kyle Garcia",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343135",
      t: "Terrence Fitzgerald",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343136",
      t: "Kerry Wilson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343137",
      t: "Jason Wilson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343138",
      t: "Kenneth Davis",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343139",
      t: "Lucas Lucero",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343140",
      t: "Jesse Hudson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343141",
      t: "David Osborne",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343142",
      t: "Anthony Shannon",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343143",
      t: "Joseph Lopez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343144",
      t: "Pamela Gilbert",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343145",
      t: "Victoria Aguirre",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343146",
      t: "Kristie Hawkins",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343147",
      t: "Daniel Chavez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343148",
      t: "Kelsey Mitchell",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343149",
      t: "Kristen Taylor",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343150",
      t: "Kristen Rodriguez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343151",
      t: "Tara Marquez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343152",
      t: "James Lewis",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343153",
      t: "Anthony Robinson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343154",
      t: "Alexandra Perez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343155",
      t: "Steven Wallace",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343156",
      t: "Jennifer Valdez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343157",
      t: "Benjamin Erickson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343158",
      t: "Travis Chen",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343159",
      t: "Jeffrey Kelley",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343160",
      t: "Andrew Stout",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343161",
      t: "Philip Larson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343162",
      t: "Sharon Miller",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343163",
      t: "Micheal King",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343164",
      t: "Daniel Farmer",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343165",
      t: "Hector Stewart",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343166",
      t: "Joseph McCoy",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343167",
      t: "Michael Mathews",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343168",
      t: "Jose Ellison",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343169",
      t: "Brandon Jackson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343170",
      t: "Edward Hernandez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343171",
      t: "Gina Miller",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343172",
      t: "Eric Garcia",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343173",
      t: "John Bailey",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343174",
      t: "Gary Harrison",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343175",
      t: "Patrick Newman",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343176",
      t: "Rodney Sampson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343177",
      t: "Andrea Carter",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343178",
      t: "Rhonda Johnson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343179",
      t: "Elizabeth Price",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343180",
      t: "Ricky Maddox",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343181",
      t: "Michael Griffin",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343182",
      t: "Anthony Myers",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343183",
      t: "Jeremy Burke",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343184",
      t: "Tina Reynolds",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343185",
      t: "Matthew Banks",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343186",
      t: "Brian Rocha",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343187",
      t: "Michelle Adams",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343188",
      t: "Ronald Clark",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343189",
      t: "Kimberly Jones",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343190",
      t: "Michele Lyons",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343191",
      t: "Debbie Lamb",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343192",
      t: "Sandra Wilson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343193",
      t: "Peggy Hicks",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343194",
      t: "David King",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343195",
      t: "Kristopher Lynch",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343196",
      t: "Steven Perez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343197",
      t: "Michael Wyatt",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343198",
      t: "Cody Guerrero",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343199",
      t: "Molly Compton",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343200",
      t: "Michael Smith",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343201",
      t: "Teresa Winters",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343202",
      t: "Christopher Lawson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343203",
      t: "Stephanie Bell",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343204",
      t: "Devon Johnson",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343205",
      t: "Eddie Sullivan",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343206",
      t: "Benjamin Mitchell",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343207",
      t: "Sarah Garner",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343208",
      t: "Lisa Miles",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343209",
      t: "Lisa Wallace",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343210",
      t: "Alex Ross",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343211",
      t: "Kenneth Dunlap",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343212",
      t: "Juan Rangel",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343213",
      t: "Kristin Cook",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343214",
      t: "Tami Orozco",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343215",
      t: "Julie Sanchez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343216",
      t: "Tiffany Page",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343217",
      t: "Elizabeth Warner",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343218",
      t: "Kayla Bruce",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343219",
      t: "Patricia Carroll",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343220",
      t: "Mark Edwards",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343221",
      t: "David Williams",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343222",
      t: "Billy Owen",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343223",
      t: "Todd Bright",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343224",
      t: "Lisa Burnett",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343225",
      t: "Jeffrey Henry",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343226",
      t: "David Cooper",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343227",
      t: "Jeremy Simon",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343228",
      t: "Kimberly Martinez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343229",
      t: "Karen Brown",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343230",
      t: "Linda Lyons",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343231",
      t: "James Lutz",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343232",
      t: "Martha Gomez",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343233",
      t: "Haley Miller",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",
      id: "343234",
      t: "Melissa Reynolds",
      c: defaultNodeColour,
      x: 0,
      y: 0,
    },
    {
      type: "node",

// ...truncated 3897 lines
<!doctype html>
<html lang="en" style="background-color: #2d383f">
  <head>
    <meta charset="utf-8" />
    <title>Arrange Items</title>
    <link rel="stylesheet" type="text/css" href="@ci/theme/kl/css/keylines.css" />
    <link rel="stylesheet" type="text/css" href="@ci/theme/kl/css/minimalsdk.css" />
    <link rel="stylesheet" type="text/css" href="@ci/theme/kl/css/sdk-layout.css" />
    <link rel="stylesheet" type="text/css" href="@ci/theme/kl/css/demo.css" />
  </head>
  <body>
    <div id="klchart" class="klchart"></div>
    <div id="applemenumask"></div>
    <script type="module" src="./code.js"></script>
  </body>
</html>

Terms of use

These terms do not alter or supersede any existing agreements between you (or your employer) and us.

By accessing or using any Content you agree to be bound by these Terms of Use. Please review these terms carefully before using the website.

The contents of this website, including but not limited to any text, code samples, API references, schemas, interactive tools, and other materials (collectively, the 'Content'), are made available for informational and internal evaluation purposes only. All intellectual property rights in the Content are reserved. No licence is granted to use the Content for any commercial purpose, or to copy, distribute, modify, reverse-engineer, or incorporate any part of the Content into any product or service, without our prior written consent.

This Content is provided “as is” and “as available,” without any representations, warranties, or guarantees of any kind, whether express or implied, including but not limited to implied warranties of merchantability, fitness for a particular purpose, non-infringement, or accuracy. To the fullest extent permitted by applicable law, we expressly exclude and disclaim all implied warranties, conditions, and other terms that might otherwise be implied.

We disclaim all liability for any loss or damage, whether direct, indirect, incidental, consequential, or otherwise, arising from any reliance placed on the Content or from your use of it, to the fullest extent permitted by applicable law. By continuing to access or use the Content, you acknowledge and agree to these terms.