itables 2.3.0__tar.gz → 2.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {itables-2.3.0 → itables-2.4.0}/PKG-INFO +38 -15
- {itables-2.3.0 → itables-2.4.0}/README.md +14 -11
- {itables-2.3.0 → itables-2.4.0}/itables/__init__.py +2 -7
- {itables-2.3.0 → itables-2.4.0}/itables/dash.py +1 -7
- itables-2.4.0/itables/datatables_format.py +160 -0
- {itables-2.3.0 → itables-2.4.0}/itables/downsample.py +14 -11
- itables-2.4.0/itables/html/datatables_template.html +14 -0
- itables-2.4.0/itables/html/dt_bundle.css +1 -0
- itables-2.4.0/itables/html/dt_bundle.js +144 -0
- itables-2.4.0/itables/html/init_datatables.html +4 -0
- itables-2.4.0/itables/itables_for_streamlit/asset-manifest.json +13 -0
- {itables-2.3.0 → itables-2.4.0}/itables/itables_for_streamlit/index.html +1 -1
- itables-2.4.0/itables/itables_for_streamlit/static/css/main.fffc57ef.css +2 -0
- itables-2.4.0/itables/itables_for_streamlit/static/css/main.fffc57ef.css.map +1 -0
- itables-2.4.0/itables/itables_for_streamlit/static/js/main.15cf0d5c.js +3 -0
- itables-2.3.0/itables/itables_for_streamlit/static/js/main.8b03a1d9.js.LICENSE.txt → itables-2.4.0/itables/itables_for_streamlit/static/js/main.15cf0d5c.js.LICENSE.txt +1 -1
- itables-2.4.0/itables/itables_for_streamlit/static/js/main.15cf0d5c.js.map +1 -0
- itables-2.4.0/itables/javascript.py +815 -0
- itables-2.4.0/itables/options.py +99 -0
- {itables-2.3.0 → itables-2.4.0}/itables/sample_dfs.py +43 -29
- {itables-2.3.0 → itables-2.4.0}/itables/shiny.py +14 -10
- itables-2.4.0/itables/streamlit.py +20 -0
- itables-2.4.0/itables/typing.py +199 -0
- {itables-2.3.0 → itables-2.4.0}/itables/utils.py +1 -1
- {itables-2.3.0 → itables-2.4.0}/itables/version.py +1 -1
- itables-2.4.0/itables/widget/__init__.py +108 -0
- itables-2.4.0/itables/widget/static/widget.css +1 -0
- itables-2.4.0/itables/widget/static/widget.js +144 -0
- {itables-2.3.0 → itables-2.4.0}/itables_for_dash/ITable.py +19 -26
- itables-2.4.0/itables_for_dash/__init__.py +59 -0
- itables-2.4.0/itables_for_dash/async-ITable.js +3 -0
- {itables-2.3.0 → itables-2.4.0}/itables_for_dash/async-ITable.js.LICENSE.txt +1 -1
- itables-2.4.0/itables_for_dash/async-ITable.js.map +1 -0
- itables-2.4.0/itables_for_dash/itables_for_dash.min.js +2 -0
- itables-2.4.0/itables_for_dash/itables_for_dash.min.js.map +1 -0
- itables-2.4.0/itables_for_dash/metadata.json +1 -0
- {itables-2.3.0 → itables-2.4.0}/itables_for_dash/package-info.json +5 -5
- itables-2.4.0/itables_for_dash/properties.py +83 -0
- {itables-2.3.0 → itables-2.4.0}/pyproject.toml +8 -8
- itables-2.3.0/itables/datatables_format.py +0 -146
- itables-2.3.0/itables/html/column_filters/initComplete.js +0 -14
- itables-2.3.0/itables/html/column_filters/pre_dt_code.js +0 -8
- itables-2.3.0/itables/html/datatables_template.html +0 -20
- itables-2.3.0/itables/html/dt_bundle.css +0 -1
- itables-2.3.0/itables/html/dt_bundle.js +0 -144
- itables-2.3.0/itables/html/init_datatables.html +0 -25
- itables-2.3.0/itables/itables_for_streamlit/asset-manifest.json +0 -13
- itables-2.3.0/itables/itables_for_streamlit/static/css/main.2bc6c309.css +0 -2
- itables-2.3.0/itables/itables_for_streamlit/static/css/main.2bc6c309.css.map +0 -1
- itables-2.3.0/itables/itables_for_streamlit/static/js/main.8b03a1d9.js +0 -3
- itables-2.3.0/itables/itables_for_streamlit/static/js/main.8b03a1d9.js.map +0 -1
- itables-2.3.0/itables/javascript.py +0 -979
- itables-2.3.0/itables/options.py +0 -75
- itables-2.3.0/itables/streamlit.py +0 -13
- itables-2.3.0/itables/widget/__init__.py +0 -121
- itables-2.3.0/itables/widget/static/widget.css +0 -1
- itables-2.3.0/itables/widget/static/widget.js +0 -144
- itables-2.3.0/itables_for_dash/__init__.py +0 -53
- itables-2.3.0/itables_for_dash/async-ITable.js +0 -3
- itables-2.3.0/itables_for_dash/async-ITable.js.map +0 -1
- itables-2.3.0/itables_for_dash/itables_for_dash.min.js +0 -2
- itables-2.3.0/itables_for_dash/itables_for_dash.min.js.map +0 -1
- itables-2.3.0/itables_for_dash/metadata.json +0 -1
- itables-2.3.0/itables_for_dash/properties.py +0 -77
- {itables-2.3.0 → itables-2.4.0}/.gitignore +0 -0
- {itables-2.3.0 → itables-2.4.0}/LICENSE +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/interactive.py +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/logo/loading.svg +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/logo/logo.svg +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/logo/text.svg +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/logo/wide.svg +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/logo/with_text.svg +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/samples/countries.csv +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/samples/indicators.csv +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables/samples/population.csv +0 -0
- {itables-2.3.0 → itables-2.4.0}/itables_for_dash/_imports_.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: itables
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4.0
|
|
4
4
|
Summary: Pandas and Polar DataFrames as interactive DataTables
|
|
5
5
|
Project-URL: Homepage, https://mwouts.github.io/itables/
|
|
6
6
|
Project-URL: Documentation, https://mwouts.github.io/itables
|
|
@@ -39,31 +39,39 @@ Classifier: Intended Audience :: Science/Research
|
|
|
39
39
|
Classifier: License :: OSI Approved :: MIT License
|
|
40
40
|
Classifier: Programming Language :: Python
|
|
41
41
|
Classifier: Programming Language :: Python :: 3
|
|
42
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
43
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
44
42
|
Classifier: Programming Language :: Python :: 3.9
|
|
45
43
|
Classifier: Programming Language :: Python :: 3.10
|
|
46
44
|
Classifier: Programming Language :: Python :: 3.11
|
|
47
45
|
Classifier: Programming Language :: Python :: 3.12
|
|
48
46
|
Classifier: Programming Language :: Python :: 3.13
|
|
49
|
-
Requires-Python: >=3.
|
|
47
|
+
Requires-Python: >=3.9
|
|
50
48
|
Requires-Dist: ipython
|
|
51
49
|
Requires-Dist: numpy
|
|
52
50
|
Requires-Dist: pandas
|
|
53
51
|
Provides-Extra: all
|
|
54
52
|
Requires-Dist: anywidget; extra == 'all'
|
|
53
|
+
Requires-Dist: dash; extra == 'all'
|
|
55
54
|
Requires-Dist: matplotlib; extra == 'all'
|
|
56
55
|
Requires-Dist: polars; extra == 'all'
|
|
57
56
|
Requires-Dist: pyarrow; extra == 'all'
|
|
58
57
|
Requires-Dist: pytz; extra == 'all'
|
|
58
|
+
Requires-Dist: shiny; extra == 'all'
|
|
59
|
+
Requires-Dist: shinywidgets; extra == 'all'
|
|
60
|
+
Requires-Dist: streamlit; extra == 'all'
|
|
59
61
|
Requires-Dist: traitlets; extra == 'all'
|
|
62
|
+
Requires-Dist: typeguard>=4.4.1; extra == 'all'
|
|
60
63
|
Requires-Dist: world-bank-data; extra == 'all'
|
|
64
|
+
Provides-Extra: check-type
|
|
65
|
+
Requires-Dist: typeguard>=4.4.1; extra == 'check-type'
|
|
66
|
+
Provides-Extra: dash
|
|
67
|
+
Requires-Dist: dash; extra == 'dash'
|
|
61
68
|
Provides-Extra: dev
|
|
62
69
|
Requires-Dist: anywidget; extra == 'dev'
|
|
63
70
|
Requires-Dist: dash; extra == 'dev'
|
|
64
71
|
Requires-Dist: ipykernel; extra == 'dev'
|
|
65
72
|
Requires-Dist: jupyterlab; extra == 'dev'
|
|
66
73
|
Requires-Dist: jupytext; extra == 'dev'
|
|
74
|
+
Requires-Dist: marimo; extra == 'dev'
|
|
67
75
|
Requires-Dist: matplotlib; extra == 'dev'
|
|
68
76
|
Requires-Dist: nbconvert; extra == 'dev'
|
|
69
77
|
Requires-Dist: polars; extra == 'dev'
|
|
@@ -73,7 +81,10 @@ Requires-Dist: pytest-cov; extra == 'dev'
|
|
|
73
81
|
Requires-Dist: pytz; extra == 'dev'
|
|
74
82
|
Requires-Dist: requests; extra == 'dev'
|
|
75
83
|
Requires-Dist: shiny; extra == 'dev'
|
|
84
|
+
Requires-Dist: shinywidgets; extra == 'dev'
|
|
85
|
+
Requires-Dist: streamlit; extra == 'dev'
|
|
76
86
|
Requires-Dist: traitlets; extra == 'dev'
|
|
87
|
+
Requires-Dist: typeguard>=4.4.1; extra == 'dev'
|
|
77
88
|
Requires-Dist: watchfiles; extra == 'dev'
|
|
78
89
|
Requires-Dist: world-bank-data; extra == 'dev'
|
|
79
90
|
Provides-Extra: polars
|
|
@@ -82,6 +93,11 @@ Requires-Dist: pyarrow; extra == 'polars'
|
|
|
82
93
|
Provides-Extra: samples
|
|
83
94
|
Requires-Dist: pytz; extra == 'samples'
|
|
84
95
|
Requires-Dist: world-bank-data; extra == 'samples'
|
|
96
|
+
Provides-Extra: shiny
|
|
97
|
+
Requires-Dist: shiny; extra == 'shiny'
|
|
98
|
+
Requires-Dist: shinywidgets; extra == 'shiny'
|
|
99
|
+
Provides-Extra: streamlit
|
|
100
|
+
Requires-Dist: streamlit; extra == 'streamlit'
|
|
85
101
|
Provides-Extra: style
|
|
86
102
|
Requires-Dist: matplotlib; extra == 'style'
|
|
87
103
|
Provides-Extra: test
|
|
@@ -89,6 +105,7 @@ Requires-Dist: anywidget; extra == 'test'
|
|
|
89
105
|
Requires-Dist: dash; extra == 'test'
|
|
90
106
|
Requires-Dist: ipykernel; extra == 'test'
|
|
91
107
|
Requires-Dist: jupytext; extra == 'test'
|
|
108
|
+
Requires-Dist: marimo; extra == 'test'
|
|
92
109
|
Requires-Dist: matplotlib; extra == 'test'
|
|
93
110
|
Requires-Dist: nbconvert; extra == 'test'
|
|
94
111
|
Requires-Dist: polars; extra == 'test'
|
|
@@ -98,7 +115,10 @@ Requires-Dist: pytest-cov; extra == 'test'
|
|
|
98
115
|
Requires-Dist: pytz; extra == 'test'
|
|
99
116
|
Requires-Dist: requests; extra == 'test'
|
|
100
117
|
Requires-Dist: shiny; extra == 'test'
|
|
118
|
+
Requires-Dist: shinywidgets; extra == 'test'
|
|
119
|
+
Requires-Dist: streamlit; extra == 'test'
|
|
101
120
|
Requires-Dist: traitlets; extra == 'test'
|
|
121
|
+
Requires-Dist: typeguard>=4.4.1; extra == 'test'
|
|
102
122
|
Requires-Dist: world-bank-data; extra == 'test'
|
|
103
123
|
Provides-Extra: widget
|
|
104
124
|
Requires-Dist: anywidget; extra == 'widget'
|
|
@@ -114,10 +134,11 @@ Description-Content-Type: text/markdown
|
|
|
114
134
|
[](https://anaconda.org/conda-forge/itables)
|
|
115
135
|
[](https://pypi.python.org/pypi/itables)
|
|
116
136
|
[](https://github.com/psf/black)
|
|
117
|
-
[](https://mwouts.github.io/itables/widget.html)
|
|
137
|
+
[](https://mwouts.github.io/itables/apps/widget.html)
|
|
138
|
+
[](https://mwouts.github.io/itables/apps/dash.html)
|
|
118
139
|
[](https://itables.streamlit.app)
|
|
119
140
|
|
|
120
|
-
This packages changes how Pandas and Polars DataFrames are rendered in
|
|
141
|
+
This packages changes how Pandas and Polars DataFrames are rendered in Python notebooks and applications.
|
|
121
142
|
With `itables` you can display your tables as interactive [DataTables](https://datatables.net/)
|
|
122
143
|
that you can sort, paginate, scroll or filter.
|
|
123
144
|
|
|
@@ -145,7 +166,7 @@ or
|
|
|
145
166
|
conda install itables -c conda-forge
|
|
146
167
|
```
|
|
147
168
|
|
|
148
|
-
Activate the interactive mode for all series and dataframes with
|
|
169
|
+
Activate the interactive mode for all series and dataframes in Jupyter with
|
|
149
170
|
```python
|
|
150
171
|
import itables
|
|
151
172
|
|
|
@@ -157,14 +178,8 @@ and then render any DataFrame as an interactive table that you can sort, search
|
|
|
157
178
|
If you prefer to render only selected DataFrames as interactive tables, call `itables.init_notebook_mode(all_interactive=False)`, then use `itables.show` to show just one Series or DataFrame as an interactive table:
|
|
158
179
|

|
|
159
180
|
|
|
160
|
-
Since ITables v1.0, the [jQuery](https://jquery.com/) and [DataTables](https://datatables.net/) libraries and CSS
|
|
161
|
-
are injected in the notebook when you execute `init_notebook_mode` with its default argument `connected=False`.
|
|
162
|
-
Thanks to this the interactive tables will work even without a connection to the internet.
|
|
163
181
|
|
|
164
|
-
|
|
165
|
-
execute `init_notebook_mode`.
|
|
166
|
-
|
|
167
|
-
## Supported notebook environments
|
|
182
|
+
## ITables in Notebooks
|
|
168
183
|
|
|
169
184
|
ITables works in all the usual Jupyter Notebook environments, including Jupyter Notebook, Jupyter Lab, Jupyter nbconvert (i.e. the tables are still interactive in the HTML export of a notebook), Jupyter Book, Google Colab and Kaggle.
|
|
170
185
|
|
|
@@ -174,8 +189,16 @@ ITables works well in VS Code, both in Jupyter Notebooks and in interactive Pyth
|
|
|
174
189
|
|
|
175
190
|
## ITables in Python applications
|
|
176
191
|
|
|
177
|
-
|
|
192
|
+
ITables is also available as
|
|
178
193
|
- a [Jupyter Widget](https://mwouts.github.io/itables/widget.html)
|
|
179
194
|
- a [Dash](https://mwouts.github.io/itables/dash.html) component
|
|
180
195
|
- a [Streamlit](https://mwouts.github.io/itables/streamlit.html) component,
|
|
181
196
|
- and it also works in [Shiny](https://mwouts.github.io/itables/shiny.html) applications.
|
|
197
|
+
|
|
198
|
+
## Licence
|
|
199
|
+
|
|
200
|
+
ITables is developed by [Marc Wouts](https://github.com/mwouts) on [GitHub](https://github.com/mwouts/itables),
|
|
201
|
+
under a MIT license.
|
|
202
|
+
|
|
203
|
+
ITables is a wrapper for [datatables.net](https://datatables.net/) which is developed by Allan Jardine
|
|
204
|
+
[(sponsor him!)](https://github.com/sponsors/AllanJard), also under a MIT license.
|
|
@@ -7,10 +7,11 @@
|
|
|
7
7
|
[](https://anaconda.org/conda-forge/itables)
|
|
8
8
|
[](https://pypi.python.org/pypi/itables)
|
|
9
9
|
[](https://github.com/psf/black)
|
|
10
|
-
[](https://mwouts.github.io/itables/widget.html)
|
|
10
|
+
[](https://mwouts.github.io/itables/apps/widget.html)
|
|
11
|
+
[](https://mwouts.github.io/itables/apps/dash.html)
|
|
11
12
|
[](https://itables.streamlit.app)
|
|
12
13
|
|
|
13
|
-
This packages changes how Pandas and Polars DataFrames are rendered in
|
|
14
|
+
This packages changes how Pandas and Polars DataFrames are rendered in Python notebooks and applications.
|
|
14
15
|
With `itables` you can display your tables as interactive [DataTables](https://datatables.net/)
|
|
15
16
|
that you can sort, paginate, scroll or filter.
|
|
16
17
|
|
|
@@ -38,7 +39,7 @@ or
|
|
|
38
39
|
conda install itables -c conda-forge
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
Activate the interactive mode for all series and dataframes with
|
|
42
|
+
Activate the interactive mode for all series and dataframes in Jupyter with
|
|
42
43
|
```python
|
|
43
44
|
import itables
|
|
44
45
|
|
|
@@ -50,14 +51,8 @@ and then render any DataFrame as an interactive table that you can sort, search
|
|
|
50
51
|
If you prefer to render only selected DataFrames as interactive tables, call `itables.init_notebook_mode(all_interactive=False)`, then use `itables.show` to show just one Series or DataFrame as an interactive table:
|
|
51
52
|

|
|
52
53
|
|
|
53
|
-
Since ITables v1.0, the [jQuery](https://jquery.com/) and [DataTables](https://datatables.net/) libraries and CSS
|
|
54
|
-
are injected in the notebook when you execute `init_notebook_mode` with its default argument `connected=False`.
|
|
55
|
-
Thanks to this the interactive tables will work even without a connection to the internet.
|
|
56
54
|
|
|
57
|
-
|
|
58
|
-
execute `init_notebook_mode`.
|
|
59
|
-
|
|
60
|
-
## Supported notebook environments
|
|
55
|
+
## ITables in Notebooks
|
|
61
56
|
|
|
62
57
|
ITables works in all the usual Jupyter Notebook environments, including Jupyter Notebook, Jupyter Lab, Jupyter nbconvert (i.e. the tables are still interactive in the HTML export of a notebook), Jupyter Book, Google Colab and Kaggle.
|
|
63
58
|
|
|
@@ -67,8 +62,16 @@ ITables works well in VS Code, both in Jupyter Notebooks and in interactive Pyth
|
|
|
67
62
|
|
|
68
63
|
## ITables in Python applications
|
|
69
64
|
|
|
70
|
-
|
|
65
|
+
ITables is also available as
|
|
71
66
|
- a [Jupyter Widget](https://mwouts.github.io/itables/widget.html)
|
|
72
67
|
- a [Dash](https://mwouts.github.io/itables/dash.html) component
|
|
73
68
|
- a [Streamlit](https://mwouts.github.io/itables/streamlit.html) component,
|
|
74
69
|
- and it also works in [Shiny](https://mwouts.github.io/itables/shiny.html) applications.
|
|
70
|
+
|
|
71
|
+
## Licence
|
|
72
|
+
|
|
73
|
+
ITables is developed by [Marc Wouts](https://github.com/mwouts) on [GitHub](https://github.com/mwouts/itables),
|
|
74
|
+
under a MIT license.
|
|
75
|
+
|
|
76
|
+
ITables is a wrapper for [datatables.net](https://datatables.net/) which is developed by Allan Jardine
|
|
77
|
+
[(sponsor him!)](https://github.com/sponsors/AllanJard), also under a MIT license.
|
|
@@ -1,12 +1,7 @@
|
|
|
1
1
|
from itables import downsample, options, sample_dfs
|
|
2
2
|
|
|
3
|
-
from .javascript import
|
|
4
|
-
|
|
5
|
-
JavascriptFunction,
|
|
6
|
-
init_notebook_mode,
|
|
7
|
-
show,
|
|
8
|
-
to_html_datatable,
|
|
9
|
-
)
|
|
3
|
+
from .javascript import init_notebook_mode, show, to_html_datatable
|
|
4
|
+
from .typing import JavascriptCode, JavascriptFunction
|
|
10
5
|
from .version import __version__
|
|
11
6
|
|
|
12
7
|
__all__ = [
|
|
@@ -1,21 +1,15 @@
|
|
|
1
|
+
from itables import __version__
|
|
1
2
|
from itables_for_dash import (
|
|
2
3
|
ITABLE_PROPERTIES,
|
|
3
4
|
ITable,
|
|
4
|
-
ITableComponent,
|
|
5
5
|
ITableOutputs,
|
|
6
|
-
__version__,
|
|
7
|
-
get_itable_component_kwargs,
|
|
8
|
-
itables_for_dash_is_available,
|
|
9
6
|
updated_itable_outputs,
|
|
10
7
|
)
|
|
11
8
|
|
|
12
9
|
__all__ = [
|
|
13
10
|
"ITable",
|
|
14
|
-
"ITableComponent",
|
|
15
11
|
"ITABLE_PROPERTIES",
|
|
16
|
-
"get_itable_component_kwargs",
|
|
17
12
|
"ITableOutputs",
|
|
18
13
|
"updated_itable_outputs",
|
|
19
|
-
"itables_for_dash_is_available",
|
|
20
14
|
"__version__",
|
|
21
15
|
]
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import warnings
|
|
3
|
+
from typing import Optional
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pandas as pd
|
|
7
|
+
import pandas.io.formats.format as fmt
|
|
8
|
+
|
|
9
|
+
try:
|
|
10
|
+
import polars as pl
|
|
11
|
+
except ImportError:
|
|
12
|
+
pl = None
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _format_column(x, escape_html: bool):
|
|
16
|
+
dtype_kind = x.dtype.kind
|
|
17
|
+
if dtype_kind in ["b", "i"]:
|
|
18
|
+
return x
|
|
19
|
+
|
|
20
|
+
if dtype_kind == "s":
|
|
21
|
+
if escape_html:
|
|
22
|
+
return x
|
|
23
|
+
return [escape_html_chars(i) for i in x]
|
|
24
|
+
|
|
25
|
+
try:
|
|
26
|
+
x = fmt.format_array(x._values, None, justify="all", leading_space=False) # type: ignore
|
|
27
|
+
except TypeError:
|
|
28
|
+
# Older versions of Pandas don't have 'leading_space'
|
|
29
|
+
x = fmt.format_array(x._values, None, justify="all") # type: ignore
|
|
30
|
+
|
|
31
|
+
if dtype_kind == "f":
|
|
32
|
+
try:
|
|
33
|
+
x = np.array(x).astype(float)
|
|
34
|
+
except ValueError:
|
|
35
|
+
pass
|
|
36
|
+
|
|
37
|
+
x = [escape_non_finite_float(f) for f in x]
|
|
38
|
+
|
|
39
|
+
if escape_html:
|
|
40
|
+
return [escape_html_chars(i) for i in x]
|
|
41
|
+
|
|
42
|
+
return x
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def escape_non_finite_float(value):
|
|
46
|
+
"""Encode non-finite float values to strings that will be parsed by parseJSON"""
|
|
47
|
+
if not isinstance(value, float):
|
|
48
|
+
return value
|
|
49
|
+
if np.isnan(value):
|
|
50
|
+
return "___NaN___"
|
|
51
|
+
if value == np.inf:
|
|
52
|
+
return "___Infinity___"
|
|
53
|
+
if value == -np.inf:
|
|
54
|
+
return "___-Infinity___"
|
|
55
|
+
return value
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def escape_html_chars(value):
|
|
59
|
+
"""Escape HTML special characters"""
|
|
60
|
+
if isinstance(value, str):
|
|
61
|
+
from pandas.io.formats.printing import pprint_thing # type: ignore
|
|
62
|
+
|
|
63
|
+
return pprint_thing(
|
|
64
|
+
value, escape_chars={"&": r"&", "<": r"<", ">": r">"}
|
|
65
|
+
).strip()
|
|
66
|
+
return value
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def generate_encoder(warn_on_unexpected_types=True):
|
|
70
|
+
class TableValuesEncoder(json.JSONEncoder):
|
|
71
|
+
def default(self, o):
|
|
72
|
+
if isinstance(o, (bool, int, float, str)):
|
|
73
|
+
return json.JSONEncoder.default(self, o)
|
|
74
|
+
if isinstance(o, np.bool_):
|
|
75
|
+
return bool(o)
|
|
76
|
+
if isinstance(o, np.integer):
|
|
77
|
+
return int(o)
|
|
78
|
+
if isinstance(o, np.floating):
|
|
79
|
+
return float(o)
|
|
80
|
+
try:
|
|
81
|
+
if o is pd.NA:
|
|
82
|
+
return str(o)
|
|
83
|
+
except AttributeError:
|
|
84
|
+
pass
|
|
85
|
+
|
|
86
|
+
if warn_on_unexpected_types:
|
|
87
|
+
warnings.warn(
|
|
88
|
+
f"Unexpected type '{type(o)}' for '{o}'.\n"
|
|
89
|
+
"You can report this warning at https://github.com/mwouts/itables/issues\n"
|
|
90
|
+
"To silence this warning, please run:\n"
|
|
91
|
+
" itables.options.warn_on_unexpected_types = False",
|
|
92
|
+
category=RuntimeWarning,
|
|
93
|
+
)
|
|
94
|
+
return str(o)
|
|
95
|
+
|
|
96
|
+
return TableValuesEncoder
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _isetitem(df, i, value):
|
|
100
|
+
"""Older versions of Pandas don't have df.isetitem"""
|
|
101
|
+
try:
|
|
102
|
+
df.isetitem(i, value)
|
|
103
|
+
except AttributeError:
|
|
104
|
+
df.iloc[:, i] = value
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def datatables_rows(
|
|
108
|
+
df,
|
|
109
|
+
column_count: Optional[int] = None,
|
|
110
|
+
warn_on_unexpected_types: bool = False,
|
|
111
|
+
escape_html: bool = True,
|
|
112
|
+
):
|
|
113
|
+
"""Format the values in the table and return the data, row by row, as requested by DataTables"""
|
|
114
|
+
# We iterate over columns using an index rather than the column name
|
|
115
|
+
# to avoid an issue in case of duplicated column names #89
|
|
116
|
+
if column_count is None or len(df.columns) == column_count:
|
|
117
|
+
empty_columns = []
|
|
118
|
+
else:
|
|
119
|
+
# When the header requires more columns (#141), we append empty columns on the left
|
|
120
|
+
missing_columns = column_count - len(df.columns)
|
|
121
|
+
assert missing_columns > 0
|
|
122
|
+
empty_columns = [[None] * len(df)] * missing_columns
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
# Pandas DataFrame
|
|
126
|
+
data = list(
|
|
127
|
+
zip(
|
|
128
|
+
*(
|
|
129
|
+
empty_columns
|
|
130
|
+
+ [_format_column(x, escape_html) for _, x in df.items()]
|
|
131
|
+
)
|
|
132
|
+
)
|
|
133
|
+
)
|
|
134
|
+
return json.dumps(
|
|
135
|
+
data,
|
|
136
|
+
cls=generate_encoder(warn_on_unexpected_types),
|
|
137
|
+
allow_nan=False,
|
|
138
|
+
)
|
|
139
|
+
except AttributeError:
|
|
140
|
+
# Polars DataFrame
|
|
141
|
+
assert pl is not None
|
|
142
|
+
|
|
143
|
+
# Convert Polars Struct to string #290
|
|
144
|
+
if any(isinstance(df[col].dtype, pl.Struct) for col in df.columns):
|
|
145
|
+
columns = {col: df[col] for col in df.columns}
|
|
146
|
+
for col in df.columns:
|
|
147
|
+
if isinstance(df[col].dtype, pl.Struct):
|
|
148
|
+
try:
|
|
149
|
+
columns[col] = df[col].cast(str)
|
|
150
|
+
except pl.exceptions.InvalidOperationError:
|
|
151
|
+
columns[col] = [str(x) for x in df[col]]
|
|
152
|
+
df = pl.DataFrame(columns)
|
|
153
|
+
|
|
154
|
+
data = df.rows()
|
|
155
|
+
data = [[escape_non_finite_float(f) for f in row] for row in data]
|
|
156
|
+
|
|
157
|
+
if escape_html:
|
|
158
|
+
data = [[escape_html_chars(i) for i in row] for row in data]
|
|
159
|
+
|
|
160
|
+
return json.dumps(data, cls=generate_encoder(False), allow_nan=False)
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import math
|
|
2
|
+
from typing import Union
|
|
2
3
|
|
|
3
4
|
import pandas as pd
|
|
4
5
|
|
|
5
|
-
from .datatables_format import _isetitem
|
|
6
|
-
|
|
7
6
|
|
|
8
7
|
def nbytes(df):
|
|
9
8
|
try:
|
|
@@ -31,7 +30,9 @@ def as_nbytes(mem):
|
|
|
31
30
|
return int(float(mem))
|
|
32
31
|
|
|
33
32
|
|
|
34
|
-
def downsample(
|
|
33
|
+
def downsample(
|
|
34
|
+
df, max_rows: int = 0, max_columns: int = 0, max_bytes: Union[int, str] = 0
|
|
35
|
+
):
|
|
35
36
|
"""Return a subset of the dataframe that fits the limits"""
|
|
36
37
|
org_rows, org_columns, org_bytes = len(df), len(df.columns), nbytes(df)
|
|
37
38
|
max_bytes_numeric = as_nbytes(max_bytes)
|
|
@@ -113,16 +114,16 @@ def _downsample(df, max_rows=0, max_columns=0, max_bytes=0, target_aspect_ratio=
|
|
|
113
114
|
first_half = max_columns - second_half
|
|
114
115
|
assert first_half >= second_half
|
|
115
116
|
if second_half:
|
|
116
|
-
|
|
117
|
+
if isinstance(df, pd.DataFrame):
|
|
117
118
|
df = pd.concat(
|
|
118
119
|
(df.iloc[:, :first_half], df.iloc[:, -second_half:]), axis=1
|
|
119
120
|
)
|
|
120
|
-
|
|
121
|
+
else:
|
|
121
122
|
df = df[df.columns[:first_half]].hstack(df[df.columns[-second_half:]])
|
|
122
123
|
else:
|
|
123
|
-
|
|
124
|
+
if isinstance(df, pd.DataFrame):
|
|
124
125
|
df = df.iloc[:, :first_half]
|
|
125
|
-
|
|
126
|
+
else:
|
|
126
127
|
df = df[df.columns[:first_half]]
|
|
127
128
|
|
|
128
129
|
df_nbytes = nbytes(df)
|
|
@@ -146,12 +147,14 @@ def _downsample(df, max_rows=0, max_columns=0, max_bytes=0, target_aspect_ratio=
|
|
|
146
147
|
)
|
|
147
148
|
|
|
148
149
|
# max_bytes is smaller than the average size of one cell
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
150
|
+
if isinstance(df, pd.DataFrame):
|
|
151
|
+
return pd.DataFrame("...", index=df.index[:1], columns=df.columns[:1])
|
|
152
|
+
|
|
153
|
+
else:
|
|
153
154
|
import polars as pl # noqa
|
|
154
155
|
|
|
156
|
+
assert isinstance(df, pl.DataFrame)
|
|
157
|
+
|
|
155
158
|
df = pl.DataFrame({df.columns[0]: ["..."]})
|
|
156
159
|
return df
|
|
157
160
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<!--| quarto-html-table-processing: none -->
|
|
2
|
+
<table id="table_id"></table>
|
|
3
|
+
<link href="https://www.unpkg.com/dt_for_itables/dt_bundle.css" rel="stylesheet">
|
|
4
|
+
<script type="module">
|
|
5
|
+
import { ITable, jQuery as $ } from 'https://www.unpkg.com/dt_for_itables/dt_bundle.js';
|
|
6
|
+
|
|
7
|
+
document.querySelectorAll("#table_id:not(.dataTable)").forEach(table => {
|
|
8
|
+
if (!(table instanceof HTMLTableElement))
|
|
9
|
+
return;
|
|
10
|
+
|
|
11
|
+
let dt_args = {};
|
|
12
|
+
new ITable(table, dt_args);
|
|
13
|
+
});
|
|
14
|
+
</script>
|