Cytoscape.jsをPython Flaskで呼び出してネットワーク図を描画したり動かしたりしてみた

<img src="https://qiita-image-store.s3.amazonaws.com/0/204284/5788717c-346a-f9fa-f1a9-60794dbf91ec.png" style="margin: auto;" width=90% alt="20181003_cytoscape_qiita.png"/>

[JavaScript版のCytoscape]((http://js.cytoscape.org/))でネットワーク図を綺麗に描画したり動かしたりしたくなり、Pythonの軽量のウェブアプリケーションフレームワーク[Flask]((http://flask.pocoo.org/))をはじめて使ってみました。

Flask、HTML、CSS、JavaScriptと全部慣れない中の作業だったので苦労しましたが、なんとか表示させるところまでできました。中でも、Flaskがとてもわかりやすくて助かりました。

# 準備

### 1. Flaskをインストール

macOS SierraでHomebrew+pyenv+Anacondaという組み合わせの環境です。
ここにpipでインストール。

```
$ pip install Flask
```

### 2. Cytoscape.jsをダウンロード

git cloneでOK。

```
$ git clone https://github.com/cytoscape/cytoscape.js.git
```

ダウンロードすると`cytoscape.js`という名前のディレクトリが作られ、その配下にたくさんのファイルが配置されているのがわかります。作るの大変だっただろうなぁ、、、

<details><summary>ツリー構造が長すぎるのですが、興味があればどうぞ</summary><div>

```
.
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── README.md
├── benchmark
│   ├── a-star.js
│   ├── add-remove-class.js
│   ├── add-remove.js
│   ├── add.js
│   ├── all
│   │   └── index.js
│   ├── all-are-neighbors.js
│   ├── all-are.js
│   ├── any-same.js
│   ├── bellman-ford.js
│   ├── betweenness-centrality.js
│   ├── bfs.js
│   ├── classes.js
│   ├── closeness-centrality.js
│   ├── collection-creation.js
│   ├── contains.js
│   ├── degree-centrality.js
│   ├── dfs.js
│   ├── dijkstra.js
│   ├── floyd-warshall.js
│   ├── graphs
│   │   ├── abcde.json
│   │   ├── gal.json
│   │   └── random.js
│   ├── has-class.js
│   ├── id-selector.js
│   ├── init.js
│   ├── is.js
│   ├── karger-stein.js
│   ├── kruskal.js
│   ├── page-rank.js
│   ├── same.js
│   ├── selector-filter.js
│   ├── single
│   │   └── index.js
│   └── suite
│       └── index.js
├── bower.json
├── debug
│   ├── add-remove.js
│   ├── bind.js
│   ├── compound.js
│   ├── filter.js
│   ├── images
│   │   ├── favicon.png
│   │   ├── gnu-small.png
│   │   ├── gnu.jpg
│   │   ├── gnu.png
│   │   └── gnu.svg
│   ├── index.html
│   ├── init.js
│   ├── layout.js
│   ├── livereload.js
│   ├── memory.html
│   ├── notify.js
│   ├── style.css
│   ├── style.js
│   ├── tests.js
│   ├── toggles.js
│   └── view.js
├── dist
│   ├── cytoscape.js
│   └── cytoscape.min.js
├── documentation
│   ├── CNAME
│   ├── css
│   │   ├── font-awesome.css
│   │   ├── highlight
│   │   │   ├── arta.css
│   │   │   ├── ascetic.css
│   │   │   ├── atelier-dune.dark.css
│   │   │   ├── atelier-dune.light.css
│   │   │   ├── atelier-forest.dark.css
│   │   │   ├── atelier-forest.light.css
│   │   │   ├── atelier-heath.dark.css
│   │   │   ├── atelier-heath.light.css
│   │   │   ├── atelier-lakeside.dark.css
│   │   │   ├── atelier-lakeside.light.css
│   │   │   ├── atelier-seaside.dark.css
│   │   │   ├── atelier-seaside.light.css
│   │   │   ├── brown_paper.css
│   │   │   ├── brown_papersq.png
│   │   │   ├── dark.css
│   │   │   ├── default.css
│   │   │   ├── docco.css
│   │   │   ├── far.css
│   │   │   ├── foundation.css
│   │   │   ├── github.css
│   │   │   ├── googlecode.css
│   │   │   ├── idea.css
│   │   │   ├── ir_black.css
│   │   │   ├── magula.css
│   │   │   ├── mono-blue.css
│   │   │   ├── monokai.css
│   │   │   ├── monokai_sublime.css
│   │   │   ├── obsidian.css
│   │   │   ├── paraiso.dark.css
│   │   │   ├── paraiso.light.css
│   │   │   ├── pojoaque.css
│   │   │   ├── pojoaque.jpg
│   │   │   ├── railscasts.css
│   │   │   ├── rainbow.css
│   │   │   ├── school_book.css
│   │   │   ├── school_book.png
│   │   │   ├── solarized_dark.css
│   │   │   ├── solarized_light.css
│   │   │   ├── sunburst.css
│   │   │   ├── tomorrow-night-blue.css
│   │   │   ├── tomorrow-night-bright.css
│   │   │   ├── tomorrow-night-eighties.css
│   │   │   ├── tomorrow-night.css
│   │   │   ├── tomorrow.css
│   │   │   ├── vs.css
│   │   │   ├── xcode.css
│   │   │   └── zenburn.css
│   │   ├── hl.min.css
│   │   ├── reset.css
│   │   └── style.css
│   ├── demos
│   │   ├── 0365589fdb70b58af282 -> ./spread-layout
│   │   ├── 04030586763520be8d7a -> ./circle-layout
│   │   ├── 173313aba1f31cae49a5 -> ./pie-style
│   │   ├── 18504640d9a03c178fff -> ./edge-types
│   │   ├── 29419ca0e6430a7185a5 -> ./genemania-export
│   │   ├── 2abfc41c86c1e3cb0700 -> ./labels
│   │   ├── 2ebdc40f1c2540de6cf0 -> ./colajs-graph
│   │   ├── 310dca83ba6970812dd0 -> ./multiple-instances
│   │   ├── 444dc95703caa319c147 -> ./concentric-layout
│   │   ├── 546dd8ca4872cc87106a -> ./qtip-extension
│   │   ├── 57e7cc43342193d9d21a -> ./performance-tuning
│   │   ├── 59e38e9f20e25a293e44 -> ./cose-bilkent-layout-compound
│   │   ├── 5b192c88616af2f75344 -> ./compound-nodes
│   │   ├── 6000-elements
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── 621d51ea7de19608127e -> ./initialisation
│   │   ├── 689efca4fcb0fd05671b -> ./architecture
│   │   ├── 6c9907e7896f8ae23f9f -> ./cose-bilkent-layout
│   │   ├── 7b511e1f48ffd044ad66 -> ./cose-layout
│   │   ├── 7e2f4d29ff7ef1a1bba5 -> ./animated-bfs
│   │   ├── aedff159b0df05ccfaa5 -> ./images-breadthfirst-layout
│   │   ├── animated-bfs
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── architecture
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── b7c65115947d9e0e8ec8 -> ./visual-style
│   │   ├── cde4db55e581d10405f5 -> ./wine-cheese-map
│   │   ├── circle-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cola-compound
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── colajs-graph
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── compound-nodes
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── concentric-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cose-bilkent-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cose-bilkent-layout-compound
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── cose-layout
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── dagre-layout
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── e52c2fbc0b09edd6ec46 -> ./dagre-layout
│   │   ├── eb861f83fb741628342f -> ./linkout-example
│   │   ├── edge-types
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── f64e811fc3311414e083 -> ./tokyo-railways
│   │   ├── f70c9e45c43f40f7dfe1 -> ./grid-layout
│   │   ├── genemania-export
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── grid-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── images-breadthfirst-layout
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── initialisation
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── labels
│   │   │   ├── code.js
│   │   │   ├── cy-style.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── linkout-example
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── multiple-instances
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── performance-tuning
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── pie-style
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── qtip-extension
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── spread-layout
│   │   │   ├── code.js
│   │   │   ├── data.json
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   ├── tokyo-railways
│   │   │   ├── index.html
│   │   │   ├── style.css
│   │   │   └── tokyo-railways.js
│   │   ├── visual-style
│   │   │   ├── code.js
│   │   │   ├── index.html
│   │   │   └── style.css
│   │   └── wine-cheese-map
│   │       └── index.html
│   ├── docmaker.js
│   ├── docmaker.json
│   ├── font
│   │   ├── FontAwesome.otf
│   │   ├── fontawesome-webfont.eot
│   │   ├── fontawesome-webfont.svg
│   │   ├── fontawesome-webfont.ttf
│   │   ├── fontawesome-webfont.woff
│   │   └── fontawesome-webfont.woff2
│   ├── img
│   │   ├── cytoscape-logo.png
│   │   ├── cytoscape-logo.svg
│   │   └── demos
│   │       ├── 6000-elements.png
│   │       ├── angularjs-example.png
│   │       ├── animated-bfs.png
│   │       ├── architecture.png
│   │       ├── automove.png
│   │       ├── circle-layout.png
│   │       ├── cola-compound.png
│   │       ├── cola-layout.png
│   │       ├── colajs-graph.png
│   │       ├── compound-nodes.png
│   │       ├── concentric-layout.png
│   │       ├── cose-bilkent-layout-compound.png
│   │       ├── cose-bilkent-layout.png
│   │       ├── cose-layout.png
│   │       ├── cxtmenu.png
│   │       ├── dagre-layout.png
│   │       ├── edge-types.png
│   │       ├── edgehandles.png
│   │       ├── euler-layout.png
│   │       ├── genemania-export.png
│   │       ├── grid-layout.png
│   │       ├── images-breadthfirst-layout.png
│   │       ├── initialisation.png
│   │       ├── klay-layout.png
│   │       ├── labels.png
│   │       ├── linkout-example.png
│   │       ├── multiple-instances.png
│   │       ├── performance-tuning.png
│   │       ├── pie-style.png
│   │       ├── popper-tippy.png
│   │       ├── popper.png
│   │       ├── qtip-extension.png
│   │       ├── spread-layout.png
│   │       ├── tokyo-railways.png
│   │       ├── visual-style.png
│   │       └── wine-cheese-map.png
│   ├── index.html
│   ├── js
│   │   ├── cytoscape.min.js
│   │   └── script.js
│   ├── md
│   │   ├── animation
│   │   │   ├── apply.md
│   │   │   ├── pause.md
│   │   │   ├── play.md
│   │   │   ├── progress.md
│   │   │   ├── promise.md
│   │   │   ├── reverse.md
│   │   │   └── stop.md
│   │   ├── animations.md
│   │   ├── architecture.md
│   │   ├── collection
│   │   │   ├── aStar.md
│   │   │   ├── absoluteComplement.md
│   │   │   ├── addClass.md
│   │   │   ├── affinityPropagation.md
│   │   │   ├── algorithms.md
│   │   │   ├── allAre.md
│   │   │   ├── allAreNeighbors.md
│   │   │   ├── animate.md
│   │   │   ├── anySame.md
│   │   │   ├── bellmanFord.md
│   │   │   ├── betweennessCentrality.md
│   │   │   ├── boundingBox.md
│   │   │   ├── breadthFirstSearch.md
│   │   │   ├── classes.md
│   │   │   ├── closenessCentrality.md
│   │   │   ├── closenessCentralityNormalized.md
│   │   │   ├── codirectedEdges.md
│   │   │   ├── collection.md
│   │   │   ├── commonAncestors.md
│   │   │   ├── compoundNodes.md
│   │   │   ├── connectedEdges.md
│   │   │   ├── connectedNodes.md
│   │   │   ├── contains.md
│   │   │   ├── controlPoints.md
│   │   │   ├── data.md
│   │   │   ├── degree.md
│   │   │   ├── degreeCentrality.md
│   │   │   ├── degreeCentralityNormalized.md
│   │   │   ├── delay.md
│   │   │   ├── depthFirstSearch.md
│   │   │   ├── diff.md
│   │   │   ├── difference.md
│   │   │   ├── dijkstra.md
│   │   │   ├── edgesTo.md
│   │   │   ├── edgesWith.md
│   │   │   ├── emit.md
│   │   │   ├── eq.md
│   │   │   ├── every.md
│   │   │   ├── filter.md
│   │   │   ├── flashClass.md
│   │   │   ├── floydWarshall.md
│   │   │   ├── forEach.md
│   │   │   ├── fuzzyCMeans.md
│   │   │   ├── grabify.md
│   │   │   ├── group.md
│   │   │   ├── hasClass.md
│   │   │   ├── hierarchicalClustering.md
│   │   │   ├── incomers.md
│   │   │   ├── intersection.md
│   │   │   ├── is.md
│   │   │   ├── json.md
│   │   │   ├── jsons.md
│   │   │   ├── kMeans.md
│   │   │   ├── kMedoids.md
│   │   │   ├── kargerStein.md
│   │   │   ├── kruskal.md
│   │   │   ├── layout.md
│   │   │   ├── layoutDimensions.md
│   │   │   ├── layoutPositions.md
│   │   │   ├── lock.md
│   │   │   ├── map.md
│   │   │   ├── markovClustering.md
│   │   │   ├── max.md
│   │   │   ├── merge.md
│   │   │   ├── midpoint.md
│   │   │   ├── min.md
│   │   │   ├── move.md
│   │   │   ├── neighborhood.md
│   │   │   ├── numericStyle.md
│   │   │   ├── numericStyleUnits.md
│   │   │   ├── on.md
│   │   │   ├── once.md
│   │   │   ├── one.md
│   │   │   ├── outgoers.md
│   │   │   ├── pageRank.md
│   │   │   ├── parallelEdges.md
│   │   │   ├── position.md
│   │   │   ├── positions.md
│   │   │   ├── predecessors.md
│   │   │   ├── promiseOn.md
│   │   │   ├── reduce.md
│   │   │   ├── remove.md
│   │   │   ├── removeClass.md
│   │   │   ├── removeCss.md
│   │   │   ├── removeData.md
│   │   │   ├── removeListener.md
│   │   │   ├── renderedCss.md
│   │   │   ├── restore.md
│   │   │   ├── same.md
│   │   │   ├── scratch.md
│   │   │   ├── segmentPoints.md
│   │   │   ├── select.md
│   │   │   ├── selectify.md
│   │   │   ├── size.md
│   │   │   ├── some.md
│   │   │   ├── sort.md
│   │   │   ├── source.md
│   │   │   ├── sources.md
│   │   │   ├── stop.md
│   │   │   ├── style.md
│   │   │   ├── successors.md
│   │   │   ├── symmetricDifference.md
│   │   │   ├── target.md
│   │   │   ├── targets.md
│   │   │   ├── toggleClass.md
│   │   │   ├── ungrabify.md
│   │   │   ├── union.md
│   │   │   ├── unlock.md
│   │   │   ├── unmerge.md
│   │   │   ├── unselect.md
│   │   │   └── unselectify.md
│   │   ├── core
│   │   │   ├── add.md
│   │   │   ├── animate.md
│   │   │   ├── autolock.md
│   │   │   ├── autoungrabify.md
│   │   │   ├── autounselectify.md
│   │   │   ├── batch.md
│   │   │   ├── boxSelectionEnabled.md
│   │   │   ├── center.md
│   │   │   ├── collection.md
│   │   │   ├── core.md
│   │   │   ├── delay.md
│   │   │   ├── destroy.md
│   │   │   ├── elements.md
│   │   │   ├── emit.md
│   │   │   ├── extent.md
│   │   │   ├── fit.md
│   │   │   ├── forceRender.md
│   │   │   ├── getElementById.md
│   │   │   ├── init.md
│   │   │   ├── jpg.md
│   │   │   ├── json.md
│   │   │   ├── layout.md
│   │   │   ├── load.md
│   │   │   ├── mount.md
│   │   │   ├── notation.md
│   │   │   ├── offRender.md
│   │   │   ├── on.md
│   │   │   ├── onRender.md
│   │   │   ├── one.md
│   │   │   ├── pan.md
│   │   │   ├── panBy.md
│   │   │   ├── panningEnabled.md
│   │   │   ├── png.md
│   │   │   ├── promiseOn.md
│   │   │   ├── remove.md
│   │   │   ├── removeListener.md
│   │   │   ├── reset.md
│   │   │   ├── resize.md
│   │   │   ├── stop.md
│   │   │   ├── style.md
│   │   │   ├── unmount.md
│   │   │   ├── userPanningEnabled.md
│   │   │   ├── userZoomingEnabled.md
│   │   │   ├── viewport.md
│   │   │   ├── zoom.md
│   │   │   └── zoomingEnabled.md
│   │   ├── demos.md
│   │   ├── downloads.md
│   │   ├── events.md
│   │   ├── extensions.md
│   │   ├── getting-started.md
│   │   ├── intro.md
│   │   ├── layout
│   │   │   ├── emit.md
│   │   │   ├── events.md
│   │   │   ├── intro.md
│   │   │   ├── manipulation.md
│   │   │   ├── on.md
│   │   │   ├── one.md
│   │   │   ├── promiseOn.md
│   │   │   ├── removeListener.md
│   │   │   ├── run.md
│   │   │   └── stop.md
│   │   ├── layouts
│   │   │   ├── breadthfirst.md
│   │   │   ├── circle.md
│   │   │   ├── concentric.md
│   │   │   ├── cose.md
│   │   │   ├── grid.md
│   │   │   ├── null.md
│   │   │   ├── preset.md
│   │   │   └── random.md
│   │   ├── links.md
│   │   ├── notation.md
│   │   ├── performance.md
│   │   ├── selectors.md
│   │   └── style.md
│   └── template.html
├── package-lock.json
├── package.json
├── rollup.config.js
├── snippets
│   ├── animated-bfs.js
│   ├── data
│   │   └── performance-tuning.json
│   ├── images.js
│   ├── performance-tuning.js
│   └── visual.js
├── src
│   ├── animation.js
│   ├── cjs.js
│   ├── collection
│   │   ├── algorithms
│   │   │   ├── a-star.js
│   │   │   ├── affinity-propagation.js
│   │   │   ├── bellman-ford.js
│   │   │   ├── betweenness-centrality.js
│   │   │   ├── bfs-dfs.js
│   │   │   ├── closeness-centrality.js
│   │   │   ├── clustering-distances.js
│   │   │   ├── degree-centrality.js
│   │   │   ├── dijkstra.js
│   │   │   ├── floyd-warshall.js
│   │   │   ├── hierarchical-clustering.js
│   │   │   ├── index.js
│   │   │   ├── k-clustering.js
│   │   │   ├── karger-stein.js
│   │   │   ├── kruskal.js
│   │   │   ├── markov-clustering.js
│   │   │   └── page-rank.js
│   │   ├── animation.js
│   │   ├── cache-traversal-call.js
│   │   ├── class.js
│   │   ├── comparators.js
│   │   ├── compounds.js
│   │   ├── data.js
│   │   ├── degree.js
│   │   ├── dimensions
│   │   │   ├── bounds.js
│   │   │   ├── edge-points.js
│   │   │   ├── index.js
│   │   │   ├── position.js
│   │   │   └── width-height.js
│   │   ├── element.js
│   │   ├── events.js
│   │   ├── filter.js
│   │   ├── group.js
│   │   ├── index.js
│   │   ├── iteration.js
│   │   ├── layout.js
│   │   ├── style.js
│   │   ├── switch-functions.js
│   │   ├── traversing.js
│   │   └── zsort.js
│   ├── core
│   │   ├── add-remove.js
│   │   ├── animation
│   │   │   ├── cubic-bezier.js
│   │   │   ├── ease.js
│   │   │   ├── easings.js
│   │   │   ├── index.js
│   │   │   ├── spring.js
│   │   │   ├── start.js
│   │   │   ├── step-all.js
│   │   │   └── step.js
│   │   ├── events.js
│   │   ├── export.js
│   │   ├── index.js
│   │   ├── layout.js
│   │   ├── notification.js
│   │   ├── renderer.js
│   │   ├── search.js
│   │   ├── style.js
│   │   └── viewport.js
│   ├── define
│   │   ├── animation.js
│   │   ├── data.js
│   │   ├── events.js
│   │   └── index.js
│   ├── emitter.js
│   ├── event.js
│   ├── extension.js
│   ├── extensions
│   │   ├── index.js
│   │   ├── layout
│   │   │   ├── breadthfirst.js
│   │   │   ├── circle.js
│   │   │   ├── concentric.js
│   │   │   ├── cose.js
│   │   │   ├── grid.js
│   │   │   ├── index.js
│   │   │   ├── null.js
│   │   │   ├── preset.js
│   │   │   └── random.js
│   │   └── renderer
│   │       ├── base
│   │       │   ├── arrow-shapes.js
│   │       │   ├── coord-ele-math
│   │       │   │   ├── coords.js
│   │       │   │   ├── edge-arrows.js
│   │       │   │   ├── edge-control-points.js
│   │       │   │   ├── edge-endpoints.js
│   │       │   │   ├── edge-projection.js
│   │       │   │   ├── index.js
│   │       │   │   ├── labels.js
│   │       │   │   ├── nodes.js
│   │       │   │   ├── rendered-style.js
│   │       │   │   └── z-ordering.js
│   │       │   ├── images.js
│   │       │   ├── index.js
│   │       │   ├── load-listeners.js
│   │       │   ├── node-shapes.js
│   │       │   └── redraw.js
│   │       ├── canvas
│   │       │   ├── arrow-shapes.js
│   │       │   ├── drawing-edges.js
│   │       │   ├── drawing-elements.js
│   │       │   ├── drawing-images.js
│   │       │   ├── drawing-label-text.js
│   │       │   ├── drawing-nodes.js
│   │       │   ├── drawing-redraw.js
│   │       │   ├── drawing-shapes.js
│   │       │   ├── ele-texture-cache-lookup.js
│   │       │   ├── ele-texture-cache.js
│   │       │   ├── export-image.js
│   │       │   ├── index.js
│   │       │   ├── layered-texture-cache.js
│   │       │   ├── node-shapes.js
│   │       │   └── texture-cache-defs.js
│   │       ├── index.js
│   │       └── null
│   │           └── index.js
│   ├── heap.js
│   ├── index.js
│   ├── is.js
│   ├── map.js
│   ├── math.js
│   ├── promise.js
│   ├── selector
│   │   ├── data.js
│   │   ├── expressions.js
│   │   ├── index.js
│   │   ├── matching.js
│   │   ├── new-query.js
│   │   ├── parse.js
│   │   ├── query-type-match.js
│   │   ├── state.js
│   │   ├── tokens.js
│   │   └── type.js
│   ├── set.js
│   ├── style
│   │   ├── apply.js
│   │   ├── bypass.js
│   │   ├── container.js
│   │   ├── get-for-ele.js
│   │   ├── index.js
│   │   ├── json.js
│   │   ├── parse.js
│   │   ├── properties.js
│   │   └── string-sheet.js
│   ├── stylesheet.js
│   ├── test.js
│   ├── util
│   │   ├── colors.js
│   │   ├── extend.js
│   │   ├── hash.js
│   │   ├── index.js
│   │   ├── maps.js
│   │   ├── memoize.js
│   │   ├── regex.js
│   │   ├── sort.js
│   │   ├── strings.js
│   │   └── timing.js
│   ├── version.js
│   └── window.js
└── test
    ├── collection-affinity-propagation.js
    ├── collection-algorithms.js
    ├── collection-astar.js
    ├── collection-building-and-filtering.js
    ├── collection-comparison.js
    ├── collection-compound-nodes.js
    ├── collection-data.js
    ├── collection-fuzzy-c-means.js
    ├── collection-graph-manipulation.js
    ├── collection-hierarchical.js
    ├── collection-iteration.js
    ├── collection-k-means.js
    ├── collection-k-medoids.js
    ├── collection-markov-clustering.js
    ├── collection-metadata.js
    ├── collection-position-and-dimensions.js
    ├── collection-selection.js
    ├── collection-style.js
    ├── collection-traversing.js
    ├── core-export.js
    ├── core-graph-manipulation.js
    ├── core-init.js
    ├── events.js
    ├── extensions.js
    ├── index.html
    ├── lib
    │   ├── bluebird.js
    │   ├── chai.js
    │   ├── expect.js
    │   ├── mocha.css
    │   └── mocha.js
    ├── modules
    │   ├── emitter.js
    │   └── util.js
    ├── requires
    │   └── foo.js
    └── selectors.js
```

</div></details>

# Flask用のディレクトリを作る

次に、Flask用の`flask_cy`ディレクトリを作り、その下に`templates`ディレクトリと`static`ディレクトリを作ります。

- `templates`ディレクトリはHTMLファイルを置く場所
- `static`ディレクトリはCSSファイルとJavaScriptファイルを置く場所

```
$ mkdir flask_cy
$ cd flask_cy
$ mkdir templates
$ mkdir static
$ mkdir static/css
```
`static`ディレクトリの下に、git cloneでダウンロードしていた`cytoscape.js`フォルダをまるっと移動します。（ドラッグ&ドロップ等）

よく考えたら`static`ディレクトリでgit cloneすればよかったorz

# Python、HTML、CSS、JavaScriptのコードを作成

今回はJavaScriptのコードはHTMLに入れ込むことにしたので、以下の3つのファイルを作成しました。

- cy_app.py
- cy_temp2.html　（HTML+JS）
- style.css

### 1. Pythonコード

```python:cy_app.py
import json
from flask import Flask, render_template
import sys

json_file = str(sys.argv[1])

app = Flask(__name__)

@app.route("/")
def cy():
    with open(json_file , 'r') as f:
        elements = json.load(f)

    #elemという名前でcy_temp2.htmlにjsonデータを渡す
    return render_template("cy_temp2.html",elem=elements)

if __name__ == "__main__":
    app.run(debug=True)
```
nodeとedgeの情報のみが含まれるjsonファイルを、pythonコードの第2引数として与えることを想定したソースコードです。

### 2. HTML+JS & CSSコード

これらのコードは以下のデモのソースコードを参考に作成しました。

元にしたデモは[コチラ](http://js.cytoscape.org/demos/initialisation/)
ライセンスページは[コチラ](https://github.com/cytoscape/cytoscape.js/blob/unstable/LICENSE)

<details><summary>HTMLとCSSの詳細はコチラ</summary><div>

```html:cy_temp2.html
<!DOCTYPE html>
<html>
  <head>
    <meta name="description" content="[Cytoscape]" />
    <link href="/static/css/style.css" rel="stylesheet" />
    <meta charset=utf-8 />
    <meta name="viewport" content="user-scalable=no, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, minimal-ui">
    <title>Cytoscape result</title>
    <script src="/static/cytoscape.js/documentation/js/cytoscape.min.js"></script>
  </head>
  <body>
    <div id="cy"></div>
    <script type="text/javascript">
        var cy = cytoscape({
          container: document.querySelector('#cy'),

          boxSelectionEnabled: false,
          autounselectify: true,

          style: cytoscape.stylesheet()
            .selector('node')
              .css({
                'content': 'data(name)',
                'text-valign': 'center',
                'color': 'white',
                'text-outline-width': 2,
                'background-color': '#000080',
                'text-outline-color': '#000080'
              })
            .selector('edge')
              .css({
                'curve-style': 'bezier',
                'line-color': '#8b0000',
                'width': 1
              })
            .selector(':selected')
              .css({
                'background-color': 'black',
                'line-color': 'black',
                'target-arrow-color': 'black',
                'source-arrow-color': 'black'
              })
            .selector('.faded')
              .css({
                'opacity': 0.25,
                'text-opacity': 0
              }),

          elements: {{ elem|tojson }}, //ここに読み込んだjsonデータを流し込む

          layout: {
            name: 'cose'
          }
        });

        cy.on('tap', 'node', function(e){
          var node = e.cyTarget;
          var neighborhood = node.neighborhood().add(node);

          cy.elements().addClass('faded');
          neighborhood.removeClass('faded');
        });

        cy.on('tap', function(e){
          if( e.cyTarget === cy ){
            cy.elements().removeClass('faded');
          }
        });
    </script>
  </body>
</html>
```
```css:style.css
@charset 'utf-8';

body { 
  font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
}
```

[Cytoscape.jsのレイアウトの参照ページ](http://manual.cytoscape.org/en/stable/Navigation_and_Layout.html)

</div></details>

HTMLファイルで重要なのは中程にある`elements: {{ elem|tojson }}`の部分です。これにより、Flaskから受け取ったデータをjson形式で置くことができます。

# Pythonを実行してブラウザで表示

ターミナルの`flask_cy`ディレクトリで以下のコードを実行します。

```
$ python cy_app.py yeastelem.json
 * Serving Flask app "cy_app" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.X:5000/ (Press CTRL+C to quit)
```
jsonファイルはcyREST-Pythonに付属のyeast.jsonファイルのelements部分のみを取り出したものを使用しました。

[cyRESTのウェブサイト](http://apps.cytoscape.org/apps/cyrest)
[cyRESTのGitHub](https://github.com/idekerlab/cy-rest-python)

これでウェブブラウザのURL欄に`http://127.0.0.X:5000/`を入力すると、ネットワーク図が表示されます。

![20181003_cytoscape_qiita.gif](https://qiita-image-store.s3.amazonaws.com/0/204284/3611a5cb-6caf-7f72-527c-408c404a88a4.gif)

画面キャプチャしながら動かしているのでややカクカクしていますが、何もしないで動かしたときはかなりスムーズに動いて良い感じでした。

### 他に参考にしたページ
[軽量WebフレームワークのFlaskに入門](https://www.yoheim.net/blog.php?q=20160505)
[Flaskの簡単な使い方](https://qiita.com/zaburo/items/5091041a5afb2a7dffc8)
[Cytoscape.jsを試してみた](http://steavevaivai.hatenablog.com/entry/2017/03/25/065734)