Skip to content

Consider adding control over output size to the grammar #238

@cpsievert

Description

@cpsievert

Vega has this really annoying restriction where height and width cannot be set on a "compound" (i.e., faceted, hconcat, vconcat, etc) chart. Instead, the height and width must be set individually on each panel.

Maybe there's a better way, but currently I'm needing to map an overall size to panel sizes like this:

def inject_compound_sizes(
    vl: dict[str, Any],
    container_width: int,
    container_height: int,
) -> None:
    """
    Inject cell ``width``/``height`` into a compound Vega-Lite spec in-place.

    For faceted charts, divides the container width by the number of columns
    (from the ``columns`` key, defaulting to the number of facet levels or 1).
    For hconcat/concat, divides by the number of sub-specs.
    For vconcat, each sub-spec gets the full width.

    Subtracts padding estimates so the rendered cells fill the container,
    including space for legends when present.
    """
    padding_x = 80  # y-axis labels + title padding
    padding_y = 120  # facet headers, x-axis labels + title, bottom padding
    if _has_legend(vl):
        padding_x += _LEGEND_WIDTH
    usable_w = max(container_width - padding_x, 100)
    usable_h = max(container_height - padding_y, 100)

    if "facet" in vl:
        ncol = vl.get("columns", 1)
        cell_w = usable_w // max(ncol, 1)
        inner = vl.get("spec", {})
        inner["width"] = cell_w
        inner["height"] = usable_h
    elif "hconcat" in vl:
        n = len(vl["hconcat"])
        cell_w = usable_w // max(n, 1)
        for sub in vl["hconcat"]:
            sub["width"] = cell_w
            sub["height"] = usable_h
    elif "concat" in vl:
        ncol = vl.get("columns", len(vl["concat"]))
        cell_w = usable_w // max(ncol, 1)
        for sub in vl["concat"]:
            sub["width"] = cell_w
            sub["height"] = usable_h
    elif "vconcat" in vl:
        n = len(vl["vconcat"])
        cell_h = usable_h // max(n, 1)
        for sub in vl["vconcat"]:
            sub["width"] = usable_w
            sub["height"] = cell_h

Would be great if we could find an "official" way to do this and have the logic live in rust.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions