cytoscape / cytoscape.js

Graph theory (network) library for visualisation and analysis

Home Page:https://js.cytoscape.org

Repository from Github https://github.comcytoscape/cytoscape.jsRepository from Github https://github.comcytoscape/cytoscape.js

Bezier control points seems incorrect in version 3.31.2

dwchMikael opened this issue · comments

Hi,

Seems to be an issue with the bezier control points. Looks like it is a new issue for version 3.31.2. Sorry in advance if I've misunderstood something and this is not a bug.

Environment info

  • Cytoscape.js version : 3.31.2
  • Browser/Node.js & version :

Current (buggy) behaviour

Control points for bezier edges between two nodes are not stable when we move one of the nodes in a circle around the other node. The vector between the two nodes seems to not be calculated correctly.
Edge control point calculation is using an incorrect vector between the two nodes in a pairInfo.
Commit 85ad43f changed the pairInfo vector calculation to use absolute values for dy and dx. Meaning the vector between two nodes is always pointing to down and to the right. Because of this the control points for bezier curves are not always placed correctly. And the edges are not drawn correctly, depending the direction of the true vector between the two nodes.

Desired behaviour

The bezier edges should be stable under rotation. Meaning look "the same" just rotated.

Minimum steps to reproduce

  1. Open up the edge type demo, https://js.cytoscape.org/demos/edge-types/
  2. Focus on the two nodes for the top left example labeled "bezier".
  3. Drag the left most node such that it is placed below the other node. Preferably make the angle between them 45 deg.

Screenshot before dragging:
Image

Screenshot after dragging the left most node:
Image

Or add the following playwright test case:
test('diagonal bottom left to top right', async ({page}) => { let controlPoints = await page.evaluate(() => { const cy = window.cy; cy.style().fromJson([{ selector: 'edge', style: { 'curve-style': 'bezier', 'control-point-step-size': Math.sqrt(200) } }]).update(); cy.add([{ data: {id: 'a'} }, { data: {id: 'b'} }, { data: {id: 'ab1', source: 'a', target: 'b'} }, { data: {id: 'ab2', source: 'a', target: 'b'} }]); var presetOptions = { name: 'preset', positions: { a: {x: 0, y: 100}, b: {x: 100, y: 0} } }; cy.layout(presetOptions).run(); let pt_ab1_1 = cy.$('#ab1').controlPoints()[0]; let pt_ab2_1 = cy.$('#ab2').controlPoints()[0]; return [pt_ab1_1, pt_ab2_1] }); // Step size 14.14, sqrt(10*10+10*10). // Gives a 5 pixel translation away from the mid-point, // if the vector between the nodes are at a 45 deg angle. // Mid-point is at (50,50) expect(controlPoints[0].x).toBeCloseTo(45, 5); expect(controlPoints[0].y).toBeCloseTo(45, 5); expect(controlPoints[1].x).toBeCloseTo(55, 5); expect(controlPoints[1].y).toBeCloseTo(55, 5); });

An attempt to fix it is done in dwchMikael@9f11142 but not sure if this would break any other feature.

For reviewers

Reviewers should ensure that the following tasks are carried out for incorporated issues:

  • Ensure that the reporter has included a reproducible demo. They can easily fork this JSBin demo: http://jsbin.com/fiqugiq
  • The issue has been associated with a corresponding milestone.
  • The commits have been incorporated into the corresponding branches. Bug-fix patches go on
    • master and
    • unstable.
  • The issue has been labelled as a bug, if necessary.

@dwchMikael would you try removing the abs() from these two lines: 85ad43f#r155832875

It looks like for the sqrt()s, it's using the squared dx,dy values so negative values should be OK.

Let us know if this sorts things out for you.

Yeah, removing the Math.abs() fixes this issue.

Fair enough. We'll put that in a patch release on Monday then

Thank you! And thanks for the quick response on the issue, and also the patch release!

@dwchMikael 3.31.3 has been released with the patch

Thanks for the thorough report