//
//     Copyright © 2011-2025 Cambridge Intelligence Limited.
//     All rights reserved.
//
//     Sample Code
//
//!    Get the perfect look and feel for your network.
import KeyLines from "keylines";
import styles from "./stylingcharts-styles.js";

let selectedStyle;
let chart;
let timebar;
let timeBarShown = false;
let previousSelection = [];
let lightMonochromeSelection = {};
let customNav = [];
// Highlight the selected nodes activity in the timebar
function showSelection() {
  const items = [];
  const selectedIds = chart.selection();
  let neighbouringNodes = [];

  selectedIds.forEach((id, index) => {
    const item = chart.getItem(id);
    let links = [];
    if (item.type === "node") {
      const neighbours = chart.graph().neighbours(id, { all: true });
      links = neighbours.links;
      neighbouringNodes = neighbours.nodes;
    } else {
      links.push(id);
      neighbouringNodes.push(item.id1, item.id2);
    }
    items.push({
      id: links,
      index,
      c: selectedStyle.name === "minimalist" ? "#333" : "#ddd",
    });
  });

  timebar.selection(items);
}
// synchronise the timebar and chart displayed data
function onTimeBarChange() {
  chart.filter(timebar.inRange, { animate: false, type: "link" });
}

// Toggle timeBar visibility
let range = {};
async function toggleTimeBar() {
  timeBarShown = !timeBarShown;
  // If the timebar is hidden update the chart height
  // remove all the events linked to the hidden timebar and save the selected range.
  // Follow the oposite procedure when loading the timebar
  const container = document.getElementById("klchart").parentNode;
  if (timeBarShown) {
    container.classList.remove("timeBarHidden");
    chart.on("selection-change", showSelection);
    if (document.fullscreenElement) {
      const { dt1, dt2 } = range;
      timebar.range(dt1, dt2);
    }
    timebar.on("change", onTimeBarChange);
  } else {
    container.classList.add("timeBarHidden");
    chart.off("selection-change", showSelection);
    range = timebar.range();
    timebar.off("change");
  }
}

function onFontIconSelectionChange() {
  const selectedStyling = previousSelection || [];
  previousSelection = [];
  chart.selection().forEach((selectedId) => {
    const selectedItem = chart.getItem(selectedId);
    if (selectedItem.type === "node") {
      const isActor = selectedItem.d.type === "actor";
      const styleSelected = {
        id: selectedId,
        fi: {
          t: selectedItem.fi.t,
          ff: selectedItem.fi.ff,
          c: "#3A474E",
        },
      };
      const revertStyling = {
        id: selectedId,
        fi: {
          t: selectedItem.fi.t,
          ff: selectedItem.fi.ff,
          c: isActor ? "#e0f2f1" : "#f0f4c3",
        },
      };
      selectedStyling.push(styleSelected);
      previousSelection.push(revertStyling);
    }
  });
  chart.setProperties(selectedStyling);
}

function toggleNodeLabel({ id, modifierKeys }) {
  if (id === "_overviewIcon") return;
  if (!id || (chart.getItem(id).type === "link" && !modifierKeys.shift)) {
    Object.keys(lightMonochromeSelection).forEach((key) => {
      chart.setProperties({ id: key, t: undefined });
    });
    lightMonochromeSelection = {};
    return;
  }

  if (lightMonochromeSelection[id] && !chart.selection().includes(id)) {
    chart.setProperties({ id, t: undefined });
    delete lightMonochromeSelection[id];
  } else {
    lightMonochromeSelection[id] = true;
    chart.setProperties({ id, t: chart.getItem(id).d?.labelText });
  }
}

async function loadNewstyle() {
  // Load the chart & timebar options
  if (selectedStyle.styleOptions.chartOptions) {
    if (selectedStyle.styleOptions.timebarDisplayed) {
      timebar.options(selectedStyle.styleOptions.timeBarOptions);
    }
    chart.options(selectedStyle.styleOptions.chartOptions);
  }

  // Load the style data for both chart and timebar
  if (selectedStyle.styleOptions.data) {
    const promises = [];
    if (selectedStyle.styleOptions.timebarDisplayed) {
      timebar.load(selectedStyle.styleOptions.data);
      promises.push(timebar.zoom("fit"));
    }
    chart.load(selectedStyle.styleOptions.data);
    promises.push(chart.zoom("fit"));
    await Promise.all(promises);
  }

  // Remove previous used events
  chart.off("selection-change", onFontIconSelectionChange);
  chart.off("click", toggleNodeLabel);
  const props = [];
  const nodeColors = {};
  // Set the styling properties as defined by the style for the nodes & links
  if (selectedStyle.styleOptions.nodes) {
    chart.each({ type: "node" }, (item) => {
      const nodeStyles = Object.assign(
        {},
        selectedStyle.styleOptions.nodes.mainStyle,
        selectedStyle.styleOptions.nodes[item.d.type] || {}
      );
      props.push(Object.assign({ id: item.id }, nodeStyles));
      if (selectedStyle.styleOptions.links.gradient) {
        nodeColors[item.id] = nodeStyles.fi.c;
      }
    });
  }
  if (selectedStyle.styleOptions.links) {
    chart.each({ type: "link" }, (item) => {
      const linkStyles = selectedStyle.styleOptions.links.gradient
        ? Object.assign(selectedStyle.styleOptions.links, {
            c: nodeColors[item.id1],
            c2: nodeColors[item.id2],
          })
        : selectedStyle.styleOptions.links;
      props.push(Object.assign({ id: item.id }, linkStyles));
    });
  }
  // Show the custom style navigation controls
  if (selectedStyle.styleOptions.customNavigation) {
    customNav = document.getElementsByClassName(selectedStyle.name);
    for (let i = 0; i < customNav.length; i++) {
      customNav[i].style.display = "block";
    }
    // Update the colour of the custom navigation for the minimalist dark style
    if (selectedStyle.name.indexOf("minimalist") === 0) {
      document.getElementById("timeBar").style.color =
        selectedStyle.name === "minimalistDark" ? "#ddd" : "black";
    }
  }
  // Attach style specific events
  if (selectedStyle.name === "awesomeGloom") {
    chart.on("selection-change", onFontIconSelectionChange);
  }

  if (selectedStyle.name === "lightMonochrome") {
    chart.on("click", toggleNodeLabel);
  }

  chart.setProperties(props);

  // Load the layout and its options
  await chart.layout(
    selectedStyle.styleOptions.layout.name,
    selectedStyle.styleOptions.layout.layoutOptions
  );

  // Run custom style donut animation
  if (selectedStyle.name === "popArt") {
    chart.each({ type: "node" }, (node) => {
      props.push({
        id: node.id,
        donut: {
          w: 10,
          bw: 2,
        },
      });
    });
    chart.animateProperties(props, { time: 300, easing: "cubic" });
  }
  if (selectedStyle.styleOptions.timebarDisplayed && !timeBarShown) {
    await toggleTimeBar();
  }
  return true;
}

async function hidePreviousstyleControls(event) {
  // hide previous style description
  document.getElementById(`${selectedStyle.name}Descr`).style.display = "none";
  // hide previous custom navigation
  if (selectedStyle.styleOptions.customNavigation) {
    for (let i = 0; i < customNav.length; i++) {
      customNav[i].style.display = "none";
    }
  }
  // hide timebar if you leave a minimalist style
  if (selectedStyle.styleOptions.timebarDisplayed && timeBarShown) {
    if (!styles[event.value].styleOptions.timebarDisplayed) {
      await toggleTimeBar();
    }
  }
  // update the selected style
  selectedStyle = styles[event.value];
  // show the new style description
  document.getElementById(`${selectedStyle.name}Descr`).style.display = "block";

  return true;
}

async function hidePreviousData() {
  const chartItems = chart.serialize().items;
  // get all the ids of the serialized data
  const itemIds = chartItems.map((elem) => elem.id);
  // hide the items with animation
  await chart.hide(itemIds, { animate: true, time: 1000 });
  // remove the data from the timebar
  if (timeBarShown) {
    timebar.clear();
  }
}

async function applystyle() {
  await hidePreviousstyleControls(this);
  await hidePreviousData();
  await loadNewstyle();
  return true;
}

function doZoom(name) {
  chart.zoom(name, { animate: true, time: 350 });
}

// Attach the custom interactions used in all the styles
function intialiseInteractions() {
  document
    .getElementById("style-choice")
    .addEventListener("change", applystyle);
  document.getElementById("home").addEventListener("click", () => {
    doZoom("fit");
  });
  document.getElementById("zoomIn").addEventListener("click", () => {
    doZoom("in");
  });
  document.getElementById("zoomOut").addEventListener("click", () => {
    doZoom("out");
  });
  document.getElementById("timeBar").addEventListener("click", toggleTimeBar);
  document.getElementById("timeBarZoom").addEventListener("click", () => {
    timebar.zoom("fit");
  });
}

// Load the initial minimalist style on both chart and timebar
async function klReady(loadedChart) {
  chart = loadedChart[0];
  timebar = loadedChart[1];
  selectedStyle = styles.minimalist;
  await loadNewstyle();
  intialiseInteractions();
}

async function startKeyLines() {
  const options = {
    chartOptions: {
      iconFontFamily: "Font Awesome 5 Free",
      navigation: {
        shown: false,
      },
    },
    timeBarOptions: {
      showControlBar: false,
      sliders: "none",
    },
  };

  chart = await KeyLines.create([
    {
      container: "klchart",
      type: "chart",
      options: options.chartOptions,
    },
    {
      container: "kltimebar",
      type: "timebar",
      options: options.timeBarOptions,
    },
  ]);
  klReady(chart);
}

function loadAndStart() {
  document.fonts.load('24px "Font Awesome 5 Free"').then(startKeyLines);
}

window.addEventListener("DOMContentLoaded", loadAndStart);
<!DOCTYPE html>
<html lang="en" style="background-color: #2d383f;">
  <head>
    <meta charset="UTF-8">
    <title>Styling Charts</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="/stylingcharts.css">
    <link rel="stylesheet" type="text/css" href="/css/fontawesome5/fontawesome.css">
    <link rel="stylesheet" type="text/css" href="/css/fontawesome5/solid.css">
    <link rel="stylesheet" type="text/css" href="/css/fontawesome5/regular.css">
    <style type="text/css">
      .sdkLink {
        font-weight: bold;
        color: black;
        pointer-events: none;
        cursor: default;
      }
      
      
    </style>
    <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="/stylingcharts.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 klchart-timebar" id="klchart">
            <div class="awesomeGloom">
              <ul>
                <li><a class="awesomeGloomNav" id="zoomIn" rel="tooltip" title="Zoom in"><i class="fa fa-plus-circle"></i></a></li>
                <li><a class="awesomeGloomNav" id="zoomOut" rel="tooltip" title="Zoom out"><i class="fa fa-minus-circle"></i></a></li>
              </ul>
            </div>
            <div class="lightMonochrome">
              <ul>
                <li><a class="lightMonochromeNav" id="home" rel="tooltip" title="Home"><i class="fa fa-home"></i></a></li>
              </ul>
            </div>
            <div class="minimalist minimalistDark"><a id="timeBar" rel="tooltip" title="Show/hide"><i class="fa fa-chart-bar"></i></a></div>
          </div>
          <div class="kltimebar" id="kltimebar">
            <div class="minimalist timeBarZoom"><a id="timeBarZoom" rel="tooltip" title="Reset range"><i class="fa fa-arrows-alt-h"></i></a></div>
          </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%;">Styling Charts</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">
                <p>Explore the different views in the menu below to see how customisable keylines
                  charts can be.
                </p><br>
                <div class="form-inline">
                  <select class="input-medium" id="style-choice">
                    <option value="minimalist" selected>Minimalist</option>
                    <option value="minimalistDark">Minimalist Dark</option>
                    <option value="nameBadges">Name Badges</option>
                    <option value="popArt">Pop Art</option>
                    <option value="awesomeGloom">Awesome Gloom</option>
                    <option value="lightMonochrome">Light Monochrome</option>
                  </select>
                </div>
                <div class="style-descr"><span id="minimalistDescr">
                    <p>
                      A minimalist view can often be more effective as it reduces the amount of information
                      users are subjected to, producing a clean, clear chart.
                    </p>
                    <p>Although keylines has many features that can be useful, it's never a good idea to include
                      all of them in one view, as this causes sensory overload.
                    </p>
                    <p>
                      Having a simpler feel to your chart can be useful when highlighting certain items. A
                      bright colour stands out more against a less vibrant background.
                    </p>
                    <p>
                      You can also create custom controls for your charts and time bars. Here we've used
                      overlaid page elements with the <span style="font-size: 18px"><i class="fas fa-chart-bar"></i></span>
                      and <span style="font-size: 18px"><i class="fas fa-arrows-alt-h"></i></span> font icons for toggling the
                      time bar and fitting the time range into the view respectively.
                      
                    </p></span><span style="display: none" id="minimalistDarkDescr">
                    <p>
                      Simple views can be visually striking when done well. Using a dark background with
                      contrasting lighter items reduces the strain on users' eyes and can increase readability.
                    </p>
                    <p>
                      You can also let users toggle the visibilty of components. Try clicking the button in the
                      top right to hide and show the time bar.
                    </p>
                    <p>
                      You can also link the chart and time bars to respond to
                      <a class="sdkLink" href="reference.htm#ChartEvents">user interaction</a>
                      simultaneously. Try clicking on the chart and scrolling in on the time bar to see how
                      they interact with each other.
                      
                    </p></span><span style="display: none" id="nameBadgesDescr">
                    <p>
                      Although chart items are designed for specific purposes, their flexibility enables you to
                      use them in almost limitless ways.
                    </p>
                    <p>
                      This view shows
                      <a class="sdkLink" href="reference.htm#ItemFormat_Glyph">glyphs</a>
                      being used as a label and
                      <a class="sdkLink" href="reference.htm#ItemFormat_Halo">halos</a>
                      creating a 3-dimensional effect through adding shadows to nodes. The nodes are connected
                      smoothly with links following a
                      <a class="sdkLink" href="reference.htm#Chart_layout_options_linkShape">curve</a>.
                    </p>
                    <p>
                      The styling of items can also be easily updated when they are selected. In this view node
                      borders and links are highlighted in red and given a dashed line style. The styling of
                      selected items can be set using
                      <a class="sdkLink" href="reference.htm#ChartOptions_selectedLink">chart options</a>.
                      
                    </p></span><span style="display: none" id="popArtDescr">
                    <p>
                      Making sure that data is displayed intuitively means that you can give more value in a
                      single view. By using
                      <a class="sdkLink" href="reference.htm#ItemFormat_Donut">donuts</a>
                      you can easily convey large amounts of metadata for each node in a clean,
                      easy-to-understand format.
                    </p>
                    <p>
                      You can also use a variety of different
                      <a class="sdkLink" href="reference.htm#Chart_layout">layouts</a>
                      that come built into keylines. This view uses the sequential layout (with links following a 
                      <a class="sdkLink" href="reference.htm#Chart_layout_options_linkShape">curve</a>) to
                      intuitively imply a hierarchy.
                      
                    </p></span><span style="display: none" id="awesomeGloomDescr">
                    <p>With keylines you can easily configure the chart to respond to user actions.
                      Using the
                      <a class="sdkLink" href="reference.htm#ChartOptions_selectedNode">selectedNode</a>
                      styling option is a good way to draw attention to items.
                    </p>
                    <p>
                      You can also set item styles individually, giving intuitive visuals to items so users
                      understand the data quicker and easier.
                    </p>
                    <p>
                      This view uses relevant
                      <a class="sdkLink" href="reference.htm#ItemFormat_FontIcon">font icons</a>
                      on nodes to show if they are a movie or an actor, and the movie nodes are also
                      <a class="sdkLink" href="reference.htm#ItemFormat_Node_properties_e">enlarged</a>
                      to make them stand out.
                    </p>
                    <p>keylines supports all font families as well as
                      <a class="sdkLink" href="reference.htm#ItemFormat_Node_properties_u">custom images</a>.
                      
                    </p></span><span style="display: none" id="lightMonochromeDescr">
                    <p>It's important to make it easy to navigate charts. keylines has an
                      <a class="sdkLink" href="reference.htm#ChartOptions_overview">overview window</a>
                      that shows where the view window is in relation to the whole network, giving users a
                      sense of where they are.
                    </p>
                    <p>Try clicking the box in the bottom right of the chart.</p>
                    <p>
                      Other controls such as a 'home' button can also help users to return to a comfortable
                      starting point. Try zooming into the chart and then clicking the
                      <span style="color: #cc3333; font-size: 18px"><i class="fas fa-home"></i></span> icon in the top left to
                      <a class="sdkLink" href="reference.htm#Chart_zoom">zoom to fit</a>
                      the network back into view.
                      
                    </p></span></div>
              </div>
            </form>
          </div>
        </div>
      </div>
    </div>
    <div id="moreParent">
      <div id="moreContainer">
      </div>
    </div>
    <div id="lazyScripts">
    </div>
  </body>
</html>
#klchart{
  transition: height  1s;
  height: calc(100% - 130px);
}

#kltimebar{
  height: 130px;
  display: block;
}

.awesomeGloom {
    display: none;
    position: absolute;
    left: 0px;
    top: 0px;
    padding: 0;
    margin: 0;
    font-size: 28px;
    z-index: 9001;
  }
  
  .awesomeGloom ul {
    list-style-type: none;
    margin-top:18px;
    margin-left:15px;
  }
  
  .awesomeGloom li {
    margin-bottom: 5px;
    text-align: center;
  }
  
  .awesomeGloom a i {
    text-decoration: none;
    cursor: pointer;
  }

  .awesomeGloomNav{
    color: #f0f4c3;
  }

  .awesomeGloomNav:hover{
    color: #d9e368;
  }

  .minimalist{
    position: absolute;
    font-size: 25px;
    right: 20px;
    top: 15px;
}

  #timeBar{
    color: black;
    cursor: pointer;
  }

  .timeBarZoom{
    position: absolute;
    font-size: 20px;
    left: 20px;
    top: 15px;
    width: 24px;
    border-right: 2px solid black;
    border-left: 2px solid black;
}

  #timeBarZoom{
    color: black;
    cursor: pointer;
  }

  .theme-descr{
    margin-top: 30px;
    display: block;
  }

  .form-inline{
    margin-bottom: 20px
  }
  .lightMonochrome{
    display: none;
    position: absolute;
    left: 0px;
    top: 0px;
    padding: 0;
    margin: 0;
    font-size: 28px;
    z-index: 9001;
  }

  .lightMonochrome ul {
    list-style-type: none;
    margin-top:18px;
    margin-left:15px;
  }
  
  .lightMonochrome li {
    margin-bottom: 5px;
    text-align: center;
  }
  
  .lightMonochrome a i {
    text-decoration: none;
    cursor: pointer;
  }

  .lightMonochromeNav{
    color: #cc3333;
  }

  .lightMonochromeNav:hover{
    color: #a65959;
  }
  .timeBarHidden #klchart {
    height: 100% !important;
  }

  .timeBarHidden #kltimebar {
    display: none;
  }
// @if isPublic
import KeyLines from "keylines"
// @endif
import { data, shadows, donuts, matrix, lightStyle } from './stylingcharts-data.js';

const styles = {};

function getImageAlignment() {
  const imageAlignment = {};
  const fontIconAlignmentDefinitions = {
    'fas fa-video': { e: 0.8 },
    'fas fa-desktop': { e: 0.9 },
  };
  // get a list of the font icon class names
  const icons = Object.keys(fontIconAlignmentDefinitions);
  icons.forEach((icon) => {
    // find the unicode value of each, and add to the imageAlignment object
    imageAlignment[icon] = fontIconAlignmentDefinitions[icon];
  });
  return imageAlignment;
}

// Generate random date data for the time bar styles for the minimalist styles
function randomDate(start, end) {
  return new Date(start.getTime() + (Math.random() * (end.getTime() - start.getTime())));
}

data.items.forEach((item) => {
  const startDate = new Date(2018, 0, 1);
  const endDate = new Date();
  if (item.type === 'link') {
    const dt1 = randomDate(startDate, endDate);
    // Choose an end up to 30 days after the start
    const dt2 = randomDate(dt1, new Date(dt1.getTime() + 1000 * 60 * 60 * 24 * 30));
    item.dt = { dt1, dt2 };
  }
});

// Minimalist definition
const minimalist = {
  name: 'minimalist',
  styleOptions: {
    data,
    chartOptions: {
      arrows: 'small',
      logo: false,
      navigation: {
        shown: false,
      },
      overview: {
        backColour: 'white',
        borderColour: 'lightgrey',
        icon: true,
      },
      backColour: '#fff',
      fontFamily: 'sans-serif',
      selectedNode: {
        ha0: {
          r: 52,
          w: 8,
          c: '#ffcb00',
        },
        fbc: 'rgba(0,0,0,0)',
        c: '#ffcb00',
      },
      selectedLink: {
        c: '#ffcb00',
        w: 5,
      },
    },
    timeBarOptions: {
      area: { colour: '#b3b3b3' },
      backColour: '#fff',
      fontColour: '#444',
      fontFamily: 'sans-serif',
      maxRange: {
        units: 'year',
        value: 3,
      },
      minScale: {
        units: 'min',
      },
      scale: {
        highlightColour: 'rgba(0,0,0,0)',
      },
      showControlBar: false,
      sliders: 'none',
      type: 'area',
    },
    nodes: {
      mainStyle: {
        c: 'white',
        b: '#444',
        fbc: 'rgba(0,0,0,0)',
        fc: '#444',
        fs: 22,
        tc: false,
        e: 1,
        bw: 1,
      },
    },
    links: {
      c: '#444',
      w: 1,
      a2: true,
    },
    layout: {
      name: 'organic',
      layoutOptions: null,
    },
    customNavigation: true,
    timebarDisplayed: true,
  },
};


// Invert the colours of the minimalist style
// Minimalist Dark definition
const minimalistDark = { name: 'minimalistDark',
  styleOptions: {
    data,
    chartOptions: {
      arrows: 'normal',
      backColour: '#123',
      overview: { icon: false, shown: false },
      fontFamily: 'georgia',
      selectedNode: {
        ha0: {
          r: 35,
          w: 5,
          c: '#f2f2f2',
        },
        fbc: '#f2f2f2',
        fc: '#123',
      },
      selectedLink: {
        c: '#f2f2f2',
        w: 5,
      },
    },
    timeBarOptions: {
      backColour: '#123',
      fontColour: '#ddd',
      fontFamily: 'georgia',
      histogram: {
        colour: '#808c99',
        highlightColour: '#606B77',
      },
      maxRange: {
        units: 'month',
        value: 24,
      },
      minScale: {
        units: 'week',
        value: 2,
      },
      scale: {
        highlightColour: '#204060',
      },
      showControlBar: false,
      sliders: 'free',
      sliderColour: 'rgba(17, 34, 51, 0.6)',
      sliderLineColour: '#ddd',
      type: 'histogram',
    },
    nodes: {
      mainStyle: {
        c: '#606B77',
        b: '#ddd',
        fc: '#ddd',
        fbc: 'rgba(0,0,0,0)',
        fs: 22,
        tc: false,
        e: 1,
        bw: 1,
      },
    },
    links: {
      c: '#ddd',
      w: 1,
      a2: true,
    },
    layout: {
      name: 'organic',
      layoutOptions: null,
    },
    customNavigation: true,
    timebarDisplayed: true,
  } };

// Name Badges definition
// Create the two different types of glyphs displayed on the style

shadows.items.forEach((item) => {
  if (item.type === 'node') {
    item.g = [{ r: 45,
      w: true,
      b: 'rgba(0,0,0,0)',
      t: item.d.fullName,
      fc: '#444',
      ff: 'sans-serif' }];
    if (item.t === 'JP' || item.t === 'DM') {
      item.g[0] = Object.assign(item.g[0], { p: 45, e: 1.5, c: 'rgba(200,200,200,0.8)' });
      item.c = '#FFBF00';
      item.e = 2;
      item.fc = '#444';
    } else {
      item.g[0] = Object.assign(item.g[0], { p: 180, e: 2, c: 'rgba(0,0,0,0)' });
      item.c = '#FF6352';
      item.fc = 'white';
      item.e = 1;
    }
  }
});

const nameBadges = { name: 'nameBadges',
  styleOptions: {
    data: shadows,
    chartOptions: {
      arrows: 'normal',
      backColour: '#E8E8E8',
      overview: {
        backColour: '#CECECE',
        borderColour: '#888888',
        icon: true,
      },
      selectedNode: {
        bs: 'dashed',
        b: '#FF7062',
        fb: 'rgba(255, 112, 98,0.6)',
      },
      selectedLink: {
        c: '#FF7062',
        ls: 'dashed',
      },
    },
    nodes: {
      mainStyle: {
        b: 'white',
        fbc: 'rgba(0,0,0,0)',
        fs: 22,
        tc: true,
        bw: 7,
        ha0: { c: 'rgba(220,220,220,1)', r: 34, w: 1 },
        ha1: { c: 'rgba(220,220,220,0.8)', r: 35, w: 1 },
        ha2: { c: 'rgba(220,220,220,0.6)', r: 36, w: 1 },
        ha3: { c: 'rgba(220,220,220,0.4)', r: 37, w: 1 },
        ha4: { c: 'rgba(220,220,220,0.2)', r: 38, w: 1 },
        ff: 'sans-serif',
      },
    },
    links: {
      c: '#888',
      t: '',
      off: 0,
      w: 3,
      a2: true,
    },
    layout: {
      name: 'hierarchy',
      layoutOptions: {
        linkShape: 'curved',
        top: ['343116', '343130'],
        tightness: 3.5,
      },
    },
    timebarDisplayed: false,
  } };

// Pop Art definition
// Set random values for the donuts, glyphs and link width,
// assign levels for the sequential layout and set custon enlargment values
// for specific nodes.
donuts.items.forEach((item) => {
  if (item.type === 'node') {
    item.donut = {
      c: ['#FFBF00', '#7F9FFF', '#FF9F7F', '#CFFFBF'],
      w: 0,
      b: '#112251',
      bw: 0,
      v: [Math.random() * 3, 2, Math.random() * 5, 3],
    };

    item.g = [{
      p: 0,
      r: 0,
      c: 'white',
      b: 'white',
      fc: '#444',
      e: 2.4,
      t: Math.round(Math.random() * 10, 1).toString(),
    }];

    // Mid level node
    if (item.d.reports && donuts.items.find((donutItem) => donutItem.d.reports === item.t)) {
      item.d.level = 1;
      item.e = 2;
    } else {
      item.e = 1;
      // Top level node who reports to no one
      if (!item.d.reports) {
        item.d.level = 0;
      } else {
        item.d.level = 2;
      }
    }
  } else {
    item.w = Math.round(Math.random() * 20, 1);
  }
});

const popArt = { name: 'popArt',
  styleOptions: {
    data: donuts,
    chartOptions: {
      arrows: 'normal',
      backColour: '#112251',
      fontFamily: 'American Typewriter',
      overview: { icon: false, shown: false },
      selectedNode: {
        ha0: {
          r: 45,
          w: 15,
          c: '#FF7062',
        },
        fbc: '#FF7062',
        fc: 'white',
      },
      selectedLink: {
        c: '#FF7062',
        ls: 'dotted',
      },
    },
    nodes: {
      mainStyle: {
        fc: '#FF9F7F',
        c: 'white',
        b: '#444',
        fbc: 'rgba(0,0,0,0)',
        fs: 22,
        tc: false,
        bw: 1,
      },
    },
    links: {
      c: '#eee',
      a2: true,
    },
    layout: {
      name: 'sequential',
      layoutOptions: {
        top: [],
        level: 'level',
        straighten: false,
        stretch: 1.5,
        linkShape: 'curved'
      },
    },
    timebarDisplayed: false,
  } };

// Aweseome Gloom definition
// Assign different font icons & font families depending on whether the node is an actor or
// a movie
const awesomeGloom = { name: 'awesomeGloom',
  styleOptions: {
    data: matrix,
    chartOptions: {
      arrows: 'normal',
      navigation: { shown: false },
      backColour: '#37474f',
      fontFamily: 'sans-serif',
      overview: { icon: false, shown: false },
      selectedNode: {
        fs: 20,
        c: '#f0f4c3',
        fc: '#cfd8dc',
      },
      selectedLink: {
        c: '#f0f4c3',
      },
      imageAlignment: getImageAlignment(),
    },
    nodes: {
      mainStyle: {
        c: 'rgba(0,0,0,0)',
        tc: false,
        fbc: 'rgba(0,0,0,0)',
        fc: '#cfd8dc',
        fb: true,
        b: '#607d8b',
        bw: 1,
      },
      actor: {
        fs: 12,
        fi: {
          t: "far fa-user",
          ff: 'Font Awesome 5 Free',
          c: '#e0f2f1',
        },
      },
      movie: {
        fs: 15,
        fi: { t: 'fas fa-video',
          ff: 'Font Awesome 5 Free',
          c: '#f0f4c3',
        },
      },
    },
    links: {
      w: 2,
      c: '#62727b',
    },
    layout: {
      name: 'lens',
      layoutOptions: null,
    },
    customNavigation: true,
    timebarDisplayed: false,
  },
};

// Assign the appropriate styling depending on node type defined above and set link gradients
const lightMonochrome = { name: 'lightMonochrome',
  styleOptions: {
    data: lightStyle,
    chartOptions: {
      arrows: 'normal',
      backColour: '#fff',
      fontFamily: 'sans-serif',
      overview: {
        backColour: '#fff',
        borderColour: '#df2020',
        icon: true,
      },
      selectedNode: {
        b: '#808080',
        c: 'rgba(242,242,242,0.8)',
        fbc: 'rgba(255,255,255,0.7)',
        fc: '#595959',
        fs: 20,
        e: 2.5,
        fb: true,
      },
      selectedLink: {
        c: '#333333',
        c2: '#333333',
        w: 10,
      },
      imageAlignment: getImageAlignment(),
    },
    nodes: {
      mainStyle: {
        fc: 'rgba(0,0,0,0)',
        fbc: 'rgba(0,0,0,0)',
        c: 'rgba(0,0,0,0)',
      },
      server: {
        fi: {
          t: 'fas fa-server',
          c: '#cc3333',
        },
      },
      service: {
        fi: {
          t: 'fas fa-mobile-alt',
          c: '#a65959',
        },
      },
      business: {
        fi: {
          t: 'fas fa-dollar-sign',
          c: '#808080',
        },
      },
      san: {
        fi: {
          t: 'fas fa-globe',
          c: '#df2020',
        },
      },
      virtual: {
        fi: {
          t: 'fas fa-desktop',
          c: '#b94646',
        },
      },
    },
    links: {
      w: 4,
      off: 0,
      a2: true,
      gradient: true,
    },
    layout: {
      name: 'radial',
      layoutOptions: {
        top: ['141'],
        tightness: 0
      },
    },
    customNavigation: true,
    timebarDisplayed: false,
  } };

// Push the separately defined styles into the main styles object
const createdStyles = [minimalist, minimalistDark, nameBadges, popArt, awesomeGloom,
  lightMonochrome];
createdStyles.forEach((elem) => {
  const newStyle = {};
  newStyle[elem.name] = Object.assign({}, elem);
  Object.assign(styles, newStyle);
});

export default styles;
Loading source