widgetti / ipyaggrid Goto Github PK
View Code? Open in Web Editor NEWUsing ag-Grid in Jupyter notebooks.
License: MIT License
Using ag-Grid in Jupyter notebooks.
License: MIT License
I have a voila that displays an AG Grid, as soon as the table is created the Voila theme is changed.
See below minimal reproducible example. As can be seen, the Voila page is initially shown with a dark background, after 10 seconds the page automatically turns into white background (as soon as the AG Grid is constructed).
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from time import sleep\n",
"from ipyaggrid import Grid\n",
"print('Theme is dark now')\n",
"sleep(10)\n",
"Grid(grid_data=[{'Foo': 'spam', 'Bar': 'eggs'}], grid_options={'columnDefs': [{'field': 'Foo'}, {'field': 'Bar'}]})\n",
"print('Theme is light now')"
]
}
],
"metadata": {
"jupytext": {
"formats": "ipynb,py:light",
"text_representation": {
"extension": ".py",
"format_name": "light",
"format_version": "1.4",
"jupytext_version": "1.2.0"
}
},
"kernelspec": {
"display_name": "Python 3.8.10 ('env_local')",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
},
"voila": {
"theme": "dark"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Python 3.8.10
jupyter == 1.0.0
voila == 0.4.0
ipyaggrid == 0.4.0
as per title the toggle delete button has no effect
Dear widgetti,
thank you for your ag-grid python package.
I noticed that after some seconds (10-20 seconds) a simple grids cell's edits are overwritten with .grid_data_in
:
from ipyaggrid import Grid
import pandas as pd
df = pd.DataFrame(columns=["test1","test2","test3"])
for i in range(10):
df.loc[len(df)] = pd.Series(dtype='float64')
grid_options = {
'columnDefs' : [{'headerName':c,'field': c} for c in df.columns],
'rowSelection': 'multiple',
'enableRangeSelection': True,
'defaultColDef': {'editable': True},
}
g1 = Grid(grid_data=df,grid_options=grid_options,sync_on_edit=True,sync_grid=True,theme='ag-theme-balham',columns_fit='auto',index=False)
display(g1)
reproduces the issue. Is there something one can do about it. Is this related to #38 ?
Thank you for your help :).
Best
Micha
It seems that if I use the current code working in jupyterlab, the HTML export is broken (from jupyterlab)
Example:
from ipyaggrid import Grid
grid_options = {
'columnDefs':[{'field':'x'}],
'enableFilter':True,
'enableSorting':True,
'animateRows':True,
}
g = Grid(grid_options=grid_options,
grid_data=[{'x':'1'}],
paste_from_excel=True)
g
print(g.export_html(build=True))
--> save this to HTML and open it in browser
This results in an HTML page that doesn't load anything.
There are console errors that are in the console log:
require.min.js:1 GET file:///Users/XXXX/jupyterlab/ipyaggrid.js net::ERR_FILE_NOT_FOUND
embed-amd.js:26 Falling back to https://cdn.jsdelivr.net/npm/ for ipyaggrid@~0.2.2
embed-amd.js:16 TypeError: o._deserialize_state is not a function
at xc._make_model (embed-amd.js:16:581882)
It's possible that the error is "just" that it's loading the old library from npm, which is broken. But I don't know what's the right way to fix this. I'm not sure if the good practice is to have the ipyaggrid.js as a file embeded in the widget or downloaded from npm, and also how the npm file is even generated
The "Export to Excel" button uses the extension xls
instead of xlsx
.
Given this minimal example:
import pandas as pd
import requests
from ipyaggrid import Grid
url = 'https://raw.githubusercontent.com/widgetti/ipyaggrid/master/data/meteorites.json'
meteorites = pd.DataFrame(requests.get(url).json()).set_index("id")
g = Grid(
grid_data=meteorites,
export_excel=True,
grid_options= {
'columnDefs' : [{'field': c} for c in meteorites.columns],
}
)
display(g)
Clicking on the "Export to Excel" button triggers the download of a file called my_file.xls
, which makes Excel complain about the extension:
Below a simple reproducible example:
get_add_delete_row_fn
that adds 3 options to the right click context menu for deleting rows and adding rows above or belowgrid.get_grid()
and display grid.grid_data_out['grid']
the output is not updated right away (it still shows the data previous to deletion/addition)grid.grid_data_out['grid']
the data is updated correctly.this is the function to add the the context menu the option for deleting and inserting rows
import pandas as pd
import numpy as np
from ipyaggrid import Grid
def get_add_delete_row_fn(blank_row=None):
blank_row = blank_row or 'null'
fn = f'''
function (params) {{
let blankRow = {{}};
params.columnApi.getAllColumns().forEach((column) => {{
blankRow[column.getColId()] = '';
}});
if ({blank_row} !== null) {{
blankRow = {blank_row};
}};
// console.log({blank_row});
// console.log(blankRow);
return [
{{
name: 'Delete Row(s)',
action: function () {{
let selectedRows = params.api.getSelectedRows();
// console.log(selectedRows);
// let selectedData = selectedNodes.map(node => node.data);
params.api.applyTransaction({{ remove: selectedRows }});
}},
}},
{{
name: "Insert Row Above",
action: function() {{
let newData = blankRow;
params.api.applyTransaction({{add: [blankRow], addIndex: params.node.rowIndex}});
}},
}},
{{
name: "Insert Row Below",
action: function() {{
let newData = blankRow;
params.api.applyTransaction({{add: [blankRow], addIndex: params.node.rowIndex + 1}});
}},
}},
'copy',
'paste',
'separator',
// other context items...
];
}}
'''
return fn
This is the grid creation
df = pd.DataFrame([{'a': i, 'b': i+1, 'c':i+2} for i in range(10)])
g = Grid(
grid_data=df,
grid_options={
'columnDefs': [{'field': col} for col in df],
'enableSorting': True,
'enableFilter': True,
'enableColResize': True,
'enableRangeSelection': True,
'getContextMenuItems': get_add_delete_row_fn(),
'rowSelection': 'multiple'
},
theme='ag-theme-balham',
show_toggle_edit=True,
sync_on_edit=True,
)
g
Now to reproduce the example could you please:
g.get_grid()
display(g.grid_data_out['grid'])
You will see that the data is not updated, but the cell is executed
The UI tests seem to be broken. Can we pin all the versions of the dependencies to get repeatable results?
Hello guys,
just wondering if this is still being maintained.
Really appreciate you work on ipyaggrid
but as it's been almost 3 months since there's been a reply to the most recent issues opened, I just wonder if there's any problem at all and if this is still under active developement.
Thank you very much
Gio
here's a 3 liner example on how to reproduce the error:
import pandas as pd
from ipyaggrid import Grid
df = pd.date_range(end=pd.Timestamp.today().floor('d'), periods=10).rename('date').to_frame().reset_index(drop=True).rename_axis('index')
df.iloc[0, 0] = np.nan
Grid(
grid_data=df,
index=True,
grid_options={
'columnDefs': [{'field': col} for col in df.reset_index()]
}
)
you can see that it works ONLY if you comment this line df.iloc[0, 0] = np.nan
Thanks
Gio
As per title, when the dataframe columns have multiple levels, all the column defs passed explicitly are ignored, giving no control at all on the grid.
if it possible to change this behaviour?
thanks
Hello
I'd like to add ipyaggrid to conda forge so we can install it via conda, I'm happy to take care of the process https://conda-forge.org/docs/maintainer/adding_pkgs.html#
Currently I'm blocked because we are missing the source contribution files in pypi https://pypi.org/project/ipyaggrid/0.3.1/#files and I can't use graykull
I've created a PR to fix it, once merged I can create the conda recipe. Could you please have a look? Thanks!
Hi,
I'm trying to add an oncellclicked event to my table where the cell value is returned when user click the cell, I know this is possible using AG grid, just wondering is there a way to add this event using Python. Thanks!
A warning is displayed at console that a deprecated function is being used:
AG Grid: since version 28.0.x getAllColumns has been renamed, please use getColumns instead
Grid selections aren't being captured by event listener in a Jupyter notebook. I've tried in both Databricks and Microsoft Spark notebooks, neither of which seem to be working.
The grid itself is being populated. I've tested making selections on the grid by row as well as checkbox. I then tested the Export to CSV, Export Rows, Export Columns, and Export Range Data options. Export to CSV creates the CSV export but of the full grid, not the selections. The other export options do not appear to be functioning at all.
I've tried implementing with a button to call grid.get_selected_rows() and capture the selections into a dataframe but the dataframe is empty. I also tried creating a dataframe in a subsequent cell that calls grid.get_selected_rows() as well, also empty dataframe.
I've attached sample notebook code to recreate.
import pandas as pd
import ipywidgets as widgets
import pandas as pd
from ipyaggrid import Grid
from IPython.display import display
data = {
'ID': [1, 2, 3, 4, 5],
'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
'Age': [24, 30, 35, 22, 29],
'City': ['New York', 'Los Angeles', 'Chicago', 'Houston', 'Phoenix'],
'Subscription': ['Yes', 'No', 'Yes', 'No', 'Yes']
}
pdf_subscription_load = pd.DataFrame(data)
display(pdf_subscription_load)
grid_options = {
'columnDefs': [{'headerName': col, 'field': col, 'checkboxSelection': (col == 'subscription_name'), 'sortable': True, 'filter': True} for col in pdf_subscription_load.columns],
'enableSorting': True,
'enableFilter': True,
'enableColResize': True,
'enableRangeSelection': True,
'rowSelection': 'multiple',
}
grid = Grid(grid_data=pdf_subscription_load,
grid_options=grid_options,
grid_options_multi=[], # Additional grid options for multi-grid setups
columns_fit='size_to_fit',
index=False,
keep_multiindex=False,
compress_data=True,
quick_filter=True, # Enable or disable quick filtering
export_csv=True, # Enable or disable CSV export
export_excel=True, # Enable or disable Excel export
show_toggle_delete=True, # Show or hide delete toggle
show_toggle_edit=True, # Show or hide edit toggle
sync_on_edit=True, # Synchronize edits
sync_grid=True, # Synchronize the grid
paste_from_excel=False, # Allow pasting from Excel
export_mode='buttons', # Set export mode
export_to_df=True, # Export to DataFrame
hide_grid=False, # Hide or show the grid
theme='ag-theme-balham') # Theme
button = widgets.Button(description="Confirm Selection")
def on_button_click(b):
# Use the get_selected_rows method to capture selected rows
selected_rows_df = grid.get_selected_rows()
# Assuming you have a way to display or use the selected rows DataFrame
print(selected_rows_df) # For demonstration, this will print the DataFrame to the output
button.on_click(on_button_click)
display(grid)
display(button)
selected_rows_df = grid.get_selected_rows()
display(selected_rows_df)`
Hi. I use "ipyaggrid" lib. I want to convert all price values to float format with 2 decimal places and add a prefix £. Please tell me what I'm doing wrong and how to fix it, that I'm getting an error TypeError: Unserializable object <function currency_renderer at 0x0000026B9F46AB60> of type <class 'function'>. Thanks for any help
def currency_renderer(params): formatted_value = "£{:.2f}".format(float(params.value)) return formatted_value
`
def create_aggrid(df):
currency_columns = ['size', 'pnl', 'commission']
column_defs = [
{
'headerName': column,
'field': column,
'cellRenderer': currency_renderer if column in currency_columns else None
}
for column in df.columns
]
grid_options = {
'columnDefs' : column_defs,
'defaultColDef': {'sortable': 'true', 'filter': 'true', 'resizable': 'true'},
}
ag_grid = grid.Grid(grid_data=df,
export_mode="buttons",
columns_fit='auto',
grid_options=grid_options,
theme='ag-theme-balham',
keep_multiindex=False,
center=True)
return ag_grid
`
as per title,
I have a grid that gets updated periodically in the background and contains a lot of data so need to scroll to read it.
After calling grid.update_grid_date
the scroll reset to the top of the grid which makes it very difficult to read as the update happens every 30 seconds.
Is there a way to prevent this behaviour?
Thanks
Gio
Can we release the latest changes?
Let me know if this is something I could trigger myself.
is it possible to figure make the grid full height?
I couldn't find anything in the doc
Thanks
Python 3.9.16
Jupyter Notebook 6.5.2
ipywidgets 8.0.4
ipyaggrid 0.3.2
When i run my cell ,it throw errors:
[Open Browser Console for more detailed log - Double click to close this message]
Model class 'AgGridModel' from module 'ipyaggrid' is loaded but can not be instantiated
TypeError: o._deserialize_state is not a function
at u._make_model (http://localhost:8888/nbextensions/jupyter-js-widgets/extension.js?v=20230219013016:2:747339)
The notebook have worked well for 2 years,but after i update my conda,then it broke.
I am using the open ipyaggrid on a standalone machine (no network) and the tables display trial use when the license is clearly MIT. Please help
This issue is to track a potential improvement on this lib.
Currently, the HTML export of ipyaggrid Grid component is based on the "automatic" export of ipywidget components to HTML ( cf https://ipywidgets.readthedocs.io/en/7.6.3/embedding.html ) . This is fine (in case it works), but possibly the generated HTML/js code is bloated/slow, because it has to embed ipywidget JS dependencies etc. In essence, when we do ipyaggrid HTML export we now have gone full circle, because we have a html/js lib (ag-grid), wrapped in python, wrapped in js, again exported in HTML :D
A possible way to improve this would be to add another HTML export method, where ipyaggrid would manually generate the "pure" ag-grid code, with only dependencies on ag-grid and not on ipywidgets
I've only started using ipyaggrid but I'm exited about using it in standalone HTML reports.
However, I've found that creating grid objects seem to have a memory leak. Every time I create a grid into the same variable name, the memory usage increases. Even if I delete the variable and do a garbage collection, it continues to climb. My use-case is a follows:
I'm using:
ipyaggrid 0.5.1
ipykernel 6.25.2
ipython 8.14.0
ipywidgets 8.0.3
I'm having to cache my database query results to tinker around with ipyaggrid because I have to restart the kernel so often to get the RAM back down.
I'm open to workarounds if anyone can help with that.
def griddler(df, pin_list=[], height=400):
col_defs = ipyaggrid.Util.build_colDefs_for_si_cols(df)
for d in col_defs:
if "field" in d.keys():
if d['field'] in pin_list:
d['pinned'] = 'left'
grid_options = {
'columnDefs' : col_defs,
'enableSorting': True,
'enableFilter': True,
'enableColResize': True,
'enableRangeSelection': True,
}
df_str = pd.DataFrame()
for c in df.columns:
df_str[c] = df[c].astype("string")
g = None
g = ipyaggrid.Grid(grid_data=df_str,
height=400,
grid_options=grid_options,
quick_filter=True,
sync_on_edit=False,
show_toggle_edit=True,
export_csv=True,
theme='ag-theme-blue',
show_toggle_delete=False,
columns_fit='auto',
index=False,
keep_multiindex=False,
sync_grid=False)
return g
This example of how to use ipyaggrid shows the initialization of the agGrid with a fully loaded data (frame), which corresponds to the client-side row model.
g = Grid(grid_data = data, grid_options=grid_options, export_mode="buttons", theme='ag-theme-balham')
Does ipyaggrid support agGrid in the Server-Side Row Model? If so, where can I read about it? If not, could you give me some guidelines on what I should do to enable it?
I've studied the sources a little. Seems like that this use case is not supported. Inside widget_builder.js seems to be the only place where you inject the data:
// instantiate grid
const grid = new Grid(gridDiv, gridOptions);
window.grid = grid;
// inject gridData
gridOptions.api.setRowData(gridData);
Maybe under your guidance I could implement the support for the SSR mode for agGrid and create a PR? Since agGrid's SSR model basically requires just a datasource object with getRows
method, we could create it in python env and pass it to Grid
during the instantiation
g = Grid(datasource= ds,
Hi all, we are using ipyaggrid and planning to support jupyter lab 4, I wonder that does the latest version support jupyter lab 4?
If not, I would try to make it work internally and raise pr (maybe around this summer?
Is there a way in python to programmatically auto size the columns after the grid has been created (for example after updating the data)?
thanks
Hello
It seems there are still issues with the HTML export
Specifically, if I now follow the steps in #10 , I'm able to generate a HTML file that works as standalone, it's great ! (file attached below)
However, if I try to open the open the HTML from the jupyter lab HTML viewer, it fails... Note that the jupyterlab instance is the one that produced the HTML file initially, so it terms of versions etc this is the same.
When I try to open the HTML file in jupyterlab (with the "trust HTML" on), I get the following error in the console:
embed-amd.js:26 Uncaught TypeError: Failed to construct 'URL': Invalid URL
at embed-amd.js:26:37945
at Object.<anonymous> (embed-amd.js:26:41241)
at Object.execCb (require.min.js:1:12861)
at b.check (require.min.js:1:6615)
at b.enable (require.min.js:1:9363)
at Object.enable (require.min.js:1:11918)
at b.<anonymous> (require.min.js:1:9220)
at require.min.js:1:814
at each (require.min.js:1:289)
at b.enable (require.min.js:1:8720)
(anonymous) @ embed-amd.js:26
(anonymous) @ embed-amd.js:26
execCb @ require.min.js:1
check @ require.min.js:1
enable @ require.min.js:1
enable @ require.min.js:1
(anonymous) @ require.min.js:1
(anonymous) @ require.min.js:1
each @ require.min.js:1
enable @ require.min.js:1
init @ require.min.js:1
(anonymous) @ require.min.js:1
setTimeout (async)
req.nextTick @ require.min.js:1
o @ require.min.js:1
requirejs @ require.min.js:1
(anonymous) @ embed-amd.js:29
(anonymous) @ embed-amd.js:29
DevTools failed to load source map: Could not load content for https://unpkg.com/@jupyter-widgets/html-manager@*/dist/embed-amd-render.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
Can someone help me understand the following:
thanks!
Hi,
I have tried to use the ipyaggrid to turn a dataframe to a editable table.
It work perfect in voila or jupyter notebook.
However, it does not work when I try to set a responsive setting.
A responsive setting like a mobile setting or Ipad setting ( https://developer.chrome.com/docs/devtools/device-mode/).
I cannot edit the table value when I use Google DevTools
Thank you
as per title,
Thanks !
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.