Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Beziers don't seem to render nicely #3315

Closed
bryjohnston opened this issue Jan 7, 2025 · 6 comments
Closed

Beziers don't seem to render nicely #3315

bryjohnston opened this issue Jan 7, 2025 · 6 comments
Labels
bug A bug in the code of Cytoscape.js

Comments

@bryjohnston
Copy link

I am doing this through plotly dash cytoscape but I do not think that actually matters here, please let me know if that's not ok to post. The issue is only with cytoscape, not dash.

I am trying create a graph but I cannot find suitable values for the control point distance, weight, etc.

I suspect this has to do with the fact I am using rather small edge and node sizes. I am hoping to get my bezier curves to look like in the demo but mine will only form little mountains at best. my too big bezier curves

I made a simple dash app to demonstrate the issue, allowing the control of each parameter. I have tried enabled and disabled control-point-step-size vs control-point-distance.

from dash import Dash, html, callback, Input, Output, dcc
import dash_bootstrap_components as dbc
import dash_cytoscape as dcs

node_data = [{'data': {'id': '1', 'label': '1'},
              'position': {'x': 0, 'y': 0}},
             {'data': {'id': '2', 'label': '2'},
              'position': {'x': 10, 'y': 0}}]
edge_data = [{'data': {'source': '1', 'target': '2'}},
             {'data': {'source': '1', 'target': '2'}},
             {'data': {'source': '1', 'target': '2'}}]

app = Dash(__name__, external_stylesheets=[dbc.themes.FLATLY])

app.layout = html.Div(dbc.Stack([dcs.Cytoscape(id='cytoscape-app',
                                               layout={'name': 'preset'},
                                               elements=node_data + edge_data,
                                               style={"width": "95vw",
                                                      "height": "75vh"}),
                                 'Control Point Step Size:',
                                 dcc.Input(id='cp-stepsize', type="number",
                                           step=0.1, value=26.6),
                                 'Control Point Distance:',
                                 dcc.Input(id='cp-distance', type="number",
                                           step=0.1, value=26.6),
                                 'Control Point Weight:',
                                 dcc.Input(id='cp-weight', type="number",
                                           step=0.1, value=0.5),
                                 'Node Size:',
                                 dcc.Input(id='nsize', type="number",
                                           step=0.1, value=2),
                                 'Edge Size:',
                                 dcc.Input(id='esize', type="number",
                                           step=0.1, value=1),]))


@callback(Output('cytoscape-app', 'stylesheet'),
          Input('cp-stepsize', 'value'),
          Input('cp-distance', 'value'),
          Input('cp-weight', 'value'),
          Input('nsize', 'value'),
          Input('esize', 'value'))
def style_graph(stepsize, distance, weight, nsize, esize):
    stylesheet = [{'selector': 'node',
                   'style': {'width': nsize,
                             'height': nsize,
                             'overlay-padding': 0}},
                  {'selector': 'edge',
                   'style': {'width': esize,
                             'curve-style': 'bezier',
                             'control-point-step-size': stepsize,
                             'control-point-distance': distance,
                             'control-point-weight': weight,
                             'edge-distances': 'node-position',
                             'overlay-padding': 0}}]
    return stylesheet


if __name__ == '__main__':
    app.run(debug=True)
@bryjohnston bryjohnston added the bug A bug in the code of Cytoscape.js label Jan 7, 2025
@maxkfranz
Copy link
Member

Hi, @bryjohnston.

It looks like it's working in this demo: https://jsbin.com/gunozik/edit?js,output

Would you fork that demo to show a case where it's not working for you?

@bryjohnston
Copy link
Author

I'm not sure how to fork this but I was able to replicate by changing the javascript file to this:

window.addEventListener('DOMContentLoaded', function(){ // on dom ready

// photos from flickr with creative commons license
  
var cy = cytoscape({
  container: document.getElementById('cy'),
  
  style: cytoscape.stylesheet()
    .selector('node')
      .style({
        'height': 2,
        'width': 2,
        'background-fit': 'cover',
        'border-color': '#000',
        'border-width': 0.5,
        'border-opacity': 0.5
      })
    .selector('edge')
      .style({
        'width': 1,
        'line-color': '#ffaaaa',
        'curve-style': 'bezier',
        'control-point-step-size': 10
      })
    ,
  
  elements: {
    nodes: [
      { data: { id: 'cat' },
        position: {x: 0, y: 0}},
      { data: { id: 'bird' },
        position: {x: 0, y: 10}}
    ],
    edges: [
      { data: { source: 'cat', target: 'bird' } }]
  },
  layout: {
    name: 'preset'
  }
}); // cy init
  

cy.edges().forEach(edge => {
  const src = edge.source().id();
  const tgt = edge.target().id();
  
  cy.add({ data: { source: src, target: tgt } });
});
  

}); // on dom ready

@bryjohnston
Copy link
Author

with this version, no matter how I change control point step size the graph does not look nice

@YinDongFang
Copy link

size too small, You can set edge style arrow-scale: 0.1

    .selector('edge')
      .style({
        'width': 1,
        'line-color': '#ffaaaa',
        'curve-style': 'bezier',
        'control-point-step-size': 10,
        'arrow-scale': 0.1,
      })

@maxkfranz
Copy link
Member

You can also use the edge-distances property to control the beziers further: https://js.cytoscape.org/#style/bezier-edges

In your case, the first step would be to set the endpoints appropriately in the stylesheet, e.g.

edge {
  source-endpoint: outside-to-line;
  target-endpoint: outside-to-line;
}

If you use custom endpoint values (px or %), then setting edge-distances is useful.

@maxkfranz
Copy link
Member

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug in the code of Cytoscape.js
Projects
None yet
Development

No branches or pull requests

3 participants