Skip to content

Commit 5f24079

Browse files
eni-awowaleowenlittlejohnsflamingbear
authored
Migrate formatting_html.py into xarray core (#8930)
* DAS-2066: formatting_html.py merge * Revert "DAS-2066: formatting_html.py merge" oopsies This reverts commit d68ae3c. * Adding datatree functions to core * Deleted formatting_html.py and test_formatting_html.py in datatree_ * renamed all of the relevant functions so they represent datatree * added comment for mypy * added dict[any, any] as type hint for children * added dict[Any, Any] as type hint for children * updated typhint to dict[str, DataTree] and increased pixel min width to 700 * replaced Any with DataTree * added type checking * DAS-2066 - Incorporate CSS changes for DataTree display. * DAS-2066 - Fix tests. --------- Co-authored-by: Owen Littlejohns <owen.m.littlejohns@nasa.gov> Co-authored-by: Matt Savoie <matthew.savoie@colorado.edu>
1 parent 9eb180b commit 5f24079

File tree

6 files changed

+332
-336
lines changed

6 files changed

+332
-336
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ Bug fixes
4040

4141
Internal Changes
4242
~~~~~~~~~~~~~~~~
43+
- Migrates ``formatting_html`` functionality for `DataTree` into ``xarray/core`` (:pull: `8930`)
44+
By `Eni Awowale <https://github.com/eni-awowale>`_, `Julia Signell <https://github.com/jsignell>`_
45+
and `Tom Nicholas <https://github.com/TomNicholas>`_.
4346
- Migrates ``datatree_mapping`` functionality into ``xarray/core`` (:pull:`8948`)
4447
By `Matt Savoie <https://github.com/flamingbear>`_ `Owen Littlejohns
4548
<https://github.com/owenlittlejohns>` and `Tom Nicholas <https://github.com/TomNicholas>`_.

xarray/core/datatree.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
check_isomorphic,
2424
map_over_subtree,
2525
)
26+
from xarray.core.formatting_html import (
27+
datatree_repr as datatree_repr_html,
28+
)
2629
from xarray.core.indexes import Index, Indexes
2730
from xarray.core.merge import dataset_update_method
2831
from xarray.core.options import OPTIONS as XR_OPTS
@@ -38,9 +41,6 @@
3841
from xarray.core.variable import Variable
3942
from xarray.datatree_.datatree.common import TreeAttrAccessMixin
4043
from xarray.datatree_.datatree.formatting import datatree_repr
41-
from xarray.datatree_.datatree.formatting_html import (
42-
datatree_repr as datatree_repr_html,
43-
)
4444
from xarray.datatree_.datatree.ops import (
4545
DataTreeArithmeticMixin,
4646
MappedDatasetMethodsMixin,

xarray/core/formatting_html.py

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22

33
import uuid
44
from collections import OrderedDict
5+
from collections.abc import Mapping
56
from functools import lru_cache, partial
67
from html import escape
78
from importlib.resources import files
9+
from typing import TYPE_CHECKING
810

911
from xarray.core.formatting import (
1012
inline_index_repr,
@@ -18,6 +20,9 @@
1820
("xarray.static.css", "style.css"),
1921
)
2022

23+
if TYPE_CHECKING:
24+
from xarray.core.datatree import DataTree
25+
2126

2227
@lru_cache(None)
2328
def _load_static_files():
@@ -341,3 +346,129 @@ def dataset_repr(ds) -> str:
341346
]
342347

343348
return _obj_repr(ds, header_components, sections)
349+
350+
351+
def summarize_datatree_children(children: Mapping[str, DataTree]) -> str:
352+
N_CHILDREN = len(children) - 1
353+
354+
# Get result from datatree_node_repr and wrap it
355+
lines_callback = lambda n, c, end: _wrap_datatree_repr(
356+
datatree_node_repr(n, c), end=end
357+
)
358+
359+
children_html = "".join(
360+
(
361+
lines_callback(n, c, end=False) # Long lines
362+
if i < N_CHILDREN
363+
else lines_callback(n, c, end=True)
364+
) # Short lines
365+
for i, (n, c) in enumerate(children.items())
366+
)
367+
368+
return "".join(
369+
[
370+
"<div style='display: inline-grid; grid-template-columns: 100%; grid-column: 1 / -1'>",
371+
children_html,
372+
"</div>",
373+
]
374+
)
375+
376+
377+
children_section = partial(
378+
_mapping_section,
379+
name="Groups",
380+
details_func=summarize_datatree_children,
381+
max_items_collapse=1,
382+
expand_option_name="display_expand_groups",
383+
)
384+
385+
386+
def datatree_node_repr(group_title: str, dt: DataTree) -> str:
387+
header_components = [f"<div class='xr-obj-type'>{escape(group_title)}</div>"]
388+
389+
ds = dt.ds
390+
391+
sections = [
392+
children_section(dt.children),
393+
dim_section(ds),
394+
coord_section(ds.coords),
395+
datavar_section(ds.data_vars),
396+
attr_section(ds.attrs),
397+
]
398+
399+
return _obj_repr(ds, header_components, sections)
400+
401+
402+
def _wrap_datatree_repr(r: str, end: bool = False) -> str:
403+
"""
404+
Wrap HTML representation with a tee to the left of it.
405+
406+
Enclosing HTML tag is a <div> with :code:`display: inline-grid` style.
407+
408+
Turns:
409+
[ title ]
410+
| details |
411+
|_____________|
412+
413+
into (A):
414+
|─ [ title ]
415+
| | details |
416+
| |_____________|
417+
418+
or (B):
419+
└─ [ title ]
420+
| details |
421+
|_____________|
422+
423+
Parameters
424+
----------
425+
r: str
426+
HTML representation to wrap.
427+
end: bool
428+
Specify if the line on the left should continue or end.
429+
430+
Default is True.
431+
432+
Returns
433+
-------
434+
str
435+
Wrapped HTML representation.
436+
437+
Tee color is set to the variable :code:`--xr-border-color`.
438+
"""
439+
# height of line
440+
end = bool(end)
441+
height = "100%" if end is False else "1.2em"
442+
return "".join(
443+
[
444+
"<div style='display: inline-grid; grid-template-columns: 0px 20px auto; width: 100%;'>",
445+
"<div style='",
446+
"grid-column-start: 1;",
447+
"border-right: 0.2em solid;",
448+
"border-color: var(--xr-border-color);",
449+
f"height: {height};",
450+
"width: 0px;",
451+
"'>",
452+
"</div>",
453+
"<div style='",
454+
"grid-column-start: 2;",
455+
"grid-row-start: 1;",
456+
"height: 1em;",
457+
"width: 20px;",
458+
"border-bottom: 0.2em solid;",
459+
"border-color: var(--xr-border-color);",
460+
"'>",
461+
"</div>",
462+
"<div style='",
463+
"grid-column-start: 3;",
464+
"'>",
465+
r,
466+
"</div>",
467+
"</div>",
468+
]
469+
)
470+
471+
472+
def datatree_repr(dt: DataTree) -> str:
473+
obj_type = f"datatree.{type(dt).__name__}"
474+
return datatree_node_repr(obj_type, dt)

xarray/datatree_/datatree/formatting_html.py

Lines changed: 0 additions & 135 deletions
This file was deleted.

0 commit comments

Comments
 (0)