user10046100
user10046100

Reputation: 85

Zooming in a D3 visualization that uses WebGL through stardustjs

I'm currently making a force network visualization that involves a large number of nodes and edges (over 50k+) using a new library called stardust.js. Stardust uses WebGL to make the rendering of nodes and edges much quicker than Canvas/D3.

However, I am unable to figure out how to add zoom and pan to this visualization.

According to this thread on stardust's google group, the creator of the stardust library mentions that there is no support for zoom and pan right now, but it is possible to implement this by setting in the mark specification by setting zoom and pan specifications as parameters.

import { Circle } from P2D;

mark MyMark(translateX: float, translateY: float, scale: float, x: float, y: float, radius: float) {
    Circle(Vector2(x * scale + translateX, y * scale + translateY), radius);
}
https://stackoverflow.com/editing-help
// In the js code you can do something like:
marks.attr("translateX", 10).attr("translateY", 15).attr("scale", 2);

This library uses a kind of Typescript language where one defines "marks" (which is what all the nodes and edges are), and it should be possible to define these marks with the above parameters. But how can one implement this?

Is there an easier way to do this? Can one add a library like Pixi.js on to this visualization to make it zoom and pan?

Upvotes: 4

Views: 1579

Answers (1)

rioV8
rioV8

Reputation: 28633

There is no need to define custom marks (it can be done with custom marks).

The position of the objects is controlled by a Stardust.scale().

var positions = Stardust.array("Vector2")
    .value(d => [d.x, d.y])
    .data(nodes);

var positionScale = Stardust.scale.custom("array(pos, value)")
    .attr("pos", "Vector2Array", positions)

By modifying the value function you can zoom and translate.

By attaching the zoom to the canvas the star dust drag is no longer working. But that is a different problem.

I used the example https://stardustjs.github.io/examples/graph/

In the zoom callback save the zoom parameters and request a new render of the graph.

var fps = new FPS();

var zoom_scale = 1.0, zoom_t_x = 0.0, zoom_t_y = 0.0;

d3.select(canvas).call(d3.zoom().on("zoom", zoomed));
function zoomed() {
    zoom_scale = d3.event.transform.k;
    zoom_t_x = d3.event.transform.x;
    zoom_t_y = d3.event.transform.y;
    requestRender();
}

function render() {

    positions.value(d => [d.x*zoom_scale + zoom_t_x, d.y*zoom_scale + zoom_t_y]);

    ......
}


The example contains an error.

When you use a slider the simulation never stops because the alphaTarget is set to 0.3.

force.alphaTarget(0.3).restart();

It should be changed to

force.alpha(0.3).alphaTarget(0).restart();

Upvotes: 3

Related Questions