Appearance
Data-driven styles
This example shows how to use nodes and edges data as well as rule slice and map to style your graph.
ts
import Ogma from '@linkurious/ogma';
import { getIconCode } from './utils';
const fontFamily = 'IBM Plex Sans';
interface NodeData {
properties: {
name: string;
funding_total?: number;
picture: string;
};
categories: ('INVESTOR' | 'MARKET' | 'COMPANY' | 'PERSON')[];
}
interface EdgeData {
properties: {
raised_amount_usd: number;
};
type: 'INVESTED_IN' | 'ACQUIRED' | 'HAS_MARKET';
}
const ogma = new Ogma<NodeData, EdgeData>({
container: 'graph-container'
});
// Load data from a json file.
const graph = await Ogma.parse.jsonFromUrl<NodeData, EdgeData>(
'solarCity-nostyle.json'
);
await ogma.setGraph(graph);
await ogma.view.locateGraph();
// Define the Node style rules
ogma.styles.addNodeRule({
// the label is the value os the property name.
text: {
content: node => node.getData('properties.name'),
font: fontFamily,
size: 14
},
// the size is proportional to the funding_total property
radius: ogma.rules.slices({
field: 'properties.funding_total',
values: { nbSlices: 7, min: 3, max: 10 }
}),
// the color is based on the funding_total property (from red to purple)
color: ogma.rules.slices({
field: 'properties.funding_total',
values: [
'#161344',
'#453455',
'#632654',
'#86315b',
'#a93c63',
'#cd476a',
'#E94E5E'
],
fallback: '#F79970'
}),
// assign icons based on the node category
icon: {
content: ogma.rules.map({
field: 'categories',
values: {
COMPANY: getIconCode('icon-rocket'),
INVESTOR: getIconCode('icon-landmark'),
MARKET: getIconCode('icon-gem'),
PERSON: getIconCode('icon-user-round')
}
}),
font: 'Lucide',
scale: 0.6,
style: 'bold',
color: 'white'
}
});
// Define the Edge style rules
ogma.styles.addEdgeRule({
// the label is the value os the property name.
text: {
content: edge => edge.getData('type'),
font: fontFamily
},
// the size is proportional to the raised_amount_usd property
width: ogma.rules.slices({
field: 'properties.raised_amount_usd',
values: { nbSlices: 3, min: 0.75, max: 3 }
}),
// the color is based on the raised_amount_usd property (from blue to black)
color: ogma.rules.slices({
field: 'properties.raised_amount_usd',
values: ['#EB7D7D', '#E94E5E', '#132b43'],
fallback: '#38040E',
reverse: true
}),
// the shape is based on the type of edge
shape: ogma.rules.map({
field: 'type',
values: {
INVESTED_IN: 'arrow',
ACQUIRED: 'tapered',
HAS_MARKET: 'dotted'
}
})
});
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
href="https://cdn.jsdelivr.net/npm/lucide-static@0.483.0/font/lucide.css"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&display=swap"
rel="stylesheet"
/>
<link type="text/css" rel="stylesheet" href="styles.css" />
</head>
<body>
<div id="graph-container"></div>
<!-- we force the loading of the font awesome -->
<i class="fa fa-camera-retro fa-1x" style="color: rgba(0, 0, 0, 0)"></i>
<script type="module" src="index.ts"></script>
</body>
</html>
css
:root {
--font-family: 'IBM Plex Sans', sans-serif;
}
#graph-container {
top: 0;
bottom: 0;
left: 0;
right: 0;
position: absolute;
margin: 0;
overflow: hidden;
}
json
{
"nodes": [
{
"id": 8666,
"data": {
"properties": {
"name": "Elon Musk",
"permalink": "/person/elon-musk",
"url": "http://www.crunchbase.com/person/elon-musk",
"picture": "img/musk.jpg"
},
"categories": [
"PERSON",
"INVESTOR"
]
},
"x": 25.858288814166933,
"y": -7.103984513542148
},
{
"id": 6870,
"data": {
"properties": {
"name": "SolarCity",
"permalink": "/organization/solarcity",
"founded_at": "01/01/2006",
"first_funding_at": "15/09/2006",
"market": " Construction ",
"founded_quarter": "2006-Q1",
"founded_year": 2006,
"state": "CA",
"url": "http://www.crunchbase.com/organization/solarcity",
"country": "USA",
"homepage_url": "http://www.solarcity.com",
"logo": "http://www.crunchbase.com/organization/solarcity/primary-image/raw",
"founded_month": "2006-01",
"funding_rounds": 13,
"status": "operating",
"funding_total": 1045040000,
"region": "SF Bay Area",
"category": "|Construction|Clean Technology|",
"last_funding_at": "18/06/2013"
},
"categories": [
"COMPANY",
"INVESTOR"
]
},
"x": 0.09298533946275711,
"y": 0.41120362281799316
},
{
"id": 7396,
"data": {
"properties": {
"name": "Tesla Motors",
"permalink": "/organization/tesla-motors",
"founded_at": "01/01/2003",
"first_funding_at": "01/04/2004",
"market": " Automotive ",
"founded_quarter": "2003-Q1",
"founded_year": 2003,
"state": "CA",
"url": "http://www.crunchbase.com/organization/tesla-motors",
"country": "USA",
"homepage_url": "http://www.teslamotors.com",
"logo": "http://www.crunchbase.com/organization/tesla-motors/primary-image/raw",
"founded_month": "2003-01",
"funding_rounds": 11,
"status": "operating",
"funding_total": 823000000,
"region": "SF Bay Area",
"category": "|Automotive|",
"last_funding_at": "10/10/2012"
},
"categories": [
"COMPANY"
]
},
"x": 85.876122673705,
"y": -21.207117111759345
},
{
"id": 2982,
"data": {
"properties": {
"name": "First Solar",
"permalink": "/organization/first-solar",
"founded_at": "01/01/1999",
"first_funding_at": "18/06/2013",
"market": " Semiconductors ",
"founded_quarter": "1999-Q1",
"founded_year": 1999,
"state": "AZ",
"url": "http://www.crunchbase.com/organization/first-solar",
"country": "USA",
"homepage_url": "http://www.firstsolar.com",
"logo": "http://www.crunchbase.com/organization/first-solar/primary-image/raw",
"founded_month": "1999-01",
"funding_rounds": 1,
"status": "operating",
"funding_total": 427700000,
"region": "Phoenix",
"category": "|Semiconductors|Clean Technology|",
"last_funding_at": "18/06/2013"
},
"categories": [
"COMPANY",
"INVESTOR"
]
},
"x": -27.6874947092224,
"y": -21.207117111759345
},
{
"id": 3388,
"data": {
"properties": {
"name": "Google",
"permalink": "/organization/google",
"founded_at": "07/09/1998",
"first_funding_at": "01/08/1998",
"market": " Software ",
"founded_quarter": "1998-Q3",
"founded_year": 1998,
"state": "CA",
"url": "http://www.crunchbase.com/organization/google",
"country": "USA",
"homepage_url": "https://www.google.com",
"logo": "http://www.crunchbase.com/organization/google/primary-image/raw",
"founded_month": "1998-09",
"funding_rounds": 2,
"status": "operating",
"funding_total": 25100000,
"region": "SF Bay Area",
"category": "|Software|Video Streaming|Information Technology|Blogging Platforms|Email|Search|",
"last_funding_at": "07/06/1999"
},
"categories": [
"COMPANY"
]
},
"x": 17.30193137441551,
"y": -22.990838850758205
},
{
"id": 8372,
"data": {
"properties": {
"name": "Zep Solar",
"permalink": "/organization/zep-solar",
"founded_at": "01/01/2009",
"first_funding_at": "20/11/2013",
"market": " Clean Technology ",
"founded_quarter": "2009-Q1",
"founded_year": 2009,
"state": "CA",
"url": "http://www.crunchbase.com/organization/zep-solar",
"country": "USA",
"homepage_url": "http://www.zepsolar.com",
"logo": "http://www.crunchbase
...
ts
// dummy icon element to retrieve the HEX code, it should be hidden
const placeholder = document.createElement('span');
document.body.appendChild(placeholder);
placeholder.style.visibility = 'hidden';
// helper routine to get the icon HEX code
export function getIconCode(className: string) {
placeholder.className = className;
const code = getComputedStyle(placeholder, ':before').content;
return code[1];
}