Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for granular section restyling via convenience api #341

Merged
merged 33 commits into from
Sep 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
200fd72
WIP allow for granular section restyling via convenience api
timkpaine May 14, 2024
f80e1cd
fix lint
timkpaine May 15, 2024
5c18797
working on tests
timkpaine May 15, 2024
07680cd
Merge branch 'main' into tkp/sectionstyle
machow Sep 16, 2024
10d6cd9
refactor: prepare to use loc classes directly, not strings
machow Sep 17, 2024
39902a0
refactor: clean up last use of .locname
machow Sep 17, 2024
6627b6a
fix: support spanner label targeting
machow Sep 19, 2024
85f0967
feat: add style.css for raw css
machow Sep 19, 2024
eced055
tests: add kitchen sink location snapshot test
machow Sep 19, 2024
98db730
tests: update snapshots
machow Sep 19, 2024
17b990a
fix: title style tag needs space before
machow Sep 19, 2024
e4b6b6c
fix: resolve_rows_i can always handle None expr
machow Sep 24, 2024
978bce4
feat: implement LocRowGroupLabel styles
machow Sep 24, 2024
2fab150
feat: support LocRowLabel styles
machow Sep 24, 2024
7cccdaf
feat: support LocSourceNotes styles
machow Sep 24, 2024
8f5dada
tests: add source note to styles test, update snapshot
machow Sep 24, 2024
b549c7e
tests: correctly target row of data in snapshot
machow Sep 24, 2024
8b4b811
refactor: remove LocStubheadLabel
machow Sep 24, 2024
033ef5b
docs: add targeted styles page to get-started
machow Sep 24, 2024
a3bf5df
chore: remove print statement
machow Sep 24, 2024
3ba7818
feat: implement loc.headers
machow Sep 27, 2024
e8070ab
Merge branch 'main' into tkp/sectionstyle
machow Sep 27, 2024
90095a4
feat: implement LocFooter styles
machow Sep 27, 2024
9b746e9
tests: update snapshots
machow Sep 27, 2024
805c155
fix: extra space in body html tag
machow Sep 27, 2024
9e623e0
refactor: remove groups attr from Loc classes
machow Sep 27, 2024
1a2e9d4
refactor: remove StyleInfo.locnum attr, .loc always a Loc class
machow Sep 27, 2024
e2bea6a
refactor: remove redundant or unimplemented set_style concretes
machow Sep 27, 2024
cbc39bd
refactor!: rename or remove locations based on Rich feedback
machow Sep 27, 2024
e87ab10
tests: update snapshots
machow Sep 27, 2024
bdbe223
refactor!: rename loc.row_group_labels to row_groups
machow Sep 27, 2024
367194d
docs: get targeted styles working again
machow Sep 27, 2024
febbd70
docs: flesh out targeted styles a bit
machow Sep 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/_quarto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ website:
- get-started/column-selection.qmd
- get-started/row-selection.qmd
- get-started/nanoplots.qmd
- get-started/targeted-styles.qmd

format:
html:
Expand Down
131 changes: 131 additions & 0 deletions docs/get-started/targeted-styles.qmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
---
title: Targeted styles
jupyter: python3
---

In [Styling the Table Body](./basic-styling), we discussed styling table data with `.tab_style()`.
In this article we'll cover how the same method can be used to style many other parts of the table, like the header, specific spanner labels, the footer, and more.

:::{.callout-warning}
This feature is currently a work in progress, and not yet released. Great Tables must be installed from github in order to try it.
:::


## Kitchen sink

Below is a big example that shows all possible `loc` specifiers being used.

```{python}
from great_tables import GT, exibble, loc, style

# https://colorbrewer2.org/#type=qualitative&scheme=Paired&n=12
brewer_colors = [
"#a6cee3",
"#1f78b4",
"#b2df8a",
"#33a02c",
"#fb9a99",
"#e31a1c",
"#fdbf6f",
"#ff7f00",
"#cab2d6",
"#6a3d9a",
"#ffff99",
"#b15928",
]

c = iter(brewer_colors)

gt = (
GT(exibble.loc[[0, 1, 4], ["num", "char", "fctr", "row", "group"]])
.tab_header("title", "subtitle")
.tab_stub(rowname_col="row", groupname_col="group")
.tab_source_note("yo")
.tab_spanner("spanner", ["char", "fctr"])
.tab_stubhead("stubhead")
)

(
gt.tab_style(style.fill(next(c)), loc.body())
# Columns -----------
# TODO: appears in browser, but not vs code
.tab_style(style.fill(next(c)), loc.column_labels(columns="num"))
.tab_style(style.fill(next(c)), loc.column_header())
.tab_style(style.fill(next(c)), loc.spanner_labels(ids=["spanner"]))
# Header -----------
.tab_style(style.fill(next(c)), loc.header())
.tab_style(style.fill(next(c)), loc.subtitle())
.tab_style(style.fill(next(c)), loc.title())
# Footer -----------
.tab_style(style.borders(weight="3px"), loc.source_notes())
.tab_style(style.fill(next(c)), loc.footer())
# Stub --------------
.tab_style(style.fill(next(c)), loc.row_groups())
.tab_style(style.borders(weight="3px"), loc.stub(rows=1))
.tab_style(style.fill(next(c)), loc.stub())
.tab_style(style.fill(next(c)), loc.stubhead())
)
```

## Body

```{python}
gt.tab_style(style.fill("yellow"), loc.body())
```

## Column labels

```{python}
(
gt
.tab_style(style.fill("yellow"), loc.column_header())
.tab_style(style.fill("blue"), loc.column_labels(columns="num"))
.tab_style(style.fill("red"), loc.spanner_labels(ids=["spanner"]))
)

```



## Header

```{python}
(
gt.tab_style(style.fill("yellow"), loc.header())
.tab_style(style.fill("blue"), loc.title())
.tab_style(style.fill("red"), loc.subtitle())
)
```

## Footer

```{python}
(
gt.tab_style(
style.fill("yellow"),
loc.source_notes(),
).tab_style(
style.borders(weight="3px"),
loc.footer(),
)
)
```

## Stub

```{python}
(
gt.tab_style(style.fill("yellow"), loc.stub())
.tab_style(style.fill("blue"), loc.row_groups())
.tab_style(
style.borders(style="dashed", weight="3px", color="red"),
loc.stub(rows=[1]),
)
)
```

## Stubhead

```{python}
gt.tab_style(style.fill("yellow"), loc.stubhead())
```
14 changes: 7 additions & 7 deletions great_tables/_gt_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from collections.abc import Sequence
from dataclasses import dataclass, field, replace
from enum import Enum, auto
from typing import Any, Callable, Tuple, TypeVar, overload, TYPE_CHECKING
from typing import Any, Callable, Literal, Tuple, TypeVar, Union, overload, TYPE_CHECKING

from typing_extensions import Self, TypeAlias

Expand All @@ -28,6 +28,7 @@

if TYPE_CHECKING:
from ._helpers import Md, Html, UnitStr, Text
from ._locations import Loc

Check warning on line 31 in great_tables/_gt_data.py

View check run for this annotation

Codecov / codecov/patch

great_tables/_gt_data.py#L31

Added line #L31 was not covered by tests

T = TypeVar("T")

Expand Down Expand Up @@ -610,7 +611,7 @@
# TODO: validate
return self.__class__(self.rows, self.group_rows.reorder(group_order))

def group_indices_map(self) -> list[tuple[int, str | None]]:
def group_indices_map(self) -> list[tuple[int, GroupRowInfo | None]]:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now returning GroupRowInfo directly, since we need the group ids, not just their defaulted labels to match group name locs

return self.group_rows.indices_map(len(self.rows))

def __iter__(self):
Expand Down Expand Up @@ -740,7 +741,7 @@

return self.__class__(reordered)

def indices_map(self, n: int) -> list[tuple[int, str | None]]:
def indices_map(self, n: int) -> list[tuple[int, GroupRowInfo]]:
"""Return pairs of row index, group label for all rows in data.

Note that when no groupings exist, n is used to return from range(n).
Expand All @@ -751,7 +752,7 @@

if not len(self._d):
return [(ii, None) for ii in range(n)]
return [(ind, info.defaulted_label()) for info in self for ind in info.indices]
return [(ind, info) for info in self for ind in info.indices]


# Spanners ----
Expand Down Expand Up @@ -852,7 +853,7 @@

@dataclass(frozen=True)
class FootnoteInfo:
locname: str | None = None
locname: Loc | None = None
grpname: str | None = None
colname: str | None = None
locnum: int | None = None
Expand All @@ -869,8 +870,7 @@

@dataclass(frozen=True)
class StyleInfo:
locname: str
locnum: int
locname: Loc
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

locname with a Loc class now fully identifies a style info, so no need for locnum

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great!

grpname: str | None = None
colname: str | None = None
rownum: int | None = None
Expand Down
Loading