Skip to content

Commit

Permalink
Rebase contributions.
Browse files Browse the repository at this point in the history
  • Loading branch information
thomcom committed Jun 6, 2022
1 parent 1a76bc1 commit dee3fc0
Show file tree
Hide file tree
Showing 19 changed files with 713 additions and 4 deletions.
7 changes: 7 additions & 0 deletions examples/extra-large-graphs/edge.fast.frag.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
precision mediump float;

varying vec4 v_color;

void main(void) {
gl_FragColor = v_color;
}
18 changes: 18 additions & 0 deletions examples/extra-large-graphs/edge.fast.vert.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
attribute vec2 a_position;
attribute vec4 a_color;

uniform mat3 u_matrix;

varying vec4 v_color;

void main() {
// Scale from [[-1 1] [-1 1]] to the container:
gl_Position = vec4(
(u_matrix * vec3(a_position, 1)).xy,
0,
1
);

// Extract the color:
v_color = a_color;
}
99 changes: 99 additions & 0 deletions examples/extra-large-graphs/edge.gpu.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
* Sigma.js WebGL Renderer Fast Edge Program
* ==========================================
*
* Program rendering edges using GL_LINES which is presumably very fast but
* won't render thickness correctly on some GPUs and has some quirks.
* @module
*/
import { AbstractEdgeProgram } from "sigma/rendering/webgl/programs/common/edge";
import { RenderParams } from "sigma/rendering/webgl/programs/common/program";

import fragmentShaderSource from "./edge.fast.frag.glsl";
import vertexShaderSource from "./edge.fast.vert.glsl";

let POINTS = 2;
const ATTRIBUTES = 3;

export default class EdgeGpuProgram extends AbstractEdgeProgram {
positionLocation: GLint;
colorLocation: GLint;
matrixLocation: WebGLUniformLocation;

constructor(gl: WebGLRenderingContext) {
super(gl, vertexShaderSource, fragmentShaderSource, POINTS, ATTRIBUTES);

// Locations:
this.positionLocation = gl.getAttribLocation(this.program, "a_position");
this.colorLocation = gl.getAttribLocation(this.program, "a_color");

// Uniform locations:
const matrixLocation = gl.getUniformLocation(this.program, "u_matrix");
if (matrixLocation === null) throw new Error("EdgeGpuProgram: error while getting matrixLocation");
this.matrixLocation = matrixLocation;

this.bind();
}

bind(): void {
const gl = this.gl;

// Bindings
gl.enableVertexAttribArray(this.positionLocation);
gl.enableVertexAttribArray(this.colorLocation);

gl.vertexAttribPointer(
this.positionLocation,
2,
gl.FLOAT,
false,
this.attributes * Float32Array.BYTES_PER_ELEMENT,
0,
);
gl.vertexAttribPointer(
this.colorLocation,
4,
gl.UNSIGNED_BYTE,
true,
this.attributes * Float32Array.BYTES_PER_ELEMENT,
8,
);
}

computeIndices(): void {
//nothing to do
}

/* The node program for my example
process(data, hidden: boolean, offset: number): void {
this.array = data.buffer.getColumn('nodes').toArray();
POINTS = this.array.length / ATTRIBUTES;
this.points = POINTS;
}
*/

process(
sourceData,
targetData,
data,
hidden: boolean,
offset: number,
): void {
this.array = data.buffer.getColumn('edges').toArray();
POINTS = this.array.length / ATTRIBUTES;
this.points = POINTS;
}

render(params: RenderParams): void {
if (this.hasNothingToRender()) return;

const gl = this.gl;
const program = this.program;

gl.useProgram(program);

gl.uniformMatrix3fv(this.matrixLocation, false, params.matrix);

gl.drawArrays(gl.LINES, 0, this.array.length / ATTRIBUTES);
}
}
47 changes: 47 additions & 0 deletions examples/extra-large-graphs/generate-graph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* This example aims at showcasing sigma's performances.
*/

const fs = require('fs');
const seedrandom = require('seedrandom');

const {Graph} = require('graphology');

const circlepack = require( "graphology-layout/circlepack");
const clusters = require( "graphology-generators/random/clusters");

const rng = seedrandom("sigma");
const state = {
order: 1000000,
size: 2000000,
clusters: 3,
edgesRenderer: 'edges-fast'
};

// 1. Generate a graph:
const graph = clusters(Graph, { ...state, rng });
circlepack.assign(graph, {
hierarchyAttributes: ["cluster"],
});
const colors = {};
for (let i = 0; i < +state.clusters; i++) {
colors[i] = "#" + Math.floor(rng() * 16777215).toString(16);
}
let i = 0;
graph.forEachNode((node, { cluster }) => {
graph.mergeNodeAttributes(node, {
size: graph.degree(node) / 3,
label: `Node n°${++i}, in cluster n°${cluster}`,
color: colors[cluster + ""],
});
});

// 2. Save the graph:
fs.writeFile('./large-graph.json', JSON.stringify(graph.toJSON(), {}, 2), (err) => {
if(err) {
console.log('unable to savfe file');
} else {
console.log('file saved?');
}
});
console.log('Finished step 2');
49 changes: 49 additions & 0 deletions examples/extra-large-graphs/generate-graph.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* This example aims at showcasing sigma's performances.
*/

const fs = require('fs');
const seedrandom = require('seedrandom');

const {Graph} = require('graphology');

const circlepack = require('graphology-layout/circlepack');
const clusters = require('graphology-generators/random/clusters');
const FA2Layout = require('graphology-layout-forceatlas2/worker');
const forceAtlas2 = require('graphology-layout-forceatlas2');

const rng = seedrandom('sigma');
const state = {
order: parseInt(process.argv[2]),
size: parseInt(process.argv[3]),
clusters: parseInt(process.argv[4]),
edgesRenderer: 'edges-fast'
};

// 1. Generate a graph:
const graph = clusters(Graph, {...state, rng});
circlepack.assign(graph, {
hierarchyAttributes: ['cluster'],
});
const colors = {};
for (let i = 0; i < +state.clusters; i++) {
colors[i] = '#' + Math.floor(rng() * 16777215).toString(16);
}
let i = 0;
graph.forEachNode((node, {cluster}) => {
graph.mergeNodeAttributes(node, {
size: graph.degree(node),
label: `Node n°${++i}, in cluster n°${cluster}`,
color: colors[cluster + ''],
});
});

// 2. Save the graph:
fs.writeFile(process.argv[5], JSON.stringify(graph.toJSON(), null, 2), (err) => {
if (err) {
console.log('unable to save file');
} else {
console.log('file saved?');
}
});
console.log('Finished step 2');
61 changes: 61 additions & 0 deletions examples/extra-large-graphs/gpu-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/**
* This example aims at showcasing sigma's performances.
*/

<<<<<<< HEAD
import arrow from 'apache-arrow';
=======
import {Table} from 'apache-arrow';
>>>>>>> main

async function request(obj) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.open(obj.method || 'GET', obj.url || obj);
if (obj.headers) {
Object.keys(obj.headers).forEach(key => { xhr.setRequestHeader(key, obj.headers[key]); });
}
xhr.onload = () => {
try {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(xhr.statusText);
}
} catch (e) { reject(e); }
};
xhr.onerror = () => reject(xhr.statusText);
xhr.send(obj.body);
});
}

const SERVER = 'http://localhost:3000';
const DATASET_ROUTE = '/graphology/read_large_demo?filename=../../public/fewer-edges.json';
const NODES_ROUTE = '/graphology/get_column/nodes';
const NODES_BOUNDS_ROUTE = '/graphology/nodes/bounds';
const NODES_BUFFER_ROUTE = '/graphology/nodes/';
const EDGES_BUFFER_ROUTE = '/graphology/edges/';
const TABLE_ROUTE = '/graphology/get_table';

const GpuLoader = {
init: async () => request(SERVER + DATASET_ROUTE),
getTable: async (table) => {
return arrow.tableFromIPC(fetch(SERVER + TABLE_ROUTE + '/' + table, {method: 'GET'}));
},
getColumn: async (table, column) => {
const table_route = {'nodes': '/graphology/get_column/nodes/'}[table];
const column_route = SERVER + table_route + column;
return arrow.tableFromIPC(fetch(column_route, {method: 'GET'}));
},
getNodesBounds: async () => request(SERVER + NODES_BOUNDS_ROUTE),
getNodesBuffer: async () => {
const route = SERVER + NODES_BUFFER_ROUTE;
return arrow.tableFromIPC(fetch(route, {method: 'GET'}));
},
getEdgesBuffer: async () => {
const route = SERVER + EDGES_BUFFER_ROUTE;
return arrow.tableFromIPC(fetch(route, {method: 'GET'}));
}
};

export default GpuLoader;
89 changes: 89 additions & 0 deletions examples/extra-large-graphs/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Sigma example: Performances showcase</title>
</head>
<body>
<style>
html,
body,
#sigma-container {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
font-family: sans-serif;
}
#buttons {
position: absolute;
right: 1em;
top: 1em;
display: flex;
}

input[type="number"] {
width: 5em;
}
h4 {
margin: 0;
}
fieldset {
border: none;
}
h4,
fieldset > div {
margin-bottom: 0.2em;
}
button {
margin-right: 1em;
display: inline-block;
text-align: center;
background: white;
outline: none;
border: 1px solid dimgrey;
border-radius: 2px;
cursor: pointer;
}
</style>
<div id="sigma-container"></div>
<div id="buttons">
<form>
<fieldset>
<h4>Graph</h4>
<div>
<input type="number" id="order" name="order" min="2" step="1" value="5000" />
<label for="order">Number of nodes</label>
</div>
<div>
<input type="number" id="size" name="size" min="1" step="1" value="10000" />
<label for="size">Number of edges</label>
</div>
<div>
<input type="number" id="clusters" name="clusters" min="1" step="1" value="3" />
<label for="clusters">Number of clusters</label>
</div>
</fieldset>
<fieldset>
<h4>Edges renderer</h4>
<div>
<input type="radio" name="edges-renderer" id="edges-default" value="edges-default" />
<label for="edges-default">Default</label>
</div>
<div>
<input type="radio" name="edges-renderer" id="edges-fast" value="edges-fast" checked />
<label for="edges-fast">Faster (only 1px thick edges)</label>
</div>
</fieldset>
<fieldset>
<button type="submit">Reset graph</button>
<button type="button" id="fa2">Start layout ▶</button>
</fieldset>
</form>
</div>
<script src="build/bundle.js"></script>
</body>
</html>
Loading

0 comments on commit dee3fc0

Please sign in to comment.