├── shaolin
├── helpers.py
├── dashboards
│ ├── __init__.py
│ ├── context.py
│ ├── data_transforms.py
│ └── bokeh.py
├── .spyderproject
├── __pycache__
│ └── __init__.cpython-35.pyc
├── __init__.py
└── core
│ ├── __init__.py
│ ├── context.py
│ ├── dashboard.py
│ ├── stateless_dashboard.py
│ ├── widgets.py
│ ├── kungfu.py
│ └── shaoscript.py
├── tests
├── __init__.py
├── context.py
├── test_advanced.py
└── test_basic.py
├── setup.cfg
├── docs
├── _build
│ ├── html
│ │ ├── _static
│ │ │ ├── custom.css
│ │ │ ├── up.png
│ │ │ ├── down.png
│ │ │ ├── file.png
│ │ │ ├── minus.png
│ │ │ ├── plus.png
│ │ │ ├── comment.png
│ │ │ ├── ajax-loader.gif
│ │ │ ├── up-pressed.png
│ │ │ ├── comment-close.png
│ │ │ ├── down-pressed.png
│ │ │ ├── comment-bright.png
│ │ │ ├── pygments.css
│ │ │ ├── doctools.js
│ │ │ ├── underscore.js
│ │ │ ├── alabaster.css
│ │ │ └── basic.css
│ │ ├── objects.inv
│ │ ├── .buildinfo
│ │ ├── searchindex.js
│ │ ├── _sources
│ │ │ └── index.txt
│ │ ├── genindex.html
│ │ ├── search.html
│ │ └── index.html
│ └── doctrees
│ │ ├── index.doctree
│ │ └── environment.pickle
├── .spyderproject
├── index.rst
├── make.bat
├── Makefile
└── conf.py
├── requirements.txt
├── Makefile
├── requirements-dev.txt
├── examples
├── array_scaler.pkl
├── syntax_color.png
├── colors_data
│ ├── img_1.png
│ ├── img_2.png
│ ├── seq_pal.png
│ ├── cb_palette.png
│ ├── sea_palette.png
│ ├── new_cmappicker.png
│ └── cubehelix_palette.png
├── gplot_data
│ ├── layout.png
│ ├── widget.png
│ ├── pmfg_box.png
│ ├── tooltip.png
│ ├── full_plot.png
│ ├── high_pmfg.png
│ ├── edge_display.png
│ ├── node_display.png
│ ├── sample_matrix_panel.h5
│ └── sample_node_metrics.h5
├── scatter_data
│ ├── free.png
│ ├── img_1.png
│ ├── img_2.png
│ ├── img_3.png
│ ├── img_4.png
│ ├── mapper.png
│ ├── scale.png
│ ├── widget.png
│ ├── overlap.png
│ ├── structure.dia
│ ├── structure.png
│ ├── tooltip.png
│ ├── simple_scatter.png
│ └── structure.svg
├── dashboards_data
│ ├── img_1.png
│ ├── img_2.png
│ ├── img_3.png
│ ├── img_4.png
│ └── img_5.png
├── gcalculator_data
│ ├── img_1.png
│ ├── layout.png
│ ├── matrix.png
│ ├── widget.png
│ ├── creation.png
│ └── forex_sample.h5
├── auto_dashboard_data
│ ├── image_1.png
│ ├── image_2.png
│ ├── image_3.png
│ ├── image_4.png
│ ├── image_5.png
│ ├── image_6.png
│ └── image_7.png
├── shaolin_syntax_data
│ ├── img_1.png
│ ├── img_10.png
│ ├── img_11.png
│ ├── img_2.png
│ ├── img_3.png
│ ├── img_4.png
│ ├── img_5.png
│ ├── img_6.png
│ ├── img_7.png
│ ├── img_8.png
│ ├── img_9.png
│ ├── mem_1.png
│ ├── mem_10.png
│ ├── mem_11.png
│ ├── mem_2.png
│ ├── mem_3.png
│ ├── mem_4.png
│ ├── mem_5.png
│ ├── mem_6.png
│ ├── mem_7.png
│ ├── mem_8.png
│ └── mem_9.png
├── complex_dashboards_data
│ ├── img_1.png
│ ├── img_2.png
│ └── img_3.png
└── Untitled.ipynb
├── setup.py
└── README.md
/shaolin/helpers.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/tests/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [metadata]
2 | description-file = README.md
3 |
--------------------------------------------------------------------------------
/shaolin/dashboards/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
--------------------------------------------------------------------------------
/docs/_build/html/_static/custom.css:
--------------------------------------------------------------------------------
1 | /* This file intentionally left blank. */
2 |
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pandas >= 0.18.0
2 | numpy >= 1.11.0
3 | ipywidgets > 4.1.1
4 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | init:
2 | pip install -r requirements.txt
3 |
4 | test:
5 | nosetests tests
6 |
--------------------------------------------------------------------------------
/docs/.spyderproject:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/.spyderproject
--------------------------------------------------------------------------------
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 |
2 | pandas >= 0.18.0
3 | numpy >= 1.11.0
4 | ipywidgets > 4.1.1
5 |
--------------------------------------------------------------------------------
/shaolin/.spyderproject:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/shaolin/.spyderproject
--------------------------------------------------------------------------------
/examples/array_scaler.pkl:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/array_scaler.pkl
--------------------------------------------------------------------------------
/examples/syntax_color.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/syntax_color.png
--------------------------------------------------------------------------------
/docs/_build/html/objects.inv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/objects.inv
--------------------------------------------------------------------------------
/examples/colors_data/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/img_1.png
--------------------------------------------------------------------------------
/examples/colors_data/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/img_2.png
--------------------------------------------------------------------------------
/examples/gplot_data/layout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/layout.png
--------------------------------------------------------------------------------
/examples/gplot_data/widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/widget.png
--------------------------------------------------------------------------------
/examples/scatter_data/free.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/free.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/up.png
--------------------------------------------------------------------------------
/examples/colors_data/seq_pal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/seq_pal.png
--------------------------------------------------------------------------------
/examples/gplot_data/pmfg_box.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/pmfg_box.png
--------------------------------------------------------------------------------
/examples/gplot_data/tooltip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/tooltip.png
--------------------------------------------------------------------------------
/examples/scatter_data/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/img_1.png
--------------------------------------------------------------------------------
/examples/scatter_data/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/img_2.png
--------------------------------------------------------------------------------
/examples/scatter_data/img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/img_3.png
--------------------------------------------------------------------------------
/examples/scatter_data/img_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/img_4.png
--------------------------------------------------------------------------------
/examples/scatter_data/mapper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/mapper.png
--------------------------------------------------------------------------------
/examples/scatter_data/scale.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/scale.png
--------------------------------------------------------------------------------
/examples/scatter_data/widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/widget.png
--------------------------------------------------------------------------------
/docs/_build/doctrees/index.doctree:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/doctrees/index.doctree
--------------------------------------------------------------------------------
/docs/_build/html/_static/down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/down.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/file.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/minus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/minus.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/plus.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/plus.png
--------------------------------------------------------------------------------
/examples/colors_data/cb_palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/cb_palette.png
--------------------------------------------------------------------------------
/examples/dashboards_data/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/dashboards_data/img_1.png
--------------------------------------------------------------------------------
/examples/dashboards_data/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/dashboards_data/img_2.png
--------------------------------------------------------------------------------
/examples/dashboards_data/img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/dashboards_data/img_3.png
--------------------------------------------------------------------------------
/examples/dashboards_data/img_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/dashboards_data/img_4.png
--------------------------------------------------------------------------------
/examples/dashboards_data/img_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/dashboards_data/img_5.png
--------------------------------------------------------------------------------
/examples/gcalculator_data/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gcalculator_data/img_1.png
--------------------------------------------------------------------------------
/examples/gplot_data/full_plot.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/full_plot.png
--------------------------------------------------------------------------------
/examples/gplot_data/high_pmfg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/high_pmfg.png
--------------------------------------------------------------------------------
/examples/scatter_data/overlap.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/overlap.png
--------------------------------------------------------------------------------
/examples/scatter_data/structure.dia:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/structure.dia
--------------------------------------------------------------------------------
/examples/scatter_data/structure.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/structure.png
--------------------------------------------------------------------------------
/examples/scatter_data/tooltip.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/tooltip.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/comment.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/comment.png
--------------------------------------------------------------------------------
/examples/colors_data/sea_palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/sea_palette.png
--------------------------------------------------------------------------------
/examples/gcalculator_data/layout.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gcalculator_data/layout.png
--------------------------------------------------------------------------------
/examples/gcalculator_data/matrix.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gcalculator_data/matrix.png
--------------------------------------------------------------------------------
/examples/gcalculator_data/widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gcalculator_data/widget.png
--------------------------------------------------------------------------------
/examples/gplot_data/edge_display.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/edge_display.png
--------------------------------------------------------------------------------
/examples/gplot_data/node_display.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/node_display.png
--------------------------------------------------------------------------------
/docs/_build/doctrees/environment.pickle:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/doctrees/environment.pickle
--------------------------------------------------------------------------------
/docs/_build/html/_static/ajax-loader.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/ajax-loader.gif
--------------------------------------------------------------------------------
/docs/_build/html/_static/up-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/up-pressed.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_1.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_2.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_3.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_4.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_5.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_6.png
--------------------------------------------------------------------------------
/examples/auto_dashboard_data/image_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/auto_dashboard_data/image_7.png
--------------------------------------------------------------------------------
/examples/colors_data/new_cmappicker.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/new_cmappicker.png
--------------------------------------------------------------------------------
/examples/gcalculator_data/creation.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gcalculator_data/creation.png
--------------------------------------------------------------------------------
/examples/scatter_data/simple_scatter.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/scatter_data/simple_scatter.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_1.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_10.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_11.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_2.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_3.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_4.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_5.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_6.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_7.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_8.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/img_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/img_9.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_1.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_10.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_11.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_2.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_3.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_4.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_5.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_6.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_7.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_8.png
--------------------------------------------------------------------------------
/examples/shaolin_syntax_data/mem_9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/shaolin_syntax_data/mem_9.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/comment-close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/comment-close.png
--------------------------------------------------------------------------------
/docs/_build/html/_static/down-pressed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/down-pressed.png
--------------------------------------------------------------------------------
/examples/colors_data/cubehelix_palette.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/colors_data/cubehelix_palette.png
--------------------------------------------------------------------------------
/examples/complex_dashboards_data/img_1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/complex_dashboards_data/img_1.png
--------------------------------------------------------------------------------
/examples/complex_dashboards_data/img_2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/complex_dashboards_data/img_2.png
--------------------------------------------------------------------------------
/examples/complex_dashboards_data/img_3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/complex_dashboards_data/img_3.png
--------------------------------------------------------------------------------
/examples/gcalculator_data/forex_sample.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gcalculator_data/forex_sample.h5
--------------------------------------------------------------------------------
/examples/gplot_data/sample_matrix_panel.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/sample_matrix_panel.h5
--------------------------------------------------------------------------------
/examples/gplot_data/sample_node_metrics.h5:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/examples/gplot_data/sample_node_metrics.h5
--------------------------------------------------------------------------------
/docs/_build/html/_static/comment-bright.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/docs/_build/html/_static/comment-bright.png
--------------------------------------------------------------------------------
/shaolin/__pycache__/__init__.cpython-35.pyc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HCsoft-RD/shaolin/HEAD/shaolin/__pycache__/__init__.cpython-35.pyc
--------------------------------------------------------------------------------
/tests/context.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | import sys
4 | import os
5 | sys.path.insert(0, os.path.abspath('..'))
6 |
7 | import sample
--------------------------------------------------------------------------------
/shaolin/__init__.py:
--------------------------------------------------------------------------------
1 |
2 | from shaolin.core.dashboard import Dashboard
3 | from shaolin.core.kungfu import KungFu
4 | from shaolin.core.shaoscript import shaoscript
5 |
--------------------------------------------------------------------------------
/shaolin/core/__init__.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Mon Jun 6 21:41:19 2016
4 |
5 | @author: Guillem Duran Ballester for HCSOFT
6 |
7 | """
8 |
9 |
--------------------------------------------------------------------------------
/docs/_build/html/.buildinfo:
--------------------------------------------------------------------------------
1 | # Sphinx build info version 1
2 | # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
3 | config: 983c11a0d6ff48a0c8f5fcdbb6e00ab5
4 | tags: 645f666f9bcd5a90fca523b33c5a78b7
5 |
--------------------------------------------------------------------------------
/docs/_build/html/searchindex.js:
--------------------------------------------------------------------------------
1 | Search.setIndex({envversion:48,filenames:["index"],objects:{},objnames:{},objtypes:{},terms:{content:0,index:0,modul:0,page:0,search:0},titles:["Welcome to Shaolin’s documentation!"],titleterms:{document:0,indic:0,shaolin:0,tabl:0,welcom:0}})
--------------------------------------------------------------------------------
/tests/test_advanced.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from .context import sample
4 |
5 | import unittest
6 |
7 |
8 | class AdvancedTestSuite(unittest.TestCase):
9 | """Advanced test cases."""
10 |
11 | def test_thoughts(self):
12 | sample.hmm()
13 |
14 |
15 | if __name__ == '__main__':
16 | unittest.main()
--------------------------------------------------------------------------------
/tests/test_basic.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 | from .context import sample
4 |
5 | import unittest
6 |
7 |
8 | class BasicTestSuite(unittest.TestCase):
9 | """Basic test cases."""
10 |
11 | def test_absolute_truth_and_meaning(self):
12 | assert True
13 |
14 |
15 | if __name__ == '__main__':
16 | unittest.main()
--------------------------------------------------------------------------------
/shaolin/core/context.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Thu May 19 12:06:56 2016
4 |
5 | @author: Guillem Duran Ballester
6 | """
7 |
8 |
9 | from shaolin.core.widgets import Widget, Title, SubTitle, SubSubTitle
10 |
11 | from shaolin.core import dashboard
12 | #from shaolin.widgets.dashboards import ToggleMenu
13 | #from shaolin.shaoscript.shaoscript import shaoscript
--------------------------------------------------------------------------------
/shaolin/dashboards/context.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Thu May 19 12:10:57 2016
4 |
5 | @author: sergio
6 | """
7 |
8 |
9 | from shaolin.shaolin.widgets import Widget
10 | #from .dashboards import ToggleMenu
11 | from shaolin.core.dashboard import Dashboard
12 | from shaolin.core.stateless_dashboard import StatelessDashboard
13 | from shaolin.core.css import LayoutHacker
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. Shaolin documentation master file, created by
2 | sphinx-quickstart on Sun May 8 20:56:25 2016.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Shaolin's documentation!
7 | ===================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 |
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
23 |
--------------------------------------------------------------------------------
/docs/_build/html/_sources/index.txt:
--------------------------------------------------------------------------------
1 | .. Shaolin documentation master file, created by
2 | sphinx-quickstart on Sun May 8 20:56:25 2016.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to Shaolin's documentation!
7 | ===================================
8 |
9 | Contents:
10 |
11 | .. toctree::
12 | :maxdepth: 2
13 |
14 |
15 |
16 | Indices and tables
17 | ==================
18 |
19 | * :ref:`genindex`
20 | * :ref:`modindex`
21 | * :ref:`search`
22 |
23 |
--------------------------------------------------------------------------------
/examples/Untitled.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "code",
5 | "execution_count": null,
6 | "metadata": {
7 | "collapsed": true
8 | },
9 | "outputs": [],
10 | "source": []
11 | }
12 | ],
13 | "metadata": {
14 | "kernelspec": {
15 | "display_name": "Python 3",
16 | "language": "python",
17 | "name": "python3"
18 | },
19 | "language_info": {
20 | "codemirror_mode": {
21 | "name": "ipython",
22 | "version": 3
23 | },
24 | "file_extension": ".py",
25 | "mimetype": "text/x-python",
26 | "name": "python",
27 | "nbconvert_exporter": "python",
28 | "pygments_lexer": "ipython3",
29 | "version": "3.5.1"
30 | },
31 | "widgets": {
32 | "state": {},
33 | "version": "1.1.2"
34 | }
35 | },
36 | "nbformat": 4,
37 | "nbformat_minor": 0
38 | }
39 |
--------------------------------------------------------------------------------
/docs/_build/html/genindex.html:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | Index — Shaolin 0.0.1 documentation
11 |
12 |
13 |
14 |
15 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
Index
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
77 |
78 |
79 |
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """A setuptools based setup module.
3 | See:
4 | https://packaging.python.org/en/latest/distributing.html
5 | https://github.com/pypa/sampleproject
6 | """
7 |
8 | # Always prefer setuptools over distutils
9 | from setuptools import setup, find_packages
10 | # To use a consistent encoding
11 | from codecs import open
12 | from os import path
13 |
14 | here = path.abspath(path.dirname(__file__))
15 |
16 | # Get the long description from the README file
17 | with open(path.join(here, 'README.md'), encoding='utf-8') as f:
18 | long_description = f.read()
19 |
20 | setup(
21 | name='shaolin',
22 |
23 | # Versions should comply with PEP440. For a discussion on single-sourcing
24 | # the version across setup.py and the project code, see
25 | # https://packaging.python.org/en/latest/single_source_version.html
26 | version='0.0.1b2',
27 |
28 | description='Interactive dashboard programming framework for the jupyter notebook',
29 | long_description=long_description,
30 |
31 | # The project's main homepage.
32 | url='https://github.com/HCsoft-RD/shaolin',
33 |
34 | # Author details
35 | author='HCSoft programacion S.L. (coded by Guillem Duran Ballester)',
36 | author_email='oficina@hcsoft.net',
37 |
38 | # Choose your license
39 | license='BSD',
40 |
41 | # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
42 | classifiers=[
43 | # How mature is this project? Common values are
44 | # 3 - Alpha
45 | # 4 - Beta
46 | # 5 - Production/Stable
47 | 'Development Status :: 4 - Beta',
48 |
49 | # Indicate who your project is intended for
50 | 'Intended Audience :: Developers',
51 | 'Topic :: Software Development :: Build Tools',
52 |
53 | # Pick your license as you wish (should match "license" above)
54 | 'License :: OSI Approved :: BSD License',
55 |
56 | # Specify the Python versions you support here. In particular, ensure
57 | # that you indicate whether you support Python 2, Python 3 or both.
58 | 'Programming Language :: Python :: 3',
59 | 'Programming Language :: Python :: 3.3',
60 | 'Programming Language :: Python :: 3.4',
61 | 'Programming Language :: Python :: 3.5',
62 | 'Programming Language :: Python :: 3.6',
63 | ],
64 |
65 | # What does your project relate to?
66 | keywords=['dashboards', 'data vis', 'data analysis', 'shaolin'],
67 |
68 | # You can just specify the packages manually here if your project is
69 | # simple. Or you can use find_packages().
70 | packages=find_packages(exclude=['contrib', 'docs', 'tests']),
71 |
72 | # Alternatively, if you want to distribute just a my_module.py, uncomment
73 | # this:
74 | # py_modules=["my_module"],
75 |
76 | # List run-time dependencies here. These will be installed by pip when
77 | # your project is installed. For an analysis of "install_requires" vs pip's
78 | # requirements files see:
79 | # https://packaging.python.org/en/latest/requirements.html
80 | install_requires=['planarity','bokeh', 'pandas', 'numpy',
81 | 'networkx', 'seaborn','ipywidgets','plotly','cufflinks'],
82 |
83 | # List additional groups of dependencies here (e.g. development
84 | # dependencies). You can install these using the following syntax,
85 | # for example:
86 | # $ pip install -e .[dev,test]
87 | extras_require={
88 | 'dev': ['check-manifest'],
89 | 'test': ['coverage'],
90 | }
91 |
92 | )
93 |
94 |
95 |
--------------------------------------------------------------------------------
/docs/_build/html/search.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Search — Shaolin 0.0.1 documentation
10 |
11 |
12 |
13 |
14 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
Search
51 |
52 |
53 |
54 | Please activate JavaScript to enable the search
55 | functionality.
56 |
57 |
58 |
59 | From here you can search these documents. Enter your search
60 | words into the box below and click "search". Note that the search
61 | function will automatically search for all of the words. Pages
62 | containing fewer words won't appear in the result list.
63 |
64 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
87 |
88 |
89 |
97 |
98 |
99 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/shaolin/dashboards/data_transforms.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Wed Jun 1 23:31:50 2016
4 |
5 | @author: Guillem Duran Ballester for HCSoft
6 | """
7 | import numpy as np
8 | import pandas as pd
9 | from shaolin.core.dashboard import Dashboard
10 | class DataFrameScaler(Dashboard):
11 |
12 | def __init__(self,
13 | data,
14 | funcs=None,
15 | min=0,
16 | max=100,
17 | step=None,
18 | low=None,
19 | high=None,
20 | **kwargs):
21 | if funcs is None:
22 | self.funcs = {'raw':lambda x: x,
23 | 'zscore': lambda x: (x-np.mean(x))/np.std(x),
24 | 'log': np.log,
25 | 'rank':lambda x: pd.DataFrame(x).rank().values.flatten(),
26 | 'inv': lambda x: -x,
27 | 'cut':lambda x: pd.cut(x,[-1001, 0.1,0.3, 0.6, 0.8, 1.0,1.5, 3.0, 6.0, 12, 1001],labels=False)
28 | }
29 | else:
30 | self.funcs = funcs
31 | self._df = data.apply(self.categorical_to_num)
32 | if min is None:
33 | min = self._df.min().values[0]
34 | if max is None:
35 | max = self._df.max().values[0]
36 | if step is None:
37 | step = (max-min)/100.
38 | if low is None:
39 | low = min
40 | if high is None:
41 | high = max
42 |
43 | self.output = None
44 |
45 | dash = ['c$N=df_scaler',
46 | ['@('+str(min)+', '+str(max)+', '+str(step)+', ('+str(low)+', '+str(high)+'))$N=scale_slider&d=Scale',
47 | ['r$N=main_row',['@dd$d=Apply&N=dd_sel&val=raw&o='+str(list(self.funcs.keys())),'@True$N=scale_chk&d=Scale']]
48 | ]
49 | ]
50 | Dashboard.__init__(self, dash, mode='interactive', **kwargs)
51 | self.dd_sel.target.layout.width = "100%"
52 | self.scale_chk.widget.layout.padding = "0.25em"
53 | self.observe(self.update)
54 | self.update()
55 |
56 | @property
57 | def data(self):
58 | return self._df
59 |
60 | @data.setter
61 | def data(self, val):
62 | self._df = val.apply(self.categorical_to_num)
63 | self.update()
64 |
65 | def scale_func(self, data):
66 | Ma = np.max(data)
67 | mi = np.min(data)
68 | score = ((data-mi)/(Ma-mi))#to 0-1 interval
69 | if mi == Ma:
70 | return np.ones(len(score)) *0.5
71 | scale_h = self.scale_slider.value[1]
72 | scale_l = self.scale_slider.value[0]
73 | return score*(scale_h-scale_l)+scale_l
74 |
75 | def update(self, _=None):
76 | self.output = self.data.apply(self.funcs[self.dd_sel.value])
77 | if self.scale_chk.value:
78 | self.scale_slider.visible = True
79 | self.output = self.output.apply(self.scale_func)
80 | else:
81 | self.scale_slider.visible = False
82 | @staticmethod
83 | def categorical_to_num(data):
84 | """Converts categorical data into an array of ints"""
85 | if isinstance(data.values[0], str):
86 | cats = np.unique(data)
87 | imap = {}
88 | for i, cat in enumerate(cats):
89 | imap[cat] = i
90 | fun = lambda x: imap[x]
91 | return list(map(fun, data))
92 | else:
93 | return data
94 |
95 | @staticmethod
96 | def is_categorical_series(data):
97 | """true if data is a categorical series"""
98 | return isinstance(data.values[0], str)
99 |
--------------------------------------------------------------------------------
/docs/_build/html/_static/pygments.css:
--------------------------------------------------------------------------------
1 | .highlight .hll { background-color: #ffffcc }
2 | .highlight { background: #eeffcc; }
3 | .highlight .c { color: #408090; font-style: italic } /* Comment */
4 | .highlight .err { border: 1px solid #FF0000 } /* Error */
5 | .highlight .k { color: #007020; font-weight: bold } /* Keyword */
6 | .highlight .o { color: #666666 } /* Operator */
7 | .highlight .ch { color: #408090; font-style: italic } /* Comment.Hashbang */
8 | .highlight .cm { color: #408090; font-style: italic } /* Comment.Multiline */
9 | .highlight .cp { color: #007020 } /* Comment.Preproc */
10 | .highlight .cpf { color: #408090; font-style: italic } /* Comment.PreprocFile */
11 | .highlight .c1 { color: #408090; font-style: italic } /* Comment.Single */
12 | .highlight .cs { color: #408090; background-color: #fff0f0 } /* Comment.Special */
13 | .highlight .gd { color: #A00000 } /* Generic.Deleted */
14 | .highlight .ge { font-style: italic } /* Generic.Emph */
15 | .highlight .gr { color: #FF0000 } /* Generic.Error */
16 | .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */
17 | .highlight .gi { color: #00A000 } /* Generic.Inserted */
18 | .highlight .go { color: #333333 } /* Generic.Output */
19 | .highlight .gp { color: #c65d09; font-weight: bold } /* Generic.Prompt */
20 | .highlight .gs { font-weight: bold } /* Generic.Strong */
21 | .highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */
22 | .highlight .gt { color: #0044DD } /* Generic.Traceback */
23 | .highlight .kc { color: #007020; font-weight: bold } /* Keyword.Constant */
24 | .highlight .kd { color: #007020; font-weight: bold } /* Keyword.Declaration */
25 | .highlight .kn { color: #007020; font-weight: bold } /* Keyword.Namespace */
26 | .highlight .kp { color: #007020 } /* Keyword.Pseudo */
27 | .highlight .kr { color: #007020; font-weight: bold } /* Keyword.Reserved */
28 | .highlight .kt { color: #902000 } /* Keyword.Type */
29 | .highlight .m { color: #208050 } /* Literal.Number */
30 | .highlight .s { color: #4070a0 } /* Literal.String */
31 | .highlight .na { color: #4070a0 } /* Name.Attribute */
32 | .highlight .nb { color: #007020 } /* Name.Builtin */
33 | .highlight .nc { color: #0e84b5; font-weight: bold } /* Name.Class */
34 | .highlight .no { color: #60add5 } /* Name.Constant */
35 | .highlight .nd { color: #555555; font-weight: bold } /* Name.Decorator */
36 | .highlight .ni { color: #d55537; font-weight: bold } /* Name.Entity */
37 | .highlight .ne { color: #007020 } /* Name.Exception */
38 | .highlight .nf { color: #06287e } /* Name.Function */
39 | .highlight .nl { color: #002070; font-weight: bold } /* Name.Label */
40 | .highlight .nn { color: #0e84b5; font-weight: bold } /* Name.Namespace */
41 | .highlight .nt { color: #062873; font-weight: bold } /* Name.Tag */
42 | .highlight .nv { color: #bb60d5 } /* Name.Variable */
43 | .highlight .ow { color: #007020; font-weight: bold } /* Operator.Word */
44 | .highlight .w { color: #bbbbbb } /* Text.Whitespace */
45 | .highlight .mb { color: #208050 } /* Literal.Number.Bin */
46 | .highlight .mf { color: #208050 } /* Literal.Number.Float */
47 | .highlight .mh { color: #208050 } /* Literal.Number.Hex */
48 | .highlight .mi { color: #208050 } /* Literal.Number.Integer */
49 | .highlight .mo { color: #208050 } /* Literal.Number.Oct */
50 | .highlight .sb { color: #4070a0 } /* Literal.String.Backtick */
51 | .highlight .sc { color: #4070a0 } /* Literal.String.Char */
52 | .highlight .sd { color: #4070a0; font-style: italic } /* Literal.String.Doc */
53 | .highlight .s2 { color: #4070a0 } /* Literal.String.Double */
54 | .highlight .se { color: #4070a0; font-weight: bold } /* Literal.String.Escape */
55 | .highlight .sh { color: #4070a0 } /* Literal.String.Heredoc */
56 | .highlight .si { color: #70a0d0; font-style: italic } /* Literal.String.Interpol */
57 | .highlight .sx { color: #c65d09 } /* Literal.String.Other */
58 | .highlight .sr { color: #235388 } /* Literal.String.Regex */
59 | .highlight .s1 { color: #4070a0 } /* Literal.String.Single */
60 | .highlight .ss { color: #517918 } /* Literal.String.Symbol */
61 | .highlight .bp { color: #007020 } /* Name.Builtin.Pseudo */
62 | .highlight .vc { color: #bb60d5 } /* Name.Variable.Class */
63 | .highlight .vg { color: #bb60d5 } /* Name.Variable.Global */
64 | .highlight .vi { color: #bb60d5 } /* Name.Variable.Instance */
65 | .highlight .il { color: #208050 } /* Literal.Number.Integer.Long */
--------------------------------------------------------------------------------
/docs/_build/html/index.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | Welcome to Shaolin’s documentation! — Shaolin 0.0.1 documentation
10 |
11 |
12 |
13 |
14 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
Welcome to Shaolin’s documentation!
44 |
Contents:
45 |
49 |
50 |
51 |
Indices and tables
52 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
96 |
97 |
98 |
109 |
110 |
111 |
112 |
113 |
114 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Shaolin
3 |
4 |
5 | ## Framework for interactive widget-based dashboards programming. Feedback is really appreciated
6 |
7 |
8 | **Shaolin**(**S**tructure **H**elper for d**A**shb**O**ard **LIN**king) is an ipywidgets based framework that allows to create interactive dashboards that can be linked with each other to build complex applications.
9 |
10 | Its still in a alpha alpha version, the beta version will be realeased before 17 july.
11 |
12 | Installation: **pip install shaolin**.
13 |
14 | ## Alpha version disclaimer
15 |
16 | This package is a few months old and has only been tested by me. Everything should work with medium size data (Pandas and plotting using the svg backend instead of WebGL). If you plan on using shaolin for business please contact me.
17 |
18 | ### Dependencies:
19 | - six
20 | - numpy
21 | - pandas
22 | - planarity
23 | - networkx
24 | - bokeh
25 | - seaborn
26 | - vpython
27 | - plotly
28 | - cufflinks
29 |
30 |
31 |
32 |
33 | # Main features
34 |
35 |
36 | The documentation is located in the [examples](https://github.com/HCsoft-RD/shaolin/tree/master/examples) folder.
37 |
38 | ### ipywidgets based and pydata compatible
39 |
40 | This framework is build on top of standard pydata libraries like pandas and numpy and uses only the ipywidgets package for the interface management, although
41 | shaolin provides a simplified interface that extends the ipywidgets capabilities.
42 |
43 | ### Own syntax for quickly defining new Dashboards
44 |
45 | Shaolin has a simplified syntax that allows to program dashboards consisting on multiple widgets more quickly.
46 |
47 | - [Syntax for defining widgets](https://github.com/HCsoft-RD/shaolin/blob/master/examples/Shaolin%20syntax.ipynb)
48 | - [Dashboard introduction](https://github.com/HCsoft-RD/shaolin/blob/master/examples/Dashboards.ipynb)
49 |
50 | ### Link different Dashboard to create complex applications
51 |
52 | It is possible to combine multiple dashboards into a new one in order to perform complex tasks like data analysis or plotting.
53 |
54 | - [Dashboard programming tutorial](https://github.com/HCsoft-RD/shaolin/blob/master/examples/Creating%20complex%20Dashboards.ipynb)
55 |
56 | ### Save and share your dashboards easily
57 |
58 | You can load and save the state of a dashboard easily with no additional effort.
59 |
60 | ### No more writing widgets css
61 |
62 | Modify any visual property of a dashboard interactively using widgets.
63 |
64 |
65 | *********************
66 | # Sample Dashboards
67 |
68 | Shaolin comes batteries included with Dashboard created for performing various standard data analysis tasks that you can use as a base to build your own applications.
69 |
70 | ### Colormap creation
71 | Use a colormap picker capable of creating any matplotlib and seaborn colormap or palette.
72 |
73 | - [Colormap tutorial](https://github.com/HCsoft-RD/shaolin/blob/master/examples/Shaolin%20Colors.ipynb)
74 |
75 | ### Full customizable scatter plot
76 |
77 | Plot an interactive bokeh scatter plot with tooltips from any pandas DataFrame, Panel or Panel4D. You will be able to modify any visual property of the plot with just a few clicks. I bet you wont need to program another scatter plot after trying this ;)
78 |
79 | - [Scatter plot introduction](https://github.com/HCsoft-RD/shaolin/blob/master/examples/Scatter%20Plot%20introduction.ipynb)
80 |
81 | ### Networkx compatibility
82 | We have dashboards that map the networkx interface to calculate any graph metric, any graph layout and the capability of converting time series correlation matrices into graphs.
83 | You will also be able to plot any graph using the networkx capabilities in a fully customizable bokeh plot.
84 |
85 | - [Shaolin GraphCalculator tutorial] (https://github.com/HCsoft-RD/shaolin/blob/master/examples/GraphCalculator.ipynb)
86 | - [Shaolin Bokeh GraphPlot tutorial] (https://github.com/HCsoft-RD/shaolin/blob/master/examples/GraphPlot.ipynb)
87 |
88 | ### Slicers
89 | Widgets for slicing any pandas structure or numpy array.
90 |
91 | ###plot mappers
92 | These Dashboards provide everything you need to create new interactive plots with almost no code.
93 |
94 | ### Plotly compatibility
95 | Define a custom plot layout using widgets and use the cufflinks library with a pandas DataFrame without writing a single line of code.
96 |
97 | # Upcoming features
98 |
99 | I hope most of there are available in the beta release.
100 |
101 | ###Walkers
102 |
103 | It will extend the capabilities of the GraphCalculator for making interactive animated graphs in real time. This is really usefull for visualizing correlation matrix time series.
104 |
105 |
106 | Compatibility for mapping data to interactive matplotlib plots using MplD3.
107 |
108 |
--------------------------------------------------------------------------------
/shaolin/core/dashboard.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Thu May 19 12:02:20 2016
4 |
5 | @author: Guillem Duran Ballester
6 | """
7 | #import six
8 | #import pickle
9 | from shaolin.core import stateless_dashboard as sld
10 | #from .css import LayoutHacker
11 |
12 | class Dashboard(sld.StatelessDashboard):
13 | """Clash for managing arbitrary Dashboards"""
14 | def __init__(self,dash, state=None, **kwargs):
15 | sld.StatelessDashboard.__init__(self, dash, **kwargs)
16 | #self._state = self._load_state(state)
17 |
18 | def __call__(self,**kwargs):
19 | return self.kwargs
20 | def __getitem__(self,index):
21 | if index is None or isinstance(index,(int,bool)):
22 | return self.widget
23 | else:
24 | raise ValueError("index must be integer or None or bool")
25 | """"
26 | @property
27 | def state(self):
28 | return self._state
29 | @state.setter
30 | def state(self, val):
31 | self._state = val
32 | self.apply_state()
33 | def _update_state(self, _=None):
34 | self._state = self._state_manager.output
35 |
36 | def _load_state(self, state):
37 | if isinstance(state, six.string_types):
38 | try:
39 | with open(state, "rb") as input_file:
40 | state = pickle.load(input_file)
41 | except:
42 | return None
43 | if not state is None:
44 | self.apply_state(state)
45 | return state
46 |
47 | @property
48 | def kwargs(self):
49 | return StatelessDashboard.kwargs
50 |
51 | @kwargs.setter
52 | def kwargs(self,vals):
53 | Children values as a kwargs dict for easier interactivity
54 |
55 | for name in vals.keys():
56 | attr = getattr(self, name)
57 | if isinstance(attr, Dashboard):
58 | attr.kwargs = vals['name']
59 | else:
60 | attr.value = vals['name']
61 | @property
62 | def state_manager(self):
63 | self._state_manager = LayoutHacker(self)
64 | self._state_manager.observe(self._update_state)
65 | self._update_state()
66 | return self._state_manager.widget
67 |
68 | def apply_state(self, state_dict=None):
69 | "loads a generated state dict and applies it to the dashboard"
70 | if state_dict is None:
71 | state_dict = self._state
72 | if state_dict is None:
73 | self.state_manager()
74 | for attr in self.mode_dict['all']:
75 | for css_tra, items_dict in state_dict[attr]['css_traits'].items():
76 | for widget,val in items_dict.items():
77 | layout = getattr(getattr(self, attr), widget).layout
78 | if val != '':
79 | setattr(layout,css_tra,val)
80 | for tget_attr, val in state_dict[attr]['widget_attrs'].items():
81 | tget_wid = getattr(self, attr).target
82 | if val != '':
83 | setattr(tget_wid, tget_attr, val)"""
84 |
85 | class ToggleMenu(Dashboard):
86 | def __init__(self,
87 | children,
88 | description='',
89 | buttons_shao=None,
90 | name=None,
91 | button_labels=None,
92 | button_type='togs',
93 | button_pos='bottom',
94 | **kwargs):
95 | self.child_names = self.get_children_names(children)
96 | if button_labels is None:
97 | self.button_labels = self.child_names
98 | else:
99 | self.button_labels = button_labels
100 |
101 | if buttons_shao is None:
102 | opts = dict(zip(self.button_labels,self.child_names))
103 | buttons_shao = ['@'+button_type+'$N=buttons&d='+str(description)+'&o='+str(opts)]
104 |
105 | self.children_dash = children
106 | #children = ['fs$d=fs','fs$d=fs2']
107 | #buttons = ['r$n=buttons', buttons_shao]
108 | if button_pos == 'bottom':
109 | dash = ['V$n=toggleMenu',
110 | children+buttons_shao
111 | ]
112 | elif button_pos == 'top':
113 | dash = ['V$n=toggleMenu',
114 | buttons_shao+children
115 | ]
116 | elif button_pos == 'right':
117 | dash = ['r$n=toggleMenu',
118 | children+buttons_shao
119 | ]
120 | elif button_pos == 'left':
121 | dash = ['r$n=toggleMenu',
122 | buttons_shao+children
123 | ]
124 | Dashboard.__init__(self, dash, func=None, name=name, **kwargs)
125 | self.update_toggle()
126 | self.buttons.target.observe(self.update_toggle)
127 |
128 | def get_children_names(self,children):
129 | names = []
130 | for c in children:
131 | try:
132 | names += [self.name_from_shaoscript(c)]
133 | except:
134 | names += [c.name]
135 |
136 | return names
137 |
138 | def update_toggle(self,_=None):
139 |
140 | for name in self.child_names:
141 | child = getattr(self,name)
142 | if name == self.buttons.value:
143 | child.visible = True
144 | else:
145 | child.visible = False
--------------------------------------------------------------------------------
/examples/scatter_data/structure.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | pandas data
9 |
10 |
11 |
12 |
13 |
14 |
15 | Slicer
16 |
17 |
18 |
19 |
20 |
21 |
22 | Scaler
23 |
24 |
25 |
26 |
27 |
28 |
29 | Defaults
30 |
31 |
32 |
33 |
34 |
35 |
36 | Tooltip data
37 |
38 |
39 |
40 |
41 |
42 |
43 | output DataFrame
44 |
45 |
46 |
47 |
48 | Plot data mapper
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | Bokeh source
75 |
76 |
77 |
78 |
79 |
80 |
81 | Plot
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
--------------------------------------------------------------------------------
/docs/_build/html/_static/doctools.js:
--------------------------------------------------------------------------------
1 | /*
2 | * doctools.js
3 | * ~~~~~~~~~~~
4 | *
5 | * Sphinx JavaScript utilities for all documentation.
6 | *
7 | * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | /**
13 | * select a different prefix for underscore
14 | */
15 | $u = _.noConflict();
16 |
17 | /**
18 | * make the code below compatible with browsers without
19 | * an installed firebug like debugger
20 | if (!window.console || !console.firebug) {
21 | var names = ["log", "debug", "info", "warn", "error", "assert", "dir",
22 | "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace",
23 | "profile", "profileEnd"];
24 | window.console = {};
25 | for (var i = 0; i < names.length; ++i)
26 | window.console[names[i]] = function() {};
27 | }
28 | */
29 |
30 | /**
31 | * small helper function to urldecode strings
32 | */
33 | jQuery.urldecode = function(x) {
34 | return decodeURIComponent(x).replace(/\+/g, ' ');
35 | };
36 |
37 | /**
38 | * small helper function to urlencode strings
39 | */
40 | jQuery.urlencode = encodeURIComponent;
41 |
42 | /**
43 | * This function returns the parsed url parameters of the
44 | * current request. Multiple values per key are supported,
45 | * it will always return arrays of strings for the value parts.
46 | */
47 | jQuery.getQueryParameters = function(s) {
48 | if (typeof s == 'undefined')
49 | s = document.location.search;
50 | var parts = s.substr(s.indexOf('?') + 1).split('&');
51 | var result = {};
52 | for (var i = 0; i < parts.length; i++) {
53 | var tmp = parts[i].split('=', 2);
54 | var key = jQuery.urldecode(tmp[0]);
55 | var value = jQuery.urldecode(tmp[1]);
56 | if (key in result)
57 | result[key].push(value);
58 | else
59 | result[key] = [value];
60 | }
61 | return result;
62 | };
63 |
64 | /**
65 | * highlight a given string on a jquery object by wrapping it in
66 | * span elements with the given class name.
67 | */
68 | jQuery.fn.highlightText = function(text, className) {
69 | function highlight(node) {
70 | if (node.nodeType == 3) {
71 | var val = node.nodeValue;
72 | var pos = val.toLowerCase().indexOf(text);
73 | if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) {
74 | var span = document.createElement("span");
75 | span.className = className;
76 | span.appendChild(document.createTextNode(val.substr(pos, text.length)));
77 | node.parentNode.insertBefore(span, node.parentNode.insertBefore(
78 | document.createTextNode(val.substr(pos + text.length)),
79 | node.nextSibling));
80 | node.nodeValue = val.substr(0, pos);
81 | }
82 | }
83 | else if (!jQuery(node).is("button, select, textarea")) {
84 | jQuery.each(node.childNodes, function() {
85 | highlight(this);
86 | });
87 | }
88 | }
89 | return this.each(function() {
90 | highlight(this);
91 | });
92 | };
93 |
94 | /*
95 | * backward compatibility for jQuery.browser
96 | * This will be supported until firefox bug is fixed.
97 | */
98 | if (!jQuery.browser) {
99 | jQuery.uaMatch = function(ua) {
100 | ua = ua.toLowerCase();
101 |
102 | var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
103 | /(webkit)[ \/]([\w.]+)/.exec(ua) ||
104 | /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
105 | /(msie) ([\w.]+)/.exec(ua) ||
106 | ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
107 | [];
108 |
109 | return {
110 | browser: match[ 1 ] || "",
111 | version: match[ 2 ] || "0"
112 | };
113 | };
114 | jQuery.browser = {};
115 | jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true;
116 | }
117 |
118 | /**
119 | * Small JavaScript module for the documentation.
120 | */
121 | var Documentation = {
122 |
123 | init : function() {
124 | this.fixFirefoxAnchorBug();
125 | this.highlightSearchWords();
126 | this.initIndexTable();
127 | },
128 |
129 | /**
130 | * i18n support
131 | */
132 | TRANSLATIONS : {},
133 | PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; },
134 | LOCALE : 'unknown',
135 |
136 | // gettext and ngettext don't access this so that the functions
137 | // can safely bound to a different name (_ = Documentation.gettext)
138 | gettext : function(string) {
139 | var translated = Documentation.TRANSLATIONS[string];
140 | if (typeof translated == 'undefined')
141 | return string;
142 | return (typeof translated == 'string') ? translated : translated[0];
143 | },
144 |
145 | ngettext : function(singular, plural, n) {
146 | var translated = Documentation.TRANSLATIONS[singular];
147 | if (typeof translated == 'undefined')
148 | return (n == 1) ? singular : plural;
149 | return translated[Documentation.PLURALEXPR(n)];
150 | },
151 |
152 | addTranslations : function(catalog) {
153 | for (var key in catalog.messages)
154 | this.TRANSLATIONS[key] = catalog.messages[key];
155 | this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')');
156 | this.LOCALE = catalog.locale;
157 | },
158 |
159 | /**
160 | * add context elements like header anchor links
161 | */
162 | addContextElements : function() {
163 | $('div[id] > :header:first').each(function() {
164 | $('').
165 | attr('href', '#' + this.id).
166 | attr('title', _('Permalink to this headline')).
167 | appendTo(this);
168 | });
169 | $('dt[id]').each(function() {
170 | $('').
171 | attr('href', '#' + this.id).
172 | attr('title', _('Permalink to this definition')).
173 | appendTo(this);
174 | });
175 | },
176 |
177 | /**
178 | * workaround a firefox stupidity
179 | * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075
180 | */
181 | fixFirefoxAnchorBug : function() {
182 | if (document.location.hash)
183 | window.setTimeout(function() {
184 | document.location.href += '';
185 | }, 10);
186 | },
187 |
188 | /**
189 | * highlight the search words provided in the url in the text
190 | */
191 | highlightSearchWords : function() {
192 | var params = $.getQueryParameters();
193 | var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : [];
194 | if (terms.length) {
195 | var body = $('div.body');
196 | if (!body.length) {
197 | body = $('body');
198 | }
199 | window.setTimeout(function() {
200 | $.each(terms, function() {
201 | body.highlightText(this.toLowerCase(), 'highlighted');
202 | });
203 | }, 10);
204 | $('' + _('Hide Search Matches') + '
')
206 | .appendTo($('#searchbox'));
207 | }
208 | },
209 |
210 | /**
211 | * init the domain index toggle buttons
212 | */
213 | initIndexTable : function() {
214 | var togglers = $('img.toggler').click(function() {
215 | var src = $(this).attr('src');
216 | var idnum = $(this).attr('id').substr(7);
217 | $('tr.cg-' + idnum).toggle();
218 | if (src.substr(-9) == 'minus.png')
219 | $(this).attr('src', src.substr(0, src.length-9) + 'plus.png');
220 | else
221 | $(this).attr('src', src.substr(0, src.length-8) + 'minus.png');
222 | }).css('display', '');
223 | if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) {
224 | togglers.click();
225 | }
226 | },
227 |
228 | /**
229 | * helper function to hide the search marks again
230 | */
231 | hideSearchWords : function() {
232 | $('#searchbox .highlight-link').fadeOut(300);
233 | $('span.highlighted').removeClass('highlighted');
234 | },
235 |
236 | /**
237 | * make the url absolute
238 | */
239 | makeURL : function(relativeURL) {
240 | return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL;
241 | },
242 |
243 | /**
244 | * get the current relative url
245 | */
246 | getCurrentURL : function() {
247 | var path = document.location.pathname;
248 | var parts = path.split(/\//);
249 | $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() {
250 | if (this == '..')
251 | parts.pop();
252 | });
253 | var url = parts.join('/');
254 | return path.substring(url.lastIndexOf('/') + 1, path.length - 1);
255 | }
256 | };
257 |
258 | // quick alias for translations
259 | _ = Documentation.gettext;
260 |
261 | $(document).ready(function() {
262 | Documentation.init();
263 | });
264 |
--------------------------------------------------------------------------------
/docs/make.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 |
3 | REM Command file for Sphinx documentation
4 |
5 | if "%SPHINXBUILD%" == "" (
6 | set SPHINXBUILD=sphinx-build
7 | )
8 | set BUILDDIR=_build
9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
10 | set I18NSPHINXOPTS=%SPHINXOPTS% .
11 | if NOT "%PAPER%" == "" (
12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
14 | )
15 |
16 | if "%1" == "" goto help
17 |
18 | if "%1" == "help" (
19 | :help
20 | echo.Please use `make ^` where ^ is one of
21 | echo. html to make standalone HTML files
22 | echo. dirhtml to make HTML files named index.html in directories
23 | echo. singlehtml to make a single large HTML file
24 | echo. pickle to make pickle files
25 | echo. json to make JSON files
26 | echo. htmlhelp to make HTML files and a HTML help project
27 | echo. qthelp to make HTML files and a qthelp project
28 | echo. devhelp to make HTML files and a Devhelp project
29 | echo. epub to make an epub
30 | echo. epub3 to make an epub3
31 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter
32 | echo. text to make text files
33 | echo. man to make manual pages
34 | echo. texinfo to make Texinfo files
35 | echo. gettext to make PO message catalogs
36 | echo. changes to make an overview over all changed/added/deprecated items
37 | echo. xml to make Docutils-native XML files
38 | echo. pseudoxml to make pseudoxml-XML files for display purposes
39 | echo. linkcheck to check all external links for integrity
40 | echo. doctest to run all doctests embedded in the documentation if enabled
41 | echo. coverage to run coverage check of the documentation if enabled
42 | echo. dummy to check syntax errors of document sources
43 | goto end
44 | )
45 |
46 | if "%1" == "clean" (
47 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
48 | del /q /s %BUILDDIR%\*
49 | goto end
50 | )
51 |
52 |
53 | REM Check if sphinx-build is available and fallback to Python version if any
54 | %SPHINXBUILD% 1>NUL 2>NUL
55 | if errorlevel 9009 goto sphinx_python
56 | goto sphinx_ok
57 |
58 | :sphinx_python
59 |
60 | set SPHINXBUILD=python -m sphinx.__init__
61 | %SPHINXBUILD% 2> nul
62 | if errorlevel 9009 (
63 | echo.
64 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
65 | echo.installed, then set the SPHINXBUILD environment variable to point
66 | echo.to the full path of the 'sphinx-build' executable. Alternatively you
67 | echo.may add the Sphinx directory to PATH.
68 | echo.
69 | echo.If you don't have Sphinx installed, grab it from
70 | echo.http://sphinx-doc.org/
71 | exit /b 1
72 | )
73 |
74 | :sphinx_ok
75 |
76 |
77 | if "%1" == "html" (
78 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
79 | if errorlevel 1 exit /b 1
80 | echo.
81 | echo.Build finished. The HTML pages are in %BUILDDIR%/html.
82 | goto end
83 | )
84 |
85 | if "%1" == "dirhtml" (
86 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
87 | if errorlevel 1 exit /b 1
88 | echo.
89 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
90 | goto end
91 | )
92 |
93 | if "%1" == "singlehtml" (
94 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
95 | if errorlevel 1 exit /b 1
96 | echo.
97 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
98 | goto end
99 | )
100 |
101 | if "%1" == "pickle" (
102 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
103 | if errorlevel 1 exit /b 1
104 | echo.
105 | echo.Build finished; now you can process the pickle files.
106 | goto end
107 | )
108 |
109 | if "%1" == "json" (
110 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
111 | if errorlevel 1 exit /b 1
112 | echo.
113 | echo.Build finished; now you can process the JSON files.
114 | goto end
115 | )
116 |
117 | if "%1" == "htmlhelp" (
118 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
119 | if errorlevel 1 exit /b 1
120 | echo.
121 | echo.Build finished; now you can run HTML Help Workshop with the ^
122 | .hhp project file in %BUILDDIR%/htmlhelp.
123 | goto end
124 | )
125 |
126 | if "%1" == "qthelp" (
127 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
128 | if errorlevel 1 exit /b 1
129 | echo.
130 | echo.Build finished; now you can run "qcollectiongenerator" with the ^
131 | .qhcp project file in %BUILDDIR%/qthelp, like this:
132 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\Shaolin.qhcp
133 | echo.To view the help file:
134 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\Shaolin.ghc
135 | goto end
136 | )
137 |
138 | if "%1" == "devhelp" (
139 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
140 | if errorlevel 1 exit /b 1
141 | echo.
142 | echo.Build finished.
143 | goto end
144 | )
145 |
146 | if "%1" == "epub" (
147 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
148 | if errorlevel 1 exit /b 1
149 | echo.
150 | echo.Build finished. The epub file is in %BUILDDIR%/epub.
151 | goto end
152 | )
153 |
154 | if "%1" == "epub3" (
155 | %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3
156 | if errorlevel 1 exit /b 1
157 | echo.
158 | echo.Build finished. The epub3 file is in %BUILDDIR%/epub3.
159 | goto end
160 | )
161 |
162 | if "%1" == "latex" (
163 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
164 | if errorlevel 1 exit /b 1
165 | echo.
166 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
167 | goto end
168 | )
169 |
170 | if "%1" == "latexpdf" (
171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
172 | cd %BUILDDIR%/latex
173 | make all-pdf
174 | cd %~dp0
175 | echo.
176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
177 | goto end
178 | )
179 |
180 | if "%1" == "latexpdfja" (
181 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
182 | cd %BUILDDIR%/latex
183 | make all-pdf-ja
184 | cd %~dp0
185 | echo.
186 | echo.Build finished; the PDF files are in %BUILDDIR%/latex.
187 | goto end
188 | )
189 |
190 | if "%1" == "text" (
191 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
192 | if errorlevel 1 exit /b 1
193 | echo.
194 | echo.Build finished. The text files are in %BUILDDIR%/text.
195 | goto end
196 | )
197 |
198 | if "%1" == "man" (
199 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
200 | if errorlevel 1 exit /b 1
201 | echo.
202 | echo.Build finished. The manual pages are in %BUILDDIR%/man.
203 | goto end
204 | )
205 |
206 | if "%1" == "texinfo" (
207 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo
208 | if errorlevel 1 exit /b 1
209 | echo.
210 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo.
211 | goto end
212 | )
213 |
214 | if "%1" == "gettext" (
215 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale
216 | if errorlevel 1 exit /b 1
217 | echo.
218 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale.
219 | goto end
220 | )
221 |
222 | if "%1" == "changes" (
223 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
224 | if errorlevel 1 exit /b 1
225 | echo.
226 | echo.The overview file is in %BUILDDIR%/changes.
227 | goto end
228 | )
229 |
230 | if "%1" == "linkcheck" (
231 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
232 | if errorlevel 1 exit /b 1
233 | echo.
234 | echo.Link check complete; look for any errors in the above output ^
235 | or in %BUILDDIR%/linkcheck/output.txt.
236 | goto end
237 | )
238 |
239 | if "%1" == "doctest" (
240 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
241 | if errorlevel 1 exit /b 1
242 | echo.
243 | echo.Testing of doctests in the sources finished, look at the ^
244 | results in %BUILDDIR%/doctest/output.txt.
245 | goto end
246 | )
247 |
248 | if "%1" == "coverage" (
249 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage
250 | if errorlevel 1 exit /b 1
251 | echo.
252 | echo.Testing of coverage in the sources finished, look at the ^
253 | results in %BUILDDIR%/coverage/python.txt.
254 | goto end
255 | )
256 |
257 | if "%1" == "xml" (
258 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml
259 | if errorlevel 1 exit /b 1
260 | echo.
261 | echo.Build finished. The XML files are in %BUILDDIR%/xml.
262 | goto end
263 | )
264 |
265 | if "%1" == "pseudoxml" (
266 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml
267 | if errorlevel 1 exit /b 1
268 | echo.
269 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml.
270 | goto end
271 | )
272 |
273 | if "%1" == "dummy" (
274 | %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy
275 | if errorlevel 1 exit /b 1
276 | echo.
277 | echo.Build finished. Dummy builder generates no files.
278 | goto end
279 | )
280 |
281 | :end
282 |
--------------------------------------------------------------------------------
/docs/Makefile:
--------------------------------------------------------------------------------
1 | # Makefile for Sphinx documentation
2 | #
3 |
4 | # You can set these variables from the command line.
5 | SPHINXOPTS =
6 | SPHINXBUILD = sphinx-build
7 | PAPER =
8 | BUILDDIR = _build
9 |
10 | # User-friendly check for sphinx-build
11 | ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1)
12 | $(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don\'t have Sphinx installed, grab it from http://sphinx-doc.org/)
13 | endif
14 |
15 | # Internal variables.
16 | PAPEROPT_a4 = -D latex_paper_size=a4
17 | PAPEROPT_letter = -D latex_paper_size=letter
18 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
19 | # the i18n builder cannot share the environment and doctrees with the others
20 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
21 |
22 | .PHONY: help
23 | help:
24 | @echo "Please use \`make ' where is one of"
25 | @echo " html to make standalone HTML files"
26 | @echo " dirhtml to make HTML files named index.html in directories"
27 | @echo " singlehtml to make a single large HTML file"
28 | @echo " pickle to make pickle files"
29 | @echo " json to make JSON files"
30 | @echo " htmlhelp to make HTML files and a HTML help project"
31 | @echo " qthelp to make HTML files and a qthelp project"
32 | @echo " applehelp to make an Apple Help Book"
33 | @echo " devhelp to make HTML files and a Devhelp project"
34 | @echo " epub to make an epub"
35 | @echo " epub3 to make an epub3"
36 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
37 | @echo " latexpdf to make LaTeX files and run them through pdflatex"
38 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx"
39 | @echo " text to make text files"
40 | @echo " man to make manual pages"
41 | @echo " texinfo to make Texinfo files"
42 | @echo " info to make Texinfo files and run them through makeinfo"
43 | @echo " gettext to make PO message catalogs"
44 | @echo " changes to make an overview of all changed/added/deprecated items"
45 | @echo " xml to make Docutils-native XML files"
46 | @echo " pseudoxml to make pseudoxml-XML files for display purposes"
47 | @echo " linkcheck to check all external links for integrity"
48 | @echo " doctest to run all doctests embedded in the documentation (if enabled)"
49 | @echo " coverage to run coverage check of the documentation (if enabled)"
50 | @echo " dummy to check syntax errors of document sources"
51 |
52 | .PHONY: clean
53 | clean:
54 | rm -rf $(BUILDDIR)/*
55 |
56 | .PHONY: html
57 | html:
58 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
59 | @echo
60 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
61 |
62 | .PHONY: dirhtml
63 | dirhtml:
64 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
65 | @echo
66 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
67 |
68 | .PHONY: singlehtml
69 | singlehtml:
70 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
71 | @echo
72 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
73 |
74 | .PHONY: pickle
75 | pickle:
76 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
77 | @echo
78 | @echo "Build finished; now you can process the pickle files."
79 |
80 | .PHONY: json
81 | json:
82 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
83 | @echo
84 | @echo "Build finished; now you can process the JSON files."
85 |
86 | .PHONY: htmlhelp
87 | htmlhelp:
88 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
89 | @echo
90 | @echo "Build finished; now you can run HTML Help Workshop with the" \
91 | ".hhp project file in $(BUILDDIR)/htmlhelp."
92 |
93 | .PHONY: qthelp
94 | qthelp:
95 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
96 | @echo
97 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \
98 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
99 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Shaolin.qhcp"
100 | @echo "To view the help file:"
101 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Shaolin.qhc"
102 |
103 | .PHONY: applehelp
104 | applehelp:
105 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp
106 | @echo
107 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp."
108 | @echo "N.B. You won't be able to view it unless you put it in" \
109 | "~/Library/Documentation/Help or install it in your application" \
110 | "bundle."
111 |
112 | .PHONY: devhelp
113 | devhelp:
114 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
115 | @echo
116 | @echo "Build finished."
117 | @echo "To view the help file:"
118 | @echo "# mkdir -p $$HOME/.local/share/devhelp/Shaolin"
119 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Shaolin"
120 | @echo "# devhelp"
121 |
122 | .PHONY: epub
123 | epub:
124 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
125 | @echo
126 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub."
127 |
128 | .PHONY: epub3
129 | epub3:
130 | $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3
131 | @echo
132 | @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3."
133 |
134 | .PHONY: latex
135 | latex:
136 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
137 | @echo
138 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
139 | @echo "Run \`make' in that directory to run these through (pdf)latex" \
140 | "(use \`make latexpdf' here to do that automatically)."
141 |
142 | .PHONY: latexpdf
143 | latexpdf:
144 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
145 | @echo "Running LaTeX files through pdflatex..."
146 | $(MAKE) -C $(BUILDDIR)/latex all-pdf
147 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
148 |
149 | .PHONY: latexpdfja
150 | latexpdfja:
151 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
152 | @echo "Running LaTeX files through platex and dvipdfmx..."
153 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja
154 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
155 |
156 | .PHONY: text
157 | text:
158 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
159 | @echo
160 | @echo "Build finished. The text files are in $(BUILDDIR)/text."
161 |
162 | .PHONY: man
163 | man:
164 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
165 | @echo
166 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man."
167 |
168 | .PHONY: texinfo
169 | texinfo:
170 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
171 | @echo
172 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
173 | @echo "Run \`make' in that directory to run these through makeinfo" \
174 | "(use \`make info' here to do that automatically)."
175 |
176 | .PHONY: info
177 | info:
178 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
179 | @echo "Running Texinfo files through makeinfo..."
180 | make -C $(BUILDDIR)/texinfo info
181 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
182 |
183 | .PHONY: gettext
184 | gettext:
185 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
186 | @echo
187 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
188 |
189 | .PHONY: changes
190 | changes:
191 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
192 | @echo
193 | @echo "The overview file is in $(BUILDDIR)/changes."
194 |
195 | .PHONY: linkcheck
196 | linkcheck:
197 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
198 | @echo
199 | @echo "Link check complete; look for any errors in the above output " \
200 | "or in $(BUILDDIR)/linkcheck/output.txt."
201 |
202 | .PHONY: doctest
203 | doctest:
204 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
205 | @echo "Testing of doctests in the sources finished, look at the " \
206 | "results in $(BUILDDIR)/doctest/output.txt."
207 |
208 | .PHONY: coverage
209 | coverage:
210 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage
211 | @echo "Testing of coverage in the sources finished, look at the " \
212 | "results in $(BUILDDIR)/coverage/python.txt."
213 |
214 | .PHONY: xml
215 | xml:
216 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml
217 | @echo
218 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml."
219 |
220 | .PHONY: pseudoxml
221 | pseudoxml:
222 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml
223 | @echo
224 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml."
225 |
226 | .PHONY: dummy
227 | dummy:
228 | $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy
229 | @echo
230 | @echo "Build finished. Dummy builder generates no files."
231 |
--------------------------------------------------------------------------------
/shaolin/core/stateless_dashboard.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Wed May 25 15:26:23 2016
4 |
5 | @author: sergio
6 | """
7 | import traitlets
8 | from shaolin import core as sc
9 | from shaolin.core import shaoscript as scpt
10 | class StatelessDashboard(object):
11 | """Clash for managing arbitrary Dashboards"""
12 | def __init__(self, dashboard, func=None, mode='active', name=None):
13 |
14 | self.func = func
15 | self.dashboard = dashboard
16 | self.mode = mode
17 |
18 | if not name is None:
19 | self.name = name
20 | elif hasattr(dashboard, 'name'):
21 | self.name = dashboard.name
22 | else:
23 | self.name = self.name_from_shaoscript(dashboard[0])
24 | self.mode_dict = {'active' : [],
25 | 'passive': [],
26 | 'interactive' : [],
27 | 'all':[]
28 | }
29 | self._init_dash(self.dashboard)
30 | self._link_children(self.dashboard)
31 | if not self.func is None:
32 | self.observe(self.interact)
33 | #self.output = self.kwargs
34 |
35 | def _init_dashboard(self, dashboard):
36 | """Integrates a child Dashboard as an attribute of the current Dashboard"""
37 | setattr(self, dashboard.name, dashboard)
38 | if dashboard.mode == 'interactive':
39 | self.mode_dict['interactive'] += [dashboard.name]
40 | elif dashboard.mode == 'passive':
41 | self.mode_dict['passive'] += [dashboard.name]
42 | else:
43 | self.mode_dict['active'] += [dashboard.name]
44 |
45 | def _init_toggle_menu(self, children, kwargs):
46 | """Integrates a child ToggleMenu as an attribute of the current Dashboard"""
47 | dashboard = sc.dashboard.ToggleMenu(children)
48 | if 'name' in kwargs.keys():
49 | dashboard.name = kwargs['name']
50 | setattr(self, dashboard.name, dashboard)
51 | if dashboard.mode == 'interactive':
52 | self.mode_dict['interactive'] += [dashboard.name]
53 | elif dashboard.mode == 'passive':
54 | self.mode_dict['passive'] += [dashboard.name]
55 | else:
56 | self.mode_dict['active'] += [dashboard.name]
57 |
58 | def _init_widget(self, shao, kwargs):
59 | """Integrates a child Widget as an attribute of the current Dashboard"""
60 |
61 |
62 | widget = scpt.shaoscript(shao, kwargs)
63 |
64 | try:
65 | setattr(self, widget.name, widget)
66 | except Exception as e:
67 | e.args += (('Dont use widget attributes as shaoscript names,'
68 | 'they are reserved words! (You can use dashboard'
69 | 'as a generic name if you want)'),)
70 | raise e
71 |
72 |
73 | if widget.mode == 'interactive':
74 | self.mode_dict['interactive'] += [widget.name]
75 | elif widget.mode == 'passive':
76 | self.mode_dict['passive'] += [widget.name]
77 | else:
78 | self.mode_dict['active'] += [widget.name]
79 |
80 | self.mode_dict['all'] += [widget.name]
81 |
82 | def interact(self, _):
83 | """Apply the dashboard kwargs to the dashboard function"""
84 | self.func(self.output)
85 |
86 | def link(self, name_1, name_2):
87 | """Same as trailets but applied to Dashboard attribute names"""
88 | widget_1 = getattr(self, name_1).target
89 | widget_2 = getattr(self, name_2).target
90 | setattr(self, 'link_'+name_1+'_'+name_2, traitlets.link((widget_1, 'value'),
91 | (widget_2, 'value')))
92 |
93 | def dlink(self, name_1, name_2):
94 | """Same as trailets but applied to Dashboard attribute names"""
95 | widget_1 = getattr(self, name_1).target
96 | widget_2 = getattr(self, name_2).target
97 | setattr(self, 'link_'+name_1+'_'+name_2, traitlets.dlink((widget_1, 'value'),
98 | (widget_2, 'value')))
99 |
100 | def unlink(self, name_1, name_2):
101 | """Same as trailets but applied to Dashboard attribute names"""
102 | link = getattr(self, 'link_'+name_1+'_'+name_2)
103 | link.unlink()
104 |
105 | @property
106 | def visible(self):
107 | """Easy visibility management"""
108 | visible = False
109 | for name in self.mode_dict['all']:
110 | visible = visible or getattr(self, name).visible
111 | return visible
112 | @visible.setter
113 | def visible(self, val):
114 | """Easy visibility management"""
115 | for name in self.mode_dict['all']:
116 | getattr(self, name).visible = val
117 |
118 | @property
119 | def value(self):
120 | """alias for better modularity"""
121 | return self.kwargs
122 |
123 | @property
124 | def kwargs(self):
125 | """Children values as a kwargs dict for easier interactivity"""
126 | kwargs = {}
127 | for name in self.mode_dict['active']:
128 | kwargs[name] = getattr(self, name).value
129 | for name in self.mode_dict['interactive']:
130 | kwargs[name] = getattr(self, name).value
131 | return kwargs
132 |
133 |
134 | def set_kwargs(self, vals):
135 | """Children values as a kwargs dict for easier interactivity"""
136 | import shaolin.core.dashboard as sd
137 | for name in vals.keys():
138 | attr = getattr(self, name)
139 | if isinstance(attr, sd.Dashboard):
140 | attr.set_kwargs(vals[name])
141 | else:
142 | attr.value = vals[name]
143 |
144 | @property
145 | def interactive_kwargs(self):
146 | """Interactive children values as a kwargs dict for easier interactivity"""
147 | kw = {}
148 | for name in self.mode_dict['interactive']:
149 | kw[name] = getattr(self, name).value
150 | return kw
151 | @property
152 | def widget(self):
153 | """Alias for easy access to the Dashboard main widget"""
154 | return getattr(self, self.name_from_shaoscript(self.dashboard[0])).widget
155 |
156 | @staticmethod
157 | def name_from_shaoscript(string):
158 | """Get a name from a shaoscript string"""
159 | params = string.split('$')[1].split('&')
160 | desc = None
161 | name = None
162 | for p in params:
163 | pname = p.split('=')[0]
164 | if pname in ['d', 'desc', 'description', 'D']:
165 | desc = p.split('=')[1]
166 | elif pname in ['n', 'name', 'N']:
167 | name = p.split('=')[1]
168 | if name is None and desc is None:
169 | return False
170 | elif name is None:
171 | return desc.lower().replace(' ', '_')
172 | else:
173 | return name.lower().replace(' ', '_')
174 |
175 | @staticmethod
176 | def read_shaolist(shaolist):
177 | """Convert a shaolist block to a corresponding shaoscrpt, kwargs,
178 | children mapping"""
179 | #print("shaolist: {}".format(shaolist))
180 | try:
181 | len(shaolist)
182 | except TypeError:
183 | shaoscrpt = None
184 | kwargs = {}
185 | children = None
186 | return shaoscrpt, kwargs, children
187 |
188 | if shaolist[0] is sc.dashboard.ToggleMenu:
189 | shaoscrpt = sc.dashboard.ToggleMenu
190 | kwargs = {}
191 | children = shaolist[1]
192 | elif isinstance(shaolist, str):
193 | shaoscrpt = shaolist
194 | kwargs = {}
195 | children = None
196 | elif len(shaolist) == 1:
197 | #[(shaoscript,kwargs)]
198 | if isinstance(shaolist[0], tuple):
199 | kwargs = shaolist[0][1]
200 | shaoscrpt = shaolist[0][0]
201 | children = None
202 | #[shaoscript]
203 | else:
204 | shaoscrpt = shaolist[0]
205 | kwargs = {}
206 | children = None
207 | elif len(shaolist) == 2:
208 | #[(shaoscript, kwargs), children]
209 | if isinstance(shaolist[0], tuple):
210 | if shaolist[0][0] is sc.dashboard.ToggleMenu:
211 | shaoscrpt = sc.dashboard.ToggleMenu
212 | kwargs = shaolist[0][1]
213 | children = shaolist[1]
214 | return shaoscrpt, kwargs, children
215 | else:
216 | kwargs = shaolist[0][1]
217 | shaoscrpt = shaolist[0][0]
218 | children = shaolist[1]
219 | #[shaoscript,children]
220 | else:
221 | kwargs = {}
222 | shaoscrpt = shaolist[0]
223 | children = shaolist[1]
224 | else:
225 | pass
226 | return shaoscrpt, kwargs, children
227 |
228 | def observe(self, func, names='value'):
229 | """Same as ipywidgets. Applies to all interactive children widgets"""
230 | for name in self.mode_dict['interactive']:
231 | getattr(self, name).observe(func, names=names)
232 |
233 | def _link_children(self, shaolist):
234 | """Creates the dashboard structure linking each children with its parent"""
235 | shaoscrpt, kwargs, children = self.read_shaolist(shaolist)
236 | if children is None:
237 | return
238 | else:
239 | name = self.name_from_shaoscript(shaoscrpt)
240 | for child in children:
241 | shao_c, kwargs_c, c_children = self.read_shaolist(child)
242 | if shao_c is None:
243 | cname = child.name
244 | else:
245 | cname = self.name_from_shaoscript(shao_c)
246 | getattr(self, name).target.children += (getattr(self, cname).widget,)
247 | self._link_children(child)
248 |
249 | def _init_dash(self, value):
250 | """Creates all the children Widgets and dashboards the current Dashboard will have"""
251 | shaoscrpt, kwargs, children = self.read_shaolist(value)
252 | if shaoscrpt is None:
253 | self._init_dashboard(value)
254 | elif shaoscrpt is sc.dashboard.ToggleMenu:
255 | self._init_toggle_menu(children, kwargs)
256 | else:
257 | self._init_widget(shaoscrpt, kwargs)
258 | if children is None:
259 | return
260 | for child in children:
261 | self._init_dash(child)
262 |
263 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # -*- coding: utf-8 -*-
3 | #
4 | # Shaolin documentation build configuration file, created by
5 | # sphinx-quickstart on Sun May 8 20:56:25 2016.
6 | #
7 | # This file is execfile()d with the current directory set to its
8 | # containing dir.
9 | #
10 | # Note that not all possible configuration values are present in this
11 | # autogenerated file.
12 | #
13 | # All configuration values have a default; values that are commented out
14 | # serve to show the default.
15 |
16 | import sys
17 | import os
18 |
19 | # If extensions (or modules to document with autodoc) are in another directory,
20 | # add these directories to sys.path here. If the directory is relative to the
21 | # documentation root, use os.path.abspath to make it absolute, like shown here.
22 | #sys.path.insert(0, os.path.abspath('.'))
23 |
24 | # -- General configuration ------------------------------------------------
25 |
26 | # If your documentation needs a minimal Sphinx version, state it here.
27 | #needs_sphinx = '1.0'
28 |
29 | # Add any Sphinx extension module names here, as strings. They can be
30 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
31 | # ones.
32 | extensions = [
33 | 'sphinx.ext.autodoc',
34 | 'sphinx.ext.doctest',
35 | 'sphinx.ext.todo',
36 | 'sphinx.ext.coverage',
37 | 'sphinx.ext.mathjax',
38 | 'sphinx.ext.viewcode',
39 | ]
40 |
41 | # Add any paths that contain templates here, relative to this directory.
42 | templates_path = ['_templates']
43 |
44 | # The suffix(es) of source filenames.
45 | # You can specify multiple suffix as a list of string:
46 | # source_suffix = ['.rst', '.md']
47 | source_suffix = '.rst'
48 |
49 | # The encoding of source files.
50 | #source_encoding = 'utf-8-sig'
51 |
52 | # The master toctree document.
53 | master_doc = 'index'
54 |
55 | # General information about the project.
56 | project = 'Shaolin'
57 | copyright = '2016, Guillem Duran (HCSoft)'
58 | author = 'Guillem Duran (HCSoft)'
59 |
60 | # The version info for the project you're documenting, acts as replacement for
61 | # |version| and |release|, also used in various other places throughout the
62 | # built documents.
63 | #
64 | # The short X.Y version.
65 | version = '0.1'
66 | # The full version, including alpha/beta/rc tags.
67 | release = '0.0.1'
68 |
69 | # The language for content autogenerated by Sphinx. Refer to documentation
70 | # for a list of supported languages.
71 | #
72 | # This is also used if you do content translation via gettext catalogs.
73 | # Usually you set "language" from the command line for these cases.
74 | language = None
75 |
76 | # There are two options for replacing |today|: either, you set today to some
77 | # non-false value, then it is used:
78 | #today = ''
79 | # Else, today_fmt is used as the format for a strftime call.
80 | #today_fmt = '%B %d, %Y'
81 |
82 | # List of patterns, relative to source directory, that match files and
83 | # directories to ignore when looking for source files.
84 | # This patterns also effect to html_static_path and html_extra_path
85 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
86 |
87 | # The reST default role (used for this markup: `text`) to use for all
88 | # documents.
89 | #default_role = None
90 |
91 | # If true, '()' will be appended to :func: etc. cross-reference text.
92 | #add_function_parentheses = True
93 |
94 | # If true, the current module name will be prepended to all description
95 | # unit titles (such as .. function::).
96 | #add_module_names = True
97 |
98 | # If true, sectionauthor and moduleauthor directives will be shown in the
99 | # output. They are ignored by default.
100 | #show_authors = False
101 |
102 | # The name of the Pygments (syntax highlighting) style to use.
103 | pygments_style = 'sphinx'
104 |
105 | # A list of ignored prefixes for module index sorting.
106 | #modindex_common_prefix = []
107 |
108 | # If true, keep warnings as "system message" paragraphs in the built documents.
109 | #keep_warnings = False
110 |
111 | # If true, `todo` and `todoList` produce output, else they produce nothing.
112 | todo_include_todos = True
113 |
114 |
115 | # -- Options for HTML output ----------------------------------------------
116 |
117 | # The theme to use for HTML and HTML Help pages. See the documentation for
118 | # a list of builtin themes.
119 | html_theme = 'alabaster'
120 |
121 | # Theme options are theme-specific and customize the look and feel of a theme
122 | # further. For a list of options available for each theme, see the
123 | # documentation.
124 | #html_theme_options = {}
125 |
126 | # Add any paths that contain custom themes here, relative to this directory.
127 | #html_theme_path = []
128 |
129 | # The name for this set of Sphinx documents.
130 | # " v documentation" by default.
131 | #html_title = 'Shaolin v0.0.1'
132 |
133 | # A shorter title for the navigation bar. Default is the same as html_title.
134 | #html_short_title = None
135 |
136 | # The name of an image file (relative to this directory) to place at the top
137 | # of the sidebar.
138 | #html_logo = None
139 |
140 | # The name of an image file (relative to this directory) to use as a favicon of
141 | # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
142 | # pixels large.
143 | #html_favicon = None
144 |
145 | # Add any paths that contain custom static files (such as style sheets) here,
146 | # relative to this directory. They are copied after the builtin static files,
147 | # so a file named "default.css" will overwrite the builtin "default.css".
148 | html_static_path = ['_static']
149 |
150 | # Add any extra paths that contain custom files (such as robots.txt or
151 | # .htaccess) here, relative to this directory. These files are copied
152 | # directly to the root of the documentation.
153 | #html_extra_path = []
154 |
155 | # If not None, a 'Last updated on:' timestamp is inserted at every page
156 | # bottom, using the given strftime format.
157 | # The empty string is equivalent to '%b %d, %Y'.
158 | #html_last_updated_fmt = None
159 |
160 | # If true, SmartyPants will be used to convert quotes and dashes to
161 | # typographically correct entities.
162 | #html_use_smartypants = True
163 |
164 | # Custom sidebar templates, maps document names to template names.
165 | #html_sidebars = {}
166 |
167 | # Additional templates that should be rendered to pages, maps page names to
168 | # template names.
169 | #html_additional_pages = {}
170 |
171 | # If false, no module index is generated.
172 | #html_domain_indices = True
173 |
174 | # If false, no index is generated.
175 | #html_use_index = True
176 |
177 | # If true, the index is split into individual pages for each letter.
178 | #html_split_index = False
179 |
180 | # If true, links to the reST sources are added to the pages.
181 | #html_show_sourcelink = True
182 |
183 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
184 | #html_show_sphinx = True
185 |
186 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
187 | #html_show_copyright = True
188 |
189 | # If true, an OpenSearch description file will be output, and all pages will
190 | # contain a tag referring to it. The value of this option must be the
191 | # base URL from which the finished HTML is served.
192 | #html_use_opensearch = ''
193 |
194 | # This is the file name suffix for HTML files (e.g. ".xhtml").
195 | #html_file_suffix = None
196 |
197 | # Language to be used for generating the HTML full-text search index.
198 | # Sphinx supports the following languages:
199 | # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja'
200 | # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh'
201 | #html_search_language = 'en'
202 |
203 | # A dictionary with options for the search language support, empty by default.
204 | # 'ja' uses this config value.
205 | # 'zh' user can custom change `jieba` dictionary path.
206 | #html_search_options = {'type': 'default'}
207 |
208 | # The name of a javascript file (relative to the configuration directory) that
209 | # implements a search results scorer. If empty, the default will be used.
210 | #html_search_scorer = 'scorer.js'
211 |
212 | # Output file base name for HTML help builder.
213 | htmlhelp_basename = 'Shaolindoc'
214 |
215 | # -- Options for LaTeX output ---------------------------------------------
216 |
217 | latex_elements = {
218 | # The paper size ('letterpaper' or 'a4paper').
219 | #'papersize': 'letterpaper',
220 |
221 | # The font size ('10pt', '11pt' or '12pt').
222 | #'pointsize': '10pt',
223 |
224 | # Additional stuff for the LaTeX preamble.
225 | #'preamble': '',
226 |
227 | # Latex figure (float) alignment
228 | #'figure_align': 'htbp',
229 | }
230 |
231 | # Grouping the document tree into LaTeX files. List of tuples
232 | # (source start file, target name, title,
233 | # author, documentclass [howto, manual, or own class]).
234 | latex_documents = [
235 | (master_doc, 'Shaolin.tex', 'Shaolin Documentation',
236 | 'Guillem Duran (HCSoft)', 'manual'),
237 | ]
238 |
239 | # The name of an image file (relative to this directory) to place at the top of
240 | # the title page.
241 | #latex_logo = None
242 |
243 | # For "manual" documents, if this is true, then toplevel headings are parts,
244 | # not chapters.
245 | #latex_use_parts = False
246 |
247 | # If true, show page references after internal links.
248 | #latex_show_pagerefs = False
249 |
250 | # If true, show URL addresses after external links.
251 | #latex_show_urls = False
252 |
253 | # Documents to append as an appendix to all manuals.
254 | #latex_appendices = []
255 |
256 | # If false, no module index is generated.
257 | #latex_domain_indices = True
258 |
259 |
260 | # -- Options for manual page output ---------------------------------------
261 |
262 | # One entry per manual page. List of tuples
263 | # (source start file, name, description, authors, manual section).
264 | man_pages = [
265 | (master_doc, 'shaolin', 'Shaolin Documentation',
266 | [author], 1)
267 | ]
268 |
269 | # If true, show URL addresses after external links.
270 | #man_show_urls = False
271 |
272 |
273 | # -- Options for Texinfo output -------------------------------------------
274 |
275 | # Grouping the document tree into Texinfo files. List of tuples
276 | # (source start file, target name, title, author,
277 | # dir menu entry, description, category)
278 | texinfo_documents = [
279 | (master_doc, 'Shaolin', 'Shaolin Documentation',
280 | author, 'Shaolin', 'One line description of project.',
281 | 'Miscellaneous'),
282 | ]
283 |
284 | # Documents to append as an appendix to all manuals.
285 | #texinfo_appendices = []
286 |
287 | # If false, no module index is generated.
288 | #texinfo_domain_indices = True
289 |
290 | # How to display URL addresses: 'footnote', 'no', or 'inline'.
291 | #texinfo_show_urls = 'footnote'
292 |
293 | # If true, do not generate a @detailmenu in the "Top" node's menu.
294 | #texinfo_no_detailmenu = False
295 |
--------------------------------------------------------------------------------
/docs/_build/html/_static/underscore.js:
--------------------------------------------------------------------------------
1 | // Underscore.js 1.3.1
2 | // (c) 2009-2012 Jeremy Ashkenas, DocumentCloud Inc.
3 | // Underscore is freely distributable under the MIT license.
4 | // Portions of Underscore are inspired or borrowed from Prototype,
5 | // Oliver Steele's Functional, and John Resig's Micro-Templating.
6 | // For all details and documentation:
7 | // http://documentcloud.github.com/underscore
8 | (function(){function q(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)return a===c;if(a._chain)a=a._wrapped;if(c._chain)c=c._wrapped;if(a.isEqual&&b.isFunction(a.isEqual))return a.isEqual(c);if(c.isEqual&&b.isFunction(c.isEqual))return c.isEqual(a);var e=l.call(a);if(e!=l.call(c))return false;switch(e){case "[object String]":return a==String(c);case "[object Number]":return a!=+a?c!=+c:a==0?1/a==1/c:a==+c;case "[object Date]":case "[object Boolean]":return+a==+c;case "[object RegExp]":return a.source==
9 | c.source&&a.global==c.global&&a.multiline==c.multiline&&a.ignoreCase==c.ignoreCase}if(typeof a!="object"||typeof c!="object")return false;for(var f=d.length;f--;)if(d[f]==a)return true;d.push(a);var f=0,g=true;if(e=="[object Array]"){if(f=a.length,g=f==c.length)for(;f--;)if(!(g=f in a==f in c&&q(a[f],c[f],d)))break}else{if("constructor"in a!="constructor"in c||a.constructor!=c.constructor)return false;for(var h in a)if(b.has(a,h)&&(f++,!(g=b.has(c,h)&&q(a[h],c[h],d))))break;if(g){for(h in c)if(b.has(c,
10 | h)&&!f--)break;g=!f}}d.pop();return g}var r=this,G=r._,n={},k=Array.prototype,o=Object.prototype,i=k.slice,H=k.unshift,l=o.toString,I=o.hasOwnProperty,w=k.forEach,x=k.map,y=k.reduce,z=k.reduceRight,A=k.filter,B=k.every,C=k.some,p=k.indexOf,D=k.lastIndexOf,o=Array.isArray,J=Object.keys,s=Function.prototype.bind,b=function(a){return new m(a)};if(typeof exports!=="undefined"){if(typeof module!=="undefined"&&module.exports)exports=module.exports=b;exports._=b}else r._=b;b.VERSION="1.3.1";var j=b.each=
11 | b.forEach=function(a,c,d){if(a!=null)if(w&&a.forEach===w)a.forEach(c,d);else if(a.length===+a.length)for(var e=0,f=a.length;e2;a==
12 | null&&(a=[]);if(y&&a.reduce===y)return e&&(c=b.bind(c,e)),f?a.reduce(c,d):a.reduce(c);j(a,function(a,b,i){f?d=c.call(e,d,a,b,i):(d=a,f=true)});if(!f)throw new TypeError("Reduce of empty array with no initial value");return d};b.reduceRight=b.foldr=function(a,c,d,e){var f=arguments.length>2;a==null&&(a=[]);if(z&&a.reduceRight===z)return e&&(c=b.bind(c,e)),f?a.reduceRight(c,d):a.reduceRight(c);var g=b.toArray(a).reverse();e&&!f&&(c=b.bind(c,e));return f?b.reduce(g,c,d,e):b.reduce(g,c)};b.find=b.detect=
13 | function(a,c,b){var e;E(a,function(a,g,h){if(c.call(b,a,g,h))return e=a,true});return e};b.filter=b.select=function(a,c,b){var e=[];if(a==null)return e;if(A&&a.filter===A)return a.filter(c,b);j(a,function(a,g,h){c.call(b,a,g,h)&&(e[e.length]=a)});return e};b.reject=function(a,c,b){var e=[];if(a==null)return e;j(a,function(a,g,h){c.call(b,a,g,h)||(e[e.length]=a)});return e};b.every=b.all=function(a,c,b){var e=true;if(a==null)return e;if(B&&a.every===B)return a.every(c,b);j(a,function(a,g,h){if(!(e=
14 | e&&c.call(b,a,g,h)))return n});return e};var E=b.some=b.any=function(a,c,d){c||(c=b.identity);var e=false;if(a==null)return e;if(C&&a.some===C)return a.some(c,d);j(a,function(a,b,h){if(e||(e=c.call(d,a,b,h)))return n});return!!e};b.include=b.contains=function(a,c){var b=false;if(a==null)return b;return p&&a.indexOf===p?a.indexOf(c)!=-1:b=E(a,function(a){return a===c})};b.invoke=function(a,c){var d=i.call(arguments,2);return b.map(a,function(a){return(b.isFunction(c)?c||a:a[c]).apply(a,d)})};b.pluck=
15 | function(a,c){return b.map(a,function(a){return a[c]})};b.max=function(a,c,d){if(!c&&b.isArray(a))return Math.max.apply(Math,a);if(!c&&b.isEmpty(a))return-Infinity;var e={computed:-Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;b>=e.computed&&(e={value:a,computed:b})});return e.value};b.min=function(a,c,d){if(!c&&b.isArray(a))return Math.min.apply(Math,a);if(!c&&b.isEmpty(a))return Infinity;var e={computed:Infinity};j(a,function(a,b,h){b=c?c.call(d,a,b,h):a;bd?1:0}),"value")};b.groupBy=function(a,c){var d={},e=b.isFunction(c)?c:function(a){return a[c]};j(a,function(a,b){var c=e(a,b);(d[c]||(d[c]=[])).push(a)});return d};b.sortedIndex=function(a,
17 | c,d){d||(d=b.identity);for(var e=0,f=a.length;e>1;d(a[g])=0})})};b.difference=function(a){var c=b.flatten(i.call(arguments,1));return b.filter(a,function(a){return!b.include(c,a)})};b.zip=function(){for(var a=i.call(arguments),c=b.max(b.pluck(a,"length")),d=Array(c),e=0;e=0;d--)b=[a[d].apply(this,b)];return b[0]}};
24 | b.after=function(a,b){return a<=0?b():function(){if(--a<1)return b.apply(this,arguments)}};b.keys=J||function(a){if(a!==Object(a))throw new TypeError("Invalid object");var c=[],d;for(d in a)b.has(a,d)&&(c[c.length]=d);return c};b.values=function(a){return b.map(a,b.identity)};b.functions=b.methods=function(a){var c=[],d;for(d in a)b.isFunction(a[d])&&c.push(d);return c.sort()};b.extend=function(a){j(i.call(arguments,1),function(b){for(var d in b)a[d]=b[d]});return a};b.defaults=function(a){j(i.call(arguments,
25 | 1),function(b){for(var d in b)a[d]==null&&(a[d]=b[d])});return a};b.clone=function(a){return!b.isObject(a)?a:b.isArray(a)?a.slice():b.extend({},a)};b.tap=function(a,b){b(a);return a};b.isEqual=function(a,b){return q(a,b,[])};b.isEmpty=function(a){if(b.isArray(a)||b.isString(a))return a.length===0;for(var c in a)if(b.has(a,c))return false;return true};b.isElement=function(a){return!!(a&&a.nodeType==1)};b.isArray=o||function(a){return l.call(a)=="[object Array]"};b.isObject=function(a){return a===Object(a)};
26 | b.isArguments=function(a){return l.call(a)=="[object Arguments]"};if(!b.isArguments(arguments))b.isArguments=function(a){return!(!a||!b.has(a,"callee"))};b.isFunction=function(a){return l.call(a)=="[object Function]"};b.isString=function(a){return l.call(a)=="[object String]"};b.isNumber=function(a){return l.call(a)=="[object Number]"};b.isNaN=function(a){return a!==a};b.isBoolean=function(a){return a===true||a===false||l.call(a)=="[object Boolean]"};b.isDate=function(a){return l.call(a)=="[object Date]"};
27 | b.isRegExp=function(a){return l.call(a)=="[object RegExp]"};b.isNull=function(a){return a===null};b.isUndefined=function(a){return a===void 0};b.has=function(a,b){return I.call(a,b)};b.noConflict=function(){r._=G;return this};b.identity=function(a){return a};b.times=function(a,b,d){for(var e=0;e /g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")};b.mixin=function(a){j(b.functions(a),
28 | function(c){K(c,b[c]=a[c])})};var L=0;b.uniqueId=function(a){var b=L++;return a?a+b:b};b.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var t=/.^/,u=function(a){return a.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};b.template=function(a,c){var d=b.templateSettings,d="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+a.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(d.escape||t,function(a,b){return"',_.escape("+
29 | u(b)+"),'"}).replace(d.interpolate||t,function(a,b){return"',"+u(b)+",'"}).replace(d.evaluate||t,function(a,b){return"');"+u(b).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",e=new Function("obj","_",d);return c?e(c,b):function(a){return e.call(this,a,b)}};b.chain=function(a){return b(a).chain()};var m=function(a){this._wrapped=a};b.prototype=m.prototype;var v=function(a,c){return c?b(a).chain():a},K=function(a,c){m.prototype[a]=
30 | function(){var a=i.call(arguments);H.call(a,this._wrapped);return v(c.apply(b,a),this._chain)}};b.mixin(b);j("pop,push,reverse,shift,sort,splice,unshift".split(","),function(a){var b=k[a];m.prototype[a]=function(){var d=this._wrapped;b.apply(d,arguments);var e=d.length;(a=="shift"||a=="splice")&&e===0&&delete d[0];return v(d,this._chain)}});j(["concat","join","slice"],function(a){var b=k[a];m.prototype[a]=function(){return v(b.apply(this._wrapped,arguments),this._chain)}});m.prototype.chain=function(){this._chain=
31 | true;return this};m.prototype.value=function(){return this._wrapped}}).call(this);
32 |
--------------------------------------------------------------------------------
/docs/_build/html/_static/alabaster.css:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | @import url("basic.css");
19 |
20 | /* -- page layout ----------------------------------------------------------- */
21 |
22 | body {
23 | font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
24 | font-size: 17px;
25 | background-color: white;
26 | color: #000;
27 | margin: 0;
28 | padding: 0;
29 | }
30 |
31 |
32 | div.document {
33 | width: 940px;
34 | margin: 30px auto 0 auto;
35 | }
36 |
37 | div.documentwrapper {
38 | float: left;
39 | width: 100%;
40 | }
41 |
42 | div.bodywrapper {
43 | margin: 0 0 0 220px;
44 | }
45 |
46 | div.sphinxsidebar {
47 | width: 220px;
48 | font-size: 14px;
49 | line-height: 1.5;
50 | }
51 |
52 | hr {
53 | border: 1px solid #B1B4B6;
54 | }
55 |
56 | div.body {
57 | background-color: #ffffff;
58 | color: #3E4349;
59 | padding: 0 30px 0 30px;
60 | }
61 |
62 | div.body > .section {
63 | text-align: left;
64 | }
65 |
66 | div.footer {
67 | width: 940px;
68 | margin: 20px auto 30px auto;
69 | font-size: 14px;
70 | color: #888;
71 | text-align: right;
72 | }
73 |
74 | div.footer a {
75 | color: #888;
76 | }
77 |
78 | p.caption {
79 | font-family: ;
80 | font-size: inherit;
81 | }
82 |
83 |
84 | div.relations {
85 | display: none;
86 | }
87 |
88 |
89 | div.sphinxsidebar a {
90 | color: #444;
91 | text-decoration: none;
92 | border-bottom: 1px dotted #999;
93 | }
94 |
95 | div.sphinxsidebar a:hover {
96 | border-bottom: 1px solid #999;
97 | }
98 |
99 | div.sphinxsidebarwrapper {
100 | padding: 18px 10px;
101 | }
102 |
103 | div.sphinxsidebarwrapper p.logo {
104 | padding: 0;
105 | margin: -10px 0 0 0px;
106 | text-align: center;
107 | }
108 |
109 | div.sphinxsidebarwrapper h1.logo {
110 | margin-top: -10px;
111 | text-align: center;
112 | margin-bottom: 5px;
113 | text-align: left;
114 | }
115 |
116 | div.sphinxsidebarwrapper h1.logo-name {
117 | margin-top: 0px;
118 | }
119 |
120 | div.sphinxsidebarwrapper p.blurb {
121 | margin-top: 0;
122 | font-style: normal;
123 | }
124 |
125 | div.sphinxsidebar h3,
126 | div.sphinxsidebar h4 {
127 | font-family: 'Garamond', 'Georgia', serif;
128 | color: #444;
129 | font-size: 24px;
130 | font-weight: normal;
131 | margin: 0 0 5px 0;
132 | padding: 0;
133 | }
134 |
135 | div.sphinxsidebar h4 {
136 | font-size: 20px;
137 | }
138 |
139 | div.sphinxsidebar h3 a {
140 | color: #444;
141 | }
142 |
143 | div.sphinxsidebar p.logo a,
144 | div.sphinxsidebar h3 a,
145 | div.sphinxsidebar p.logo a:hover,
146 | div.sphinxsidebar h3 a:hover {
147 | border: none;
148 | }
149 |
150 | div.sphinxsidebar p {
151 | color: #555;
152 | margin: 10px 0;
153 | }
154 |
155 | div.sphinxsidebar ul {
156 | margin: 10px 0;
157 | padding: 0;
158 | color: #000;
159 | }
160 |
161 | div.sphinxsidebar ul li.toctree-l1 > a {
162 | font-size: 120%;
163 | }
164 |
165 | div.sphinxsidebar ul li.toctree-l2 > a {
166 | font-size: 110%;
167 | }
168 |
169 | div.sphinxsidebar input {
170 | border: 1px solid #CCC;
171 | font-family: 'goudy old style', 'minion pro', 'bell mt', Georgia, 'Hiragino Mincho Pro', serif;
172 | font-size: 1em;
173 | }
174 |
175 | div.sphinxsidebar hr {
176 | border: none;
177 | height: 1px;
178 | color: #AAA;
179 | background: #AAA;
180 |
181 | text-align: left;
182 | margin-left: 0;
183 | width: 50%;
184 | }
185 |
186 | /* -- body styles ----------------------------------------------------------- */
187 |
188 | a {
189 | color: #004B6B;
190 | text-decoration: underline;
191 | }
192 |
193 | a:hover {
194 | color: #6D4100;
195 | text-decoration: underline;
196 | }
197 |
198 | div.body h1,
199 | div.body h2,
200 | div.body h3,
201 | div.body h4,
202 | div.body h5,
203 | div.body h6 {
204 | font-family: 'Garamond', 'Georgia', serif;
205 | font-weight: normal;
206 | margin: 30px 0px 10px 0px;
207 | padding: 0;
208 | }
209 |
210 | div.body h1 { margin-top: 0; padding-top: 0; font-size: 240%; }
211 | div.body h2 { font-size: 180%; }
212 | div.body h3 { font-size: 150%; }
213 | div.body h4 { font-size: 130%; }
214 | div.body h5 { font-size: 100%; }
215 | div.body h6 { font-size: 100%; }
216 |
217 | a.headerlink {
218 | color: #DDD;
219 | padding: 0 4px;
220 | text-decoration: none;
221 | }
222 |
223 | a.headerlink:hover {
224 | color: #444;
225 | background: #EAEAEA;
226 | }
227 |
228 | div.body p, div.body dd, div.body li {
229 | line-height: 1.4em;
230 | }
231 |
232 | div.admonition {
233 | margin: 20px 0px;
234 | padding: 10px 30px;
235 | background-color: #FCC;
236 | border: 1px solid #FAA;
237 | }
238 |
239 | div.admonition tt.xref, div.admonition a tt {
240 | border-bottom: 1px solid #fafafa;
241 | }
242 |
243 | dd div.admonition {
244 | margin-left: -60px;
245 | padding-left: 60px;
246 | }
247 |
248 | div.admonition p.admonition-title {
249 | font-family: 'Garamond', 'Georgia', serif;
250 | font-weight: normal;
251 | font-size: 24px;
252 | margin: 0 0 10px 0;
253 | padding: 0;
254 | line-height: 1;
255 | }
256 |
257 | div.admonition p.last {
258 | margin-bottom: 0;
259 | }
260 |
261 | div.highlight {
262 | background-color: white;
263 | }
264 |
265 | dt:target, .highlight {
266 | background: #FAF3E8;
267 | }
268 |
269 | div.note {
270 | background-color: #EEE;
271 | border: 1px solid #CCC;
272 | }
273 |
274 | div.seealso {
275 | background-color: #EEE;
276 | border: 1px solid #CCC;
277 | }
278 |
279 | div.topic {
280 | background-color: #eee;
281 | }
282 |
283 | p.admonition-title {
284 | display: inline;
285 | }
286 |
287 | p.admonition-title:after {
288 | content: ":";
289 | }
290 |
291 | pre, tt, code {
292 | font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono', 'Bitstream Vera Sans Mono', monospace;
293 | font-size: 0.9em;
294 | }
295 |
296 | .hll {
297 | background-color: #FFC;
298 | margin: 0 -12px;
299 | padding: 0 12px;
300 | display: block;
301 | }
302 |
303 | img.screenshot {
304 | }
305 |
306 | tt.descname, tt.descclassname, code.descname, code.descclassname {
307 | font-size: 0.95em;
308 | }
309 |
310 | tt.descname, code.descname {
311 | padding-right: 0.08em;
312 | }
313 |
314 | img.screenshot {
315 | -moz-box-shadow: 2px 2px 4px #eee;
316 | -webkit-box-shadow: 2px 2px 4px #eee;
317 | box-shadow: 2px 2px 4px #eee;
318 | }
319 |
320 | table.docutils {
321 | border: 1px solid #888;
322 | -moz-box-shadow: 2px 2px 4px #eee;
323 | -webkit-box-shadow: 2px 2px 4px #eee;
324 | box-shadow: 2px 2px 4px #eee;
325 | }
326 |
327 | table.docutils td, table.docutils th {
328 | border: 1px solid #888;
329 | padding: 0.25em 0.7em;
330 | }
331 |
332 | table.field-list, table.footnote {
333 | border: none;
334 | -moz-box-shadow: none;
335 | -webkit-box-shadow: none;
336 | box-shadow: none;
337 | }
338 |
339 | table.footnote {
340 | margin: 15px 0;
341 | width: 100%;
342 | border: 1px solid #EEE;
343 | background: #FDFDFD;
344 | font-size: 0.9em;
345 | }
346 |
347 | table.footnote + table.footnote {
348 | margin-top: -15px;
349 | border-top: none;
350 | }
351 |
352 | table.field-list th {
353 | padding: 0 0.8em 0 0;
354 | }
355 |
356 | table.field-list td {
357 | padding: 0;
358 | }
359 |
360 | table.field-list p {
361 | margin-bottom: 0.8em;
362 | }
363 |
364 | table.footnote td.label {
365 | width: .1px;
366 | padding: 0.3em 0 0.3em 0.5em;
367 | }
368 |
369 | table.footnote td {
370 | padding: 0.3em 0.5em;
371 | }
372 |
373 | dl {
374 | margin: 0;
375 | padding: 0;
376 | }
377 |
378 | dl dd {
379 | margin-left: 30px;
380 | }
381 |
382 | blockquote {
383 | margin: 0 0 0 30px;
384 | padding: 0;
385 | }
386 |
387 | ul, ol {
388 | /* Matches the 30px from the narrow-screen "li > ul" selector below */
389 | margin: 10px 0 10px 30px;
390 | padding: 0;
391 | }
392 |
393 | pre {
394 | background: #EEE;
395 | padding: 7px 30px;
396 | margin: 15px 0px;
397 | line-height: 1.3em;
398 | }
399 |
400 | dl pre, blockquote pre, li pre {
401 | margin-left: 0;
402 | padding-left: 30px;
403 | }
404 |
405 | dl dl pre {
406 | margin-left: -90px;
407 | padding-left: 90px;
408 | }
409 |
410 | tt, code {
411 | background-color: #ecf0f3;
412 | color: #222;
413 | /* padding: 1px 2px; */
414 | }
415 |
416 | tt.xref, code.xref, a tt {
417 | background-color: #FBFBFB;
418 | border-bottom: 1px solid white;
419 | }
420 |
421 | a.reference {
422 | text-decoration: none;
423 | border-bottom: 1px dotted #004B6B;
424 | }
425 |
426 | /* Don't put an underline on images */
427 | a.image-reference, a.image-reference:hover {
428 | border-bottom: none;
429 | }
430 |
431 | a.reference:hover {
432 | border-bottom: 1px solid #6D4100;
433 | }
434 |
435 | a.footnote-reference {
436 | text-decoration: none;
437 | font-size: 0.7em;
438 | vertical-align: top;
439 | border-bottom: 1px dotted #004B6B;
440 | }
441 |
442 | a.footnote-reference:hover {
443 | border-bottom: 1px solid #6D4100;
444 | }
445 |
446 | a:hover tt, a:hover code {
447 | background: #EEE;
448 | }
449 |
450 |
451 | @media screen and (max-width: 870px) {
452 |
453 | div.sphinxsidebar {
454 | display: none;
455 | }
456 |
457 | div.document {
458 | width: 100%;
459 |
460 | }
461 |
462 | div.documentwrapper {
463 | margin-left: 0;
464 | margin-top: 0;
465 | margin-right: 0;
466 | margin-bottom: 0;
467 | }
468 |
469 | div.bodywrapper {
470 | margin-top: 0;
471 | margin-right: 0;
472 | margin-bottom: 0;
473 | margin-left: 0;
474 | }
475 |
476 | ul {
477 | margin-left: 0;
478 | }
479 |
480 | li > ul {
481 | /* Matches the 30px from the "ul, ol" selector above */
482 | margin-left: 30px;
483 | }
484 |
485 | .document {
486 | width: auto;
487 | }
488 |
489 | .footer {
490 | width: auto;
491 | }
492 |
493 | .bodywrapper {
494 | margin: 0;
495 | }
496 |
497 | .footer {
498 | width: auto;
499 | }
500 |
501 | .github {
502 | display: none;
503 | }
504 |
505 |
506 |
507 | }
508 |
509 |
510 |
511 | @media screen and (max-width: 875px) {
512 |
513 | body {
514 | margin: 0;
515 | padding: 20px 30px;
516 | }
517 |
518 | div.documentwrapper {
519 | float: none;
520 | background: white;
521 | }
522 |
523 | div.sphinxsidebar {
524 | display: block;
525 | float: none;
526 | width: 102.5%;
527 | margin: 50px -30px -20px -30px;
528 | padding: 10px 20px;
529 | background: #333;
530 | color: #FFF;
531 | }
532 |
533 | div.sphinxsidebar h3, div.sphinxsidebar h4, div.sphinxsidebar p,
534 | div.sphinxsidebar h3 a {
535 | color: white;
536 | }
537 |
538 | div.sphinxsidebar a {
539 | color: #AAA;
540 | }
541 |
542 | div.sphinxsidebar p.logo {
543 | display: none;
544 | }
545 |
546 | div.document {
547 | width: 100%;
548 | margin: 0;
549 | }
550 |
551 | div.footer {
552 | display: none;
553 | }
554 |
555 | div.bodywrapper {
556 | margin: 0;
557 | }
558 |
559 | div.body {
560 | min-height: 0;
561 | padding: 0;
562 | }
563 |
564 | .rtd_doc_footer {
565 | display: none;
566 | }
567 |
568 | .document {
569 | width: auto;
570 | }
571 |
572 | .footer {
573 | width: auto;
574 | }
575 |
576 | .footer {
577 | width: auto;
578 | }
579 |
580 | .github {
581 | display: none;
582 | }
583 | }
584 |
585 |
586 | /* misc. */
587 |
588 | .revsys-inline {
589 | display: none!important;
590 | }
591 |
592 | /* Make nested-list/multi-paragraph items look better in Releases changelog
593 | * pages. Without this, docutils' magical list fuckery causes inconsistent
594 | * formatting between different release sub-lists.
595 | */
596 | div#changelog > div.section > ul > li > p:only-child {
597 | margin-bottom: 0;
598 | }
599 |
600 | /* Hide fugly table cell borders in ..bibliography:: directive output */
601 | table.docutils.citation, table.docutils.citation td, table.docutils.citation th {
602 | border: none;
603 | /* Below needed in some edge cases; if not applied, bottom shadows appear */
604 | -moz-box-shadow: none;
605 | -webkit-box-shadow: none;
606 | box-shadow: none;
607 | }
--------------------------------------------------------------------------------
/docs/_build/html/_static/basic.css:
--------------------------------------------------------------------------------
1 | /*
2 | * basic.css
3 | * ~~~~~~~~~
4 | *
5 | * Sphinx stylesheet -- basic theme.
6 | *
7 | * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS.
8 | * :license: BSD, see LICENSE for details.
9 | *
10 | */
11 |
12 | /* -- main layout ----------------------------------------------------------- */
13 |
14 | div.clearer {
15 | clear: both;
16 | }
17 |
18 | /* -- relbar ---------------------------------------------------------------- */
19 |
20 | div.related {
21 | width: 100%;
22 | font-size: 90%;
23 | }
24 |
25 | div.related h3 {
26 | display: none;
27 | }
28 |
29 | div.related ul {
30 | margin: 0;
31 | padding: 0 0 0 10px;
32 | list-style: none;
33 | }
34 |
35 | div.related li {
36 | display: inline;
37 | }
38 |
39 | div.related li.right {
40 | float: right;
41 | margin-right: 5px;
42 | }
43 |
44 | /* -- sidebar --------------------------------------------------------------- */
45 |
46 | div.sphinxsidebarwrapper {
47 | padding: 10px 5px 0 10px;
48 | }
49 |
50 | div.sphinxsidebar {
51 | float: left;
52 | width: 230px;
53 | margin-left: -100%;
54 | font-size: 90%;
55 | word-wrap: break-word;
56 | overflow-wrap : break-word;
57 | }
58 |
59 | div.sphinxsidebar ul {
60 | list-style: none;
61 | }
62 |
63 | div.sphinxsidebar ul ul,
64 | div.sphinxsidebar ul.want-points {
65 | margin-left: 20px;
66 | list-style: square;
67 | }
68 |
69 | div.sphinxsidebar ul ul {
70 | margin-top: 0;
71 | margin-bottom: 0;
72 | }
73 |
74 | div.sphinxsidebar form {
75 | margin-top: 10px;
76 | }
77 |
78 | div.sphinxsidebar input {
79 | border: 1px solid #98dbcc;
80 | font-family: sans-serif;
81 | font-size: 1em;
82 | }
83 |
84 | div.sphinxsidebar #searchbox input[type="text"] {
85 | width: 170px;
86 | }
87 |
88 | div.sphinxsidebar #searchbox input[type="submit"] {
89 | width: 30px;
90 | }
91 |
92 | img {
93 | border: 0;
94 | max-width: 100%;
95 | }
96 |
97 | /* -- search page ----------------------------------------------------------- */
98 |
99 | ul.search {
100 | margin: 10px 0 0 20px;
101 | padding: 0;
102 | }
103 |
104 | ul.search li {
105 | padding: 5px 0 5px 20px;
106 | background-image: url(file.png);
107 | background-repeat: no-repeat;
108 | background-position: 0 7px;
109 | }
110 |
111 | ul.search li a {
112 | font-weight: bold;
113 | }
114 |
115 | ul.search li div.context {
116 | color: #888;
117 | margin: 2px 0 0 30px;
118 | text-align: left;
119 | }
120 |
121 | ul.keywordmatches li.goodmatch a {
122 | font-weight: bold;
123 | }
124 |
125 | /* -- index page ------------------------------------------------------------ */
126 |
127 | table.contentstable {
128 | width: 90%;
129 | }
130 |
131 | table.contentstable p.biglink {
132 | line-height: 150%;
133 | }
134 |
135 | a.biglink {
136 | font-size: 1.3em;
137 | }
138 |
139 | span.linkdescr {
140 | font-style: italic;
141 | padding-top: 5px;
142 | font-size: 90%;
143 | }
144 |
145 | /* -- general index --------------------------------------------------------- */
146 |
147 | table.indextable {
148 | width: 100%;
149 | }
150 |
151 | table.indextable td {
152 | text-align: left;
153 | vertical-align: top;
154 | }
155 |
156 | table.indextable dl, table.indextable dd {
157 | margin-top: 0;
158 | margin-bottom: 0;
159 | }
160 |
161 | table.indextable tr.pcap {
162 | height: 10px;
163 | }
164 |
165 | table.indextable tr.cap {
166 | margin-top: 10px;
167 | background-color: #f2f2f2;
168 | }
169 |
170 | img.toggler {
171 | margin-right: 3px;
172 | margin-top: 3px;
173 | cursor: pointer;
174 | }
175 |
176 | div.modindex-jumpbox {
177 | border-top: 1px solid #ddd;
178 | border-bottom: 1px solid #ddd;
179 | margin: 1em 0 1em 0;
180 | padding: 0.4em;
181 | }
182 |
183 | div.genindex-jumpbox {
184 | border-top: 1px solid #ddd;
185 | border-bottom: 1px solid #ddd;
186 | margin: 1em 0 1em 0;
187 | padding: 0.4em;
188 | }
189 |
190 | /* -- general body styles --------------------------------------------------- */
191 |
192 | div.body p, div.body dd, div.body li, div.body blockquote {
193 | -moz-hyphens: auto;
194 | -ms-hyphens: auto;
195 | -webkit-hyphens: auto;
196 | hyphens: auto;
197 | }
198 |
199 | a.headerlink {
200 | visibility: hidden;
201 | }
202 |
203 | h1:hover > a.headerlink,
204 | h2:hover > a.headerlink,
205 | h3:hover > a.headerlink,
206 | h4:hover > a.headerlink,
207 | h5:hover > a.headerlink,
208 | h6:hover > a.headerlink,
209 | dt:hover > a.headerlink,
210 | caption:hover > a.headerlink,
211 | p.caption:hover > a.headerlink,
212 | div.code-block-caption:hover > a.headerlink {
213 | visibility: visible;
214 | }
215 |
216 | div.body p.caption {
217 | text-align: inherit;
218 | }
219 |
220 | div.body td {
221 | text-align: left;
222 | }
223 |
224 | .field-list ul {
225 | padding-left: 1em;
226 | }
227 |
228 | .first {
229 | margin-top: 0 !important;
230 | }
231 |
232 | p.rubric {
233 | margin-top: 30px;
234 | font-weight: bold;
235 | }
236 |
237 | img.align-left, .figure.align-left, object.align-left {
238 | clear: left;
239 | float: left;
240 | margin-right: 1em;
241 | }
242 |
243 | img.align-right, .figure.align-right, object.align-right {
244 | clear: right;
245 | float: right;
246 | margin-left: 1em;
247 | }
248 |
249 | img.align-center, .figure.align-center, object.align-center {
250 | display: block;
251 | margin-left: auto;
252 | margin-right: auto;
253 | }
254 |
255 | .align-left {
256 | text-align: left;
257 | }
258 |
259 | .align-center {
260 | text-align: center;
261 | }
262 |
263 | .align-right {
264 | text-align: right;
265 | }
266 |
267 | /* -- sidebars -------------------------------------------------------------- */
268 |
269 | div.sidebar {
270 | margin: 0 0 0.5em 1em;
271 | border: 1px solid #ddb;
272 | padding: 7px 7px 0 7px;
273 | background-color: #ffe;
274 | width: 40%;
275 | float: right;
276 | }
277 |
278 | p.sidebar-title {
279 | font-weight: bold;
280 | }
281 |
282 | /* -- topics ---------------------------------------------------------------- */
283 |
284 | div.topic {
285 | border: 1px solid #ccc;
286 | padding: 7px 7px 0 7px;
287 | margin: 10px 0 10px 0;
288 | }
289 |
290 | p.topic-title {
291 | font-size: 1.1em;
292 | font-weight: bold;
293 | margin-top: 10px;
294 | }
295 |
296 | /* -- admonitions ----------------------------------------------------------- */
297 |
298 | div.admonition {
299 | margin-top: 10px;
300 | margin-bottom: 10px;
301 | padding: 7px;
302 | }
303 |
304 | div.admonition dt {
305 | font-weight: bold;
306 | }
307 |
308 | div.admonition dl {
309 | margin-bottom: 0;
310 | }
311 |
312 | p.admonition-title {
313 | margin: 0px 10px 5px 0px;
314 | font-weight: bold;
315 | }
316 |
317 | div.body p.centered {
318 | text-align: center;
319 | margin-top: 25px;
320 | }
321 |
322 | /* -- tables ---------------------------------------------------------------- */
323 |
324 | table.docutils {
325 | border: 0;
326 | border-collapse: collapse;
327 | }
328 |
329 | table caption span.caption-number {
330 | font-style: italic;
331 | }
332 |
333 | table caption span.caption-text {
334 | }
335 |
336 | table.docutils td, table.docutils th {
337 | padding: 1px 8px 1px 5px;
338 | border-top: 0;
339 | border-left: 0;
340 | border-right: 0;
341 | border-bottom: 1px solid #aaa;
342 | }
343 |
344 | table.field-list td, table.field-list th {
345 | border: 0 !important;
346 | }
347 |
348 | table.footnote td, table.footnote th {
349 | border: 0 !important;
350 | }
351 |
352 | th {
353 | text-align: left;
354 | padding-right: 5px;
355 | }
356 |
357 | table.citation {
358 | border-left: solid 1px gray;
359 | margin-left: 1px;
360 | }
361 |
362 | table.citation td {
363 | border-bottom: none;
364 | }
365 |
366 | /* -- figures --------------------------------------------------------------- */
367 |
368 | div.figure {
369 | margin: 0.5em;
370 | padding: 0.5em;
371 | }
372 |
373 | div.figure p.caption {
374 | padding: 0.3em;
375 | }
376 |
377 | div.figure p.caption span.caption-number {
378 | font-style: italic;
379 | }
380 |
381 | div.figure p.caption span.caption-text {
382 | }
383 |
384 |
385 | /* -- other body styles ----------------------------------------------------- */
386 |
387 | ol.arabic {
388 | list-style: decimal;
389 | }
390 |
391 | ol.loweralpha {
392 | list-style: lower-alpha;
393 | }
394 |
395 | ol.upperalpha {
396 | list-style: upper-alpha;
397 | }
398 |
399 | ol.lowerroman {
400 | list-style: lower-roman;
401 | }
402 |
403 | ol.upperroman {
404 | list-style: upper-roman;
405 | }
406 |
407 | dl {
408 | margin-bottom: 15px;
409 | }
410 |
411 | dd p {
412 | margin-top: 0px;
413 | }
414 |
415 | dd ul, dd table {
416 | margin-bottom: 10px;
417 | }
418 |
419 | dd {
420 | margin-top: 3px;
421 | margin-bottom: 10px;
422 | margin-left: 30px;
423 | }
424 |
425 | dt:target, .highlighted {
426 | background-color: #fbe54e;
427 | }
428 |
429 | dl.glossary dt {
430 | font-weight: bold;
431 | font-size: 1.1em;
432 | }
433 |
434 | .field-list ul {
435 | margin: 0;
436 | padding-left: 1em;
437 | }
438 |
439 | .field-list p {
440 | margin: 0;
441 | }
442 |
443 | .optional {
444 | font-size: 1.3em;
445 | }
446 |
447 | .sig-paren {
448 | font-size: larger;
449 | }
450 |
451 | .versionmodified {
452 | font-style: italic;
453 | }
454 |
455 | .system-message {
456 | background-color: #fda;
457 | padding: 5px;
458 | border: 3px solid red;
459 | }
460 |
461 | .footnote:target {
462 | background-color: #ffa;
463 | }
464 |
465 | .line-block {
466 | display: block;
467 | margin-top: 1em;
468 | margin-bottom: 1em;
469 | }
470 |
471 | .line-block .line-block {
472 | margin-top: 0;
473 | margin-bottom: 0;
474 | margin-left: 1.5em;
475 | }
476 |
477 | .guilabel, .menuselection {
478 | font-family: sans-serif;
479 | }
480 |
481 | .accelerator {
482 | text-decoration: underline;
483 | }
484 |
485 | .classifier {
486 | font-style: oblique;
487 | }
488 |
489 | abbr, acronym {
490 | border-bottom: dotted 1px;
491 | cursor: help;
492 | }
493 |
494 | /* -- code displays --------------------------------------------------------- */
495 |
496 | pre {
497 | overflow: auto;
498 | overflow-y: hidden; /* fixes display issues on Chrome browsers */
499 | }
500 |
501 | td.linenos pre {
502 | padding: 5px 0px;
503 | border: 0;
504 | background-color: transparent;
505 | color: #aaa;
506 | }
507 |
508 | table.highlighttable {
509 | margin-left: 0.5em;
510 | }
511 |
512 | table.highlighttable td {
513 | padding: 0 0.5em 0 0.5em;
514 | }
515 |
516 | div.code-block-caption {
517 | padding: 2px 5px;
518 | font-size: small;
519 | }
520 |
521 | div.code-block-caption code {
522 | background-color: transparent;
523 | }
524 |
525 | div.code-block-caption + div > div.highlight > pre {
526 | margin-top: 0;
527 | }
528 |
529 | div.code-block-caption span.caption-number {
530 | padding: 0.1em 0.3em;
531 | font-style: italic;
532 | }
533 |
534 | div.code-block-caption span.caption-text {
535 | }
536 |
537 | div.literal-block-wrapper {
538 | padding: 1em 1em 0;
539 | }
540 |
541 | div.literal-block-wrapper div.highlight {
542 | margin: 0;
543 | }
544 |
545 | code.descname {
546 | background-color: transparent;
547 | font-weight: bold;
548 | font-size: 1.2em;
549 | }
550 |
551 | code.descclassname {
552 | background-color: transparent;
553 | }
554 |
555 | code.xref, a code {
556 | background-color: transparent;
557 | font-weight: bold;
558 | }
559 |
560 | h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
561 | background-color: transparent;
562 | }
563 |
564 | .viewcode-link {
565 | float: right;
566 | }
567 |
568 | .viewcode-back {
569 | float: right;
570 | font-family: sans-serif;
571 | }
572 |
573 | div.viewcode-block:target {
574 | margin: -1px -10px;
575 | padding: 0 10px;
576 | }
577 |
578 | /* -- math display ---------------------------------------------------------- */
579 |
580 | img.math {
581 | vertical-align: middle;
582 | }
583 |
584 | div.body div.math p {
585 | text-align: center;
586 | }
587 |
588 | span.eqno {
589 | float: right;
590 | }
591 |
592 | /* -- printout stylesheet --------------------------------------------------- */
593 |
594 | @media print {
595 | div.document,
596 | div.documentwrapper,
597 | div.bodywrapper {
598 | margin: 0 !important;
599 | width: 100%;
600 | }
601 |
602 | div.sphinxsidebar,
603 | div.related,
604 | div.footer,
605 | #top-link {
606 | display: none;
607 | }
608 | }
--------------------------------------------------------------------------------
/shaolin/core/widgets.py:
--------------------------------------------------------------------------------
1 |
2 | """
3 | Created on Wed Apr 20 10:22:21 2016
4 |
5 | @author: Guillem Duran for HCSOFT
6 | """
7 |
8 | import ipywidgets as wid
9 |
10 | class Widget(object):
11 | """This is a wrapper for any selector widget so its description can be tweaked with css
12 | Parameters. This will also make backwadrs compatible the instantiation with layout properties.
13 | ----------
14 | widget : ipydidgets widget
15 | this is intender for selector widgets, but it can be
16 | any widget with from the ipywidgets package.
17 | description : String or None
18 | Text for the description of the widget. Acs as the description
19 | parameter of the widget but can be tweaked with css
20 | desc_css : String or None
21 | css for the description text.
22 | custom_id : String or None
23 | A custom attribute tag for the description div.
24 | kwargs : **kwargs
25 | Arguments of the widget we are wrapping.
26 | """
27 | def __init__(self,
28 | widget,
29 | class_=None,
30 | id=None,
31 | name=None,
32 | html=None,
33 | js=None,
34 | css=None,
35 | visible=True,
36 | mode='active',
37 | **kwargs):
38 |
39 | if id is None:
40 | id = ''
41 | else:
42 | id = id.lower().replace(' ', '_')
43 | if html is None:
44 | html = ''
45 | if js is None:
46 | js = ''
47 | if css is None:
48 | css = ''
49 | if name is None:
50 | name = ''
51 | else:
52 | name = name.lower().replace(' ', '_')
53 | if class_ is None:
54 | class_ = ''
55 | self.mode = mode
56 | self.name = name
57 | self.id = id
58 | self.class_ = class_
59 | self.html = html
60 | self.js = js
61 | self.css = css
62 | """
63 | #this ensures a unique class name for javascript hacking
64 | self._hack_id = ''.join(random.choice('0123456789ABCDEFGHIJK') for i in range(16))
65 | self._hack_widget = wid.HTML(value='
'\
66 | +''\
67 | +''+self.html)
68 | self._hack_widget.layout.display = 'none'
69 | self._hack_widget.layout.visibility = 'hidden'
70 |
71 | self._label_css = ''
72 | #if 'description' in kwargs.keys():
73 | # self.description = kwargs['description']
74 | # kwargs.pop('description')
75 |
76 | self._description = description
77 | self.label = wid.HTML(value=''+self._description+'
')
79 | if self._description == '':
80 | self.label.layout.display = 'none'
81 | self.label.layout.visibility = 'hidden'
82 | """
83 | #self.target = widget(**kwargs)
84 | self.widget = widget(**kwargs)#wid.HBox(children=[self.target])#
85 |
86 | #self.widget.layout.width = self.target.layout.width
87 | #self.add_ids()
88 | self.visible = visible
89 |
90 | self.autoset_max_width()
91 |
92 | self.widget.layout.min_width = "100px"
93 | #shorthands for widge and value
94 | def __call__(self,**kwaargs):
95 | return self.widget.value
96 | def __getitem__(self,index):
97 | if index is None or isinstance(index,(int,bool)):
98 | return self.widget
99 | else:
100 | raise ValueError("index must be integer or None or bool")
101 | #Attributes for mimicking standard widget interface
102 | #----------------------------------------------------
103 | @property
104 | def width(self):
105 | return self.widget.layout.width
106 | @width.setter
107 | def width(self,val):
108 | if isinstance(val,str):
109 | if not val[-1] =='%':
110 | if self.widget.layout.max_width is None:
111 | self.widget.layout.max_width = val
112 | else:
113 | self.widget.layout.max_width = str(max(float(self.widget.layout.max_width[:-2]),
114 | float(val[:-2])))+'px'
115 | self.widget.layout.width = val
116 | elif isinstance(val,(tuple,list)):
117 | self.widget.layout.width = val[0]
118 | self.widget.layout.max_width = val[1]
119 |
120 |
121 |
122 | @property
123 | def target(self):
124 | return self.widget
125 | @property
126 | def layout(self):
127 | return self.widget.layout
128 |
129 | @property
130 | def hack(self):
131 | return self._hack_widget
132 | @hack.setter
133 | def hack(self, val):
134 | self._hack_widget = val
135 |
136 | @property
137 | def value(self):
138 | """Get the value of the wrapped widget"""
139 | if hasattr(self.target, 'value'):
140 | return self.target.value
141 | @value.setter
142 | def value(self, val):
143 | if hasattr(self.target, 'value'):
144 | self.target.value = val
145 |
146 | @property
147 | def options(self):
148 | """Same interface as widgets but easier to iterate"""
149 | try:
150 | return self.target.options
151 | except AttributeError:
152 | return None
153 | @options.setter
154 | def options(self, val):
155 | try:
156 | self.target.options = val
157 |
158 | except AttributeError:
159 | try:
160 | self._update_options(val)
161 | except:
162 | pass
163 |
164 | @property
165 | def visible(self):
166 | """Easier visibility changing"""
167 | return self.widget.layout.visibility == 'visible' \
168 | and self.widget.layout.display == ''
169 | @visible.setter
170 | def visible(self, val):
171 | """Easier visibility changing"""
172 | if val:
173 | self.widget.layout.visibility = 'visible'
174 | self.widget.layout.display = ''
175 | else:
176 | self.widget.layout.visibility = 'hidden'
177 | self.widget.layout.display = 'none'
178 |
179 |
180 | @property
181 | def description(self):
182 | """Same interface as widgets but easier to iterate"""
183 | return self.target.description
184 |
185 | @description.setter
186 | def description(self, val):
187 | """Same interface as widgets but easier to iterate"""
188 | self._description = val
189 | self.label = wid.HTML(value=''+self._description+'
')
190 | if val == '':
191 | self.label.layout.display = 'none'
192 | self.label.layout.visibility = 'hidden'
193 | else:
194 | self.label.layout.display = ''
195 | self.label.layout.visibility = 'visible'
196 |
197 | @property
198 | def orientation(self):
199 | """Same interface as widgets but easier to iterate"""
200 | try:
201 | return self.target.orientation
202 | except AttributeError:
203 | return None
204 | @orientation.setter
205 | def orientation(self, val):
206 | """Same interface as widgets but easier to iterate"""
207 | try:
208 | self.target.orientation = val
209 | except AttributeError:
210 | pass
211 |
212 | def update(self, val):
213 | self.value = val
214 |
215 | def observe(self, func, names='value'):
216 | """A quickly way to add observe calls to the widget"""
217 | if isinstance(self.target,
218 | wid.Widget.widget_types['Jupyter.Button']):
219 | self.target.on_click(func)
220 | if hasattr(self.target, 'value'):
221 | self.target.observe(func, names=names)
222 |
223 | def autoset_max_width(self):
224 | if not isinstance(self.widget,(wid.Box,wid.Tab,wid.Accordion,wid.HTML,wid.Image)):
225 | self.widget.layout.max_width = '300px'
226 | self._max_width_px ='300px'
227 | self.widget.layout.min_width = '30px'
228 | self._min_width_px ='30px'
229 | #Methods
230 | #------------------------------
231 | def _update_options(self, cols):
232 | """This is for avoiding trailet errors due to invalid selections
233 | when updating the widgets options values """
234 | current = set(self.target.options)
235 | inter = current.intersection(set(cols))
236 | if inter == set(()):
237 | oldopt = self.target.options + ['dummy']
238 | self.target.options = oldopt
239 | self.value = ('dummy',)
240 | newopt = ['dummy'] + cols
241 | self.target.options = newopt
242 | self.value = (cols[0],)
243 | self.target.options = cols
244 | else:
245 | self.value = tuple(current.intersection(set(cols)))
246 | self.target.options = cols
247 |
248 | def add_ids(self):
249 | hack_id = self._hack_id
250 | class_tag = str(self.class_)
251 | if class_tag == '':
252 | class_tag = ""
253 | id_tag = str(self.id)
254 | if id_tag == '':
255 | child_id = hack_id
256 | else:
257 | child_id = id_tag
258 | javascript = """
259 | function iterateChildren(c,level) {
260 | var i;
261 | level = level+1;
262 | for (i = 0; i < c.length; i++) {
263 | if (typeof c[i] != 'undefined') {
264 | if (typeof c[i].style != 'undefined') {
265 | c[i].id += '"""+child_id+"""'+"-"+level+"-"+i;
266 | }
267 | children = c[i].childNodes;
268 | iterateChildren(children,level)
269 | }
270 | }
271 | }
272 |
273 | function markChildren_"""+hack_id+"""(hack_id) {
274 | var widget = document.getElementById('"""+hack_id+"""').parentElement.parentElement;
275 | widget.id += "shao ";
276 | widget.id += '"""+id_tag+"""';
277 | widget.classList.add('"""+class_tag+"""') ;
278 | var c = widget.childNodes;
279 | //iterateChildren(c,0);
280 | }
281 | var hack_id = 'H6D2B1S9C0G';
282 | markChildren_"""+hack_id+"""(hack_id);
283 | """
284 | self.update_hack(js=javascript)
285 | self.hack.visibility = 'hidden'
286 |
287 | def update_hack(self,
288 | hack_id=None,
289 | html=None,
290 | css=None,
291 | js=None):
292 | """updates css hack"""
293 | if not html is None:
294 | self.html = html
295 | if not js is None:
296 | self.js = js
297 | if not css is None:
298 | self.css = css
299 | if not hack_id is None:
300 | self._hack_id = hack_id
301 | value = '
'\
302 | +''\
303 | +''+self.html
304 | self.hack.value = value
305 |
306 |
307 |
308 | class Title(Widget):
309 | """Widget used to mimic the markwodn syntax of the notebook"""
310 | def __init__(self, value='Title', **kwargs):
311 | self._text = value
312 | kwargs['value'] = ""+value+" "
313 | Widget.__init__(self, widget=wid.HTML, **kwargs)
314 | @property
315 | def text(self):
316 | return self._text
317 | @text.setter
318 | def text(self,value):
319 | self._text = value
320 | self.value = ""+value+" "
321 |
322 | class SubTitle(Widget):
323 | """Widget used to mimic the markwodn syntax of the notebook"""
324 | def __init__(self, value='Title', **kwargs):
325 | self._text = value
326 | kwargs['value'] = ""+value+" "
327 | Widget.__init__(self, widget=wid.HTML, **kwargs)
328 | @property
329 | def text(self):
330 | return self._text
331 | @text.setter
332 | def text(self,value):
333 | self._text = value
334 | self.value = ""+value+" "
335 |
336 | class SubSubTitle(Widget):
337 | """Widget used to mimic the markwodn syntax of the notebook"""
338 | def __init__(self, value='Title', **kwargs):
339 | self._text = value
340 | kwargs['value'] = ""+value+" "
341 | Widget.__init__(self, widget=wid.HTML, **kwargs)
342 | @property
343 | def text(self):
344 | return self._text
345 | @text.setter
346 | def text(self,value):
347 | self._text = value
348 | self.value = ""+value+" "
349 |
--------------------------------------------------------------------------------
/shaolin/core/kungfu.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | import string
3 | import random
4 | import inspect
5 | import six
6 | import numpy as np
7 | import ipywidgets as wid
8 | from shaolin.core.shaoscript import shaoscript
9 | from shaolin.core.dashboard import Dashboard
10 | from shaolin.core.widgets import Title, SubTitle, SubSubTitle
11 | from shaolin.dashboards.colormap import ColormapPicker
12 |
13 |
14 | class KungFu(Dashboard):
15 | def __init__(self,
16 | name='dash',
17 | box='5c',
18 | interact=None,
19 | mode=None,
20 | func=None,
21 | dash=None,
22 | group_n=3,
23 | **kwargs):
24 | self._group_n = group_n
25 | self.__dic_mode = mode
26 | self.__interact = interact
27 | if self.__interact and mode is None:
28 | self.__dic_mode = 'interactive'
29 | if not func is None:
30 | a = inspect.getargspec(func)
31 | c_kwargs = dict(zip(a.args[-len(a.defaults):],a.defaults))
32 | c_kwargs.update(kwargs)
33 | else:
34 | c_kwargs = kwargs
35 |
36 | children = self.get_children_widgets(c_kwargs)
37 | self.name = name
38 | dash = dash or self.process_children_layout(box,children)#dash or [box+'$n='+name,children]
39 | #print(dash)
40 | Dashboard.__init__(self,dash,name=name,mode=mode)
41 | self._func = func
42 | self.observe(self.fun)
43 |
44 | #shorthands for widget and value
45 | @staticmethod
46 | def is_text_widget(w):
47 | shao_titles = Title, SubTitle, SubSubTitle
48 | return isinstance(w,shao_titles) or isinstance(w[0],wid.Label)
49 | @staticmethod
50 | def compare_widgets(a,b):
51 | pass
52 |
53 | @staticmethod
54 | def _get_first_child(children):
55 | title = []
56 | buttons = []
57 | subtitle = []
58 | subsubtitle = []
59 | progress = []
60 | for c in children:
61 | if isinstance(c,Title):
62 | title.append(c)
63 | elif isinstance(c,SubTitle):
64 | subtitle.append(c)
65 | elif isinstance(c,SubSubTitle):
66 | subsubtitle.append(c)
67 | elif isinstance(c.widget,(wid.FloatProgress,wid.IntProgress)):
68 | progress.append(c)
69 | elif isinstance(c.widget,wid.Button):
70 | buttons.append(c)
71 | first = title + subtitle +subsubtitle + progress +buttons
72 | #print(first)
73 | return first
74 |
75 | @staticmethod
76 | def _get_sliders_child(children):
77 | slid = []
78 | slid_types = (wid.FloatSlider,wid.IntSlider,wid.IntText,wid.FloatText)
79 | for c in children:
80 | if isinstance(c.widget,slid_types):
81 | slid.append(c)
82 | return slid
83 | @staticmethod
84 | def _get_colors_child(children):
85 |
86 | colors = []
87 |
88 | for c in children:
89 | if isinstance(c.widget,wid.ColorPicker) or isinstance(c,ColormapPicker):
90 | colors.append(c)
91 | return colors
92 |
93 | @staticmethod
94 | def _get_text_child(children):
95 | text = []
96 | text_types = (wid.Text,wid.Textarea)
97 | for c in children:
98 | if isinstance(c.widget,text_types):
99 | text.append(c)
100 | return text
101 |
102 | @staticmethod
103 | def _get_selection_child(children):
104 | select = []
105 | select_types = (wid.Select,wid.SelectionSlider,
106 | wid.Dropdown,wid.ToggleButtons,
107 | wid.SelectMultiple,wid.RadioButtons)
108 | for c in children:
109 | if isinstance(c.widget,select_types):
110 | select.append(c)
111 | return select
112 |
113 | @staticmethod
114 | def _get_bool_child(children):
115 | bools = []
116 | bool_types = (wid.Checkbox,wid.ToggleButton,wid.Valid)
117 | for c in children:
118 | if isinstance(c.widget,bool_types):
119 | bools.append(c)
120 | return bools
121 |
122 | @staticmethod
123 | def _get_range_child(children):
124 | ranges = []
125 | range_types = (wid.FloatRangeSlider,wid.IntRangeSlider)
126 | for c in children:
127 | if isinstance(c.widget,range_types):
128 | ranges.append(c)
129 | return ranges
130 |
131 | def create_boxes(self,children,is_col=True,num=5,name=None,child_names=None):
132 | def id_generator(size=6, chars=string.ascii_uppercase + string.digits):
133 | return ''.join(random.choice(chars) for _ in range(size))
134 |
135 |
136 | name = name or id_generator()
137 | child_names = child_names or [id_generator() for _ in range(len(children))]
138 | if isinstance(is_col,bool):
139 | b = 'c$n='+name if is_col else 'r$n='+name
140 | if len(children)<=num:
141 | return [b,children]
142 |
143 | pases = int(np.floor(len(children)/num))
144 | j = 0
145 | sub_children = []
146 | for p in range(pases):
147 | sub = []
148 | for j in range(p*num,p*num+num):
149 | sub.append(children[j])
150 | sub_b = 'c$n='+id_generator() if not is_col else 'r$n='+id_generator()
151 | sub_children.append([sub_b,sub])
152 | last_sub = []
153 | for i in range(j+1,len(children)):
154 | last_sub.append(children[i])
155 | sub_b = 'c$n='+id_generator() if not is_col else 'r$n='+id_generator()
156 | sub_children.append([sub_b,last_sub])
157 | if isinstance(is_col,str):
158 | b = is_col+'$n='+name+'&t='+str(tuple(child_names)).replace('(',\
159 | '').replace(')','').replace("'",'').replace('"','')
160 | return [b,children]
161 | return [b,sub_children]
162 |
163 | def group_children(self,children,is_col,num=5):
164 | #title and buttons
165 | #is_col = not is_col
166 | first_child = self._get_first_child(children)
167 | first_child_b = self.create_boxes(first_child,is_col,num,name='main') if len(first_child)>=1 else []
168 | #print("first child:",first_child)
169 | #Sliders int and floar
170 | sliders = self._get_sliders_child(children)
171 | sliders_b = self.create_boxes(sliders,is_col,num,name='numeric') if len(sliders)>=1 else []
172 | #print("sliders:",sliders)
173 | #text widget
174 | text = self._get_text_child(children)
175 | text_b = self.create_boxes(text,is_col,num,name='text') if len(text)>=1 else []
176 | #print("text:",text)
177 | #selection widgets
178 | select = self._get_selection_child(children)
179 | select_b = self.create_boxes(select,is_col,num,name='selection') if len(select)>=1 else []
180 | #print("select:",select)
181 | #boolean widgets
182 | bools = self._get_bool_child(children)
183 | bools_b = self.create_boxes(bools,is_col,num,name='booleans') if len(bools)>=1 else []
184 | #color widgets
185 | colors = self._get_colors_child(children)
186 | colors_b = self.create_boxes(colors,is_col,num,name='colors') if len(colors)>=1 else []
187 | #other widgets
188 | others = []
189 | for c in children:
190 | if c not in first_child\
191 | and c not in sliders and c not in text\
192 | and c not in select and c not in bools and c not in colors:
193 | others.append(c)
194 | others_b = self.create_boxes(others,is_col,num,name='others') if len(others)>=1 else []
195 | #print("bools:",bools)
196 | new_children = []
197 | child_names = []
198 | if first_child != []:
199 | new_children.append(first_child_b)
200 | child_names.append(self.name)
201 | if sliders != []:
202 | new_children.append(sliders_b)
203 | child_names.append('Numeric')
204 | if select != []:
205 | new_children.append(select_b)
206 | child_names.append('Options')
207 | if bools != []:
208 | new_children.append(bools_b)
209 | child_names.append('Boolean')
210 | if text != []:
211 | new_children.append(text_b)
212 | child_names.append('String')
213 | if colors != []:
214 | new_children.append(colors_b)
215 | child_names.append('Colors')
216 | if others != []:
217 | new_children.append(others_b)
218 | child_names.append('Other')
219 | return new_children,child_names
220 |
221 | def process_children_layout(self,box='5c',children=None):
222 | def filter_box_type(box):
223 | col_words = [ 'column','cols', 'col','c', 'vbox', 'v']
224 | row_words = ['rows', 'row','r', 'HBox', 'box', 'h']
225 | tabs_or_accord = ['accordion','accord','ac','a'] +['tabs','tab','t']
226 |
227 | if '|' in box:
228 | box = box.replace('|','')
229 | group_ch = True
230 | else:
231 | group_ch = False
232 | is_col = True
233 | for w in row_words:
234 | if w in box.lower():
235 | box = box.lower().replace(w,'')
236 | is_col = False
237 | for w in col_words:
238 | if w in box.lower():
239 | box = box.lower().replace(w,'')
240 |
241 | for w in tabs_or_accord:
242 | if w in box.lower():
243 | box = box.lower().replace(w,'')
244 |
245 | is_col = w
246 | if box !='':
247 | num = int(box)
248 | else:
249 | num=5
250 | return is_col,num,group_ch
251 |
252 | assert(isinstance(children,list))
253 | #group the childfren
254 | is_col,num,group_ch = filter_box_type(box)
255 | if group_ch:
256 | rev = not is_col
257 | children, child_names = self.group_children(children,rev,num=num)
258 | #children like [form fi,sli,sel,bools,text]
259 | if isinstance(is_col,str):
260 | #two rows/cols with all the blockslen (child_names)
261 | return self.create_boxes(children,is_col,num=2,child_names=child_names)
262 | else:
263 | return self.create_boxes(children,is_col,num=num,child_names=child_names)
264 | return self.create_boxes(children,is_col,num)
265 |
266 | def fun(self,_=None):
267 | if not self._func is None and not self.__interact is None :
268 | return self._func(**self.kwargs)
269 |
270 | def kwargs_from_key(self,key):
271 | kws = {}
272 | if not self.__dic_mode is None and not 'mode' in kws.keys():
273 | kws['mode'] = self.__dic_mode
274 | if key.startswith('@'):
275 | k = key[1:]
276 | kws['mode'] = 'interactive'
277 | elif key.startswith('I_'):
278 | k = key[2:]
279 | kws['mode'] = 'interactive'
280 | elif key.startswith('/'):
281 | k = key[1:]
282 | kws['mode'] = 'passive'
283 | elif key.startswith('P_'):
284 | k = key[2:]
285 | kws['mode'] = 'passive'
286 | else:
287 | k = key
288 | kws['name']=k
289 | kws['description']=k.capitalize().replace('_',' ')
290 |
291 | return kws
292 |
293 | def get_children_widgets(self,kwargs):
294 | def is_shaoscript(x):
295 | return "$" in x if isinstance(x,six.string_types) else False
296 | children = []
297 | for k, v in kwargs.items():
298 | kws = self.kwargs_from_key(k)
299 | if is_shaoscript(v):
300 | children.append(shaoscript(v,kws))
301 | else:
302 | if isinstance(v,str):
303 | children.append(shaoscript('text$v='+v,kws))
304 | else:
305 | children.append(shaoscript(v,kws))
306 | return children
307 |
308 | @staticmethod
309 | def dict_to_children(self,kwargs):
310 | def is_shaoscript(x):
311 | return "$" in x if isinstance(x,six.string_types) else False
312 | children = []
313 | for k, v in kwargs.items():
314 | if is_shaoscript(v):
315 | children.append(shaoscript(v))
316 | else:
317 | kws = dict(name=k,description=k.capitalize().replace('_',' '))
318 | if not self.__dic_mode is None:
319 | kws['mode'] = self.__dic_mode
320 | if isinstance(v,str):
321 | children.append(shaoscript('text$v='+v,kws))
322 | else:
323 | children.append(shaoscript(v,kws))
324 | return children
--------------------------------------------------------------------------------
/shaolin/core/shaoscript.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Thu May 19 12:03:50 2016
4 |
5 | @author: sergio
6 | """
7 |
8 | import ast
9 | import six
10 | import ipywidgets as wid
11 | from shaolin.core.object_notation import object_notation
12 | from shaolin.core import widgets
13 |
14 | #from .widgets import widgets.Widget, widgets.Title, widgets.SubTitle, widgets.SubSubTitle
15 |
16 | def shaoscript(word, kwargs=None):
17 | """Return a shaolin widgets.Widget from a ShaoScript value.
18 | Parameters
19 | ----------
20 | word : string, object
21 | String can be the name of a widgets.Widget in shaoscript syntax, or a string
22 | conaining the full definition of a widgets.Widget using the shaoscript syntax to
23 | also define its kwargs.
24 | kwargs: dict, default: None
25 | Contains the kwargs values for the widgets.Widget that will be returned. The
26 | key value parameters contained in the dict will be overriden by those
27 | defined in word.
28 | Returns
29 | -------
30 | widgets.Widget: shaolin widgets.Widget.
31 |
32 | """
33 |
34 | kwargs = kwargs or {}
35 | #create a widgets.Widget from a string. get its widgets.Widget type and kwargs
36 | if isinstance(word, six.string_types):
37 | word, kwargs = _handle_shaoscript_syntax(word, kwargs)
38 | #word and kwargs from shaoscript syntax
39 | #if the word corresponds to a widgets.Widget definition
40 | if isinstance(word, six.string_types):
41 | return _string_to_wiget(word, kwargs)
42 | #If word is already an ipywidgets.Widget class
43 | elif isinstance(word, tuple(wid.Widget.widget_types.values())):
44 | return widgets.Widget(word, **kwargs)
45 | #word has to be a python object representing object notation
46 | try:
47 | return object_notation(word, kwargs)
48 | except:
49 | raise ValueError('''Bad shaoscript syntax. \n
50 | Failed to convert word: {} with kwargs:{}.'''\
51 | .format(word, kwargs))
52 |
53 | def _handle_shaoscript_syntax(string, kwargs=None):
54 | """Return a string defining a shaolin widgets.Widget and a dictionary containinng
55 | its kwargs.
56 | Parameters
57 | ----------
58 | string : string
59 | String can be the name of a widgets.Widget in shaoscript syntax, or a string
60 | conaining the full definition of a widgets.Widget using the shaoscript syntax to
61 | also define its kwargs.
62 | kwargs: dict, default: None
63 | Contains the kwargs values for the widgets.Widget that will be returned. The
64 | key value parameters contained in the dict will be overriden by those
65 | defined in word.
66 | Returns
67 | -------
68 | word: string
69 | Contains only the type of the widgets.Widget in shaoscript notation.
70 | kwargs: dict
71 | Dictionary containing the kwargs for creating a shaolin widgets.Widget.
72 |
73 | Shaoscript custom parameters available
74 | --------------------------------------
75 | paramters(aliases): value parsing
76 |
77 | 'options'('o', 'opt','opts'): ast.literal_eval
78 | 'description'('d','desc'): str
79 | 'id': str
80 | 'class_'('c','cls'): str
81 | 'visible'('vis'): boolean
82 | 'orientation'('ori','orient'): 'vertical','horizontal'
83 | 'name'('n'): str
84 | 'value'('val','v'): str
85 | val being a string means that non string values cannot be set this way.
86 | Use object notation in the definition of the widgets.Widget.
87 |
88 | """
89 | kwargs = kwargs or {}
90 | #take into account interactivity
91 | main_key = string[0]
92 | if main_key == '@':
93 | kwargs['mode'] = 'interactive'
94 | sliced = string[1:]
95 | elif main_key == '/':
96 | kwargs['mode'] = 'active'
97 | sliced = string[1:]
98 | else:
99 | sliced = string
100 | word = sliced
101 | #separating widgets.Widget descriptor from atributes
102 | split = word.split('$')
103 | if _is_object_notation(split[0]):
104 | word = ast.literal_eval(split[0])
105 | else:
106 | word = split[0]
107 | #string defines kwargs
108 |
109 | kwargs = shaoscript_to_kwargs(split[1], kwargs) if len(split) == 2 else kwargs
110 | return word, kwargs
111 |
112 | def _is_object_notation(string):
113 | """Checks if a string can be converted to object notation"""
114 | try:
115 | onw = ast.literal_eval(string)
116 | __ =object_notation(onw, {})
117 | return True
118 | except:
119 | return False
120 |
121 |
122 | def shaoscript_to_kwargs(string, kwargs):
123 | params = string.split('&')
124 | for par in params:
125 | key, val = decode_param(par)
126 | kwargs[key] = val
127 | #name infered from description
128 | if 'description' in kwargs.keys()\
129 | and 'name' not in kwargs.keys():
130 | kwargs['name'] = kwargs['description'].lower().replace(' ', '_')
131 | #id infered from name
132 | if 'name' in kwargs.keys()\
133 | and not 'id' in kwargs.keys():
134 | kwargs['id'] = kwargs['name'].lower().replace('_', '-')
135 | return kwargs
136 |
137 | def decode_param(string):
138 | """
139 | Converts a string representing a parameter in shaoscript syntax to a pair of key, value
140 | a valid parameter in shaoscript will have the following form:
141 |
142 | param --> 'name=val'
143 | There are some parameters that have custom parsing and are allowed aliases.
144 | The aliases are not case sensitive.
145 |
146 | Paramters(aliases): value parsing
147 | ---------------------------------
148 | 'options'('o', 'opt','opts'): ast.literal_eval
149 | 'description'('d','desc'): str
150 | 'id': str
151 | 'class_'('c','cls'): str
152 | 'visible'('vis'): boolean
153 | 'orientation'('ori','orient'): 'vertical','horizontal'
154 | 'name'('n'): str
155 | 'value'('val','v'): str
156 | val being a string means that non string values cannot be set this way.
157 | Use object notation in the definition of the widgets.Widget.
158 | 'placeholder'('ph','pholder'): str
159 | '_widgets.Titles'('widgets.Titles','t','widgets.Title','tit'): dict
160 | the val attribute will be the names of each widgets.Title separated by commas.
161 | no need to specify string simbols "" or '', as conversion will be taken
162 | care of internally.
163 |
164 |
165 | """
166 | key, val = string.split('=')
167 | key = key.lower()
168 | if key in ['o','opt','opts','options']:
169 | name = 'options'
170 | val = ast.literal_eval(val)
171 | elif key in ['d','desc', 'description']:
172 | name = 'description'
173 | elif key == 'id':
174 | name = 'id'
175 | elif key in ['continuous_update', 'cu','cont','cupdate']:
176 | name = 'continuous_update'
177 | val = True if val in ['1','True'] else False
178 | elif key in ['class_','cls']:
179 | name = 'class_'
180 | elif key in ['visible', 'vis']:
181 | name = 'visible'
182 | val = 'visible' if val in ['0', 'False','None'] else 'hidden'
183 | elif key in ['ori', 'orientation','orient']:
184 | name = 'orientation'
185 | if val in ['v','vert', 'vertical']:
186 | val = 'vertical'
187 | elif val in ['h','hori', 'horizontal']:
188 | val = 'horizontal'
189 | elif key in ['n', 'name']:
190 | name = 'name'
191 | elif key in ['v','val', 'value']:
192 | name = 'value'
193 | #val = ast.literal_eval(val)
194 | elif key in ['mode', 'm']:
195 | name = 'mode'
196 | elif key in ['placeholder','ph','pholder']:
197 | name='placeholder'
198 | elif key in ['_titles','title','t','widget_titles','tit']:
199 | name = '_titles'
200 | widgets.Titles_names = val.split(',')
201 | val = dict(zip(range(len(widgets.Titles_names)),widgets.Titles_names))
202 | else:
203 | name = key
204 | val = ast.literal_eval(val)
205 | return name, val
206 |
207 | def _string_to_wiget(word, kwargs):
208 | def create_colormap(kwargs):
209 | from shaolin.dashboards import colormap as cmap
210 | if 'id' in kwargs.keys():
211 | del kwargs['id']
212 | return cmap.ColormapPicker(**kwargs)
213 | """Creates a shaolin widgets.Widget from a string and a dictionary of kwargs"""
214 | assert isinstance(word, six.string_types)
215 | word = word.lower()
216 | #Layout
217 | #---------------------------------
218 | if word in ['c', 'col', 'column', 'vbox', 'v']:
219 | if not 'mode' in kwargs.keys():
220 | kwargs['mode'] = 'passive'
221 | return widgets.Widget(wid.VBox, **kwargs)
222 | elif word in ['r', 'row', 'HBox', 'box', 'h']:
223 | if not 'mode' in kwargs.keys():
224 | kwargs['mode'] = 'passive'
225 | return widgets.Widget(wid.HBox, **kwargs)
226 | #Markdown
227 | #--------------------------------
228 | elif word in ['widgets.SubSubTitle', 'h3', '###', 'subsub', 'ss']:
229 | if not 'mode' in kwargs.keys():
230 | kwargs['mode'] = 'passive'
231 | return widgets.SubSubTitle(**kwargs)
232 |
233 | elif word[:3] == '###':
234 | if not 'mode' in kwargs.keys():
235 | kwargs['mode'] = 'passive'
236 | if not 'name' in kwargs.keys():
237 | kwargs['name'] = word[3:].lower().replace(' ', '_')
238 | if not 'id' in kwargs.keys():
239 | kwargs['id'] = kwargs['name'].lower().replace('_', '-')
240 | return widgets.SubSubTitle(value=word[3:], **kwargs)
241 |
242 | elif word in ['widgets.SubTitle', 'h2', '##', 'sub', 's']:
243 | if not 'mode' in kwargs.keys():
244 | kwargs['mode'] = 'passive'
245 | return widgets.SubTitle(**kwargs)
246 |
247 | elif word[:2] == '##':
248 | if not 'mode' in kwargs.keys():
249 | kwargs['mode'] = 'passive'
250 | if not 'name' in kwargs.keys():
251 | kwargs['name'] = word[2:].lower().replace(' ', '_')
252 | if not 'id' in kwargs.keys():
253 | kwargs['id'] = kwargs['name'].lower().replace('_', '-')
254 | return widgets.SubTitle(value=word[2:], **kwargs)
255 |
256 | elif word in ['widgets.Title', 'h1', '#']:
257 | if not 'mode' in kwargs.keys():
258 | kwargs['mode'] = 'passive'
259 | return widgets.Title(**kwargs)
260 |
261 | elif word[:1] == '#':
262 | if not 'mode' in kwargs.keys():
263 | kwargs['mode'] = 'passive'
264 | if not 'name' in kwargs.keys():
265 | kwargs['name'] = word[1:].lower().replace(' ', '_')
266 | if not 'id' in kwargs.keys():
267 | kwargs['id'] = kwargs['name'].lower().replace('_', '-')
268 | return widgets.Title(value=word[1:], **kwargs)
269 |
270 | #Int and float
271 | #--------------------------------
272 | elif word in ['float_slider', 'floatslider', 'fsld', 'fs']:
273 | return widgets.Widget(wid.FloatSlider, **kwargs)
274 | elif word in ['float_text', 'floattext', 'ftxt', 'ft']:
275 | return widgets.Widget(wid.FloatText, **kwargs)
276 | elif word in ['int_slider', 'intslider', 'isld', 'is']:
277 | return widgets.Widget(wid.IntSlider, **kwargs)
278 | elif word in ['int_text', 'inttext', 'itxt', 'it']:
279 | return widgets.Widget(wid.IntText, **kwargs)
280 | #Range
281 | #--------------------------------
282 | elif word in ['float_range', 'floatprogress', 'fprog', 'fp']:
283 | return widgets.Widget(wid.FloatRangeSlider, **kwargs)
284 | elif word in ['int_range', 'intrange', 'irng', 'ir']:
285 | return widgets.Widget(wid.IntRangeSlider, **kwargs)
286 | #Progress
287 | #--------------------------------
288 | elif word in ['float_progress', 'floatprogress', 'fprog', 'fp']:
289 | return widgets.Widget(wid.FloatProgress, **kwargs)
290 | elif word in ['int_progress', 'intprogress', 'iprog', 'ip']:
291 | return widgets.Widget(wid.IntProgress, **kwargs)
292 | #Button
293 | #--------------------------------
294 | elif word in ['button', 'btn', 'b']:
295 | return widgets.Widget(wid.Button, **kwargs)
296 | #string and color
297 | #---------------
298 | elif word in ['text', 'txt','str','string']:
299 | return widgets.Widget(wid.Text, **kwargs)
300 | elif word in ['color', 'colorpicker','cp','cpicker']:
301 | return widgets.Widget(wid.ColorPicker, **kwargs)
302 | #colormap
303 |
304 |
305 | elif word in ['cm', 'cmap','colormap','cmappicker']:
306 | return create_colormap(kwargs)
307 |
308 | #Options for pseudo tabs creation
309 | #--------------------------------
310 | #"""
311 | #elif word in ['radio_display_selection','r_ds','radio_ds']:
312 | # return RadioDisplaySelection(**kwargs)
313 | #elif word in ['toggle_display_selection','t_ds','toggle_ds']:
314 | # return ToggleDisplaySelection(**kwargs)
315 | #elif word in ['display_selection','ds','dsel']:
316 | # return DisplaySelection(**kwargs)
317 |
318 | #"""
319 | #Selectors
320 | #--------------------------
321 | elif word in ['select_multiple', 'selmul', 'sm']:
322 | return widgets.Widget(wid.SelectMultiple, **kwargs)
323 | elif word in ['select', 'sel']:
324 | return widgets.Widget(wid.Select, **kwargs)
325 | elif word in ['dropdown', 'dd', 'ddown']:
326 | return widgets.Widget(wid.Dropdown, **kwargs)
327 | elif word in ['selection_slider', 'selslider', 'ss']:
328 | return widgets.Widget(wid.SelectionSlider, **kwargs)
329 | elif word in ['toggle_button', 'toggle', 'tog']:
330 | return widgets.Widget(wid.ToggleButton, **kwargs)
331 | elif word in ['toggle_buttons', 'toggles', 'togs']:
332 | return widgets.Widget(wid.ToggleButtons, **kwargs)
333 | elif word in ['radio_buttons', 'radio', 'rad','rs']:
334 | return widgets.Widget(wid.RadioButtons, **kwargs)
335 | elif word in ['html', 'HTML']:
336 | return widgets.Widget(wid.HTML, **kwargs)
337 | elif word in ['TextArea', 'texta', 'textarea', 'text_area']:
338 | return widgets.Widget(wid.Textarea, **kwargs)
339 |
340 | elif word in ['tex','latex']:
341 | kwargs['value'] = '$$'+str(kwargs['value'])+'$$'
342 | if not 'mode' in kwargs.keys():
343 | kwargs['mode'] = 'passive'
344 | return widgets.Widget(wid.Label, **kwargs)
345 | elif word in ['tab','t','tabs']:
346 | if not 'mode' in kwargs.keys():
347 | kwargs['mode'] = 'passive'
348 | return widgets.Widget(wid.Tab, **kwargs)
349 | elif word in ['accordion','accord','tabs','ac','a']:
350 | if not 'mode' in kwargs.keys():
351 | kwargs['mode'] = 'passive'
352 | return widgets.Widget(wid.Accordion, **kwargs)
353 |
354 | elif word in ['datetime','datepicker','date','dpicker','dp']:
355 | return widgets.Widget(wid.DatePicker, **kwargs)
356 | else:
357 | if not 'value' in kwargs.keys():
358 | kwargs['value'] = word
359 | if not 'mode' in kwargs.keys():
360 | kwargs['mode'] = 'passive'
361 | return widgets.Widget(wid.Label, **kwargs)
362 | else:
363 | return widgets.Widget(wid.Label, **kwargs)
364 |
--------------------------------------------------------------------------------
/shaolin/dashboards/bokeh.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | Created on Wed Jun 1 23:37:47 2016
4 |
5 | @author: Guillem Duran Ballester for HCSoft
6 | """
7 | import pandas as pd
8 | from IPython.core.display import display, clear_output
9 | from bokeh.models import HoverTool
10 | import bokeh.models.sources as bks
11 | from bokeh.plotting import figure, show
12 | from bokeh.io import push_notebook, output_notebook
13 | from bokeh.embed import notebook_div
14 | from shaolin.core.dashboard import Dashboard, ToggleMenu
15 | from shaolin.dashboards.plot_mappers import PlotMapper
16 | from shaolin.core.shaoscript import shaoscript
17 |
18 | class BokehDataFrameTooltip(Dashboard):
19 |
20 | def __init__(self, data, mode='interactive', **kwargs):
21 | self._data = data
22 | dash = ['c$N=tooltip',
23 | ['###Tolltip$N=title',
24 | '@selmul$n=tooltip_cols&d=Tooltip info&o='+str(tuple(data.columns.values))
25 |
26 | ]
27 | ]
28 | self.output = data.copy()
29 | Dashboard.__init__(self, dash, mode=mode, **kwargs)
30 | self.tooltip_cols.value = tuple(data.columns.values)
31 | self.observe(self.update)
32 | self.update()
33 |
34 | @property
35 | def data(self):
36 | return self._data
37 | @data.setter
38 | def data(self, val):
39 | self._data = val
40 | self.update()
41 | def update(self, _=None):
42 | self.output = self._data[list(self.tooltip_cols.value)]
43 |
44 | def create_tooltip(self):
45 | """A function for creating a tooltip suitable for the plot. This means
46 | that by default all kinds of plots should try to include tooltips
47 | """
48 | return [("index", "$index")] + [(x, '@'+x) for x in self.output.columns]
49 |
50 | class ScatterPlot(ToggleMenu):
51 |
52 | def __init__(self, data,name='scatter_plot', **kwargs):
53 | output_notebook(hide_banner=True)
54 | self._data = data
55 | mapper = PlotMapper(data, button_type='ddown',button_pos='top', name='mapper', mode='interactive')
56 | if isinstance(data, pd.DataFrame):
57 | tooltip = BokehDataFrameTooltip(data, name='tooltip', mode='interactive')
58 | ToggleMenu.__init__(self, children=[mapper,tooltip], name=name,**kwargs)
59 | else:
60 | ToggleMenu.__init__(self, children=[mapper], name=name,**kwargs)
61 | self.buttons.value = 'mapper'
62 | self.mapper.buttons.value = 'y'
63 | if isinstance(self._data,pd.DataFrame):
64 | self.mapper.y.data_slicer.columns_slicer.dd_selector.value =\
65 | self.mapper.y.data_slicer.columns_slicer.dd_selector.target.options[1]
66 | self.observe(self.update)
67 | self.mapper.marker.marker_type.observe(self._on_marker_change)
68 |
69 | self.update_source_df()
70 | self.init_plot()
71 | self.update()
72 |
73 | def _on_marker_change(self, _=None):
74 | clear_output()
75 | self.init_plot()
76 | self.update()
77 | return display(show(self.plot))
78 |
79 | @property
80 | def data(self):
81 | return self._data
82 |
83 | def update_source_df(self):
84 | """Datasources for plots managing"""
85 | if isinstance(self._data, pd.DataFrame):
86 | self.output= self.mapper.output.join(self.tooltip.output)
87 | else:
88 | self.output= self.mapper.output
89 |
90 | def update_tooltips(self):
91 | """Update tooltip data and inject it into the plot tooltips"""
92 | if isinstance(self._data, pd.DataFrame):
93 | self.plot.tools[-1].tooltips = self.tooltip.create_tooltip()
94 |
95 | def update(self, _=None):
96 | """Set up all the combined elements needed for the plot"""
97 | self.update_source_df()
98 | if isinstance(self._data, pd.DataFrame):
99 | self.update_tooltips()
100 | self.push_data()
101 |
102 | def push_data(self):
103 | """A function to push the content of the source DataFrame
104 | to a specific plot source
105 | """
106 | self.bokeh_source.data = dict([(x, self.output[x].values) for x in self.output.columns])
107 | self.plot.xaxis.axis_label = self.mapper.x.data_slicer.description
108 | self.plot.yaxis.axis_label = self.mapper.y.data_slicer.description
109 |
110 | push_notebook()
111 |
112 | def init_plot(self):
113 | """Handle plot init"""
114 | self.bokeh_source = bks.ColumnDataSource(dict([(x, self.output[x].values)\
115 | for x in self.output.columns]))
116 | if isinstance(self._data, pd.DataFrame):
117 | tooltip = self.tooltip.create_tooltip()
118 |
119 | self.plot = figure(title="Scatter plot", width=600, height=600, webgl=False,
120 | tools="pan,wheel_zoom,box_zoom,reset,resize,crosshair",)
121 | self.plot.xaxis.axis_label = self.mapper.x.data_slicer.description
122 | self.plot.yaxis.axis_label = self.mapper.y.data_slicer.description
123 |
124 | #marker = self.marker_free_sel.marker.value
125 |
126 | _scatter = self.plot.scatter(source=self.bokeh_source,
127 | x='x', y='y',
128 | line_color='line_color',
129 | fill_color='fill_color',
130 | fill_alpha='fill_alpha',
131 | line_alpha='line_alpha',
132 | size='size',
133 | line_width='line_width',
134 | marker=self.mapper.marker.marker_type.value
135 |
136 | )
137 | if isinstance(self._data, pd.DataFrame):
138 | self.plot.add_tools(HoverTool(tooltips=tooltip, renderers=[_scatter]))
139 |
140 | def show(self):
141 | return display(self.widget, show(self.plot))
142 |
143 | @property
144 | def snapshot(self, name='bokeh_scatter'):
145 | html = notebook_div(self.plot)
146 | widget = shaoscript('html$N='+name)
147 | widget.value = html
148 | return widget
149 |
150 | class GraphPlotBokeh(ToggleMenu):
151 |
152 | def __init__(self, gc, name='scatter_plot', **kwargs):
153 | node_mapper_dict = {'size':{'max':100,
154 | 'min':5,
155 | 'step':0.5,
156 | 'high':75,
157 | 'low':25,
158 | 'default':60,
159 | 'map_data':False,
160 | 'fixed_active':False,
161 | },
162 | 'line_width':{'max':50,
163 | 'min':0,
164 | 'step':0.5,
165 | 'high':5,
166 | 'low':1,
167 | 'default':2,
168 | 'map_data':False,
169 | 'fixed_active':False,
170 | },
171 | 'fill_alpha':{'max':1.0,
172 | 'min':0.,
173 | 'step':0.05,
174 | 'high':0.95,
175 | 'low':0.3,
176 | 'default':1.,
177 | 'map_data':False,
178 | 'fixed_active':False,
179 | },
180 | 'line_alpha':{'max':1.0,
181 | 'min':0.,
182 | 'step':0.05,
183 | 'high':0.95,
184 | 'low':0.3,
185 | 'default':1.,
186 | 'map_data':False,
187 | 'fixed_active':False,
188 | },
189 | 'line_color':{'default_color':'black','map_data':False,'step':0.05,'min':0.0,'low':0.0},
190 | 'fill_color':{'default_color':'#11D4CA','map_data':False,'step':0.05,'min':0.0,'low':0.0}
191 | }
192 | edge_mapper_dict = {'size':{'max':100,
193 | 'min':5,
194 | 'step':0.5,
195 | 'high':20,
196 | 'low':7,
197 | 'default':7,
198 | 'map_data':False,
199 | 'fixed_active':False,
200 | },
201 | 'line_width':{'max':50,
202 | 'min':0,
203 | 'step':0.5,
204 | 'high':5,
205 | 'low':1,
206 | 'default':2,
207 | 'map_data':False,
208 | 'fixed_active':False,
209 | },
210 | 'fill_alpha':{'max':1.0,
211 | 'min':0.,
212 | 'step':0.05,
213 | 'high':0.95,
214 | 'low':0.3,
215 | 'default':1.,
216 | 'map_data':False,
217 | 'fixed_active':False,
218 | },
219 | 'line_alpha':{'max':1.0,
220 | 'min':0.,
221 | 'step':0.05,
222 | 'high':0.95,
223 | 'low':0.3,
224 | 'default':1.,
225 | 'map_data':False,
226 | 'fixed_active':False,
227 | },
228 | 'line_color':{'default_color':'black','map_data':False,'step':0.05,'min':0.0,'low':0.0},
229 | 'fill_color':{'default_color':'#EDB021','map_data':False,'step':0.05,'min':0.0,'low':0.0}
230 | }
231 | gc.name = 'gc'
232 | output_notebook(hide_banner=True)
233 | edge_mapper_data = self.prepare_edge_mapper_data(gc)
234 | node_mapper = PlotMapper(gc.node, mapper_dict=node_mapper_dict, button_type='ddown',button_pos='top', name='node_mapper', mode='interactive')
235 | edge_mapper = PlotMapper(edge_mapper_data, mapper_dict=edge_mapper_dict, button_type='ddown',button_pos='top', name='edge_mapper', mode='interactive')
236 | node_tooltip_data = gc.node.combine_first(gc.node_metrics.T)
237 | node_tooltip = BokehDataFrameTooltip(node_tooltip_data, name='node_tooltip')
238 | edge_tooltip = BokehDataFrameTooltip(edge_mapper_data, name='edge_tooltip')
239 | ToggleMenu.__init__(self,
240 | children=[gc,node_mapper,
241 | edge_mapper,
242 | node_tooltip,
243 | edge_tooltip],
244 | name=name,**kwargs)
245 |
246 | self.observe(self.update)
247 | self.gc.calculate.observe(self.update)
248 | self.node_mapper.marker.marker_type.observe(self._on_marker_change)
249 | self.edge_mapper.marker.marker_type.observe(self._on_marker_change)
250 | self.update_source_df()
251 | self.init_plot()
252 | self.update()
253 | self._init_layout()
254 |
255 | def prepare_edge_mapper_data(self,gc):
256 | dft = gc.edge.to_frame().reset_index()
257 | ti = list(zip(dft.minor.values,dft.major.values))
258 | dft.index = ti
259 | dft = dft.drop(['major','minor'],axis=1)
260 | return dft.ix[gc.G.edges()].copy()
261 |
262 | def _init_layout(self):
263 | params = ['size', 'line_width', 'fill_alpha', 'line_alpha', 'line_color', 'fill_color']
264 | for target in ['node','edge']:
265 | mapper = getattr(self,target+'_mapper')
266 | for p in params:
267 | getattr(mapper,p).data_slicer.index_slicer.visible = False
268 |
269 | def update_source_df(self):
270 | """Datasources for plots managing"""
271 | def index_to_columns(df):
272 | old_index = df.index
273 | new_index = pd.MultiIndex.from_tuples(df.index)
274 | df.index = new_index
275 | df = df.reset_index()
276 | df.index = old_index
277 | columns = df.columns.values
278 | columns[:2] = ['major','minor']
279 | df.columns = columns
280 | return df
281 | def fix_pos_index(edge_pos,edge_source):
282 | changed = set(edge_source.index) - set(edge_pos.index)
283 | edge_source.index = pd.MultiIndex.from_tuples(edge_source.index)
284 | edge_pos.index = pd.MultiIndex.from_tuples(edge_pos.index)
285 | for e in changed:
286 | inv = (e[1],e[0])
287 | edge_pos.loc[inv,'minor'] = e[1]
288 | edge_pos.loc[inv,'major'] = e[0]
289 | return edge_pos
290 | self.node_source= self.node_mapper.output.join(self.node_tooltip.output)
291 | #self.edge_tooltip.output.index = pd.MultiIndex.from_tuples(self.edge_tooltip.output.index.values)
292 | #self.edge_mapper.output.index = pd.MultiIndex.from_tuples(self.edge_mapper.output.index.values)
293 | self.edge_source= self.edge_mapper.output.join(self.edge_tooltip.output)
294 |
295 | node_pos = self.gc.layout.node['2d'].dropna(axis=1).copy()
296 | edge_pos = self.gc.layout.edge['2d'].copy()
297 | edge_pos = index_to_columns(edge_pos)
298 | edge_source = index_to_columns(self.edge_source)
299 | edge_pos = fix_pos_index(edge_pos,edge_source)
300 | self.output_node = pd.concat([self.node_source, node_pos], axis=1).fillna('NaN').copy()
301 | self.output_edge = edge_source.merge(edge_pos,on=['major','minor'], left_index=True).fillna('NaN').copy()#edge_pos.merge(self.edge_source,on=['major','minor'],left_index=True)
302 |
303 |
304 | def update_mappers(self):
305 | dft = self.gc.edge.to_frame().reset_index()
306 | ti = list(zip(dft.minor.values,dft.major.values))
307 | dft.index = ti
308 | dft = dft.drop(['major','minor'],axis=1)
309 | edge_mapper_data = dft.ix[self.gc.G.edges()].copy()
310 | self.edge_mapper.data = edge_mapper_data
311 | self.node_mapper.data = self.gc.node
312 | self.node_tooltip.data = self.gc.node_metrics.combine_first(self.gc.node.T).T
313 | self.edge_tooltip.data = edge_mapper_data
314 |
315 | def update_tooltips(self):
316 | """Update tooltip data and inject it into the plot tooltips"""
317 | self.plot.tools[-1].tooltips = self.edge_tooltip.create_tooltip()
318 | self.plot.tools[-2].tooltips = self.node_tooltip.create_tooltip()
319 |
320 | def update(self, _=None):
321 | """Set up all the combined elements needed for the plot"""
322 | self.update_mappers()
323 | self.update_source_df()
324 | self.update_tooltips()
325 | self.push_data()
326 |
327 | def push_data(self):
328 | """A function to push the content of the source DataFrame
329 | to a specific plot source
330 | """
331 | self.node_bokeh_source.data = dict([(x, self.output_node[x].values) for x in self.output_node.columns])
332 | self.edge_bokeh_source.data = dict([(x, self.output_edge[x].values) for x in self.output_edge.columns])
333 |
334 |
335 | push_notebook()
336 |
337 | def _on_marker_change(self, _=None):
338 | clear_output()
339 | self.init_plot()
340 | self.update()
341 | return display(show(self.plot))
342 |
343 | def init_plot(self):
344 | """Handle plot init"""
345 | self.node_bokeh_source = bks.ColumnDataSource(dict([(x,
346 | self.output_node[x].values)\
347 | for x in self.output_node.columns]))
348 | self.edge_bokeh_source = bks.ColumnDataSource(dict([(x,
349 | self.output_edge[x].values)\
350 | for x in self.output_edge.columns]))
351 | n_ttip = self.node_tooltip.create_tooltip()
352 | e_ttip = self.edge_tooltip.create_tooltip()
353 |
354 | self.plot = figure(title="Graph plot", width=600, height=600, webgl=False,
355 | tools="pan,wheel_zoom,box_zoom,reset,resize,crosshair",)
356 |
357 | #node_marker = 'circle'#self.node_marker_free_sel.marker.value
358 | #edge_marker = self.edge_marker_free_sel.marker.value
359 |
360 | self.plot.segment('x0', 'y0',
361 | 'x1', 'y1',
362 | color='line_color',
363 | line_width='line_width',
364 | alpha='line_alpha',
365 | source=self.edge_bokeh_source)
366 |
367 | edg_center = self.plot.scatter(source=self.edge_bokeh_source,
368 | x='cx', y='cy',
369 | line_color='line_color',
370 | fill_color='fill_color',
371 | alpha='fill_alpha',
372 | size='size',
373 | line_width='line_width',
374 | marker=self.edge_mapper.marker.marker_type.value
375 | )#,
376 | #marker=edge_marker)
377 |
378 | nod = self.plot.scatter(source=self.node_bokeh_source,
379 | x='x', y='y',
380 | line_color='line_color',
381 | fill_color='fill_color',
382 | fill_alpha='fill_alpha',
383 | size='size',
384 | line_width='line_width',#,
385 | marker=self.node_mapper.marker.marker_type.value)
386 |
387 | self.plot.text(source=self.node_bokeh_source,
388 | x='x', y='y',
389 | text='label',
390 | text_align='center')
391 |
392 | self.plot.add_tools(HoverTool(tooltips=n_ttip, renderers=[nod]))
393 | self.plot.add_tools(HoverTool(tooltips=e_ttip, renderers=[edg_center]))
394 | @property
395 | def snapshot(self, name='bokeh_scatter'):
396 | html = notebook_div(self.plot)
397 | widget = shaoscript('html$N='+name)
398 | widget.value = html
399 | return widget
400 |
401 | def show(self):
402 | return display(self.widget, show(self.plot))
--------------------------------------------------------------------------------