Skip to content
  1. Examples

Virtual properties

This example show how to use the Virtual Properties transformation to add virtual properties to the nodes and edges of the graph.

ts
import Ogma, { VirtualProperties } from '@linkurious/ogma';
type NodeData = {
  type: 'person';
  firstName: string;
  lastName: string;
};
type EdgeData = {};

const ogma = new Ogma<NodeData, EdgeData>({
  container: 'graph-container',
  options: {
    backgroundColor: '#f6f6f6'
  },
  graph: {
    nodes: [
      {
        id: 0,
        data: { type: 'person', firstName: 'John', lastName: 'Smith' },
        attributes: { x: 0, y: 0 }
      },
      {
        id: 1,
        data: { type: 'person', firstName: 'James', lastName: 'Brown' },
        attributes: { x: 30, y: 0 }
      }
    ]
  }
});

ogma.styles.addRule({
  nodeAttributes: {
    text: node => {
      const data = node.getData();

      return Object.keys(data)
        .map(key => {
          const value = data[key as keyof NodeData];
          return key + ': ' + value;
        })
        .join('\n');
    },
    color: 'orange',
    icon: {
      content: '\uf007',
      font: 'Font Awesome 5 Free'
    }
  }
});

const button = document.getElementById('btn') as HTMLButtonElement;
let transformation: VirtualProperties<NodeData, EdgeData> | null;

const enableButton = () => {
  button.disabled = false;
  button.textContent = button.textContent === 'Apply' ? 'Undo' : 'Apply';
};

document.getElementById('btn')!.addEventListener('click', async () => {
  if (transformation) {
    await transformation.destroy(500);
    enableButton();
    button.disabled = true;
    transformation = null;
  } else {
    transformation = ogma.transformations.addVirtualProperties({
      nodeSelector: node => node.getData('type') === 'person',
      nodeDataFunction: node => ({
        fullName: node.getData('firstName') + ' ' + node.getData('lastName')
      })
    });
    button.disabled = true;
    await transformation.whenApplied();
    enableButton();
  }
});
html
<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <link
      href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/solid.min.css"
      rel="stylesheet"
    />

    <link type="text/css" rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <div id="graph-container"></div>
    <div class="panel">
      <button id="btn">Apply</button>
    </div>
    <script type="module" src="index.ts"></script>
  </body>
</html>
css
html,
body {
  font-family: 'Inter', sans-serif;
}

:root {
  --base-color: #4999f7;
  --active-color: var(--base-color);
  --gray: #d9d9d9;
  --white: #ffffff;
  --lighter-gray: #f4f4f4;
  --light-gray: #e6e6e6;
  --inactive-color: #cee5ff;
  --group-color: #525fe1;
  --group-inactive-color: #c2c8ff;
  --selection-color: #04ddcb;
  --darker-gray: #b6b6b6;
  --dark-gray: #555;
  --dark-color: #3a3535;
  --edge-color: var(--dark-color);
  --border-radius: 5px;
  --button-border-radius: var(--border-radius);
  --edge-inactive-color: var(--light-gray);
  --button-background-color: #ffffff;
  --shadow-color: rgba(0, 0, 0, 0.25);
  --shadow-hover-color: rgba(0, 0, 0, 0.5);
  --button-shadow: 0 0 4px var(--shadow-color);
  --button-shadow-hover: 0 0 4px var(--shadow-hover-color);
  --button-icon-color: #000000;
  --button-icon-hover-color: var(--active-color);
}

#graph-container {
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  position: absolute;
  margin: 0;
  overflow: hidden;
}

.ui {
  position: absolute;
  display: flex;
  flex-direction: column;
  gap: 0.5em;
}

#custom-group-btn {
  top: 40px;
}

.panel {
  background: var(--button-background-color);
  border-radius: var(--button-border-radius);
  box-shadow: var(--button-shadow);
  padding: 10px;
}

.panel {
  position: absolute;
  top: 20px;
  left: 20px;
}

.panel h2 {
  text-transform: uppercase;
  font-weight: 400;
  font-size: 14px;
  margin: 0;
}

.panel {
  margin-top: 1px;
  padding: 5px 10px;
  text-align: center;
}

.panel button {
  background: var(--button-background-color);
  border: none;
  border-radius: var(--button-border-radius);
  border-color: var(--shadow-color);
  padding: 5px 10px;
  cursor: pointer;
  width: 100%;
  color: var(--dark-gray);
  border: 1px solid var(--light-gray);
}

.panel button:hover {
  background: var(--lighter-gray);
  border: 1px solid var(--darker-gray);
}

.panel button[disabled] {
  color: var(--light-gray);
  border: 1px solid var(--light-gray);
  background-color: var(--lighter-gray);
}