├── 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 |
--------------------------------------------------------------------------------
/js/src/styles/icons/small-up.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/minus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/small-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/small-left.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/tree-open.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/small-up.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/tree-open.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/small-right.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/tree-closed.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/small-down.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/small-left.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/tree-closed.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/tick.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/js/src/styles/icons/filter.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/filter.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/tree-indeterminate.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/aggregation.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/js/src/styles/icons/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/plus.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/column.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/star.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/star.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/cancel.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/column.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/cancel.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/not-allowed.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/not-allowed.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/paste.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/paste.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/copy.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/copy.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/folder.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/js/src/styles/icons/previous.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/folder.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/previous.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/menu.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/next.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/menu.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/folder-open.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/cross.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/first.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/first.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/contracted.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/contracted.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/cross.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/pin.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/js/src/styles/icons/checkbox-unchecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/checkbox-unchecked.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/checkbox-unchecked-readonly.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/checkbox-unchecked-readonly.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/expanded.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/last.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/expanded.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/last.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/checkbox-checked.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/checkbox-indeterminate.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/checkbox-checked-readonly.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/checkbox-checked-readonly.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/checkbox-indeterminate-readonly.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/pivot.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/checkbox-indeterminate-readonly.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/columns.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/pivot.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/columns.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/js/src/styles/icons/indeterminate.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/eye.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/indeterminate.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/cut.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 | [](https://pypi.python.org/pypi/ipyaggrid/)
4 | [](https://pypi.python.org/pypi/ipyaggrid/)
5 | [](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 | [](https://msd.com)
26 |
--------------------------------------------------------------------------------
/js/src/styles/icons/group.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/group.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/eye-slash.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/arrows.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/asc.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/desc.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/left.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/right.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/right.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/js/src/styles/icons/grip.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/grip.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/docs/content/.vuepress/components/demo1.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
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 |
2 |
86 |
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 |
2 |
90 |
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 | [](https://msd.com)
32 |
--------------------------------------------------------------------------------
/js/src/styles/icons/none.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/none.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 |
2 |
17 |
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 |
--------------------------------------------------------------------------------
/test-zone/js/src/icons/loading.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/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 | [](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 |
--------------------------------------------------------------------------------