[sigma.js] different graphshot technique

parent 3548afdc
......@@ -2,7 +2,8 @@
import Graph from 'graphology';
import Sigma from 'sigma';
import { takeScreenshot } from '../../src/external-deps/sigmajs-screenshot.js';
//import { takeScreenshot } from '../../src/external-deps/sigmajs-screenshot.js';
import takeScreenshot from '../../src/external-deps/sigmajs-screenshot-with-canvas.js';
import CircleNodeProgram from 'sigma/rendering/webgl/programs/node.fast';
import ContourCircleNodeProgram from '../../src/external-deps/sigmajs-circle-with-contour.js';
import TriangleNodeProgram from '../../src/external-deps/sigmajs-triangle.js';
......
import Sigma from "sigma";
// Copied from https://github.com/jacomyal/sigma.js/blob/main/examples/png-snapshot/saveAsPNG.ts
// Related issue: https://github.com/jacomyal/sigma.js/issues/1348
/**
* There is a bug I can't find sources about, that makes it impossible to render
* WebGL canvases using `#drawImage` as long as they appear onscreen. There are
* basically two solutions:
* 1. Use `webGLContext#readPixels`, transform it to an ImageData, put that
* ImageData in another canvas, and draw this canvas properly using
* `#drawImage`
* 2. Hide the sigma instance
* 3. Create a new sigma instance similar to the initial one (dimensions,
* settings, graph, camera...), use it and kill it
* This exemple uses this last solution.
*/
export default function takeScreenshot(renderer) { // , inputLayers?: string[]) {
const { width, height } = renderer.getDimensions();
// This pixel ratio is here to deal with retina displays.
// Indeed, for dimensions W and H, on a retina display, the canvases
// dimensions actually are 2 * W and 2 * H. Sigma properly deals with it, but
// we need to readapt here:
const pixelRatio = window.devicePixelRatio || 1;
const tmpRoot = document.createElement("DIV");
tmpRoot.style.width = `${width}px`;
tmpRoot.style.height = `${height}px`;
tmpRoot.style.position = "absolute";
tmpRoot.style.right = "101%";
tmpRoot.style.bottom = "101%";
document.body.appendChild(tmpRoot);
// Instantiate sigma:
const tmpRenderer = new Sigma(renderer.getGraph(), tmpRoot, renderer.getSettings());
// Copy camera and force to render now, to avoid having to wait the schedule /
// debounce frame:
tmpRenderer.getCamera().setState(renderer.getCamera().getState());
tmpRenderer.refresh();
// Create a new canvas, on which the different layers will be drawn:
const canvas = document.createElement("CANVAS");
canvas.setAttribute("width", width * pixelRatio + "");
canvas.setAttribute("height", height * pixelRatio + "");
const ctx = canvas.getContext("2d");
// Draw a white background first:
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, width * pixelRatio, height * pixelRatio);
// For each layer, draw it on our canvas:
const canvases = tmpRenderer.getCanvases();
//const layers = inputLayers ? inputLayers.filter((id) => !!canvases[id]) : Object.keys(canvases);
const layers = Object.keys(canvases);
layers.forEach((id) => {
ctx.drawImage(
canvases[id],
0,
0,
width * pixelRatio,
height * pixelRatio,
0,
0,
width * pixelRatio,
height * pixelRatio,
);
});
let ret = ctx.canvas.toDataURL('image/png');
return ret;
// Save the canvas as a PNG image:
// canvas.toBlob((blob) => {
// if (blob) FileSaver.saveAs(blob, "graph.png");
// // Cleanup:
// tmpRenderer.kill();
// tmpRoot.remove();
// }, "image/png");
}
import * as twgl from 'twgl.js';
// NOTE This doesn't work on Firefox for some reason. See
// ./sigmajs-screenshot-with-canvas.js
const vertexShader = `
// a_position describes the canvas.
......@@ -164,21 +167,21 @@ export function takeScreenshot(sigma) {
twgl.resizeCanvasToDisplaySize(gl.canvas);
//gl.viewport(0, 0, gl.canvas.width, gl.canvas.height);
let texParams = function(src) {
return { //wrapS: gl.CLAMP_TO_EDGE,
//wrapT: gl.CLAMP_TO_EDGE,
//min: gl.NEAREST,
//mag: gl.NEAREST,
src };
let createTexture = function(src) {
return twgl.createTexture(gl, { //wrapS: gl.CLAMP_TO_EDGE,
//wrapT: gl.CLAMP_TO_EDGE,
//min: gl.NEAREST,
//mag: gl.NEAREST,
src });
};
const uniforms = {
u_edges : twgl.createTexture(gl, texParams(edges)),
u_edgeLabels : twgl.createTexture(gl, texParams(edgeLabels)),
u_nodes : twgl.createTexture(gl, texParams(nodes)),
u_labels : twgl.createTexture(gl, texParams(labels)),
u_hovers : twgl.createTexture(gl, texParams(hovers)),
u_hoverNodes : twgl.createTexture(gl, texParams(hoverNodes)),
u_mouse : twgl.createTexture(gl, texParams(mouse)),
u_edges : createTexture(edges),
u_edgeLabels : createTexture(edgeLabels),
u_nodes : createTexture(nodes),
u_labels : createTexture(labels),
u_hovers : createTexture(hovers),
u_hoverNodes : createTexture(hoverNodes),
u_mouse : createTexture(mouse),
u_resolution : [gl.canvas.width, gl.canvas.height]
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment