Black Lives Matter. Please consider donating to Black Girls Code today.

📣 Dash Cytoscape v0.2.0 Release - Image generation (jpg/png/svg) and responsive graphs

Hello all! Today, I would like to announce the release of Dash Cytoscape v0.2.0.

This release brings important new features to Dash Cytoscape, as well as some important bug fixes! This is the result of exactly 100 commits and issues that the Dash Cytoscape community has contributed since 2019. It features two significant PRs lead by community contributors, namely PR #88 (which adds the option to save your graph as a png/jpg/svg), as well as PR #92 (which lets you enable responsive Cytoscape graphs). Additionally, the Cytoscape team has focused on fixing issues that concerns package distributions, default props, and security-related issues. You can find examples of the new features in the Dash Cytoscape User Guide , from our Dash Docs .

I’d like to thank Christian for starting the initial work for image exporting (in 2019), Ivo for taking over the PR and adding support for SVG, and Manfred for contributing the responsive property.

Added

  • Contributed initial build of R package.
  • Added access to cytoscape.js PNG and JPG image generation API through generateImage and
    imageData properties (PR #88).
  • Added ability to download image files generated with generateImage client-side without sending
    data to the server (PR #88).
  • Used the newly added generateImage and imageData properties to enable svg generation using cytoscape-svg.
  • Added responsive cytoscape.js graph feature toggled using the responsive property (PR #93).
  • Two new documentation pages covering these features:

Changed

  • Changed the official package manager from yarn to npm.
  • utils.Tree: v0.1.1 broke compatibility with Python 2. Therefore, modified code to be compatible
    with Python 2. Added props and edge_props properties to accept arguments passed directly to
    the node’s and edge’s dictionaries, respectively (e.g., ‘classes’, ‘positions’, etc.).
  • Removed Tree's method add_child, because it is redundant with add_children called with an
    argument of length 1.
  • setup.py: Remove dash-html-components and dash_renderer from install_requires.
  • usage-events.py: Fix the size of the cytoscape graph to 500px by 500px.
  • Upgrade react-cytoscape.js to latest.

Fixed

  • setup.py: Use packages=find_packages(include=[package_name, package_name + ".*"]) so that all
    subpackages like utils will be included when you pip install dash-cytoscape.
  • Issue where dash-cytoscape cannot read property of ‘length’ of undefined when elements is not specified.
  • tests.test_interactions.
2 Likes

Thank you for the new release.

I am looking for a way to implement a zoom to a specific level on a clicked node in the graph. Please let me know if it is possible to do through callbacks in the new version?

Hi @Zhabiz! Since 0.0.x you could control the zoom level through callbacks. In this specific case, perhaps you could move your node of interest to the center of the screen, or set the initial pan to be exactly onto the node of interest, and then zoom in?

Thank you @xhlu for your response.

I tried to apply your suggestion to the provided example with the preset layout.

import dash
import dash_cytoscape as cyto
import dash_html_components as html
from dash.dependencies import Input, Output

app = dash.Dash(__name__,prevent_initial_callbacks=True)
app.layout = html.Div([
 cyto.Cytoscape(
 id='cytoscape',
 elements=[
 {'data': {'id': 'one', 'label': 'Node 1'}, 'position': {'x': 50, 'y': 50}},
 {'data': {'id': 'two', 'label': 'Node 2'}, 'position': {'x': 200, 'y': 200}},
 {'data': {'source': 'one', 'target': 'two','label': 'Node 1 to 2'}}
 ],
 # pan= {'x': 200, 'y': 200},
 layout={'name': 'preset'}
 )
])


@app.callback(
 [Output("cytoscape", "pan"),
 Output("cytoscape", "zoom"),
 ],
 [
 Input("cytoscape", "tapNodeData"),
 ]
)
def update(tapNodeData):
 print(tapNodeData)
 return {'x': 200, 'y': 200},2

if __name__ == '__main__':
 app.run_server(debug=True)

But it resulted in the following output:

It didn’t place the clicked node to the center of screen.

In the cytoscape.js, the zooming can be possible by passing level, and position and renderedPosition options as it is mentioned here:(zoom). I don’t exactly know by changing the pan here whether we change position or renderedPosition.

Could you explain a little bit and let me know about a way to fix this issue?

Thanks,

This is a bit of a hack:

  • I know that position and rendered positions can be specified and updated inside a callback. If you pass the current position as a state to your callback, and the position as an output to your callback, then you can essentially “shift” all the positions in a way that the clicked node is in the center of your screen.

I’m actually not sure whether the default zoom prop in cytoscape.js accepts a JS object in the form of

{
  level: 2.0, // the zoom level
  renderedPosition: { x: 100, y: 100 }
}

If it’s indeed possible in Cytoscape.js, then I think it should be doable in Dash Cytoscape (although I haven’t actually tested this specific scenario). Otherwise, we would need to essentially change the Dash Cytoscape react code to update zoom as a prop, and call cy.zoom(...) whenever it is called inside a callback.