├── js ├── src │ ├── styles │ │ ├── .gitignore │ │ ├── ipywidgets │ │ │ ├── nouislider.css │ │ │ ├── nouislider.less │ │ │ └── nouislider-custom.css │ │ ├── style.css │ │ ├── menu_div.css │ │ ├── README.md │ │ ├── icons │ │ │ ├── minus.svg │ │ │ ├── small-up.svg │ │ │ ├── small-down.svg │ │ │ ├── small-left.svg │ │ │ ├── tree-open.svg │ │ │ ├── small-right.svg │ │ │ ├── tree-closed.svg │ │ │ ├── tick.svg │ │ │ ├── tree-indeterminate.svg │ │ │ ├── filter.svg │ │ │ ├── aggregation.svg │ │ │ ├── plus.svg │ │ │ ├── column.svg │ │ │ ├── star.svg │ │ │ ├── cancel.svg │ │ │ ├── not-allowed.svg │ │ │ ├── paste.svg │ │ │ ├── copy.svg │ │ │ ├── folder.svg │ │ │ ├── next.svg │ │ │ ├── previous.svg │ │ │ ├── menu.svg │ │ │ ├── folder-open.svg │ │ │ ├── cross.svg │ │ │ ├── first.svg │ │ │ ├── contracted.svg │ │ │ ├── pin.svg │ │ │ ├── checkbox-unchecked.svg │ │ │ ├── checkbox-unchecked-readonly.svg │ │ │ ├── expanded.svg │ │ │ ├── last.svg │ │ │ ├── checkbox-checked.svg │ │ │ ├── checkbox-indeterminate.svg │ │ │ ├── checkbox-checked-readonly.svg │ │ │ ├── checkbox-indeterminate-readonly.svg │ │ │ ├── pivot.svg │ │ │ ├── columns.svg │ │ │ ├── eye.svg │ │ │ ├── indeterminate.svg │ │ │ ├── cut.svg │ │ │ ├── group.svg │ │ │ ├── eye-slash.svg │ │ │ ├── arrows.svg │ │ │ ├── asc.svg │ │ │ ├── desc.svg │ │ │ ├── left.svg │ │ │ ├── right.svg │ │ │ ├── grip.svg │ │ │ ├── none.svg │ │ │ └── loading.svg │ │ ├── _ag-theme-classic-vars.scss │ │ ├── switch_edit.css │ │ └── switch_delete.css │ ├── widget.js │ ├── index.js │ ├── embed.js │ ├── extension.js │ ├── widget_compress.js │ ├── labplugin.js │ └── widget_json.js ├── .prettierrc ├── README.md ├── .babelrc ├── .eslintrc.json ├── LICENSE └── package.json ├── setup.cfg ├── docs ├── .markdownlint.json ├── notebooks │ ├── requirements.txt │ ├── push-binder.sh │ ├── templates │ │ └── index.tpl.html │ └── demo-ipyaggrid-javascript.ipynb ├── content │ ├── .vuepress │ │ ├── public │ │ │ ├── favicon-16x16.png │ │ │ ├── jupyter-plus-aggrid.png │ │ │ └── msd-logo.svg │ │ ├── override.styl │ │ ├── components │ │ │ ├── demo1.vue │ │ │ ├── export-grid-1.vue │ │ │ ├── export-grid-2.vue │ │ │ └── demo2.vue │ │ └── config.js │ ├── code-snippets │ │ ├── columns-size.python │ │ ├── show-toggle-edit.python │ │ ├── index.python │ │ ├── excel-csv.python │ │ ├── show-toggle-delete-2.python │ │ ├── grid-size.python │ │ ├── paste-from-excel.python │ │ ├── multiindex.python │ │ ├── show-toggle-delete.python │ │ ├── sync-on-edit.python │ │ ├── quick-filter.python │ │ ├── sync-grid.python │ │ ├── themes.python │ │ ├── custom-css.python │ │ ├── status-bar.python │ │ ├── collapse-expand.python │ │ ├── export-grid.python │ │ ├── simple-highlight.python │ │ ├── custom-menu-1.python │ │ ├── multi-options.python │ │ └── simple-grid.python │ ├── guide │ │ └── install.md │ ├── README.md │ ├── overview │ │ ├── purpose.md │ │ └── ag-Grid.md │ └── dev │ │ ├── publish.md │ │ └── doc.md ├── package.json └── README.md ├── test-zone └── js │ ├── .babelrc │ ├── .gitignore │ ├── .prettierrc │ ├── src │ ├── entry.js │ ├── index.html │ ├── icons │ │ ├── minus.svg │ │ ├── small-up.svg │ │ ├── tree-open.svg │ │ ├── small-down.svg │ │ ├── small-left.svg │ │ ├── small-right.svg │ │ ├── tree-closed.svg │ │ ├── tick.svg │ │ ├── filter.svg │ │ ├── tree-indeterminate.svg │ │ ├── aggregation.svg │ │ ├── plus.svg │ │ ├── star.svg │ │ ├── column.svg │ │ ├── cancel.svg │ │ ├── not-allowed.svg │ │ ├── paste.svg │ │ ├── copy.svg │ │ ├── folder.svg │ │ ├── previous.svg │ │ ├── next.svg │ │ ├── menu.svg │ │ ├── folder-open.svg │ │ ├── first.svg │ │ ├── contracted.svg │ │ ├── cross.svg │ │ ├── pin.svg │ │ ├── checkbox-unchecked.svg │ │ ├── checkbox-unchecked-readonly.svg │ │ ├── expanded.svg │ │ ├── last.svg │ │ ├── checkbox-checked.svg │ │ ├── checkbox-indeterminate.svg │ │ ├── checkbox-checked-readonly.svg │ │ ├── checkbox-indeterminate-readonly.svg │ │ ├── pivot.svg │ │ ├── columns.svg │ │ ├── eye.svg │ │ ├── indeterminate.svg │ │ ├── cut.svg │ │ ├── group.svg │ │ ├── eye-slash.svg │ │ ├── arrows.svg │ │ ├── asc.svg │ │ ├── desc.svg │ │ ├── left.svg │ │ ├── right.svg │ │ ├── grip.svg │ │ ├── none.svg │ │ └── loading.svg │ ├── _ag-theme-classic-vars.scss │ └── style.scss │ ├── README.md │ ├── .eslintrc.json │ ├── package.json │ └── webpack.config.js ├── ipyaggrid ├── flexbox │ └── __init__.py ├── magics │ ├── __init__.py │ └── custom_magics.py ├── ipyaggrid.json ├── js │ ├── yarn.lock │ └── helpersBuiltin.js ├── __init__.py ├── display.py ├── community.py └── __meta__.py ├── requirements.txt ├── ipyaggrid.json ├── CHANGELOG ├── pyproject.toml ├── install.json ├── environment.yml ├── tests ├── ui │ └── snapshots │ │ └── tests │ │ └── ui │ │ └── jupyter_test.py │ │ ├── test_svg_icons-voila-chromium-linux-reference.png │ │ ├── test_svg_icons-solara-chromium-linux-reference.png │ │ ├── test_widget_aggrid-solara-chromium-linux-reference.png │ │ ├── test_widget_aggrid-voila-chromium-linux-reference.png │ │ ├── test_svg_icons-jupyter_lab-chromium-linux-reference.png │ │ ├── test_widget_aggrid-jupyter_lab-chromium-linux-reference.png │ │ ├── test_svg_icons-jupyter_notebook-chromium-linux-reference.png │ │ └── test_widget_aggrid-jupyter_notebook-chromium-linux-reference.png └── unit │ └── test_utils.py ├── MANIFEST.in ├── release.sh ├── .bumpversion.cfg ├── .github └── ci_version.py ├── .gitignore ├── LICENSE ├── README.md ├── data └── Cars.json └── setup.py /js/src/styles/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.map -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [bdist_wheel] 2 | universal=1 3 | -------------------------------------------------------------------------------- /js/src/styles/ipywidgets/nouislider.css: -------------------------------------------------------------------------------- 1 | 404: Not Found -------------------------------------------------------------------------------- /js/src/widget.js: -------------------------------------------------------------------------------- 1 | export * from './widget_grid'; 2 | -------------------------------------------------------------------------------- /docs/.markdownlint.json: -------------------------------------------------------------------------------- 1 | { 2 | "default": true 3 | } 4 | -------------------------------------------------------------------------------- /test-zone/js/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"] 3 | } 4 | -------------------------------------------------------------------------------- /ipyaggrid/flexbox/__init__.py: -------------------------------------------------------------------------------- 1 | from .flexbox_css import FlexboxCSS 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ipywidgets>=7.4.0 2 | pandas 3 | simplejson>=3.13.2 4 | -------------------------------------------------------------------------------- /ipyaggrid/magics/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from .custom_magics import CustomMagics 3 | -------------------------------------------------------------------------------- /test-zone/js/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | node_modules/ 3 | dist/ 4 | 5 | package-lock.json 6 | -------------------------------------------------------------------------------- /docs/notebooks/requirements.txt: -------------------------------------------------------------------------------- 1 | notebook>=5.6.0 2 | ipyaggrid==0.2.2 3 | bqplot==0.10.5 -------------------------------------------------------------------------------- /ipyaggrid.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_extensions": { 3 | "ipyaggrid/extension": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /ipyaggrid/ipyaggrid.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_extensions": { 3 | "ipyaggrid/extension": true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /js/src/styles/style.css: -------------------------------------------------------------------------------- 1 | @import './ipywidgets/materialcolors.css'; 2 | @import './ipywidgets/nouislider.less'; 3 | -------------------------------------------------------------------------------- /ipyaggrid/js/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | -------------------------------------------------------------------------------- /js/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 4, 4 | "singleQuote": true, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /js/README.md: -------------------------------------------------------------------------------- 1 | # ipyaggrid 2 | 3 | See documentation: [widgetti.github.io/ipyaggrid/](https://widgetti.github.io/ipyaggrid/). 4 | -------------------------------------------------------------------------------- /CHANGELOG: -------------------------------------------------------------------------------- 1 | Version 0.2.1 2 | 3 | - Add Jupyter Lab support. 4 | 5 | Next version milestone: 6 | 7 | - Fix changes due to aggrid update. -------------------------------------------------------------------------------- /test-zone/js/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "tabWidth": 4, 4 | "singleQuote": true, 5 | "trailingComma": "es5" 6 | } 7 | -------------------------------------------------------------------------------- /docs/content/.vuepress/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/docs/content/.vuepress/public/favicon-16x16.png -------------------------------------------------------------------------------- /docs/content/.vuepress/public/jupyter-plus-aggrid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/docs/content/.vuepress/public/jupyter-plus-aggrid.png -------------------------------------------------------------------------------- /js/src/styles/menu_div.css: -------------------------------------------------------------------------------- 1 | .menu-div { 2 | font-family: Arial, Helvetica, sans-serif; 3 | font-size: 11pt; 4 | } 5 | 6 | .menu-div > div > * { 7 | margin: 5px; 8 | } -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["jupyter_packaging~=0.7.9", "jupyterlab>=3.0.0,==3.*", "setuptools>=40.8.0", "wheel"] 3 | build-backend = "setuptools.build_meta" 4 | -------------------------------------------------------------------------------- /install.json: -------------------------------------------------------------------------------- 1 | { 2 | "packageManager": "python", 3 | "packageName": "ipyaggrid", 4 | "uninstallInstructions": "Use your Python package manager (pip, conda, etc.) to uninstall the package ipyaggrid" 5 | } -------------------------------------------------------------------------------- /js/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env", 5 | { 6 | "useBuiltIns": "usage", 7 | "corejs": 3, 8 | "modules": false 9 | } 10 | ] 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: dev-ipyaggrid 2 | channels: 3 | - https://conda.anaconda.org/conda-forge/ 4 | dependencies: 5 | - python>=3.10 6 | - jupyterlab 7 | - nodejs>=18.9.0 8 | - pip 9 | - pip: 10 | - notebook 11 | -------------------------------------------------------------------------------- /test-zone/js/src/entry.js: -------------------------------------------------------------------------------- 1 | require('./ag-grid.scss'); 2 | require('./theme-material.scss'); 3 | require('./theme-dark.scss'); 4 | require('./theme-blue.scss'); 5 | require('./theme-bootstrap.scss'); 6 | require('./theme-fresh.scss'); 7 | -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-voila-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-voila-chromium-linux-reference.png -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-solara-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-solara-chromium-linux-reference.png -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-solara-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-solara-chromium-linux-reference.png -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-voila-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-voila-chromium-linux-reference.png -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-jupyter_lab-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-jupyter_lab-chromium-linux-reference.png -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-jupyter_lab-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-jupyter_lab-chromium-linux-reference.png -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | 2 | # js 3 | recursive-include ipyaggrid/nbextension *.* 4 | recursive-include ipyaggrid/labextension *.* 5 | recursive-include ipyaggrid/js *.js 6 | 7 | # Misc 8 | include requirements.txt 9 | include LICENSE 10 | global-exclude *.py[co] 11 | -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-jupyter_notebook-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_svg_icons-jupyter_notebook-chromium-linux-reference.png -------------------------------------------------------------------------------- /tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-jupyter_notebook-chromium-linux-reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/widgetti/ipyaggrid/master/tests/ui/snapshots/tests/ui/jupyter_test.py/test_widget_aggrid-jupyter_notebook-chromium-linux-reference.png -------------------------------------------------------------------------------- /docs/content/code-snippets/columns-size.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [{'field': c, 'width':500} for c in dfm.columns] 3 | 4 | grid_options = { 5 | 'columnDefs' : column_defs, 6 | } 7 | 8 | g = Grid(grid_data=dfm, 9 | grid_options=grid_options, 10 | columns_fit="auto") 11 | g 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/show-toggle-edit.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [{'field': c} for c in dfm.columns[:11]] 3 | 4 | grid_options = { 5 | 'columnDefs' : column_defs, 6 | } 7 | 8 | g = Grid(grid_data=dfm, 9 | grid_options=grid_options, 10 | show_toggle_edit=True) 11 | g 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/index.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [{'field': dfm.index.name}] + [{'field': c} for c in dfm.columns[:3]] 3 | 4 | grid_options = { 5 | 'columnDefs' : column_defs, 6 | } 7 | 8 | g = Grid(grid_data=dfm, 9 | grid_options=grid_options, 10 | index=True) 11 | g 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/excel-csv.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'field': c} for c in dfm.columns[:7]] 2 | 3 | grid_options = { 4 | 'columnDefs' : column_defs, 5 | } 6 | 7 | g = Grid(grid_data=dfm, 8 | grid_options=grid_options, 9 | export_csv=True, 10 | export_excel=True) 11 | g 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/show-toggle-delete-2.python: -------------------------------------------------------------------------------- 1 | 2 | grid_options = { 3 | 'columnDefs' : column_defs, 4 | 'enableRangeSelection': True, 5 | } 6 | 7 | g = Grid(grid_data=dfm, 8 | grid_options=grid_options, 9 | quick_filter=False, 10 | show_toggle_delete=True) 11 | g 12 | -------------------------------------------------------------------------------- /test-zone/js/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/grid-size.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'field': c} for c in dfm.columns[:3]] 2 | 3 | grid_options = { 4 | 'columnDefs' : column_defs, 5 | } 6 | 7 | g = Grid(grid_data=dfm, 8 | width=600, 9 | height=500, 10 | grid_options=grid_options, 11 | center=True) 12 | g 13 | -------------------------------------------------------------------------------- /docs/content/code-snippets/paste-from-excel.python: -------------------------------------------------------------------------------- 1 | grid_options = { 2 | 'columnDefs':[{'field':''}], 3 | 'enableFilter':True, 4 | 'enableSorting':True, 5 | 'animateRows':True, 6 | } 7 | 8 | g = Grid(grid_options=grid_options, 9 | grid_data=[{'':''}], 10 | paste_from_excel=True) 11 | g 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/multiindex.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [] 3 | 4 | grid_options = { 5 | 'columnDefs' : column_defs, 6 | 'suppressColumnVirtualisation':True, 7 | } 8 | 9 | g = Grid(grid_data=df, 10 | grid_options=grid_options, 11 | keep_multiindex=True, 12 | columns_fit='auto') 13 | g 14 | -------------------------------------------------------------------------------- /js/src/styles/README.md: -------------------------------------------------------------------------------- 1 | ## ag-theme-excel 2 | 3 | **ag-theme-excel** is a custom theme included in ipyaggrid. 4 | 5 | To build it run in this folder: 6 | 7 | ```bash 8 | npx sass ag-theme-excel.scss ag-theme-excel.css 9 | ``` 10 | 11 | Only the resulting file `ag-theme-excel.css` is used in the the js part of ipyaggrid. 12 | 13 | -------------------------------------------------------------------------------- /docs/content/code-snippets/show-toggle-delete.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [{'field': c} for c in dfm.columns[:7]] 3 | 4 | grid_options = { 5 | 'columnDefs' : column_defs, 6 | 'rowSelection': 'multiple', 7 | } 8 | 9 | g = Grid(grid_data=dfm, 10 | grid_options=grid_options, 11 | show_toggle_delete=True) 12 | g 13 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e -o pipefail 3 | # usage: ./release minor -n 4 | version=$(bump2version --dry-run --list $* | grep new_version | sed -r s,"^.*=",,) 5 | echo Version tag v$version 6 | bumpversion $* --verbose 7 | (cd js && npm install) 8 | git add js/package-lock.json && git commit --amend --no-edit 9 | git push upstream master v$version 10 | -------------------------------------------------------------------------------- /js/src/index.js: -------------------------------------------------------------------------------- 1 | // Entry point for the notebook bundle containing custom model definitions. 2 | // Export widget models and views, and the npm package version number. 3 | const baseUrl = document.querySelector('body').getAttribute('data-base-url'); 4 | __webpack_public_path__ = `${baseUrl}nbextensions/ipyaggrid/`; 5 | 6 | export * from './widget'; 7 | export { version } from '../package.json'; 8 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "devDependencies": { 3 | "vuepress": "^0.14.4" 4 | }, 5 | "scripts": { 6 | "docs:dev": "vuepress dev content", 7 | "docs:build": "vuepress build content" 8 | }, 9 | "dependencies": { 10 | "ag-grid-community": "^19.0.0", 11 | "ag-grid-enterprise": "^19.0.0", 12 | "ag-grid-vue": "^19.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /docs/content/.vuepress/override.styl: -------------------------------------------------------------------------------- 1 | $accentColor = #F37726 2 | $textColor = #2c3e50 3 | $borderColor = #eaecef 4 | $codeBgColor = #282c34 5 | 6 | // Layout configuration 7 | $navbarHeight = 3.6rem 8 | $sidebarWidth = 20rem 9 | $contentWidth = 740px 10 | 11 | .theme-container.custom-home-page { 12 | .home .hero img { 13 | max-height: 230px; 14 | margin: 5rem auto 3.5rem 15 | } 16 | } -------------------------------------------------------------------------------- /js/src/embed.js: -------------------------------------------------------------------------------- 1 | // Entry point for the unpkg bundle containing custom model definitions. 2 | // 3 | // It differs from the notebook bundle in that it does not need to define a 4 | // dynamic baseURL for the static assets and may load some css that would 5 | // already be loaded by the notebook otherwise. 6 | 7 | // Export widget models and views, and the npm package version number. 8 | export * from './widget'; 9 | export { version } from '../package.json'; 10 | -------------------------------------------------------------------------------- /docs/content/code-snippets/sync-on-edit.python: -------------------------------------------------------------------------------- 1 | 2 | df2 = pd.DataFrame({'val':['a']}) 3 | column_defs = [{'headerName': 'Col', 'field': 'val', 'editable': True}] 4 | 5 | grid_options = { 6 | 'columnDefs': column_defs 7 | } 8 | 9 | g = Grid(grid_data=df2, 10 | grid_options=grid_options, 11 | sync_on_edit=True, 12 | width=200, 13 | height=100) 14 | 15 | display(g) 16 | 17 | # upon edit the updated dataframe is: g.grid_data_out['grid'] 18 | -------------------------------------------------------------------------------- /docs/content/code-snippets/quick-filter.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [{'field':'origin', 'headerName': 'Origin'}, 3 | {'field':'make', 'headerName': 'Make'}, 4 | {'field':'carName', 'headerName':'Model'}, 5 | {'field':'price', 'headerName': 'Price'}] 6 | 7 | grid_options = { 8 | 'columnDefs' : column_defs, 9 | } 10 | 11 | g = Grid(grid_data=cars, 12 | grid_options=grid_options, 13 | quick_filter=True) 14 | g 15 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 0.5.4 3 | commit = True 4 | tag = True 5 | parse = (?P\d+)(\.(?P\d+))(\.(?P\d+))((?P.)(?P\d+))? 6 | serialize = 7 | {major}.{minor}.{patch}{release}{build} 8 | {major}.{minor}.{patch} 9 | 10 | [bumpversion:part:release] 11 | optional_value = g 12 | first_value = g 13 | values = 14 | a 15 | b 16 | g 17 | 18 | [bumpversion:file:ipyaggrid/__meta__.py] 19 | 20 | [bumpversion:file:js/package.json] 21 | -------------------------------------------------------------------------------- /docs/content/code-snippets/sync-grid.python: -------------------------------------------------------------------------------- 1 | 2 | df2 = pd.DataFrame({'val':['a']}) 3 | column_defs = [{'headerName': 'Col', 'field': 'val', 'editable': True}] 4 | 5 | grid_options = { 6 | 'columnDefs': column_defs 7 | } 8 | 9 | g = Grid(grid_data=df2, 10 | grid_options=grid_options, 11 | sync_grid=True, 12 | width=200, 13 | height=100) 14 | 15 | display(g) 16 | 17 | # upon initialization or grid data update the dataframe is: g.grid_data_out['grid'] 18 | -------------------------------------------------------------------------------- /.github/ci_version.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | github_ref = os.environ["GITHUB_REF_NAME"] 4 | local_version = "master" if github_ref == "master" else github_ref.split("/")[0] 5 | 6 | target = "__version__ = _get_version(version_info)" 7 | target_file = "ipyaggrid/__meta__.py" 8 | 9 | with open(target_file, 'r') as file: 10 | filedata = file.read() 11 | 12 | filedata = filedata.replace(target, target + f" + '.post0+{local_version}'") 13 | 14 | with open(target_file, 'w') as file: 15 | file.write(filedata) 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | .vscode/ 4 | 5 | *.py[cod] 6 | */__pycache__/ 7 | *.ipynb_checkpoints/ 8 | *.egg-info/ 9 | 10 | **/node_modules 11 | 12 | */static/ 13 | ipyaggrid/nbextension/ 14 | ipyaggrid/labextension/ 15 | js/dist/ 16 | 17 | build/ 18 | dist/ 19 | 20 | */*.tgz 21 | package/ 22 | 23 | *.old* 24 | js/temp.* 25 | 26 | */yarn.lock 27 | 28 | docs/notebooks/code-snippets/ 29 | docs/notebooks/example-vue-components/ 30 | docs/notebooks/dump 31 | 32 | article/ 33 | 34 | wip/ 35 | public-test/ 36 | data/ 37 | test-zone/ 38 | -------------------------------------------------------------------------------- /docs/notebooks/push-binder.sh: -------------------------------------------------------------------------------- 1 | # git subtree push --prefix site/ origin gh-pages 2 | 3 | # git subtree push --prefix docs/notebooks/binder-ipyaggrid-customization/ origin binder-ipyaggrid-customization 4 | # git subtree push --prefix docs/notebooks/binder-ipyaggrid-export/ origin binder-ipyaggrid-export 5 | # git subtree push --prefix docs/notebooks/binder-ipyaggrid-functions/ origin binder-ipyaggrid-functions 6 | # git subtree push --prefix docs/notebooks/binder-ipyaggrid-documentation-builder/ origin binder-ipyaggrid-documentation 7 | 8 | git subtree push --prefix docs/notebooks/ origin binder-demo 9 | -------------------------------------------------------------------------------- /js/src/extension.js: -------------------------------------------------------------------------------- 1 | // This file contains the javascript that is run when the notebook is loaded. 2 | // It contains some requirejs configuration and the `load_ipython_extension` 3 | // which is required for any notebook extension. 4 | 5 | // Configure requirejs 6 | if (window.require) { 7 | window.require.config({ 8 | map: { 9 | '*': { 10 | ipyaggrid: 'nbextensions/ipyaggrid/index', 11 | }, 12 | }, 13 | }); 14 | } 15 | 16 | // Export the required load_ipython_extension 17 | const load_ipython_extension = () => {}; 18 | 19 | export default load_ipython_extension; 20 | -------------------------------------------------------------------------------- /js/src/styles/icons/minus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | minus 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/small-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-up 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/minus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | minus 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/small-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-down 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/small-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-left 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/tree-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tree-open 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/small-up.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-up 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/tree-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tree-open 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/small-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-right 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/tree-closed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tree-closed 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/small-down.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-down 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/small-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-left 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/themes.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'field': c} for c in dfm.columns[:7]] 2 | 3 | grid_options = { 4 | 'columnDefs' : column_defs, 5 | } 6 | 7 | themes = [ 8 | 'ag-theme-balham', 9 | 'ag-theme-balham-dark', 10 | 'ag-theme-material', 11 | 'ag-theme-fresh', 12 | 'ag-theme-dark', 13 | 'ag-theme-blue', 14 | 'ag-theme-bootstrap', 15 | 'ag-theme-excel', # custom style added by ipyaggrid 16 | ] 17 | 18 | g = Grid(grid_data=dfm, 19 | theme='ag-theme-balham-dark', 20 | # theme='ag-theme-balham', 21 | # theme='ag-theme-excel', 22 | grid_options=grid_options) 23 | g 24 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/small-right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | small-right 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/tree-closed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tree-closed 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/content/code-snippets/custom-css.python: -------------------------------------------------------------------------------- 1 | # putting in !important so it overrides the theme's styling as it hovers the row also 2 | css_rules = """ 3 | .ag-row-hover { 4 | background-color: lightblue !important; 5 | } 6 | 7 | .ag-column-hover { 8 | background-color: powderblue; 9 | } 10 | 11 | .ag-row-hover .ag-column-hover { 12 | background-color: deepskyblue !important; 13 | } 14 | """ 15 | 16 | column_defs = [{'field': c} for c in dfm.columns[:7]] 17 | 18 | grid_options = { 19 | 'columnDefs' : column_defs, 20 | } 21 | 22 | g = Grid(grid_data=dfm, 23 | css_rules=css_rules, 24 | grid_options=grid_options) 25 | g 26 | -------------------------------------------------------------------------------- /js/src/styles/icons/tick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tick 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/tick.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tick 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /docs/notebooks/templates/index.tpl.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | dataframe 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 | 19 | __$data.df_html$__ 20 | 21 |
22 |
23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /js/src/styles/icons/tree-indeterminate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tree-indeterminate 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | filter 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/filter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | filter 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/tree-indeterminate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | tree-indeterminate 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/aggregation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | aggregation 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/widget_compress.js: -------------------------------------------------------------------------------- 1 | import * as pako from 'pako'; 2 | 3 | window.p = pako; 4 | 5 | const gzip = {}; 6 | 7 | gzip.compress = function(jsonStr, level) { 8 | const binaryString = pako.gzip(jsonStr, { level }); 9 | return binaryString; 10 | }; 11 | 12 | gzip.uncompress = function(binaryString, level) { 13 | const string = pako.inflate(binaryString, { 14 | level, 15 | to: 'string', 16 | }); 17 | return string; 18 | }; 19 | 20 | gzip.uncompressBase64ToStr = function(base64Str, level) { 21 | const binaryString = atob(base64Str); 22 | const string = gzip.uncompress(binaryString, level); 23 | return string; 24 | }; 25 | 26 | export { gzip }; 27 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/aggregation.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | aggregation 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | plus 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/plus.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | plus 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/column.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | column 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | star 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/star.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | star 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cancel 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/column.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | column 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/cancel.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cancel 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/not-allowed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | not-allowed 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/not-allowed.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | not-allowed 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/paste.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | paste 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/paste.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | paste 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/copy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | folder 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/content/code-snippets/status-bar.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'field': c} for c in dfm.columns[:7]] 2 | 3 | css = ".ag-status-bar { min-height: 35px; }" 4 | 5 | grid_options = { 6 | 'columnDefs' : column_defs, 7 | 'enableRangeSelection': True, 8 | 'statusBar': { # new syntax since 19.0 9 | 'statusPanels': [ 10 | { 'statusPanel': 'agTotalRowCountComponent', 'align': 'left' }, 11 | { 'statusPanel': 'agFilteredRowCountComponent' }, 12 | { 'statusPanel': 'agSelectedRowCountComponent' }, 13 | { 'statusPanel': 'agAggregationComponent' } 14 | ] 15 | }, 16 | # 'enableStatusBar': True, # deprecated since 19.0 17 | } 18 | 19 | g = Grid(grid_data=dfm, 20 | grid_options=grid_options, 21 | css_rules=css) 22 | g 23 | -------------------------------------------------------------------------------- /js/src/styles/icons/next.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | next 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/previous.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | previous 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/folder.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | folder 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/previous.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | previous 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /js/src/styles/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | menu 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/next.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | next 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | menu 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /tests/unit/test_utils.py: -------------------------------------------------------------------------------- 1 | import datetime as dt 2 | import numpy as np 3 | import pytest 4 | import pandas as pd 5 | from unittest.mock import Mock 6 | 7 | from ipyaggrid.util import Util 8 | 9 | @pytest.mark.parametrize("data,expected", [ 10 | (42, '42'), 11 | ("Quick brown", '"Quick brown"'), 12 | (dt.time(12,0,0), '"12:00:00"'), 13 | ([1, 2, 3], '[1, 2, 3]'), 14 | (np.full(3, 3), '[3, 3, 3]'), 15 | (np.full((3, 3), 3), '[[3, 3, 3], [3, 3, 3], [3, 3, 3]]'), 16 | (np.full(1, dt.datetime(2023, 3, 28, 12, 0, 0)), '["2023-03-28T12:00:00"]'), 17 | (np.int32(1), '1'), 18 | (pd.NA, '""') 19 | ]) 20 | def test_json_serialisation_without_data_compression(data, expected): 21 | widget_mock = Mock(compress_data=False) 22 | assert expected == Util.data_to_json(data, widget_mock) 23 | -------------------------------------------------------------------------------- /js/src/labplugin.js: -------------------------------------------------------------------------------- 1 | import * as base from '@jupyter-widgets/base'; 2 | 3 | import * as myWidget from './widget'; 4 | import { version } from './index'; 5 | 6 | const id = 'ipyaggrid:plugin'; 7 | const requires = [base.IJupyterWidgetRegistry]; 8 | const autoStart = true; 9 | 10 | const conf = JSON.parse(document.getElementById("jupyter-config-data").textContent); 11 | __webpack_public_path__ = (conf.fullLabextensionsUrl || `${conf.baseUrl}lab/extensions`) + "/ipyaggrid/static/"; 12 | 13 | const activate = (app, widgets) => { 14 | console.log('JupyterLab extension ipyaggrid is activated!'); 15 | 16 | widgets.registerWidget({ 17 | name: 'ipyaggrid', 18 | version, 19 | exports: myWidget, 20 | }); 21 | }; 22 | 23 | export default { 24 | id, 25 | requires, 26 | activate, 27 | autoStart, 28 | }; 29 | -------------------------------------------------------------------------------- /js/src/styles/icons/folder-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | folder-open 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/folder-open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | folder-open 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cross 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /js/src/styles/icons/first.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | first 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/first.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | first 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /js/src/styles/icons/contracted.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | contracted 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/contracted.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | contracted 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/cross.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cross 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /js/src/styles/icons/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pin 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test-zone/js/README.md: -------------------------------------------------------------------------------- 1 | # Trial Zone 2 | 3 | ## 1 - Install 4 | 5 | From terminal: 6 | 7 | ```bash 8 | $ cd trial 9 | $ npm install 10 | $ npm run dev 11 | 12 | # in another terminal 13 | $ npm run serve 14 | 15 | # open browser to localhost:3001 16 | ``` 17 | 18 | ## 2 - Setup 19 | 20 | From terminal 21 | 22 | ```bash 23 | $ cd trial 24 | 25 | $ npm i -P ag-grid 26 | # idem: 27 | $ npm install --save ag-grid 28 | 29 | 30 | $ npm i -D webpack webpack-cli 31 | $ npm i -D babel-core babel-loader babel-preset-env 32 | $ npm i -D style-loader css-loader less-loader extract-text-webpack-plugin 33 | $ npm i -D html-webpack-plugin 34 | $ npm i -D rimraf serve 35 | # idem: 36 | $ npm install --save-dev rimraf serve 37 | ``` 38 | 39 | ## 3 - VS Code 40 | 41 | Install selected extensions from 42 | https://marketplace.visualstudio.com/items?itemName=mubaidr.vuejs-extension-pack 43 | 44 | To be discussed. 45 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pin 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /js/src/styles/icons/checkbox-unchecked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-unchecked 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/checkbox-unchecked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-unchecked 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /js/src/styles/icons/checkbox-unchecked-readonly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-unchecked-readonly 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/checkbox-unchecked-readonly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-unchecked-readonly 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /js/src/styles/icons/expanded.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | expanded 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /js/src/styles/icons/last.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | last 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/expanded.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | expanded 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/last.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | last 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/content/code-snippets/collapse-expand.python: -------------------------------------------------------------------------------- 1 | 2 | column_defs = [{'field':'origin', 'headerName': 'Origin', 'rowGroup':True, 'hide':True}, 3 | {'field':'make', 'headerName': 'Make', 'rowGroup':True, 'hide':True}, 4 | {'field':'carName', 'headerName':'Model'}, 5 | {'field':'price', 'headerName': 'Price', 'aggFunc':'avg'}] 6 | 7 | grid_options = { 8 | 'columnDefs' : column_defs, 9 | 'enableSorting': True, 10 | 'enableFilter': True, 11 | 'enableColResize': True, 12 | 'groupMultiAutoColumn': True, 13 | 'animateRows':True 14 | } 15 | 16 | buttons = [ 17 | {'name':'Expand All', 'action':'''gridOptions.api.expandAll();'''}, 18 | {'name':'Collapse All', 'action':'''gridOptions.api.collapseAll();'''}, 19 | ] 20 | 21 | g = Grid(grid_data=cars, 22 | theme="ag-theme-balham", 23 | grid_options=grid_options, 24 | menu = {'buttons':buttons}, 25 | quick_filter=False) 26 | g 27 | -------------------------------------------------------------------------------- /docs/content/guide/install.md: -------------------------------------------------------------------------------- 1 | # Install 2 | 3 | ## Classic Notebook 4 | 5 | From terminal: 6 | 7 | ```bash 8 | $ pip install ipyaggrid 9 | 10 | # if notebook<5.3 - but why would you not upgrade ?? 11 | $ jupyter nbextension enable --py --sys-prefix ipyaggrid 12 | ``` 13 | 14 | ## JupyterLab 15 | 16 | From terminal: 17 | 18 | ```bash 19 | $ pip install ipyaggrid 20 | $ jupyter labextension install ipyaggrid 21 | 22 | # if not already installed 23 | $ jupyter labextension install @jupyter-widgets/jupyterlab-manager 24 | ``` 25 | 26 | ## Check 27 | 28 | If you want to check your install see the [Dev Install - Check Extensions](../dev/dev_install.html#check-extensions) section. 29 | 30 | ## Uninstall 31 | 32 | + Classic Notebook 33 | 34 | ```bash 35 | # if notebook<5.3 36 | $ jupyter nbextension uninstall --py --sys-prefix ipyaggrid 37 | 38 | $ pip uninstall ipyaggrid 39 | ``` 40 | 41 | 42 | + JupyterLab: 43 | 44 | ```bash 45 | $ jupyter labextension uninstall ipyaggrid 46 | $ pip uninstall ipyaggrid 47 | ``` 48 | -------------------------------------------------------------------------------- /js/src/styles/icons/checkbox-checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-checked 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/checkbox-checked.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-checked 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /js/src/widget_json.js: -------------------------------------------------------------------------------- 1 | const JSONfunc = {}; 2 | 3 | JSONfunc.stringify = function(obj) { 4 | return JSON.stringify( 5 | obj, 6 | (key, value) => (typeof value === 'function' ? value.toString() : value) 7 | ); 8 | }; 9 | 10 | JSONfunc.parse = function(str, helpers) { 11 | // helpers used in eval 12 | return JSON.parse(str, (key, value) => { 13 | if (typeof value !== 'string') return value; 14 | 15 | const valueCompact = value.replace(/\r?\n|\r/g, '').replace(/\s+/g, ' '); 16 | let r; 17 | if (valueCompact.substring(0, 8) === 'function') { 18 | r = eval(`(${value})`); 19 | return r; 20 | } else if (valueCompact.substring(0, 8) === 'helpers.') { 21 | r = eval(value); 22 | return r; 23 | } else if (valueCompact.startsWith('__js__:')) { 24 | return Function(`"use strict"; return (${value.slice(7)})`)(); 25 | } 26 | return value; 27 | }); 28 | }; 29 | 30 | export { JSONfunc }; 31 | -------------------------------------------------------------------------------- /docs/content/README.md: -------------------------------------------------------------------------------- 1 | --- 2 | home: true 3 | description: 'The power of ag-Grid in Jupyter notebooks' 4 | heroImage: '/jupyter-plus-aggrid.png' 5 | heroText: 'ipyaggrid' 6 | actionText: Get Started → 7 | actionLink: /guide/install 8 | features: 9 | - title: Accessible 10 | details: Display pandas dataframes as dynamic HTML5 grids - Standard options are accessible through configuration. 11 | - title: Transparent 12 | details: Access all ag-Grid features through its well crafted API without contraints - Full pass-through is implemented. 13 | - title: Customizable 14 | details: Create your own Javascript functions to interact with the grid. Leverage examples in the ag-Grid docs. 15 | footer: MIT Licensed | Copyright © 2018-present Louis Raison, Olivier Borderies 16 | pageClass: custom-home-page 17 | --- 18 | 19 | ### Install 20 | 21 | ```bash 22 | # for notebook >= 5.3 23 | $ pip install ipyaggrid 24 | ``` 25 | 26 | ::: warning COMPATIBILITY NOTE 27 | Tested on Chrome, Firefox, Opera, [Min](https://minbrowser.github.io/min/). 28 | ::: 29 | -------------------------------------------------------------------------------- /docs/content/code-snippets/export-grid.python: -------------------------------------------------------------------------------- 1 | columnDefs = [ 2 | {'headerName': "Country", 'field': "country", 'rowGroup':True, 'hide':True}, 3 | {'headerName': "Sport", 'field': "sport", 'rowGroup':True, 'hide':True}, 4 | { 5 | 'headerName': "Results", 6 | 'children': [ 7 | {'headerName': "Total", 'field': 'total', 'columnGroupShow': 'closed', 'aggFunc':'sum'}, 8 | {'headerName': "Gold", 'field': 'gold', 'columnGroupShow': 'open', 'aggFunc':'sum'}, 9 | {'headerName': "Silver", 'field': 'silver', 'columnGroupShow': 'open', 'aggFunc':'sum'}, 10 | {'headerName': "Bronze", 'field': 'bronze', 'columnGroupShow': 'open', 'aggFunc':'sum'} 11 | ] 12 | }, 13 | ] 14 | 15 | 16 | grid_options = { 17 | 'columnDefs': columnDefs, 18 | 'enableFilter': True, 19 | 'enableSorting':True, 20 | } 21 | 22 | g = Grid(grid_data = data, 23 | grid_options=grid_options, 24 | export_mode="buttons", 25 | theme='ag-theme-balham') 26 | g 27 | -------------------------------------------------------------------------------- /js/src/styles/icons/checkbox-indeterminate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-indeterminate 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/checkbox-indeterminate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-indeterminate 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /js/src/styles/icons/checkbox-checked-readonly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-checked-readonly 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/checkbox-checked-readonly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-checked-readonly 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /js/src/styles/icons/checkbox-indeterminate-readonly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-indeterminate-readonly 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /js/src/styles/icons/pivot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pivot 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/checkbox-indeterminate-readonly.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | checkbox-indeterminate-readonly 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /js/src/styles/icons/columns.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | columns 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/pivot.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pivot 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/columns.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | columns 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb", "prettier"], 3 | "plugins": ["prettier", "html"], 4 | "rules": { 5 | "prettier/prettier": ["error"], 6 | "no-console": "off", 7 | "func-names": "off", 8 | "no-undef": "off", 9 | "camelcase": "off", 10 | "prefer-destructuring": [ 11 | "error", 12 | { 13 | "object": true, 14 | "array": false 15 | } 16 | ], 17 | "no-underscore-dangle": [ 18 | 2, 19 | { 20 | "allow": ["__super__", "_id"] 21 | } 22 | ], 23 | "no-param-reassign": "off", 24 | "no-use-before-define": "off", 25 | "prefer-rest-params": "off" 26 | }, 27 | "parserOptions": { 28 | "ecmaVersion": 6, 29 | "sourceType": "module", 30 | "ecmaFeatures": { 31 | "jsx": true 32 | } 33 | }, 34 | "env": { 35 | "es6": true, 36 | "browser": true, 37 | "node": true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /js/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["airbnb", "prettier"], 3 | "plugins": ["prettier", "html"], 4 | "rules": { 5 | "prettier/prettier": ["error"], 6 | "no-console": "off", 7 | "func-names": "off", 8 | "no-undef": "off", 9 | "camelcase": "off", 10 | "prefer-destructuring": [ 11 | "error", 12 | { 13 | "object": true, 14 | "array": false 15 | } 16 | ], 17 | "no-underscore-dangle": [ 18 | "error", 19 | { 20 | "allow": ["__super__", "_id","_grid_data"] 21 | } 22 | ], 23 | "no-param-reassign": "off", 24 | "no-use-before-define": "off", 25 | "prefer-rest-params": "off" 26 | }, 27 | "parserOptions": { 28 | "ecmaVersion": 6, 29 | "sourceType": "module", 30 | "ecmaFeatures": { 31 | "jsx": true 32 | } 33 | }, 34 | "env": { 35 | "es6": true, 36 | "browser": true, 37 | "node": true 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Louis Raison 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /js/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Louis Raison 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /js/src/styles/icons/eye.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | eye 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /js/src/styles/icons/indeterminate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | indeterminate 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/eye.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | eye 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/indeterminate.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | indeterminate 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /js/src/styles/_ag-theme-classic-vars.scss: -------------------------------------------------------------------------------- 1 | $foreground-opacity: 1 !default; 2 | $secondary-foreground-color-opacity: 1 !default; 3 | $disabled-foreground-color-opacity: 0.5 !default; 4 | 5 | // Sizing 6 | $grid-size: 4px !default; 7 | $icon-size: 12px !default; 8 | $header-height: $grid-size * 6 + 1 !default; 9 | $row-height: ($grid-size * 6 + 1) !default; 10 | $cell-horizontal-padding: $grid-size * 3 !default; 11 | $virtual-item-height: $grid-size * 5 !default; 12 | $header-icon-size: 14px !default; 13 | 14 | // Icons 15 | $icons-path: './icons/' !default; 16 | 17 | // Fonts 18 | $font-family: 'Helvetica Neue', sans-serif !default; 19 | $font-size: 14px !default; 20 | $font-weight: 400 !default; 21 | 22 | $secondary-font-family: $font-family !default; 23 | $secondary-font-size: 14px !default; 24 | $secondary-font-weight: 400 !default; 25 | 26 | // Misc 27 | $transition-speed: 120ms !default; 28 | $card-shadow: none; 29 | $card-radius: 0; 30 | 31 | $toolpanel-indent-size: $grid-size + $icon-size !default; 32 | $row-group-indent-size: $grid-size * 3 + $icon-size !default; 33 | 34 | // same in all themes 35 | $header-cell-moving-background-color: rgb(190, 190, 190) !default; 36 | -------------------------------------------------------------------------------- /test-zone/js/src/_ag-theme-classic-vars.scss: -------------------------------------------------------------------------------- 1 | $foreground-opacity: 1 !default; 2 | $secondary-foreground-color-opacity: 1 !default; 3 | $disabled-foreground-color-opacity: 0.5 !default; 4 | 5 | // Sizing 6 | $grid-size: 4px !default; 7 | $icon-size: 12px !default; 8 | $header-height: $grid-size * 6 + 1 !default; 9 | $row-height: ($grid-size * 6 + 1) !default; 10 | $cell-horizontal-padding: $grid-size * 3 !default; 11 | $virtual-item-height: $grid-size * 5 !default; 12 | $header-icon-size: 14px !default; 13 | 14 | // Icons 15 | $icons-path: './icons/' !default; 16 | 17 | // Fonts 18 | $font-family: 'Helvetica Neue', sans-serif !default; 19 | $font-size: 14px !default; 20 | $font-weight: 400 !default; 21 | 22 | $secondary-font-family: $font-family !default; 23 | $secondary-font-size: 14px !default; 24 | $secondary-font-weight: 400 !default; 25 | 26 | // Misc 27 | $transition-speed: 120ms !default; 28 | $card-shadow: none; 29 | $card-radius: 0; 30 | 31 | $toolpanel-indent-size: $grid-size + $icon-size !default; 32 | $row-group-indent-size: $grid-size * 3 + $icon-size !default; 33 | 34 | // same in all themes 35 | $header-cell-moving-background-color: rgb(190, 190, 190) !default; 36 | -------------------------------------------------------------------------------- /docs/content/.vuepress/public/msd-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test-zone/js/src/style.scss: -------------------------------------------------------------------------------- 1 | // Customize the look and feel of the grid with Sass variables 2 | // Up-to-date list of variables is available in the source code: https://github.com/ag-grid/ag-grid/blob/latest/src/styles/theme-fresh.scss 3 | 4 | // Temporary, due to bug in 17.0.0. should use only $icons-path: "~ag-grid/src/styles/material-icons/" 5 | $icons-path: "~ag-grid/src/styles/icons/"; 6 | $ag-mat-icons-path: "~ag-grid/src/styles/icons/"; 7 | 8 | // changes the border color 9 | $border-color: silver; 10 | 11 | // Changes the font size 12 | $font-size: 12px; 13 | 14 | // Reverts the cell horizontal padding change between ag-fresh and ag-theme-fresh 15 | $cell-horizontal-padding: 0px; 16 | 17 | // changes the default icon color 18 | $icon-color: lightslategrey; 19 | 20 | $row-height: 20px; 21 | $cell-horizontal-border:1px solid silver; 22 | $ag-range-selected-color-1: LightSlateGrey; 23 | 24 | $odd-row-background-color: white; 25 | 26 | $hover-color : transparent; 27 | $header-height : 20px; 28 | 29 | @import "~ag-grid/src/styles/ag-grid.scss"; 30 | @import "~ag-grid/src/styles/ag-theme-balham.scss"; 31 | 32 | // for example purposes, remove margin and padding of the grid 33 | html, 34 | body { 35 | height: 100%; 36 | } 37 | -------------------------------------------------------------------------------- /js/src/styles/icons/cut.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cut 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/cut.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cut 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ipyaggrid/__init__.py: -------------------------------------------------------------------------------- 1 | from .__meta__ import __version__ 2 | 3 | from .grid import Grid 4 | 5 | from .util import Util 6 | 7 | get_license = Util.get_license 8 | 9 | def _jupyter_nbextension_paths(): 10 | return [{ 11 | # fixed syntax 12 | 'section': 'notebook', 13 | # path relative to module directory - here: ipyaggrid 14 | 'src': 'nbextension', 15 | # directory in the `nbextension/` namespace 16 | 'dest': 'ipyaggrid', 17 | # path in the `nbextension/` namespace 18 | 'require': 'ipyaggrid/extension' 19 | }] 20 | 21 | def _jupyter_labextension_paths(): 22 | """Called by Jupyter Lab Server to detect if it is a valid labextension and 23 | to install the widget 24 | Returns 25 | ======= 26 | src: Source directory name to copy files from. Webpack outputs generated files 27 | into this directory and Jupyter Lab copies from this directory during 28 | widget installation 29 | dest: Destination directory name to install widget files to. Jupyter Lab copies 30 | from `src` directory into /labextensions/ directory 31 | during widget installation 32 | """ 33 | return [{ 34 | 'src': 'labextension', 35 | 'dest': 'ipyaggrid', 36 | }] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ipyaggrid 2 | 3 | [![Latest Version](https://img.shields.io/pypi/v/ipyaggrid.svg)](https://pypi.python.org/pypi/ipyaggrid/) 4 | [![Downloads](https://img.shields.io/pypi/dm/ipyaggrid.svg)](https://pypi.python.org/pypi/ipyaggrid/) 5 | [![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gl/DGothrek%2Fipyaggrid/binder-demo) 6 | 7 | ### Doc 8 | 9 | See documentation: [widgetti.github.io/ipyaggrid/](https://widgetti.github.io/ipyaggrid/). 10 | 11 | Demo notebooks are in [docs/notebooks](/docs/notebooks) and available on mybinder (see link above). 12 | 13 | ### Credits 14 | 15 | ipyaggrid was created by [Louis Raison](https://gitlab.com/DGothrek) and [oscar6echo](https://gitlab.com/oscar6echo) and originally maintained at https://gitlab.com/DGothrek/ipyaggrid . 16 | 17 | For more context, read the original article [Harnessing the power of ag-Grid in Jupyter](https://medium.com/@olivier.borderies/harnessing-the-power-of-ag-grid-in-jupyter-3ae27fb21012). 18 | 19 | [Mario Buikhuizen](https://github.com/mariobuikhuizen) and [Maarten Breddels](https://github.com/maartenbreddels) took over maintenance in 2022. 20 | 21 | ### Sponsors 22 | 23 | Project ipyaggrid receives direct funding from the following sources: 24 | 25 | [![MSD](docs/content/.vuepress/public/msd-logo.svg)](https://msd.com) 26 | -------------------------------------------------------------------------------- /js/src/styles/icons/group.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | group 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/group.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | group 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /docs/content/code-snippets/simple-highlight.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'field':'origin', 'headerName': 'Origin', 'rowGroup':True, 'hide':True}, 2 | {'field':'make', 'headerName': 'Make', 'rowGroup':True, 'hide':True}, 3 | {'field':'carName', 'headerName':'Model'}, 4 | {'field':'price', 'headerName': 'Price', 'aggFunc':'avg'}] 5 | 6 | 7 | gridOptions = { 8 | 'enableColResize': True, 9 | 'columnDefs': column_defs, 10 | 'enableFilter':True, 11 | 'enableSorting':True, 12 | 'animateRows':True, 13 | 'groupMultiAutoColumn': True, 14 | }; 15 | 16 | buttons=[{'name':'Highlight', 'action':""" 17 | gridOptions.api.forEachNodeAfterFilterAndSort(node => { 18 | if (node.aggData){ 19 | if (node.aggData.price.value > 30000){ 20 | gridOptions.api.flashCells({rowNodes: [node], columns: ["price"]}); 21 | } 22 | } else { 23 | if (node.data.price>30000){ 24 | gridOptions.api.flashCells({rowNodes: [node], columns: ["price"]}); 25 | } 26 | } 27 | }); 28 | """}] 29 | 30 | 31 | g = Grid(quick_filter=False, 32 | theme='ag-theme-balham', 33 | compress_data=True, 34 | menu = {'buttons':buttons}, 35 | grid_options=gridOptions, 36 | js_post_grid=["gridOptions.api.expandAll();"], 37 | grid_data=cars) 38 | g 39 | -------------------------------------------------------------------------------- /docs/content/code-snippets/custom-menu-1.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'field':'origin', 'headerName': 'Origin'}, 2 | {'field':'make', 'headerName': 'Make'}, 3 | {'field':'carName', 'headerName':'Model'}, 4 | {'field':'price', 'headerName': 'Price'}] 5 | 6 | 7 | grid_options = { 8 | 'enableColResize': True, 9 | 'columnDefs': column_defs, 10 | 'enableFilter':True, 11 | 'enableSorting':True, 12 | 'animateRows':True, 13 | 'groupMultiAutoColumn': True, 14 | }; 15 | 16 | g = Grid(grid_data = cars, 17 | quick_filter=True, 18 | show_toggle_edit=True, 19 | show_toggle_delete=True, 20 | export_excel=True, 21 | export_csv=True, 22 | grid_options=grid_options, 23 | menu={'buttons': 24 | [ 25 | {'name':'Log foo 1', 'action':'console.log("foo");'}, 26 | {'name':'Log bar 1', 'action':'console.log("bar");'}, 27 | {'name':'Log foo 2', 'action':'console.log("foo");'}, 28 | {'name':'Log foo 3', 'action':'console.log("foo");'}, 29 | {'name':'Log foo 4', 'action':'console.log("foo");'}, 30 | ], 31 | }, 32 | export_mode="buttons", 33 | theme='ag-theme-balham') 34 | g 35 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # ipyauth Docs 2 | 3 | This folder contains the documentation, online on [gitlab](https://widgetti.github.io/ipyaggrid/). 4 | 5 | ## Develop 6 | 7 | Run from terminal: 8 | 9 | ```bash 10 | $ yarn docs:dev 11 | ``` 12 | 13 | ## Deploy 14 | 15 | You can manually deploy as follows: 16 | 17 | ```bash 18 | # build 19 | cd docs 20 | export NODE_OPTIONS=--openssl-legacy-provider; 21 | yarn docs:build 22 | 23 | # navigate into the build output directory 24 | cd ../public 25 | 26 | # you need to remove public/ from .gitignore for manual run 27 | git add . 28 | git commit -m 'deploy' 29 | 30 | # you are deploying to https://oscar6echo.gitlab.io/ipyauth 31 | git push -f git@gitlab.com:oscar6echo/ipyauth.git master:pages 32 | # or equivalently 33 | git subtree push --prefix public/ origin pages 34 | 35 | # back repo top level 36 | cd .. 37 | ``` 38 | 39 | ## CI/CD 40 | 41 | But the **preferred way** is Gitlab CI/CD. 42 | See the config file: [.gitlab-ci.yml](../.gitlab-ci.yml). 43 | 44 | You can: 45 | 46 | + manually run it from **ipyauth** repo [pipeline section](https://gitlab.com/oscar6echo/ipyauth/pipelines) 47 | + See the log and check all is good 48 | + Remark: Make sure your output folder is `public/` nothing else 49 | 50 | Then the pipeline will run on each commit on branch `master` 51 | 52 | See the [Gitlab Pages help](https://gitlab.com/help/user/project/pages/index.md) for more info. 53 | -------------------------------------------------------------------------------- /js/src/styles/icons/eye-slash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | eye-slash 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/eye-slash.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | eye-slash 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/content/code-snippets/multi-options.python: -------------------------------------------------------------------------------- 1 | css_rules = """ 2 | .number-cell { 3 | text-align: left; 4 | } 5 | .price-high { 6 | color: red; 7 | } 8 | 9 | """ 10 | 11 | ccf = "function(params) { return params.value >32000 ? 'price-high' : ''; }" 12 | column_defs_1 = [{'field':'origin', 'headerName': 'Origin'}, 13 | {'field':'make', 'headerName': 'Make'}, 14 | {'field':'carName', 'headerName':'Model'}, 15 | {'field':'price', 'headerName': 'Price', 'cellClass': ccf}] 16 | 17 | column_defs_2 = [{'field':'origin', 'headerName': 'Origin', 'hide':True, 'rowGroup':True}, 18 | {'field':'make', 'headerName': 'Make'}, 19 | {'field':'carName', 'headerName':'Model'}, 20 | {'field':'price', 'headerName': 'Price'}] 21 | 22 | 23 | grid_options_1 = { 24 | 'columnDefs' : column_defs_1, 25 | 'enableSorting': True, 26 | 'enableFilter': True, 27 | 'enableColResize': False, 28 | } 29 | 30 | grid_options_2 = { 31 | 'columnDefs' : column_defs_2, 32 | 'enableSorting': False, 33 | 'enableFilter': False, 34 | 'enableColResize': True, 35 | 'rowSelection': 'multiple', 36 | } 37 | 38 | g = Grid(grid_data=cars, 39 | css_rules=css_rules, 40 | grid_options_multi=[('Sorting, color, filter', grid_options_1), 41 | ('Selection, grouping, no-filter', grid_options_2)], 42 | theme='ag-theme-balham') 43 | g 44 | -------------------------------------------------------------------------------- /js/src/styles/ipywidgets/nouislider.less: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | The nouislider.css file is autogenerated from nouislider.less, which imports and wraps the nouislider/src/nouislider.less styles. 4 | 5 | MIT License 6 | 7 | Copyright (c) 2019 Léon Gersen 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 14 | */ 15 | 16 | /* The .widget-slider class is deprecated */ 17 | .widget-slider, .jupyter-widget-slider { 18 | @import "nouislider/src/nouislider.less"; 19 | @import (less) "./nouislider-custom.css"; 20 | }; 21 | -------------------------------------------------------------------------------- /js/src/styles/icons/arrows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | arrows 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/arrows.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | arrows 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /docs/content/code-snippets/simple-grid.python: -------------------------------------------------------------------------------- 1 | column_defs = [{'headerName':'Continent','field':'continent','rowGroup':True, 'hide':True}, 2 | {'headerName':'Country','field':'country','rowGroup':True, 'hide':True}, 3 | {'headerName':'Status','field':'status'}, 4 | {'headerName':'Date','field':'year','cellRenderer':'''function(params){ 5 | if (params.value !== undefined && params.value !== null){ 6 | return (params.value.substring(0,4)); 7 | } 8 | return "" 9 | }''' 10 | }, 11 | {'headerName':'Name','field':'name'}, 12 | {'headerName':'Mass','field':'mass', 'aggFunc':'avg'}, 13 | {'headerName':'Latitude','field':'latitude'}, 14 | {'headerName':'Longitude','field':'longitude'}, 15 | ] 16 | 17 | grid_options = { 18 | 'columnDefs' : column_defs, 19 | 'enableSorting': True, 20 | 'enableFilter': True, 21 | 'enableColResize': True, 22 | 'enableRangeSelection': True, 23 | } 24 | 25 | g = Grid(grid_data=dfm, 26 | grid_options=grid_options, 27 | quick_filter=True, 28 | show_toggle_edit=True, 29 | export_mode="buttons", 30 | export_csv=True, 31 | export_excel=True, 32 | theme='ag-theme-balham', 33 | show_toggle_delete=True, 34 | columns_fit='auto', 35 | index=False, 36 | keep_multiindex=False) 37 | g 38 | -------------------------------------------------------------------------------- /js/src/styles/switch_edit.css: -------------------------------------------------------------------------------- 1 | .div-edit { 2 | width: 70px; 3 | padding-left: 4px; 4 | } 5 | 6 | .div-edit > .div-edit-2 { 7 | padding-right: 5px 8 | } 9 | 10 | .div-edit > div > .switch { 11 | position: relative; 12 | display: inline-block; 13 | width: 30px; 14 | height: 20px; 15 | } 16 | 17 | .div-edit > div > .switch input { 18 | display: none; 19 | } 20 | 21 | .div-edit > div > label > .slider { 22 | position: absolute; 23 | cursor: pointer; 24 | top: 0; 25 | left: 0; 26 | right: 0; 27 | bottom: 0; 28 | background-color: #ccc; 29 | -webkit-transition: 0.2s; 30 | transition: 0.2s; 31 | } 32 | 33 | .div-edit > div > label > .slider:before { 34 | position: absolute; 35 | content: ''; 36 | height: 15px; 37 | width: 15px; 38 | left: 2px; 39 | bottom: 3px; 40 | background-color: white; 41 | -webkit-transition: 0.2s; 42 | transition: 0.2s; 43 | } 44 | 45 | .div-edit > div > label > input:checked + .slider { 46 | background-color: #f37626; 47 | } 48 | 49 | .div-edit > div > label > input:focus + .slider { 50 | box-shadow: 0 0 1px #f37626; 51 | } 52 | 53 | .div-edit > div > label > input:checked + .slider:before { 54 | -webkit-transform: translateX(10px); 55 | -ms-transform: translateX(10px); 56 | transform: translateX(10px); 57 | } 58 | 59 | .div-edit > div > label > .slider.round { 60 | border-radius: 50px; 61 | } 62 | .div-edit > div > label > .slider.round:before { 63 | border-radius: 50%; 64 | } 65 | -------------------------------------------------------------------------------- /js/src/styles/icons/asc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | asc 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/asc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | asc 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /js/src/styles/switch_delete.css: -------------------------------------------------------------------------------- 1 | .div-delete { 2 | width: 85px; 3 | padding-left: 4px; 4 | } 5 | 6 | .div-delete > .div-delete-2 { 7 | padding-right: 5px 8 | } 9 | 10 | .div-delete > div > .switch { 11 | position: relative; 12 | display: inline-block; 13 | width: 30px; 14 | height: 20px; 15 | } 16 | 17 | .div-delete > div > .switch input { 18 | display: none; 19 | } 20 | 21 | .div-delete > div > label > .slider { 22 | position: absolute; 23 | cursor: pointer; 24 | top: 0; 25 | left: 0; 26 | right: 0; 27 | bottom: 0; 28 | background-color: #ccc; 29 | -webkit-transition: 0.2s; 30 | transition: 0.2s; 31 | } 32 | 33 | .div-delete > div > label > .slider:before { 34 | position: absolute; 35 | content: ''; 36 | height: 15px; 37 | width: 15px; 38 | left: 2px; 39 | bottom: 3px; 40 | background-color: white; 41 | -webkit-transition: 0.2s; 42 | transition: 0.2s; 43 | } 44 | 45 | .div-delete > div > label > input:checked + .slider { 46 | background-color: #f37626; 47 | } 48 | 49 | .div-delete > div > label > input:focus + .slider { 50 | box-shadow: 0 0 1px #f37626; 51 | } 52 | 53 | .div-delete > div > label > input:checked + .slider:before { 54 | -webkit-transform: translateX(10px); 55 | -ms-transform: translateX(10px); 56 | transform: translateX(10px); 57 | } 58 | 59 | .div-delete > div > label > .slider.round { 60 | border-radius: 50px; 61 | } 62 | .div-delete > div > label > .slider.round:before { 63 | border-radius: 50%; 64 | } 65 | -------------------------------------------------------------------------------- /js/src/styles/icons/desc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | desc 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/desc.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | desc 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ipyaggrid/magics/custom_magics.py: -------------------------------------------------------------------------------- 1 | 2 | import os 3 | import io 4 | 5 | from IPython.core import magic_arguments 6 | from IPython.core.magic import cell_magic, Magics, magics_class 7 | 8 | 9 | @magics_class 10 | class CustomMagics(Magics): 11 | @magic_arguments.magic_arguments() 12 | @magic_arguments.argument( 13 | '-a', '--append', action='store_true', default=False, 14 | help='Append contents of the cell to an existing file. ' 15 | 'The file will be created if it does not exist.' 16 | ) 17 | @magic_arguments.argument( 18 | 'filename', type=str, 19 | help='file to write' 20 | ) 21 | @cell_magic 22 | def runandwrite(self, line, cell): 23 | """ 24 | Write the contents of the cell to a file. 25 | The file will be overwritten unless the -a (--append) flag is specified. 26 | """ 27 | ip = get_ipython() 28 | ip.run_cell(cell) 29 | 30 | args = magic_arguments.parse_argstring(self.runandwrite, line) 31 | filename = os.path.expanduser(args.filename) 32 | 33 | if os.path.exists(filename): 34 | if args.append: 35 | print("Appending to %s" % filename) 36 | else: 37 | print("Overwriting %s" % filename) 38 | else: 39 | print("Writing %s" % filename) 40 | 41 | mode = 'a' if args.append else 'w' 42 | with io.open(filename, mode, encoding='utf-8') as f: 43 | f.write(cell) 44 | 45 | ip = get_ipython() 46 | ip.register_magics(CustomMagics) 47 | -------------------------------------------------------------------------------- /ipyaggrid/display.py: -------------------------------------------------------------------------------- 1 | from ipywidgets.embed import embed_data, dependency_state 2 | import os 3 | 4 | import json 5 | 6 | 7 | def export_html_code(widget): 8 | data = embed_data(views=[widget], state=dependency_state(widget)) 9 | 10 | script_tags = """ 11 | 16 | 17 | 18 | """ 22 | 23 | html_state = """ 24 | 25 | """ 28 | 29 | grid_template = """ 30 |
31 | 32 | 35 |
36 | """ 37 | 38 | manager_state = dict(data['manager_state']) 39 | widget_views = [json.dumps(view) for view in data['view_specs']] 40 | grid_div = grid_template.format(widget_views=widget_views, id=widget._id) 41 | return { 42 | 'script_tags': script_tags, 43 | 'grid_div': grid_div, 44 | 'html_state': html_state, 45 | 'manager_state': manager_state} 46 | -------------------------------------------------------------------------------- /js/src/styles/icons/left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | left 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | left 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /js/src/styles/icons/right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | right 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/right.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | right 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /js/src/styles/icons/grip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | grip 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/grip.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | grip 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /docs/content/.vuepress/components/demo1.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 55 | 56 | -------------------------------------------------------------------------------- /test-zone/js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "trial2-aggrid", 3 | "version": "0.1.0", 4 | "description": "Trial aggrid with npm and webpack", 5 | "license": "MIT", 6 | "author": "oscar6echo", 7 | "main": "src/index1.js", 8 | "scripts": { 9 | "dev": "NODE_ENV=development webpack --mode development --watch", 10 | "build": "NODE_ENV=production webpack --mode production", 11 | "clean": "rimraf dist/*", 12 | "serve": "serve -p 3001 dist/", 13 | "lint": "eslint '.src/*.js'", 14 | "format": "prettier --write '**/*.js'", 15 | "test": "echo 'Error: no test specified' && exit 1" 16 | }, 17 | "dependencies": { 18 | "ag-grid": "^18.0.1", 19 | "ag-grid-enterprise": "^18.0.1" 20 | }, 21 | "devDependencies": { 22 | "babel-core": "^6.26.3", 23 | "babel-loader": "^7.1.4", 24 | "babel-preset-env": "^1.7.0", 25 | "css-loader": "^0.28.11", 26 | "eslint": "^4.19.1", 27 | "eslint-config-airbnb": "^16.1.0", 28 | "eslint-config-prettier": "^2.9.0", 29 | "eslint-plugin-html": "^4.0.3", 30 | "eslint-plugin-import": "^2.12.0", 31 | "eslint-plugin-jsx-a11y": "^6.0.3", 32 | "eslint-plugin-prettier": "^2.6.0", 33 | "eslint-plugin-react": "^7.9.1", 34 | "extract-text-webpack-plugin": "^4.0.0-beta.0", 35 | "html-webpack-plugin": "^3.2.0", 36 | "less-loader": "^4.1.0", 37 | "sass-loader": "^7.0.3", 38 | "node-sass": "^4.9.2", 39 | "url-loader": "^0.5.9", 40 | "svg-colorize-loader": "^0.1.2", 41 | "prettier": "^1.13.5", 42 | "rimraf": "^2.6.2", 43 | "serve": "^9.1.0", 44 | "style-loader": "^0.21.0", 45 | "webpack": "^4.12.0", 46 | "webpack-cli": "^3.0.8" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /docs/content/.vuepress/components/export-grid-1.vue: -------------------------------------------------------------------------------- 1 | 87 | -------------------------------------------------------------------------------- /data/Cars.json: -------------------------------------------------------------------------------- 1 | [ 2 | { "carName": "Chevelle Malibu", "origin": "US", "make":"Chevrolet" }, 3 | { "carName": "Skylark 320", "origin": "US", "make":"Buick" }, 4 | { "carName": "Satellite", "origin": "US", "make":"Plymouth" }, 5 | { "carName": "Rebel SST", "origin": "US", "make":"AMC" }, 6 | { "carName": "Torino", "origin": "US", "make":"Ford" }, 7 | { "carName": "Galaxie 500", "origin": "US", "make":"Ford" }, 8 | { "carName": "Impala", "origin": "US", "make":"Chevrolet" }, 9 | { "carName": "Fury III", "origin": "US", "make":"Plymouth" }, 10 | { "carName": "Catalina", "origin": "US", "make":"Pontiac" }, 11 | { "carName": "Ambassador dpl", "origin": "US", "make":"AMC" }, 12 | { "carName": "Challenger se", "origin": "US", "make":"Dodge" }, 13 | { "carName": "'Cuda 340", "origin": "US", "make":"Plymouth" }, 14 | { "carName": "Monte Carlo", "origin": "US", "make":"Chevrolet" }, 15 | { "carName": "Estate Wagon (SW)", "origin": "US", "make":"Buick" }, 16 | { "carName": "Corona Mark II", "origin": "Asia", "make":"Toyota" }, 17 | { "carName": "Duster", "origin": "US", "make":"Plymouth" }, 18 | { "carName": "Hornet", "origin": "US", "make":"AMC" }, 19 | { "carName": "Maverick", "origin": "US", "make":"Ford" }, 20 | { "carName": "PL510", "origin": "Asia", "make":"Datsun" }, 21 | { "carName": "1131 Deluxe Sedan", "origin": "Europe", "make":"Volkswagen" }, 22 | { "carName": "Peugeot 504", "origin": "Europe", "make":"Peugeot" }, 23 | { "carName": "100 ls", "origin": "Europe", "make":"Audi" }, 24 | { "carName": "SAAB 99e", "origin": "Europe", "make":"SAAB" }, 25 | { "carName": "BMW 2002", "origin": "Europe", "make":"BMW" }, 26 | { "carName": "Gremlin", "origin": "US", "make":"AMC" }, 27 | { "carName": "F250", "origin": "US", "make":"Ford" }, 28 | { "carName": "C20", "origin": "US", "make":"Chevy" }, 29 | { "carName": "D200", "origin": "US", "make":"Dodge" }, 30 | { "carName": "PL411", "origin": "Asia", "make":"Datsun" } 31 | ] 32 | -------------------------------------------------------------------------------- /docs/content/.vuepress/components/export-grid-2.vue: -------------------------------------------------------------------------------- 1 | 91 | -------------------------------------------------------------------------------- /docs/content/overview/purpose.md: -------------------------------------------------------------------------------- 1 | # Purpose 2 | 3 | ## Why ? 4 | 5 | The goal of this [ipywidget](https://ipywidgets.readthedocs.io/en/latest/) is to harness the power of the excellent Javascript library [ag-Grid](https://www.ag-grid.com/), self-proclaimed the _"best HTML5 grid in the world"_ :-) on their home page. 6 | 7 | Grids, or spreadsheets, are ubiquitous in many organizations. At the same time Jupyter notebooks are growing as (one of) the best solution for scripting and interactive computing. In many contexts they tend to replace Excel. 8 | 9 | So it is critically useful to visualize and interact with tabular data, directly from from Python, more specifically [pandas](https://pandas.pydata.org/), in a notebook. 10 | 11 | ## How ? 12 | 13 | This library essentially is a custom Jupyter [ipywidget](https://ipywidgets.readthedocs.io/en/latest). 14 | 15 | For more info see the [ipywigets official documentation](https://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Custom.html) and maybe the article [Authoring Custom Jupyter Widgets](https://blog.jupyter.org/authoring-custom-jupyter-widgets-2884a462e724). 16 | 17 | Like all ipywidgets **ipyaggrid** has 2 parts: 18 | 19 | - The **Python** part: It validates the user input and prepares and passes it to the JavaScript part. It also allows the configuration of the type interactivity the user wants from the grid. 20 | - The **Javascript** part: From the user data and configuration if builds the grid and sets up the interactivity required. After manipulation (e.g. sort, pivot, group, etc) it enables the user to synchronize the data back to the Python kernel. 21 | 22 | **ipyaggrid** is: 23 | + designed to enable easy access to basic ag-Grid features but allows unlimited customization through a full access to the ag-Grid API 24 | + as transparent as possible to give flexible and unhindered access to the underlying library 25 | + adds some convenience options and buttons to the most frequently used features 26 | 27 | ## Sponsors 28 | 29 | Project ipyaggrid receives direct funding from the following sources: 30 | 31 | [![MSD](/ipyaggrid/msd-logo.svg)](https://msd.com) 32 | -------------------------------------------------------------------------------- /js/src/styles/icons/none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | none 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/none.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | none 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /docs/content/.vuepress/config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | title: 'ipyaggrid', 3 | description: 'Using ag-Grid interactively in a Jupyter notebook', 4 | base: '/ipyaggrid/', // Comment if in dev mode 5 | dest: '../public', 6 | head: [['link', { rel: 'icon', href: '/favicon-16x16.png' }]], 7 | // serviceWorker: true, 8 | themeConfig: { 9 | algolia: { 10 | apiKey: 'fd3694c4c215531b2b8b966520ce657e', 11 | indexName: 'ipyaggrid' 12 | }, 13 | 14 | repo: 'https://github.com/widgetti/ipyaggrid', 15 | editLinks: false, 16 | editLinkText: 'Edit this page on GitLab', 17 | lastUpdated: 'Last Updated', 18 | nav: [ 19 | { 20 | text: 'Overview', 21 | link: '/overview/purpose', 22 | }, 23 | { 24 | text: 'User Guide', 25 | link: '/guide/install', 26 | }, 27 | { 28 | text: 'Development', 29 | link: '/dev/dev_install', 30 | }, 31 | ], 32 | sidebarDepth: 5, 33 | sidebar: [ 34 | { 35 | title: 'Overview', 36 | collapsable: false, 37 | children: ['/overview/purpose', '/overview/ag-Grid'], 38 | }, 39 | { 40 | title: 'User Guide', 41 | collapsable: false, 42 | children: [ 43 | // '', 44 | '/guide/install', 45 | '/guide/create', 46 | '/guide/customize', 47 | '/guide/export', 48 | ], 49 | }, 50 | { 51 | title: 'Developer', 52 | collapsable: false, 53 | children: [ 54 | '/dev/dev_install', 55 | '/dev/publish', 56 | '/dev/doc', 57 | '/dev/structure', 58 | ], 59 | }, 60 | ], 61 | }, 62 | markdown: { 63 | lineNumbers: false, 64 | }, 65 | }; 66 | -------------------------------------------------------------------------------- /docs/content/dev/publish.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Publish 4 | 5 | This section is intentionally verbose in order to help ipywidget developer. 6 | 7 | ## Versions 8 | 9 | Set the **same** Javascript version in the following files. 10 | _WARNING_: This is a **manual** sync. 11 | 12 | + `ipyaggrid/js/package.json` 13 | 14 | Set the Python version in file: 15 | + `ipyaggrid/__meta__.py` 16 | 17 | ## Git 18 | 19 | Git [commit](https://git-scm.com/docs/git-commit) the code with a [tag](https://git-scm.com/docs/git-tag). 20 | 21 | ```bash 22 | # starting from repo top folder 23 | 24 | # possibly: start afresh 25 | git clean -fdxn # dry run - recommended as cannot be undone 26 | git clean -fdx 27 | 28 | # commit 29 | git add . 30 | git commit -m 'my comment' 31 | git tag '' 32 | git push 33 | git push --tags 34 | ``` 35 | 36 | ## Node 37 | 38 | Build the Javascript files and publish the node package to [npmjs.org](https://www.npmjs.com/). 39 | For more info see th [official doc](https://docs.npmjs.com/getting-started/publishing-npm-packages). 40 | 41 | ```bash 42 | # starting from repo top folder 43 | # make sure the version in js/package.json is correct 44 | 45 | # build notebook extension javascript 46 | $ cd js 47 | $ npm ci 48 | 49 | # test run to see what you will publish 50 | # npm pack 51 | 52 | # login npm if necessary 53 | npm login 54 | 55 | # publish npm package to npmjs.org - using ~/.npmrc 56 | $ npm publish --access=public 57 | # if you made a mistake you can unpublish in the first 24h 58 | ``` 59 | 60 | ## Python 61 | 62 | Publish the Python package to PyPI. 63 | For more info see the [official doc](https://packaging.python.org/tutorials/distributing-packages/). 64 | 65 | ```bash 66 | # starting from repo top folder 67 | # make sure package version is correct in __meta__.py 68 | 69 | # clear dist/ from previous bundles 70 | rm -rf dist 71 | 72 | # build Python package 73 | $ python setup.py sdist 74 | $ python setup.py bdist_wheel --universal 75 | 76 | # upload package to PyPI - using ~/.pypirc 77 | $ twine upload dist/* 78 | # if you made a mistake you can remove the package on pypi.org 79 | ``` 80 | 81 | Done. 82 | 83 | -------------------------------------------------------------------------------- /ipyaggrid/community.py: -------------------------------------------------------------------------------- 1 | from .grid import Grid as EnterpriseGrid 2 | 3 | class Grid(EnterpriseGrid): 4 | def __init__( 5 | self, 6 | width='100%', 7 | height=0, 8 | center=False, 9 | theme='ag-theme-fresh', 10 | 11 | grid_data=[], 12 | grid_options={}, 13 | grid_options_multi=[], 14 | columns_fit='size_to_fit', 15 | index=False, 16 | keep_multiindex=False, 17 | compress_data=True, 18 | 19 | quick_filter=False, 20 | export_csv=False, 21 | export_excel=False, 22 | show_toggle_delete=False, 23 | show_toggle_edit=False, 24 | sync_on_edit=False, 25 | sync_grid=True, 26 | paste_from_excel=False, 27 | export_mode='disabled', 28 | export_to_df=True, 29 | hide_grid=False, 30 | 31 | js_helpers_custom='', 32 | js_pre_helpers=[], 33 | js_pre_grid=[], 34 | js_post_grid=[], 35 | css_rules='', 36 | menu=None, 37 | user_params={} 38 | ): 39 | super().__init__( 40 | height=height, 41 | center=center, 42 | theme=theme, 43 | 44 | width=width, 45 | grid_data=grid_data, 46 | grid_options=grid_options, 47 | grid_options_multi=grid_options_multi, 48 | columns_fit=columns_fit, 49 | index=index, 50 | keep_multiindex=keep_multiindex, 51 | compress_data=compress_data, 52 | 53 | quick_filter=quick_filter, 54 | export_csv=export_csv, 55 | export_excel=export_excel, 56 | show_toggle_delete=show_toggle_delete, 57 | show_toggle_edit=show_toggle_edit, 58 | sync_on_edit=sync_on_edit, 59 | sync_grid=sync_grid, 60 | paste_from_excel=paste_from_excel, 61 | export_mode=export_mode, 62 | export_to_df=export_to_df, 63 | hide_grid=hide_grid, 64 | 65 | js_helpers_custom=js_helpers_custom, 66 | js_pre_helpers=js_pre_helpers, 67 | js_pre_grid=js_pre_grid, 68 | js_post_grid=js_post_grid, 69 | css_rules=css_rules, 70 | menu=menu, 71 | user_params=user_params, 72 | license='community', 73 | ) 74 | -------------------------------------------------------------------------------- /ipyaggrid/js/helpersBuiltin.js: -------------------------------------------------------------------------------- 1 | helpersBuiltin = { 2 | dateFormatter: function(node) { 3 | // make sure date is not undefined 4 | if (node && node.value && node.value !== "NaT") { 5 | let d = new Date(node.value); 6 | let h = d.getHours(); 7 | let m = d.getMinutes(); 8 | let s = d.getSeconds(); 9 | const offset = d.getTimezoneOffset() * 60000; 10 | d = new Date(d.getTime() - offset); 11 | const ymd = d.toISOString().substring(0, 10); 12 | if (h === 0 && m === 0 && s === 0) { 13 | return ymd; 14 | } 15 | if (h === 0) h = '00'; 16 | if (m === 0) m = '00'; 17 | if (s === 0) s = '00'; 18 | return `${ymd} ${h}:${m}:${s}`; 19 | } 20 | return null; 21 | }, 22 | 23 | formatInt: d3.format(',.0f'), 24 | formatFloat: d3.format(',.2f'), 25 | 26 | intFormatter: function(node) { 27 | return formatInt(node.value); 28 | }, 29 | 30 | floatFormatter: function(node) { 31 | return formatFloat(node.value); 32 | }, 33 | 34 | compareDates: function(filterLocalDate, cellValue) { 35 | // Assume dates are stored as iso 36 | const cellDate = new Date(cellValue); 37 | 38 | if (cellDate < filterLocalDate) { 39 | return -1; 40 | } else if (cellDate > filterLocalDate) { 41 | return 1; 42 | } 43 | return 0; 44 | }, 45 | 46 | sizeToFit: function(gridOptions) { 47 | gridOptions.api.sizeColumnsToFit(); 48 | }, 49 | 50 | autoSizeAll: function(gridOptions) { 51 | const allColumnIds = []; 52 | gridOptions.columnApi.getColumns().forEach(column => { 53 | allColumnIds.push(column.colId); 54 | }); 55 | gridOptions.columnApi.autoSizeColumns(allColumnIds); 56 | }, 57 | 58 | /** 59 | * Exporting data to CSV using ag-Grid api. 60 | * @param {Object} gridOptions 61 | */ 62 | exportToCsv: function(gridOptions) { 63 | gridOptions.api.exportDataAsCsv(); 64 | }, 65 | 66 | /** 67 | * Exporting data to Excel using ag-Grid api. 68 | * @param {Object} gridOptions 69 | */ 70 | exportToExcel: function(gridOptions) { 71 | gridOptions.api.exportDataAsExcel(); 72 | }, 73 | }; 74 | -------------------------------------------------------------------------------- /ipyaggrid/__meta__.py: -------------------------------------------------------------------------------- 1 | import glob 2 | import os 3 | from os.path import isdir 4 | 5 | def _get_version(version_info): 6 | """ 7 | converts version info tuple to version string 8 | example: 9 | (0, 1, 2, 'beta', 3) returns '0.1.2-beta.3' 10 | """ 11 | vi = [str(e) for e in version_info] 12 | suffix = '' 13 | if len(vi) > 3: 14 | suffix = '-' + '.'.join(vi[3:]) 15 | version = '.'.join(vi[:3]) + suffix 16 | return version 17 | 18 | 19 | # meta data 20 | 21 | __name__ = 'ipyaggrid' 22 | name_url = __name__.replace('_', '-') 23 | __version__ = '0.5.4' 24 | __version_js__ = __version__ 25 | 26 | 27 | __description__ = 'Jupyter widget - ag-grid in the notebook' 28 | __long_description__ = 'See repo README' 29 | __author__ = 'Mario Buikhuizen, Maarten Breddels, DGothrek' 30 | __author_email__ = 'mariobuikhuizen@gmail.com, maartenbreddels@gmail.com' 31 | 32 | # gitlab template 33 | __url__ = 'https://github.com/widgetti/ipyaggrid' 34 | 35 | __download_url__ = 'https://github.com/widgetti/ipyaggrid/archive/refs/tags/v{}.zip'.format(__version__) 36 | 37 | __keywords__ = ['ipywidget', 38 | 'javascript', 39 | 'ag-grid', 40 | ] 41 | __license__ = 'MIT' 42 | __classifiers__ = ['Development Status :: 4 - Beta', 43 | 'License :: OSI Approved :: MIT License', 44 | 'Programming Language :: Python :: 3.5', 45 | 'Programming Language :: Python :: 3.6' 46 | ] 47 | __include_package_data__ = True 48 | __package_data__ = {} 49 | __data_files__ = [ 50 | # classic notebook extension 51 | ('share/jupyter/nbextensions/ipyaggrid', [ 52 | 'ipyaggrid/nbextension/extension.js', 53 | 'ipyaggrid/nbextension/index.js', 54 | 'ipyaggrid/nbextension/index.js.map', 55 | 'ipyaggrid/nbextension/906.index.js' 56 | ]), 57 | ('etc/jupyter/nbconfig/notebook.d', [ 58 | 'ipyaggrid/ipyaggrid.json' 59 | ]), 60 | # Lab Extension 61 | ('share/jupyter/labextensions/ipyaggrid', ['install.json']), 62 | ] 63 | 64 | # Lab Extension 65 | for root, _, files in os.walk('ipyaggrid/labextension'): 66 | dir_ = os.path.relpath(root, 'ipyaggrid/labextension') 67 | target_dir = 'share/jupyter/labextensions/ipyaggrid%s' % ('' if dir_ == '.' else "/%s" % dir_) 68 | __data_files__.append((target_dir, ["%s/%s" % (root, f) for f in files])) 69 | 70 | __zip_safe__ = False 71 | __entry_points__ = {} 72 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | 2 | # necessary to push to PyPI 3 | # cf. http://peterdowns.com/posts/first-time-with-pypi.html 4 | # cf. https://tom-christie.gitlab.io/articles/pypi/ 5 | # cf. https://pythonhosted.org/setuptools/setuptools.html 6 | 7 | # commands: 8 | # 1-line: 9 | # python setup.py sdist upload -r testpypi 10 | # python setup.py sdist upload -r pypi 11 | # 2-line - recommended, more control 12 | # python setup.py sdist 13 | # twine upload dist/* 14 | 15 | 16 | from distutils.util import convert_path 17 | from setuptools import setup, find_packages 18 | 19 | packages = find_packages() 20 | module = "ipyaggrid" 21 | 22 | 23 | meta_ns = {} 24 | ver_path = convert_path(module + '/__meta__.py') 25 | with open(ver_path) as ver_file: 26 | exec(ver_file.read(), meta_ns) 27 | 28 | name = meta_ns['__name__'] 29 | packages = packages 30 | version = meta_ns['__version__'] 31 | description = meta_ns['__description__'] 32 | author = meta_ns['__author__'] 33 | author_email = meta_ns['__author_email__'] 34 | url = meta_ns['__url__'] 35 | download_url = meta_ns['__download_url__'] 36 | keywords = meta_ns['__keywords__'] 37 | license = meta_ns['__license__'] 38 | classifiers = meta_ns['__classifiers__'] 39 | include_package_data = meta_ns['__include_package_data__'] 40 | package_data = meta_ns['__package_data__'] 41 | data_files = meta_ns['__data_files__'] 42 | zip_safe = meta_ns['__zip_safe__'] 43 | entry_points = meta_ns['__entry_points__'] 44 | 45 | 46 | # read requirements.txt 47 | with open('requirements.txt', 'r') as f: 48 | content = f.read() 49 | li_req = content.split('\n') 50 | install_requires = [e.strip() for e in li_req if len(e)] 51 | 52 | with open('README.md') as f: 53 | long_description = f.read() 54 | 55 | setup( 56 | name=name, 57 | version=version, 58 | description=description, 59 | long_description=long_description, 60 | long_description_content_type="text/markdown", 61 | author=author, 62 | author_email=author_email, 63 | url=url, 64 | download_url=download_url, 65 | keywords=keywords, 66 | license=license, 67 | classifiers=classifiers, 68 | packages=packages, 69 | install_requires=install_requires, 70 | extras_require={ 71 | "unit-test": [ 72 | "pytest", 73 | ], 74 | "ui-test": [ 75 | "solara[pytest]", 76 | "jupyter_server<2", 77 | "playwright==1.32.1", 78 | "jupyterlab==3.6.3" 79 | ] 80 | }, 81 | include_package_data=include_package_data, 82 | package_data=package_data, 83 | data_files=data_files, 84 | zip_safe=zip_safe, 85 | entry_points=entry_points 86 | ) 87 | -------------------------------------------------------------------------------- /test-zone/js/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | // const webpack = require('webpack'); 3 | const ExtractTextPlugin = require('extract-text-webpack-plugin'); 4 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 5 | 6 | const extractCSS = new ExtractTextPlugin('style/[name].css'); 7 | const extractLESS = new ExtractTextPlugin('style/[name]-less.css'); 8 | const extractSASS = new ExtractTextPlugin('style/[name].scss'); 9 | 10 | module.exports = { 11 | target: 'web', 12 | entry: { 13 | app: './src/index2.js', 14 | vendor: ['ag-grid', 'lodash'], 15 | }, 16 | output: { 17 | path: path.resolve(__dirname, './dist/assets'), 18 | publicPath: '/assets/', 19 | filename: '[name].js', // [hash].[name] 20 | }, 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.js$/, 25 | loader: 'babel-loader', 26 | exclude: /node_modules/, 27 | }, 28 | { 29 | test: /\.css$/, 30 | // use: ['style-loader', 'css-loader'], 31 | use: extractCSS.extract(['css-loader']), 32 | }, 33 | { 34 | test: /\.less$/, 35 | use: extractLESS.extract(['style-loader', 'css-loader', 'less-loader']), 36 | }, 37 | { 38 | test: /\.scss$/, 39 | use: ['style-loader', 'css-loader', 'sass-loader'], 40 | }, 41 | { 42 | test: /\.svg$/, 43 | use: [ 44 | { loader: 'url-loader' }, 45 | { 46 | loader: 'svg-colorize-loader', 47 | options: { 48 | color1: '#000000', 49 | color2: '#FFFFFF', 50 | }, 51 | }, 52 | ], 53 | }, 54 | ], 55 | }, 56 | plugins: [ 57 | extractCSS, 58 | extractLESS, 59 | new HtmlWebpackPlugin({ 60 | inject: true, 61 | hash: false, 62 | template: './src/index.html', 63 | filename: path.resolve(__dirname, './dist/index.html'), 64 | }), 65 | ], 66 | optimization: { 67 | minimize: true, 68 | }, 69 | }; 70 | 71 | if (process.env.NODE_ENV === 'development') { 72 | // console.log('development mode'); 73 | module.exports.devtool = 'eval-source-map'; 74 | module.exports.plugins = (module.exports.plugins || []).concat([]); 75 | } 76 | 77 | if (process.env.NODE_ENV === 'production') { 78 | // console.log('production mode'); 79 | module.exports.devtool = 'source-map'; 80 | module.exports.plugins = (module.exports.plugins || []).concat([]); 81 | } 82 | -------------------------------------------------------------------------------- /js/src/styles/ipywidgets/nouislider-custom.css: -------------------------------------------------------------------------------- 1 | /* Copyright (c) Jupyter Development Team. 2 | * Distributed under the terms of the Modified BSD License. 3 | */ 4 | 5 | /* Custom CSS for nouislider */ 6 | 7 | .noUi-connect { 8 | background: rgb(33, 150, 243); 9 | } 10 | 11 | .noUi-horizontal { 12 | height: var(--jp-widgets-slider-track-thickness); 13 | } 14 | 15 | .noUi-vertical { 16 | width: var(--jp-widgets-slider-track-thickness); 17 | height: 100%; 18 | } 19 | 20 | .noUi-horizontal .noUi-handle { 21 | width: var(--jp-widgets-slider-handle-size); 22 | height: var(--jp-widgets-slider-handle-size); 23 | border-radius: 50%; 24 | top: calc( 25 | ( 26 | var(--jp-widgets-slider-track-thickness) - 27 | var(--jp-widgets-slider-handle-size) 28 | ) / 2 29 | ); 30 | right: calc(var(--jp-widgets-slider-handle-size) / -2); 31 | } 32 | 33 | .noUi-vertical .noUi-handle { 34 | height: var(--jp-widgets-slider-handle-size); 35 | width: var(--jp-widgets-slider-handle-size); 36 | border-radius: 50%; 37 | right: calc( 38 | ( 39 | var(--jp-widgets-slider-handle-size) - 40 | var(--jp-widgets-slider-track-thickness) 41 | ) / -2 42 | ); 43 | top: calc(var(--jp-widgets-slider-handle-size) / -2); 44 | } 45 | 46 | .noUi-handle:after { 47 | content: none; 48 | } 49 | 50 | .noUi-handle:before { 51 | content: none; 52 | } 53 | 54 | .noUi-target { 55 | background: #fafafa; 56 | border-radius: 4px; 57 | border: 1px; 58 | /* box-shadow: inset 0 1px 1px #F0F0F0, 0 3px 6px -5px #BBB; */ 59 | } 60 | 61 | .ui-slider { 62 | border: var(--jp-widgets-slider-border-width) solid var(--jp-layout-color3); 63 | background: var(--jp-layout-color3); 64 | box-sizing: border-box; 65 | position: relative; 66 | border-radius: 0px; 67 | } 68 | 69 | .noUi-handle { 70 | width: var(--jp-widgets-slider-handle-size); 71 | border: 1px solid #d9d9d9; 72 | border-radius: 3px; 73 | background: #fff; 74 | cursor: default; 75 | box-shadow: none; 76 | outline: none; 77 | } 78 | 79 | .noUi-target:not([disabled]) .noUi-handle:hover, 80 | .noUi-target:not([disabled]) .noUi-handle:focus { 81 | background-color: var(--jp-widgets-slider-active-handle-color); 82 | border: var(--jp-widgets-slider-border-width) solid 83 | var(--jp-widgets-slider-active-handle-color); 84 | } 85 | 86 | [disabled].noUi-target { 87 | opacity: 0.35; 88 | } 89 | 90 | .noUi-connects { 91 | overflow: visible; 92 | z-index: 0; 93 | background: var(--jp-layout-color3); 94 | } 95 | 96 | .noUi-vertical .noUi-connect { 97 | width: calc(100% + 2px); 98 | right: -1px; 99 | } 100 | 101 | .noUi-horizontal .noUi-connect { 102 | height: calc(100% + 2px); 103 | top: -1px; 104 | } 105 | -------------------------------------------------------------------------------- /docs/content/.vuepress/components/demo2.vue: -------------------------------------------------------------------------------- 1 | 18 | 19 | 90 | 91 | -------------------------------------------------------------------------------- /js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ipyaggrid", 3 | "version": "0.5.4", 4 | "description": "A jupyter widget embedding the ag-grid library", 5 | "author": "Louis Raison, oscar6echo", 6 | "license": "MIT", 7 | "main": "dist/index.js", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://gitlab.com/DGothrek/ipyaggrid" 11 | }, 12 | "keywords": [ 13 | "jupyter", 14 | "widgets", 15 | "ipython", 16 | "ipywidgets" 17 | ], 18 | "files": [ 19 | "src/**/*.js", 20 | "dist/*.js", 21 | "src/styles/**/*.css", 22 | "src/styles/icons/*.svg" 23 | ], 24 | "jupyterlab": { 25 | "extension": "src/labplugin", 26 | "outputDir": "../ipyaggrid/labextension", 27 | "sharedPackages": { 28 | "@jupyter-widgets/base": { 29 | "bundled": false, 30 | "singleton": true 31 | } 32 | } 33 | }, 34 | "scripts": { 35 | "clean": "rimraf dist/ && rimraf ../ipyaggrid/nbextension/ && rimraf ../ipyaggrid/labextension/", 36 | "cleanall": "npm run clean && rimraf node_modules/", 37 | "prepare": "webpack --mode production", 38 | "watch": "watch 'webpack --mode development' src/", 39 | "format": "prettier --write '**/*.{js,jsx}'", 40 | "lint": "eslint '**/*.{js,jsx}' --quiet", 41 | "test": "echo \"Error: no test specified\"", 42 | "dev": "webpack --mode=development && npm run build:labextension:dev", 43 | "build": "webpack --mode=production && npm run build:labextension", 44 | "build:labextension": "jupyter labextension build .", 45 | "build:labextension:dev": "jupyter labextension build --development True ." 46 | }, 47 | "dependencies": { 48 | "@jupyter-widgets/base": "^3.0.0 || ^4 || ^6", 49 | "@jupyter-widgets/controls": "^2.0.0 || ^3 || ^4 || ^5", 50 | "ag-grid-community": "28.1.1", 51 | "ag-grid-enterprise": "28.1.1", 52 | "d3": "^7.8.5", 53 | "lodash": "^4.17.15", 54 | "pako": "^1.0.10" 55 | }, 56 | "devDependencies": { 57 | "@babel/core": "^7.4.4", 58 | "@babel/preset-env": "^7.4.4", 59 | "@jupyterlab/builder": "^4", 60 | "css-loader": "^6", 61 | "eslint": "^5.16.0", 62 | "eslint-config-airbnb": "^17.1.1", 63 | "eslint-config-prettier": "^6.0.0", 64 | "eslint-plugin-html": "^6.0.0", 65 | "eslint-plugin-import": "^2.18.2", 66 | "eslint-plugin-jsx-a11y": "^6.2.3", 67 | "eslint-plugin-prettier": "^3.1.0", 68 | "eslint-plugin-react": "^7.14.3", 69 | "prettier": "^1.18.2", 70 | "rimraf": "^2.6.3", 71 | "style-loader": "^3", 72 | "svg-colorize-loader": "^0.1.2", 73 | "webpack": "^5", 74 | "webpack-cli": "^5" 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /docs/content/dev/doc.md: -------------------------------------------------------------------------------- 1 | # Documentation 2 | 3 | This section explains how to update and build the documentation. 4 | All docs source files are located in the repo [docs](https://gitlab.com/DGothrek/ipyaggrid/tree/master/docs) folder. 5 | 6 | ## CI-CD 7 | 8 | The documentation is a static web site powered by [vuepress](https://vuepress.vuejs.org/). 9 | It is automatically built and deployed each time a new commit is pushed to master. 10 | 11 | ## Notebooks 12 | 13 | Beyond the markdown files located in the [content](https://gitlab.com/DGothrek/ipyaggrid/tree/master/docs/content) folder, the notebooks that build the code snippets and embedded live grids are in the [notebooks](https://gitlab.com/DGothrek/ipyaggrid/tree/master/docs/notebooks) folder. 14 | 15 | Some of these notebooks are available via a [mybinder link](https://mybinder.org/v2/gl/DGothrek%2Fipyaggrid/binder-demo). 16 | 17 | Here is an overview of their roles: 18 | + [demo-build-dataframe-output-html.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/demo-build-dataframe-output-html.ipynb) 19 | + Create regular sample dataframes HTML 20 | + Shown in the [_User Guide/Create/Parameters/Multi Index_](../guide/create.html#export-to-python) section 21 | 22 | 23 | + [demo-build-multiindex-dataframe-html.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/demo-build-multiindex-dataframe-html.ipynb) 24 | + Create multi-index sample dataframes HTML 25 | + Shown in the [_User Guide/Create/Parameters/Multi Index_](../guide/create.html#multi-index) section 26 | 27 | + [load-ipywidget-css.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/load-ipywidget-css.ipynb) 28 | + Load ipywidgets CSS - to be used in custom _Excel_ style 29 | + Not present in the docs 30 | 31 | + [doc-builder.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/doc-builder.ipynb): 32 | + Creates the documentation code snippets and live demo grids, in fact vue components encapsulating the demo grids in iframes 33 | + Collection of live examples available for regular use 34 | + Link from the [_User Guide/Create_](../guide/create.html#create) section in TIP at top of page 35 | 36 | + [demo-ipyaggrid-python-functions.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/demo-ipyaggrid-python-functions.ipynb) 37 | + Collection of live examples focused on the manipulation of the grid from Python 38 | + Link from the [_User Guide/Live Demo/MyBinder_](../guide/create.html#mybinder) section 39 | 40 | + [demo-ipyaggrid-export-data.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/demo-ipyaggrid-export-data.ipynb) 41 | + Collection of live examples focused on the exporting of data from JavaScript to Python 42 | + Link from the [_User Guide/Create/Parameters/Export to Python_](../guide/create.html#export-to-python) section 43 | 44 | + [demo-ipyaggrid-customize.ipynb](https://gitlab.com/DGothrek/ipyaggrid/blob/master/docs/notebooks/demo-ipyaggrid-customize.ipynb) 45 | + Collection of live examples focused on advanced customization of the **ag-Grid** options using their API and the various JS injections points made available in **ipyaggrid** 46 | + Link from the [_User Guide/Customize/Live Demo_](../guide/customize.html#live-demo) section 47 | 48 | -------------------------------------------------------------------------------- /js/src/styles/icons/loading.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | loading 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /test-zone/js/src/icons/loading.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | loading 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /docs/notebooks/demo-ipyaggrid-javascript.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "id": "a309447d", 6 | "metadata": {}, 7 | "source": [ 8 | "# Use javascript in `grid_options` by using `__js__:` prefix" 9 | ] 10 | }, 11 | { 12 | "cell_type": "code", 13 | "execution_count": null, 14 | "id": "614ccb50", 15 | "metadata": {}, 16 | "outputs": [], 17 | "source": [ 18 | "from ipyaggrid import Grid\n", 19 | "\n", 20 | "grid = Grid(\n", 21 | " css_rules=\"\"\"\n", 22 | " .ag-cell-not-inline-editing.price-high {\n", 23 | " background-color: red;\n", 24 | " color: white;\n", 25 | " }\n", 26 | " .my-tooltip {\n", 27 | " background-color: white;\n", 28 | " border: 1px solid black;\n", 29 | " padding: 8px;\n", 30 | " }\n", 31 | " \"\"\",\n", 32 | " grid_data=[\n", 33 | " {\"make\": \"Toyota\", \"model\": \"Celica\", \"price\": 35000},\n", 34 | " {\"make\": \"Ford\", \"model\": \"Mondeo\", \"price\": 32000},\n", 35 | " {\"make\": \"Porsche\", \"model\": \"Boxster\", \"price\": 72000},\n", 36 | " ],\n", 37 | " grid_options={\n", 38 | " 'columnDefs': [\n", 39 | " {\"headerName\": \"Make\", \"field\": \"make\", \"editable\": True},\n", 40 | " {\"headerName\": \"Model\", \"field\": \"model\", \"editable\": True},\n", 41 | " {\"headerName\": \"Price\", \"field\": \"price\", \"editable\": True, 'type': 'numericColumn',\n", 42 | " 'cellClass': \"\"\"function(params) {\n", 43 | " return params.value >32000 ? 'price-high' : '';\n", 44 | " }\"\"\",\n", 45 | " \"tooltipField\": 'price',\n", 46 | " \"tooltipComponent\": \"\"\"__js__: class {\n", 47 | " init(params) {\n", 48 | " const eGui = this.eGui = document.createElement('div');\n", 49 | " \n", 50 | " if (params.value > 32000) {\n", 51 | " eGui.classList.add('my-tooltip');\n", 52 | " eGui.innerHTML = 'value to high'; \n", 53 | " }\n", 54 | " }\n", 55 | " \n", 56 | " getGui() {\n", 57 | " return this.eGui;\n", 58 | " }\n", 59 | " }\"\"\",\n", 60 | " }\n", 61 | " ],\n", 62 | " 'tooltipShowDelay': 0,\n", 63 | " 'tooltipHideDelay': 2000,\n", 64 | " },\n", 65 | ")\n", 66 | "\n", 67 | "grid" 68 | ] 69 | }, 70 | { 71 | "cell_type": "code", 72 | "execution_count": null, 73 | "id": "2ffb64ae", 74 | "metadata": {}, 75 | "outputs": [], 76 | "source": [] 77 | } 78 | ], 79 | "metadata": { 80 | "kernelspec": { 81 | "display_name": "Python 3 (ipykernel)", 82 | "language": "python", 83 | "name": "python3" 84 | }, 85 | "language_info": { 86 | "codemirror_mode": { 87 | "name": "ipython", 88 | "version": 3 89 | }, 90 | "file_extension": ".py", 91 | "mimetype": "text/x-python", 92 | "name": "python", 93 | "nbconvert_exporter": "python", 94 | "pygments_lexer": "ipython3", 95 | "version": "3.9.13" 96 | } 97 | }, 98 | "nbformat": 4, 99 | "nbformat_minor": 5 100 | } 101 | -------------------------------------------------------------------------------- /docs/content/overview/ag-Grid.md: -------------------------------------------------------------------------------- 1 | # ag-Grid 2 | 3 | This page is a brief introduction to [ag-Grid](https://www.ag-grid.com/). 4 | See the [official documentation](https://www.ag-grid.com/documentation-main/documentation.php) 5 | for exhaustive information. 6 | 7 | ## Introduction 8 | 9 | [ag-Grid](https://www.ag-grid.com/) is a powerful JavaScript library built 10 | around performance, elaborate features, and a well designed user-friendly 11 | yet powerful API. It can handle up to hundreds of thousands of lines 12 | without significant performance degradation. 13 | 14 | Checkout their [demo page](https://www.ag-grid.com/example.php) and experiment. 15 | 16 | ## Basics 17 | 18 | The grid only has one constructor `Grid` with two parameters: 19 | 20 | + the `options` containing user data and grid configuration 21 | + the `DOM element` in which the grid is to be located 22 | 23 | After the grid is built, the API is accessible as a property of `options`. 24 | It enables reshaping the grid, accessing data, etc. 25 | 26 | ### Simple grid 27 | 28 | Here is the example of a very simple grid. 29 | 30 | Code: 31 | 32 | ```javascript 33 | // Define the rows of the data to display 34 | var rowDat = [ 35 | { make: "Toyota", model: "Celica", price: 35000 }, 36 | { make: "Ford", model: "Mondeo", price: 32000 }, 37 | { make: "Porsche", model: "Boxter", price: 72000 } 38 | ]; 39 | 40 | // Set up the columns names 41 | var columnDef = [ 42 | { headerName: "Make", field: "make" }, 43 | { headerName: "Model", field: "model" }, 44 | { headerName: "Price", field: "price" } 45 | ]; 46 | 47 | // Add custom parameters 48 | var gridOptions = { 49 | columnDefs: columnDef, 50 | // A bunch of different options. 51 | enableFilter: true, 52 | defaultColDef: { 53 | editable: true 54 | }, 55 | rowSelection: "multiple", 56 | enableSorting: true 57 | }; 58 | 59 | // Use an existing DOM element 60 | var gridDiv = document.querySelector("#myGrid"); 61 | new agGrid.Grid(gridDiv, gridOptions); 62 | 63 | // API is available 64 | gridOptions.api.setRowData(rowDat); 65 | ``` 66 | 67 | 68 | 69 | Note that you can select multiple line (`Ctrl+Click` or `Cmd+Click`), sort, filter, move the 70 | columns, etc. A lot of defaults are intuitive, but nearly everything is **customizable**. 71 | 72 | ## Advanced 73 | 74 | There are many, many features. Check out the 75 | [documentation features page](https://www.ag-grid.com/features-overview/). 76 | Below a selection of those we find interesting are demonstrated. 77 | 78 | ### Grouping and Pivoting 79 | 80 | You can update groups in the `Columns` panel. For more info see the 81 | [grid pivoting doc page](https://www.ag-grid.com/javascript-grid-pivoting/). 82 | 83 | 84 | 85 | ### Rendering 86 | 87 | Cells can be heavily customized. For more info see the [cell rendering](https://www.ag-grid.com/javascript-grid-cell-rendering/) and 88 | [full width row groups rendering](https://www.ag-grid.com/javascript-grid-grouping/#full-width-groups-rendering) doc pages. 89 | 90 | 91 | 92 | To see how to build it in **ipyaggrid**: 93 | [![Binder](https://mybinder.org/badge.svg)](https://mybinder.org/v2/gl/DGothrek%2Fipyaggrid/binder-demo?filepath=doc-builder.ipynb) 94 | 95 | ### Status Bar 96 | 97 | To see the status bar in action, select a part of the grid (via `Ctrl+Click`, `Cmd+Click` or `Drag & Drop`) and read the result at the bottom right. 98 | For more info see the [status bar doc page](https://www.ag-grid.com/javascript-grid-status-bar/). 99 | 100 | --------------------------------------------------------------------------------