jacomyal / sigma.js

A JavaScript library aimed at visualizing graphs of thousands of nodes and edges
https://www.sigmajs.org/
MIT License
11.3k stars 1.59k forks source link

Opacity for edges #1426

Open h-a-s-k opened 6 months ago

h-a-s-k commented 6 months ago

When exporting using the gephi plugin, opacity seems to work fine(?), however with the latest version of sigma.js it doesn't seem to work when setting the edge color to a rgba value. This would be nice to have since sigma.js has great performance (and doesn't leak memory like a few others) but not having opacity support is a dealbreaker for me.

RaphaelHansen commented 6 months ago

+1

jacomyal commented 5 months ago

Hum, that's weird, sigma does support alpha values: image

It looks like there is an issue with how the alpha channel is handled though, because the whiter nodes and edges are, the less the alpha value is considered apparently. So I'll leave the issue opened until I solve this bug.

@h-a-s-k Could you please send some data and/or code, to help me reproduce your issue? Thanks!

RaphaelHansen commented 5 months ago

Hi Alexis,

In case h-a-s-k doesn't get back to you.

My experience is that the 'whiter' or 'brighter' a colour is the more likely it is to turn an opaque white on overlap.

` graph.forEachEdge((edge, attributes, source, target) => { const targetColor = graph.getNodeAttribute(target, "color") || "#ccc"; const edgeOpacity = 0.5;

  if (targetColor.startsWith("rgb(")) {
    const rgbValues = targetColor.substring(4, targetColor.length - 1).split(",");
    const edgeColor = `rgba(${rgbValues[0]}, ${rgbValues[1]}, ${rgbValues[2]}, ${edgeOpacity})`;
    graph.setEdgeAttribute(edge, "color", edgeColor);
  } else {
    const rgbColor = hexToRgb(targetColor);
    if (rgbColor) {
      const edgeColor = `rgba(${rgbColor.r}, ${rgbColor.g}, ${rgbColor.b}, ${edgeOpacity})`;
      graph.setEdgeAttribute(edge, "color", edgeColor);
    } else {
      graph.setEdgeAttribute(edge, "color", targetColor);
    }
  }
});`

Here you can see that the lighter pink/purple colour turns white on overlap. Screenshot 2024-05-28 at 11 22 57 am

Darker colours also get brighter, but they are able to avoid turning completely white: Screenshot 2024-05-28 at 11 18 22 am

I'm no expert in this field but my hypothesis is that it seems that the rgb values are also compounding ontop of eachother on overlap rather than the expected outcome of only the alpha value increasing when edges overlap.

Hopefully this makes sense.

h-a-s-k commented 5 months ago

I tried setting the alpha both as @RaphaelHansen did and also like you showed in https://github.com/jacomyal/sigma.js/commit/68da672a69e80cc8d1ced50d13f6268981d89809. On my graph with 100k+ edges using sigma@3.0.0-beta.19.

When every node and edge is set to red with an alpha of 0.01

edges.forEach((edge, idx) => {
    const addedEdge = graph.addEdge(edge.source, edge.target, { size: 1 });
    graph.setEdgeAttribute(addedEdge, `color`, chroma('#ff0000').alpha(0.01).hex());
});

looks like this: sigma

compared to pixi.js with same color and alpha: pixi

Also could be placebo but when panning around using the reducer method it felt slower than setting a color directly with setEdgeAttribute once:

const instance = new Sigma(graph, canvasContainer, {
    labelThreshold: 10,
    hideEdgesOnMove: false,
    renderEdgeLabels: false,

    edgeReducer: (_, attr) => {
        attr.color = chroma('#ff0000').alpha(0.01).hex();
        return attr;
    },
});
ck-coatue commented 5 months ago

I've noticed that EdgeCurvedArrowProgram handles opacity well (doesn't wash out like the other edge/node programs).

h-a-s-k commented 5 months ago

I've noticed that EdgeCurvedArrowProgram handles opacity well (doesn't wash out like the other edge/node programs).

Definitely an improvement

test sigma

but seems like past a certain (low) alpha number it straight up stops rendering them

ck-coatue commented 5 months ago

figured out if u want to do the same for nodes as well, clone the NodeCircleProgram and change line:

https://github.com/jacomyal/sigma.js/blob/23e53736c9a95bd0bc81bdef9644be11e6d630c2/packages/sigma/src/rendering/programs/node-circle/frag.glsl.ts#L31

to:

gl_FragColor = mix(vec4(v_color.rgb * v_color.a, v_color.a), transparent, t);

I took inspiration from: https://github.com/jacomyal/sigma.js/blob/23e53736c9a95bd0bc81bdef9644be11e6d630c2/packages/edge-curve/src/shader-frag.ts#L68

benny-noumena commented 4 months ago

@ck-coatue It seems that this has be undone in the current beta relase.

https://github.com/jacomyal/sigma.js/blob/721ac7e4dd02e00e828cd1538dc2310ed446809a/packages/edge-curve/src/shader-frag.ts#L73

Maybe it was for performance reason but I would love to have a way to make edges semi-transparent.

h-a-s-k commented 3 months ago

@ck-coatue It seems that this has be undone in the current beta relase.

https://github.com/jacomyal/sigma.js/blob/721ac7e4dd02e00e828cd1538dc2310ed446809a/packages/edge-curve/src/shader-frag.ts#L73

Maybe it was for performance reason but I would love to have a way to make edges semi-transparent.

Yeah last version with working transparency is @sigma/edge-curve@3.0.0-beta.10 for me