//
// 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
