substrate

A high-speed three.js substrate for visualizing biofidelic data

View the Project on GitHub aplbrain/substrate

Making Your Own Layer

If you haven’t worked with substrate before, check out the Getting Started Tutorial.

Now that we have a scene with an AxisLayer in it, let’s build our own layer.

GraphLayer.js

Create a new file in your project called GraphLayer.js.

GraphLayer.js

import Layer from 'apl-substrate/components/Layer';

export default class GraphLayer extends Layer {
    constructor(opts) {
        super(opts);
    }

    requestInit(scene) {
        // Initialize this layer.
    }
}

We’ve created a new type of Layer with a constructor (ignore it for now) and a requestInit function. requestInit is called when a Layer is added to a Visualizer, and then never again. You should use this to add items into the scene the first time; there is another function that we’ll cover later for modifying existing objects and enabling animation or interaction with your layer.

For more documentation on Layers, check out the docs.

Adding Data

Here’s our graph:

{
    nodes: [{x: 10, y: 20, z: 30}, {x: 15, y: 25, z: 35}],
    edges: [[0, 1]]
}

Simple! Two nodes, one edge between them. Let’s render the nodes as sphere and the edge as a line.

We’ll write this in the requestInit function, since we don’t want to add another copy of the graph on every frame! (You’d notice quickly; your browser would probably crash in a few seconds.)


requestInit(scene) {
    let self = this;

    let graph = {
        nodes: [{x: 10, y: 20, z: 30}, {x: 15, y: 25, z: 35}],
        edges: [[0, 1]]
    };

    graph.nodes.forEach(node => {
        let newSphere = new THREE.Mesh(
            new THREE.SphereGeometry(5, 5, 5),
            new THREE.MeshBasicMaterial({ color: 0x550000 })
        );
        newSphere.position.set(node.x, node.y, node.z);
        self.children.append(newSphere);
        self.scene.add(newSphere);
    });

    let edgeGeometry = new THREE.Geometry();
    graph.edges.forEach(edge => {
        let start = graph.nodes[edge[0]];
        let stop = graph.nodes[edge[1]];
        edgeGeometry.vertices.push(
            new THREE.Vector3(start.x, start.y, start.z)
        );
        edgeGeometry.vertices.push(
            new THREE.Vector3(stop.x, stop.y, stop.z)
        );
    });
    let edges = new THREE.Line(
        edgeGeometry,
        new THREE.LineBasicMaterial({
            color: 0x00ffff
        })
    );
    self.children.append(edges);
    scene.add(edges);
}