Skip to content

Commit

Permalink
lengthMenu can be either a 1D or 2D array (#153)
Browse files Browse the repository at this point in the history
* update the csv file only if it is missing

* passing an option with value=None is not allowed

* fix set dom=t when the table fits on one page

* Version 1.4.5
  • Loading branch information
mwouts authored Jan 23, 2023
1 parent 992a3f2 commit fe27982
Show file tree
Hide file tree
Showing 7 changed files with 132 additions and 34 deletions.
12 changes: 12 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
ITables ChangeLog
=================

1.4.5 (2023-01-23)
------------------

**Fixed**
- Fixed an issue when `lengthMenu` is a 2D array ([#151](https://github.com/mwouts/itables/issues/151))


**Changed**
- We make sure that no argument passed to `show` is equal to `None` (for all tested options, passing `None` results in a datatable that never loads)
- Running the test collection will not update the CSV files used for testing anymore


1.4.4 (2023-01-15)
------------------

Expand Down
40 changes: 32 additions & 8 deletions itables/javascript.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,21 @@ def to_html_datatable(df=None, caption=None, tableId=None, connected=True, **kwa
):
kwargs[option] = getattr(opt, option)

for name, value in kwargs.items():
if value is None:
raise ValueError(
"Please don't pass an option with a value equal to None ('{}=None')".format(
name
)
)

# These options are used here, not in DataTable
classes = kwargs.pop("classes")
style = kwargs.pop("style")
css = kwargs.pop("css")
tags = kwargs.pop("tags")

# Only display the table if the rows fit on one 'page'
if "dom" not in kwargs and len(df) <= 10: # the default page has 10 rows
if "lengthMenu" not in kwargs or len(df) <= min(kwargs["lengthMenu"]):
kwargs["dom"] = "t"
_set_dom_equals_t_if_df_fits_in_one_page(df, kwargs)

if caption is not None:
tags = '{}<caption style="white-space: nowrap; overflow: hidden">{}</caption>'.format(
Expand Down Expand Up @@ -275,10 +280,6 @@ def to_html_datatable(df=None, caption=None, tableId=None, connected=True, **kwa
"'header', 'footer' or False, not {}".format(column_filters)
)

# Do not show the page menu when the table has fewer rows than min length menu
if "paging" not in kwargs and len(df.index) <= kwargs.get("lengthMenu", [10])[0]:
kwargs["paging"] = False

# Load the HTML template
if connected:
output = read_package_file("html/datatables_template_connected.html")
Expand Down Expand Up @@ -362,6 +363,29 @@ def _column_count_in_header(table_header):
return max(line.count("</th>") for line in table_header.split("</tr>"))


def _min_rows(kwargs):
if "lengthMenu" not in kwargs:
return 10

lengthMenu = kwargs["lengthMenu"]
min_rows = lengthMenu[0]

if isinstance(min_rows, (int, float)):
return min_rows

return min_rows[0]


def _set_dom_equals_t_if_df_fits_in_one_page(df, kwargs):
"""Display just the table (not the search box, etc...) if the rows fit on one 'page'"""
if "dom" in kwargs:
return

if len(df) <= _min_rows(kwargs):
kwargs["dom"] = "t"
return


def safe_reset_index(df):
try:
return df.reset_index()
Expand Down
2 changes: 1 addition & 1 deletion itables/version.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
"""ITables' version number"""

__version__ = "1.4.4"
__version__ = "1.4.5"
30 changes: 30 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import pandas as pd
import pytest

from itables.sample_dfs import get_dict_of_test_dfs


@pytest.fixture(params=list(get_dict_of_test_dfs()))
def df(request):
name = request.param
df = get_dict_of_test_dfs()[name]
assert isinstance(df, pd.DataFrame)
return df


@pytest.fixture(params=["None", "1D-array", "2D-array"])
def lengthMenu(request):
if request.param == "None":
return None
if request.param == "1D-array":
return [2, 5, 10, 20, 50]
if request.param == "2D-array":
return [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]]
raise KeyError(request.param)


@pytest.fixture(params=["None", "lfrtip"])
def dom(request):
if request.param == "None":
return None
return request.param
42 changes: 33 additions & 9 deletions tests/test_javascript.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,38 @@
import pandas as pd
import pytest

from itables.javascript import to_html_datatable


@pytest.fixture()
def df():
return pd.DataFrame([1, 2])
from itables.javascript import (
_set_dom_equals_t_if_df_fits_in_one_page,
to_html_datatable,
)


def test_warn_on_unexpected_types_not_in_html(df):
html = to_html_datatable(df)
assert "warn_on_unexpected_types" not in html


def test_set_dom_equals_t_if_df_fits_in_one_page(df, dom, lengthMenu):
kwargs = dict(lengthMenu=lengthMenu, dom=dom)
kwargs = {key: value for key, value in kwargs.items() if value is not None}
_set_dom_equals_t_if_df_fits_in_one_page(df, kwargs)

if dom is not None:
assert kwargs["dom"] == dom
return

if lengthMenu is None:
if len(df) <= 10:
assert kwargs["dom"] == "t"
return

assert "dom" not in kwargs
return

min_rows = lengthMenu[0]
if isinstance(min_rows, list):
min_rows = min_rows[0]

if len(df) <= min_rows:
assert kwargs["dom"] == "t"
return

assert "dom" not in kwargs
return
15 changes: 11 additions & 4 deletions tests/test_sample_dfs.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pandas as pd
import pytest

from itables import show
from itables import show, to_html_datatable
from itables.datatables_format import TableValuesEncoder, _format_column
from itables.sample_dfs import (
COLUMN_TYPES,
Expand Down Expand Up @@ -48,9 +48,16 @@ def test_get_indicators():
show(df)


@pytest.mark.parametrize("df_name,df", get_dict_of_test_dfs().items())
def test_show_test_dfs(df_name, df):
show(df)
def kwargs_remove_none(**kwargs):
return {key: value for key, value in kwargs.items() if value is not None}


def test_show_test_dfs(df, lengthMenu):
show(df, **kwargs_remove_none(lengthMenu=lengthMenu))


def test_to_html_datatable(df, lengthMenu):
to_html_datatable(df, **kwargs_remove_none(lengthMenu=lengthMenu))


def test_ordered_categories():
Expand Down
25 changes: 13 additions & 12 deletions tests/test_update_samples.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
from pathlib import Path

import pytest
import world_bank_data as wb

sample_dir = Path(__file__).parent / ".." / "itables" / "samples"
SAMPLE_DIR = Path(__file__).parent / ".." / "itables" / "samples"


def test_update_countries():
def create_csv_file_if_missing(df, csv_file):
if not csv_file.exists():
with open(str(csv_file), "w") as fp:
fp.write(df.to_csv())


def test_update_countries(csv_file=SAMPLE_DIR / "countries.csv"):
df = wb.get_countries()
with open(str(sample_dir / "countries.csv"), "w") as fp:
fp.write(df.to_csv())
create_csv_file_if_missing(df, csv_file)


def test_update_population():
def test_update_population(csv_file=SAMPLE_DIR / "population.csv"):
x = wb.get_series("SP.POP.TOTL", mrv=1, simplify_index=True)
with open(str(sample_dir / "population.csv"), "w") as fp:
fp.write(x.to_csv())
create_csv_file_if_missing(x, csv_file)


@pytest.mark.skip("The indicators appear to change often")
def test_update_indicators():
def test_update_indicators(csv_file=SAMPLE_DIR / "indicators.csv"):
df = wb.get_indicators().sort_index().head(500)
with open(str(sample_dir / "indicators.csv"), "w") as fp:
fp.write(df.to_csv())
create_csv_file_if_missing(df, csv_file)

0 comments on commit fe27982

Please sign in to comment.