the table regionยค
a first sketch of adding interactive controls to the table. the controls use the @property to define the types making our variables ammenable to animations.
overall, the concept of flat table is for the uninspired. here we create experiment with perspective and z positioning. these approaches will be live you are holding and moving through data rather than a boring as single position.
its not a bad first sketch and it tells a story moving forward.
%reload_ext nbconvert_a11y.repr
from nbconvert_a11y.repr import get_table, TableOptions, new
from nbconvert_a11y.table import init_table
df = DataFrame(numpy.random.randn(2, 6), columns=pandas.MultiIndex.from_product([range(2), range(3)], names=["x", "y"]))
df = df.reindex(df.columns)
df[:] = numpy.random.randn(*df.shape)
%%
<figure>
<figcaption>
our basis for a dataframe table includes containers for captions, data, interface controls, style, and interactivity.
these design decisions were made it enhance the accessibility and assistiveness (ie labor reduction) of exploring information.
</figcaption>
```html
{{init_table("xx").prettify()}}
```
</figure>
> originally this research started focusing on notebooks. we wound up making them tables with controls in a very similar
way that is described here. the notebook use case confirms a need for a richer set of semantics around tables.
<style>
a[href="#demo"] {
display: block;
height: 300px;
width: 400px;
background: -moz-element(#demo);
background-size: content;
background-repeat: no-repeat;
font-size: 4rem;
}
</style>
Table
is a first pass at a more fluent interface for working with html tables.
@dataclass
class Table:
object: object
options: TableOptions = field(default_factory=TableOptions)
repr: bs4.Tag = None
id: str = None
def build(self, *args, **kwargs):
self.repr = get_table(self.object, self.options, *args, **kwargs)
self.id = self.repr.figure.table.attrs["id"]
return self
def _repr_html_(self):
if self.repr:
return self.repr.prettify()
%%
initialize and build the `Table` as <var>self</var>
self = table = Table(df)
self.options.axis = self.options.Axis.column
self.build(id="demo")
add an explicit caption to the table which describes the context the dataframe is being used in.
the implicit caption lives on the `self.repr.figure.table.caption` which describes the type and shape
of the table.
self.repr.figure.figcaption.append(new("q", "a random ass dataframe"))
{{table.repr}}
starting defining css properties and styles for the table.
self.repr.style.append(
```text/css
@property --dir {
syntax: "<number>";
inherits: true;
initial-value: 1;
}
@property --rotate {
syntax: "<number>";
inherits: true;
initial-value: 0;
}
@property --depth {
syntax: "<length>";
inherits: true;
initial-value: 3in;
}
@property --distance {
syntax: "<length>";
inherits: true;
initial-value: 6in;
}
@property --angle {
syntax: "<length>";
inherits: true;
initial-value: 50%;
}
form label {
display: block;
}
table[id] {
margin: 10em;
transform: rotateY(calc(1deg*var(--rotate)));
transform-style: preserve-3d;
transition: all 1s linear;
tbody {
transform-style: preserve-3d;
tr {
transform-style: preserve-3d;
perspective: var(--distance);
perspective-origin: var(--angle);
transition: all 1s linear;
background: unset !important;
td {
transform-style: preserve-3d;
transition: all 1s linear;
transform: translateZ(calc(var(--dir) * var(--val) * var(--depth))) rotateY(calc(-1deg*var(--rotate)));
}
}
}
}
```
)
use long form to add the controls so we can visually identify some of the patterns
between the css properties and input types and changes.
self.repr.form.extend((
new(
"label", "depth",
new("input", type="number", min=0, max=12, step=.5, value=3, name="depth",
onchange=\
"""document.getElementById("%s").style.setProperty("--depth", `${document.forms["%s"].elements.depth.value}in`);""" % (self.id, self.id)
), "inches"
),
new(
"label", "distance",
new("input", type="number", min=0, max=12, step=.5, value=3, name="distance",
onchange=\
"""document.getElementById("%s").style.setProperty("--distance", `${document.forms["%s"].elements.distance.value}in`);""" % (self.id, self.id)
), "inches"
),
new(
"label", "angle",
new("input", type="number", min=0, max=100, step=2, value=50, name="angle",
onchange=\
("""document.getElementById("%s").style.setProperty("--angle", `${document.forms["%s"].elements.angle.value}""" % (self.id, self.id)) + "%`);"
), "%"
),
new("label", "direction", new("input", type="number", min=-1, max=1, step=2, value=1, name="dir", onchange=\
"""document.getElementById("%s").style.setProperty("--dir", document.forms["%s"].elements.dir.value);""" % (self.id, self.id)
),)
))