
JavaScript版のCytoscapeでネットワーク図を綺麗に描画したり動かしたりしたくなり、Pythonの軽量のウェブアプリケーションフレームワークFlaskをはじめて使ってみました。
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
という名前のディレクトリが作られ、その配下にたくさんのファイルが配置されているのがわかります。作るの大変だっただろうなぁ、、、
ツリー構造が長すぎるのですが、興味があればどうぞ
.
├── 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
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コード
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コード
これらのコードは以下のデモのソースコードを参考に作成しました。
HTMLとCSSの詳細はコチラ
<!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>
@charset 'utf-8';
body {
font: 14px helvetica neue, helvetica, arial, sans-serif;
}
# cy {
height: 100%;
width: 100%;
position: absolute;
left: 0;
top: 0;
}
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部分のみを取り出したものを使用しました。
これでウェブブラウザのURL欄にhttp://127.0.0.X:5000/
を入力すると、ネットワーク図が表示されます。
画面キャプチャしながら動かしているのでややカクカクしていますが、何もしないで動かしたときはかなりスムーズに動いて良い感じでした。