Skip to content

Commit 593330b

Browse files
IvoLeistclegaspi
andauthored
Add jpg, png, svg image generation (#88)
* Add image download and callback functionality * Minor updates * Make api more concise * Update changelog * Add JSON * Revert "Add JSON" This reverts commit 4fa1fed. * Compile js and python files * Compile js and python files (add files this time) * added example app to test image generation * modified setup.py to include utils in modified package * added cytoscape-svg as extension * extended cytotscape react to enable svg export,added example app to test imageDownload * renamed buttons in example app * rebuild it using yarn fixed compound nodes issue * updated changelog, moved examples into demos/, updated E-mails in package.json * updated comments in Cytoscape.react.js, added usage-image-export.py based on usage-event.py * added usage-image-export.py to test_usage * moved cytoscape-svg into extra_index.js * resolved code linting issues * added usage-image-export gif to README * added random print statement in usage-image-export.py to pass pylint Co-authored-by: Christian Legaspi <[email protected]>
1 parent 267a416 commit 593330b

18 files changed

+1416
-76
lines changed

.gitignore

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
# Created by .ignore support plugin (hsz.mobi)
33
### VisualStudioCode template
44
.vscode/*
5-
!.vscode/settings.json
6-
!.vscode/tasks.json
7-
!.vscode/launch.json
8-
!.vscode/extensions.json
5+
.vscode/settings.json
6+
.vscode/tasks.json
7+
.vscode/launch.json
8+
.vscode/extensions.json
99
### JetBrains template
1010
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
1111
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010
* Contributed initial build of R package.
11+
* Added access to cytoscape.js PNG and JPG image generation API through `generateImage` and
12+
`imageData` properties.
13+
* Added ability to download image files generated with `generateImage` client-side without sending
14+
data to the server.
15+
* Used the newly added `generateImage` and `imageData` properties to enable svg generation using https://github.com/kinimesi/cytoscape-svg
1116

1217
### Changed
1318
* `utils.Tree`: v0.1.1 broke compatibility with Python 2. Therefore, modified code to be compatible

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,8 @@ The Pull Request and Issue Templates were inspired from the
128128
[Code](demos/usage-elements-extra.py)
129129
![View usage-elements-extra on Github](demos/images/usage-elements-extra.gif)
130130

131+
### Use export graph as image
132+
[Code](demos/usage-image-export.py)
133+
![View usage-image-export on Github](demos/images/usage-image-export.gif)
134+
131135
For an extended gallery, visit the [demos' readme](demos/README.md).

dash_cytoscape/Cytoscape.py

Lines changed: 44 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ class Cytoscape(Component):
1212
- id (string; optional): The ID used to identify this component in Dash callbacks.
1313
- className (string; optional): Sets the class name of the element (the value of an element's html
1414
class attribute).
15-
- style (dict; optional): Add inline styles to the root element.
16-
- elements (list; optional): A list of dictionaries representing the elements of the networks.
15+
- style (dict; default {width: '600px', height: '600px'}): Add inline styles to the root element.
16+
- elements (list of dicts; optional): A list of dictionaries representing the elements of the networks.
1717
1. Each dictionary describes an element, and specifies its purpose.
1818
- `group` (string): Either 'nodes' or 'edges'. If not given, it's automatically inferred.
1919
- `data` (dictionary): Element specific data.
@@ -32,7 +32,7 @@ class attribute).
3232
- `classes` (string): Space separated string of class names of the element. Those classes can be selected by a style selector.
3333
3434
2. The [official Cytoscape.js documentation](http://js.cytoscape.org/#notation/elements-json) offers an extensive overview and examples of element declaration.
35-
- stylesheet (list; optional): A list of dictionaries representing the styles of the elements.
35+
- stylesheet (list of dicts; optional): A list of dictionaries representing the styles of the elements.
3636
1. Each dictionary requires the following keys:
3737
- `selector` (string): Which elements you are styling. Generally, you select a group of elements (node, edges, both), a class (that you declare in the element dictionary), or an element by ID.
3838
- `style` (dictionary): What aspects of the elements you want to modify. This could be the size or color of a node, the shape of an edge arrow, or many more.
@@ -42,7 +42,7 @@ class attribute).
4242
exhaustively documented in the Cytoscape.js docs. Although methods such
4343
as `cy.elements(...)` and `cy.filter(...)` are not available, the selector
4444
string syntax stays the same.
45-
- layout (dict; optional): A dictionary specifying how to set the position of the elements in your
45+
- layout (dict; default {name: 'grid'}): A dictionary specifying how to set the position of the elements in your
4646
graph. The `'name'` key is required, and indicates which layout (algorithm) to
4747
use.
4848
1. The layouts available by default are:
@@ -80,33 +80,33 @@ class attribute).
8080
Note that certain keys are not supported in Dash since the value is a
8181
JavaScript function or a callback. Please visit [this issue](https://github.com/plotly/dash-cytoscape/issues/25)
8282
for more information.
83-
- pan (dict; optional): Dictionary indicating the initial panning position of the graph. The
83+
- pan (dict; default {x: 0, y: 0}): Dictionary indicating the initial panning position of the graph. The
8484
following keys are accepted:
8585
- `x` (number): The x-coordinate of the position.
8686
- `y` (number): The y-coordinate of the position.
87-
- zoom (number; optional): The initial zoom level of the graph. You can set `minZoom` and
87+
- zoom (number; default 1): The initial zoom level of the graph. You can set `minZoom` and
8888
`maxZoom` to set restrictions on the zoom level.
89-
- panningEnabled (boolean; optional): Whether panning the graph is enabled (i.e., the position of the graph is
89+
- panningEnabled (boolean; default True): Whether panning the graph is enabled (i.e., the position of the graph is
9090
mutable overall).
91-
- userPanningEnabled (boolean; optional): Whether user events (e.g. dragging the graph background) are allowed to
91+
- userPanningEnabled (boolean; default True): Whether user events (e.g. dragging the graph background) are allowed to
9292
pan the graph.
93-
- minZoom (number; optional): A minimum bound on the zoom level of the graph. The viewport can not be
93+
- minZoom (number; default 1e-50): A minimum bound on the zoom level of the graph. The viewport can not be
9494
scaled smaller than this zoom level.
95-
- maxZoom (number; optional): A maximum bound on the zoom level of the graph. The viewport can not be
95+
- maxZoom (number; default 1e50): A maximum bound on the zoom level of the graph. The viewport can not be
9696
scaled larger than this zoom level.
97-
- zoomingEnabled (boolean; optional): Whether zooming the graph is enabled (i.e., the zoom level of the graph
97+
- zoomingEnabled (boolean; default True): Whether zooming the graph is enabled (i.e., the zoom level of the graph
9898
is mutable overall).
99-
- userZoomingEnabled (boolean; optional): Whether user events (e.g. dragging the graph background) are allowed
99+
- userZoomingEnabled (boolean; default True): Whether user events (e.g. dragging the graph background) are allowed
100100
to pan the graph.
101-
- boxSelectionEnabled (boolean; optional): Whether box selection (i.e. drag a box overlay around, and release it
101+
- boxSelectionEnabled (boolean; default False): Whether box selection (i.e. drag a box overlay around, and release it
102102
to select) is enabled. If enabled, the user must taphold to pan the graph.
103-
- autoungrabify (boolean; optional): Whether nodes should be ungrabified (not grabbable by user) by
103+
- autoungrabify (boolean; default False): Whether nodes should be ungrabified (not grabbable by user) by
104104
default (if true, overrides individual node state).
105-
- autolock (boolean; optional): Whether nodes should be locked (not draggable at all) by default
105+
- autolock (boolean; default False): Whether nodes should be locked (not draggable at all) by default
106106
(if true, overrides individual node state).
107-
- autounselectify (boolean; optional): Whether nodes should be unselectified (immutable selection state) by
107+
- autounselectify (boolean; default False): Whether nodes should be unselectified (immutable selection state) by
108108
default (if true, overrides individual element state).
109-
- autoRefreshLayout (boolean; optional): Whether the layout should be refreshed when elements are added or removed.
109+
- autoRefreshLayout (boolean; default True): Whether the layout should be refreshed when elements are added or removed.
110110
- tapNode (dict; optional): The complete node dictionary returned when you tap or click it. Read-only.
111111
112112
1. Node-specific items:
@@ -164,14 +164,37 @@ class attribute).
164164
- selectedNodeData (list; optional): The list of data dictionaries of all selected nodes (e.g. using
165165
Shift+Click to select multiple nodes, or Shift+Drag to use box selection). Read-only.
166166
- selectedEdgeData (list; optional): The list of data dictionaries of all selected edges (e.g. using
167-
Shift+Click to select multiple nodes, or Shift+Drag to use box selection). Read-only."""
167+
Shift+Click to select multiple nodes, or Shift+Drag to use box selection). Read-only.
168+
- generateImage (dict; optional): Dictionary specifying options to generate an image of the current cytoscape graph.
169+
Value is cleared after data is received and image is generated. This property will
170+
be ignored on the initial creation of the cytoscape object and must be invoked through
171+
a callback after it has been rendered. The `'type'` key is required.
172+
The following keys are supported:
173+
- `type` (string): File type to ouput of 'svg, 'png', 'jpg', or 'jpeg' (alias of 'jpg')
174+
- `options` (dictionary, optional): Dictionary of options to cy.png() / cy.jpg() or cy.svg() for
175+
image generation. See http://js.cytoscape.org/#core/export for details.
176+
For `'output'`, only 'base64' and 'base64uri' are supported.
177+
Default: `{'output': 'base64uri'}`.
178+
- `action` (string, optional): Default: `'store'`. Must be one of the following:
179+
- `'store'`: Stores the image data (only jpg and png are supported) in `imageData` and invokes
180+
server-side Dash callbacks.
181+
- `'download'`: Downloads the image as a file with all data handling
182+
done client-side. No `imageData` callbacks are fired.
183+
- `'both'`: Stores image data and downloads image as file.
184+
- `filename` (string, optional): Name for the file to be downloaded. Default: 'cyto'.
185+
186+
If the app does not need the image data server side and/or it will only be used to download
187+
the image, it may be prudent to invoke `'download'` for `action` instead of
188+
`'store'` to improve performance by preventing transfer of data to the server.
189+
- imageData (string; optional): String representation of the image requested with generateImage. Null if no
190+
image was requested yet or the previous request failed. Read-only."""
168191
@_explicitize_args
169-
def __init__(self, id=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, elements=Component.UNDEFINED, stylesheet=Component.UNDEFINED, layout=Component.UNDEFINED, pan=Component.UNDEFINED, zoom=Component.UNDEFINED, panningEnabled=Component.UNDEFINED, userPanningEnabled=Component.UNDEFINED, minZoom=Component.UNDEFINED, maxZoom=Component.UNDEFINED, zoomingEnabled=Component.UNDEFINED, userZoomingEnabled=Component.UNDEFINED, boxSelectionEnabled=Component.UNDEFINED, autoungrabify=Component.UNDEFINED, autolock=Component.UNDEFINED, autounselectify=Component.UNDEFINED, autoRefreshLayout=Component.UNDEFINED, tapNode=Component.UNDEFINED, tapNodeData=Component.UNDEFINED, tapEdge=Component.UNDEFINED, tapEdgeData=Component.UNDEFINED, mouseoverNodeData=Component.UNDEFINED, mouseoverEdgeData=Component.UNDEFINED, selectedNodeData=Component.UNDEFINED, selectedEdgeData=Component.UNDEFINED, **kwargs):
170-
self._prop_names = ['id', 'className', 'style', 'elements', 'stylesheet', 'layout', 'pan', 'zoom', 'panningEnabled', 'userPanningEnabled', 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'boxSelectionEnabled', 'autoungrabify', 'autolock', 'autounselectify', 'autoRefreshLayout', 'tapNode', 'tapNodeData', 'tapEdge', 'tapEdgeData', 'mouseoverNodeData', 'mouseoverEdgeData', 'selectedNodeData', 'selectedEdgeData']
192+
def __init__(self, id=Component.UNDEFINED, className=Component.UNDEFINED, style=Component.UNDEFINED, elements=Component.UNDEFINED, stylesheet=Component.UNDEFINED, layout=Component.UNDEFINED, pan=Component.UNDEFINED, zoom=Component.UNDEFINED, panningEnabled=Component.UNDEFINED, userPanningEnabled=Component.UNDEFINED, minZoom=Component.UNDEFINED, maxZoom=Component.UNDEFINED, zoomingEnabled=Component.UNDEFINED, userZoomingEnabled=Component.UNDEFINED, boxSelectionEnabled=Component.UNDEFINED, autoungrabify=Component.UNDEFINED, autolock=Component.UNDEFINED, autounselectify=Component.UNDEFINED, autoRefreshLayout=Component.UNDEFINED, tapNode=Component.UNDEFINED, tapNodeData=Component.UNDEFINED, tapEdge=Component.UNDEFINED, tapEdgeData=Component.UNDEFINED, mouseoverNodeData=Component.UNDEFINED, mouseoverEdgeData=Component.UNDEFINED, selectedNodeData=Component.UNDEFINED, selectedEdgeData=Component.UNDEFINED, generateImage=Component.UNDEFINED, imageData=Component.UNDEFINED, **kwargs):
193+
self._prop_names = ['id', 'className', 'style', 'elements', 'stylesheet', 'layout', 'pan', 'zoom', 'panningEnabled', 'userPanningEnabled', 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'boxSelectionEnabled', 'autoungrabify', 'autolock', 'autounselectify', 'autoRefreshLayout', 'tapNode', 'tapNodeData', 'tapEdge', 'tapEdgeData', 'mouseoverNodeData', 'mouseoverEdgeData', 'selectedNodeData', 'selectedEdgeData', 'generateImage', 'imageData']
171194
self._type = 'Cytoscape'
172195
self._namespace = 'dash_cytoscape'
173196
self._valid_wildcard_attributes = []
174-
self.available_properties = ['id', 'className', 'style', 'elements', 'stylesheet', 'layout', 'pan', 'zoom', 'panningEnabled', 'userPanningEnabled', 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'boxSelectionEnabled', 'autoungrabify', 'autolock', 'autounselectify', 'autoRefreshLayout', 'tapNode', 'tapNodeData', 'tapEdge', 'tapEdgeData', 'mouseoverNodeData', 'mouseoverEdgeData', 'selectedNodeData', 'selectedEdgeData']
197+
self.available_properties = ['id', 'className', 'style', 'elements', 'stylesheet', 'layout', 'pan', 'zoom', 'panningEnabled', 'userPanningEnabled', 'minZoom', 'maxZoom', 'zoomingEnabled', 'userZoomingEnabled', 'boxSelectionEnabled', 'autoungrabify', 'autolock', 'autounselectify', 'autoRefreshLayout', 'tapNode', 'tapNodeData', 'tapEdge', 'tapEdgeData', 'mouseoverNodeData', 'mouseoverEdgeData', 'selectedNodeData', 'selectedEdgeData', 'generateImage', 'imageData']
175198
self.available_wildcard_properties = []
176199

177200
_explicit_args = kwargs.pop('_explicit_args')

dash_cytoscape/dash_cytoscape.dev.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_cytoscape/dash_cytoscape.min.js

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_cytoscape/dash_cytoscape_extra.dev.js

Lines changed: 13 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dash_cytoscape/dash_cytoscape_extra.min.js

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)