diff --git a/altair/typing.py b/altair/typing/__init__.py similarity index 94% rename from altair/typing.py rename to altair/typing/__init__.py index cd8cb1489..d80469f35 100644 --- a/altair/typing.py +++ b/altair/typing/__init__.py @@ -46,9 +46,13 @@ "ChartType", "EncodeKwds", "Optional", + "ThemeConfig", "is_chart_type", + "theme", ] +from altair.typing import theme +from altair.typing.theme import ThemeConfig from altair.utils.schemapi import Optional from altair.vegalite.v5.api import ChartType, is_chart_type from altair.vegalite.v5.schema.channels import ( diff --git a/altair/typing/theme.py b/altair/typing/theme.py new file mode 100644 index 000000000..17f9a7fd2 --- /dev/null +++ b/altair/typing/theme.py @@ -0,0 +1 @@ +from altair.vegalite.v5.schema._config import * # noqa: F403 diff --git a/altair/utils/core.py b/altair/utils/core.py index 734efe1f2..24ab7cadb 100644 --- a/altair/utils/core.py +++ b/altair/utils/core.py @@ -771,9 +771,21 @@ def decorate(cb: WrapsFunc[R], /) -> WrappedMethod[T, P, R] | WrappedFunc[P, R]: return decorate +@overload def update_nested( original: t.MutableMapping[Any, Any], update: t.Mapping[Any, Any], + copy: Literal[False] = ..., +) -> t.MutableMapping[Any, Any]: ... +@overload +def update_nested( + original: t.Mapping[Any, Any], + update: t.Mapping[Any, Any], + copy: Literal[True], +) -> t.MutableMapping[Any, Any]: ... +def update_nested( + original: Any, + update: t.Mapping[Any, Any], copy: bool = False, ) -> t.MutableMapping[Any, Any]: """ diff --git a/altair/utils/theme.py b/altair/utils/theme.py index 47e5da6ad..bbb7247bc 100644 --- a/altair/utils/theme.py +++ b/altair/utils/theme.py @@ -3,9 +3,10 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Any, Dict +from typing import TYPE_CHECKING -from .plugin_registry import Plugin, PluginRegistry +from altair.utils.plugin_registry import Plugin, PluginRegistry +from altair.vegalite.v5.schema._config import ThemeConfig if sys.version_info >= (3, 11): from typing import LiteralString @@ -16,12 +17,12 @@ from altair.utils.plugin_registry import PluginEnabler from altair.vegalite.v5.theme import AltairThemes, VegaThemes -ThemeType = Plugin[Dict[str, Any]] +ThemeType = Plugin[ThemeConfig] # HACK: See for `LiteralString` requirement in `name` # https://github.com/vega/altair/pull/3526#discussion_r1743350127 -class ThemeRegistry(PluginRegistry[ThemeType, Dict[str, Any]]): +class ThemeRegistry(PluginRegistry[ThemeType, ThemeConfig]): def enable( self, name: LiteralString | AltairThemes | VegaThemes | None = None, **options ) -> PluginEnabler: diff --git a/altair/vegalite/v5/schema/_config.py b/altair/vegalite/v5/schema/_config.py new file mode 100644 index 000000000..80864718d --- /dev/null +++ b/altair/vegalite/v5/schema/_config.py @@ -0,0 +1,7775 @@ +# The contents of this file are automatically written by +# tools/generate_schema_wrapper.py. Do not modify directly. + +from __future__ import annotations + +import sys +from typing import TYPE_CHECKING, Any, Literal, Sequence, TypedDict + +if sys.version_info >= (3, 14): + from typing import TypedDict +else: + from typing_extensions import TypedDict +from ._typing import PaddingKwds, RowColKwds + +if TYPE_CHECKING: + # ruff: noqa: F405 + from ._typing import * # noqa: F403 + + +__all__ = [ + "AreaConfigKwds", + "AutoSizeParamsKwds", + "AxisConfigKwds", + "AxisResolveMapKwds", + "BarConfigKwds", + "BindCheckboxKwds", + "BindDirectKwds", + "BindInputKwds", + "BindRadioSelectKwds", + "BindRangeKwds", + "BoxPlotConfigKwds", + "BrushConfigKwds", + "CompositionConfigKwds", + "ConfigKwds", + "DateTimeKwds", + "DerivedStreamKwds", + "ErrorBandConfigKwds", + "ErrorBarConfigKwds", + "FeatureGeometryGeoJsonPropertiesKwds", + "FormatConfigKwds", + "GeoJsonFeatureCollectionKwds", + "GeoJsonFeatureKwds", + "GeometryCollectionKwds", + "GradientStopKwds", + "HeaderConfigKwds", + "IntervalSelectionConfigKwds", + "IntervalSelectionConfigWithoutTypeKwds", + "LegendConfigKwds", + "LegendResolveMapKwds", + "LegendStreamBindingKwds", + "LineConfigKwds", + "LineStringKwds", + "LinearGradientKwds", + "LocaleKwds", + "MarkConfigKwds", + "MergedStreamKwds", + "MultiLineStringKwds", + "MultiPointKwds", + "MultiPolygonKwds", + "NumberLocaleKwds", + "OverlayMarkDefKwds", + "PaddingKwds", + "PointKwds", + "PointSelectionConfigKwds", + "PointSelectionConfigWithoutTypeKwds", + "PolygonKwds", + "ProjectionConfigKwds", + "ProjectionKwds", + "RadialGradientKwds", + "RangeConfigKwds", + "RectConfigKwds", + "ResolveKwds", + "RowColKwds", + "ScaleConfigKwds", + "ScaleInvalidDataConfigKwds", + "ScaleResolveMapKwds", + "SelectionConfigKwds", + "StepKwds", + "StyleConfigIndexKwds", + "ThemeConfig", + "TickConfigKwds", + "TimeIntervalStepKwds", + "TimeLocaleKwds", + "TitleConfigKwds", + "TitleParamsKwds", + "TooltipContentKwds", + "TopLevelSelectionParameterKwds", + "VariableParameterKwds", + "ViewBackgroundKwds", + "ViewConfigKwds", +] + + +class AreaConfigKwds(TypedDict, total=False): + """ + :class:`AreaConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + line + A flag for overlaying line on top of area marks, or an object defining the + properties of the overlayed lines. + + * If this value is an empty object (``{}``) or ``true``, lines with default + properties will be used. + + * If this value is ``false``, no lines would be automatically added to area marks. + + **Default value:** ``false``. + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + point + A flag for overlaying points on top of line or area marks, or an object defining the + properties of the overlayed points. + + * If this property is ``"transparent"``, transparent points will be used (for + enhancing tooltips and selections). + + * If this property is an empty object (``{}``) or ``true``, filled points with + default properties will be used. + + * If this property is ``false``, no points would be automatically added to line or + area marks. + + **Default value:** ``false``. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + baseline: TextBaseline_T + blend: Blend_T + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + line: bool | OverlayMarkDefKwds + lineBreak: str + lineHeight: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + point: bool | OverlayMarkDefKwds | Literal["transparent"] + radius: float + radius2: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + tension: float + text: str | Sequence[str] + theta: float + theta2: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + y: float | Literal["height"] + y2: float | Literal["height"] + + +class AutoSizeParamsKwds(TypedDict, total=False): + """ + :class:`AutoSizeParams` ``TypedDict`` wrapper. + + Parameters + ---------- + contains + Determines how size calculation should be performed, one of ``"content"`` or + ``"padding"``. The default setting (``"content"``) interprets the width and height + settings as the data rectangle (plotting) dimensions, to which padding is then + added. In contrast, the ``"padding"`` setting includes the padding within the view + size calculations, such that the width and height settings indicate the **total** + intended size of the view. + + **Default value**: ``"content"`` + resize + A boolean flag indicating if autosize layout should be re-calculated on every view + update. + + **Default value**: ``false`` + type + The sizing format type. One of ``"pad"``, ``"fit"``, ``"fit-x"``, ``"fit-y"``, or + ``"none"``. See the `autosize type + `__ documentation for + descriptions of each. + + **Default value**: ``"pad"`` + """ + + contains: Literal["content", "padding"] + resize: bool + type: AutosizeType_T + + +class AxisConfigKwds(TypedDict, total=False): + """ + :class:`AxisConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG group, removing the axis from the ARIA accessibility tree. + + **Default value:** ``true`` + bandPosition + An interpolation fraction indicating where, for ``band`` scales, axis ticks should + be positioned. A value of ``0`` places ticks at the left edge of their bands. A + value of ``0.5`` places ticks in the middle of their bands. + + **Default value:** ``0.5`` + description + A text description of this axis for `ARIA accessibility + `__ (SVG output + only). If the ``aria`` property is true, for SVG output the `"aria-label" attribute + `__ + will be set to this description. If the description is unspecified it will be + automatically generated. + disable + Disable axis by default. + domain + A boolean flag indicating if the domain (the axis baseline) should be included as + part of the axis. + + **Default value:** ``true`` + domainCap + The stroke cap for the domain line's ending style. One of ``"butt"``, ``"round"`` or + ``"square"``. + + **Default value:** ``"butt"`` + domainColor + Color of axis domain line. + + **Default value:** ``"gray"``. + domainDash + An array of alternating [stroke, space] lengths for dashed domain lines. + domainDashOffset + The pixel offset at which to start drawing with the domain dash array. + domainOpacity + Opacity of the axis domain line. + domainWidth + Stroke width of axis domain line + + **Default value:** ``1`` + format + When used with the default ``"number"`` and ``"time"`` format type, the text + formatting pattern for labels of guides (axes, legends, headers) and text marks. + + * If the format type is ``"number"`` (e.g., for quantitative fields), this is D3's + `number format pattern `__. + * If the format type is ``"time"`` (e.g., for temporal fields), this is D3's `time + format pattern `__. + + See the `format documentation `__ + for more examples. + + When used with a `custom formatType + `__, this + value will be passed as ``format`` alongside ``datum.value`` to the registered + function. + + **Default value:** Derived from `numberFormat + `__ config for number + format and from `timeFormat + `__ config for time + format. + formatType + The format type for labels. One of ``"number"``, ``"time"``, or a `registered custom + format type + `__. + + **Default value:** + + * ``"time"`` for temporal fields and ordinal and nominal fields with ``timeUnit``. + * ``"number"`` for quantitative fields as well as ordinal and nominal fields without + ``timeUnit``. + grid + A boolean flag indicating if grid lines should be included as part of the axis + + **Default value:** ``true`` for `continuous scales + `__ that are not + binned; otherwise, ``false``. + gridCap + The stroke cap for grid lines' ending style. One of ``"butt"``, ``"round"`` or + ``"square"``. + + **Default value:** ``"butt"`` + gridColor + Color of gridlines. + + **Default value:** ``"lightGray"``. + gridDash + An array of alternating [stroke, space] lengths for dashed grid lines. + gridDashOffset + The pixel offset at which to start drawing with the grid dash array. + gridOpacity + The stroke opacity of grid (value between [0,1]) + + **Default value:** ``1`` + gridWidth + The grid width, in pixels. + + **Default value:** ``1`` + labelAlign + Horizontal text alignment of axis tick labels, overriding the default setting for + the current axis orientation. + labelAngle + The rotation angle of the axis labels. + + **Default value:** ``-90`` for nominal and ordinal fields; ``0`` otherwise. + labelBaseline + Vertical text baseline of axis tick labels, overriding the default setting for the + current axis orientation. One of ``"alphabetic"`` (default), ``"top"``, + ``"middle"``, ``"bottom"``, ``"line-top"``, or ``"line-bottom"``. The ``"line-top"`` + and ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but + are calculated relative to the *lineHeight* rather than *fontSize* alone. + labelBound + Indicates if labels should be hidden if they exceed the axis range. If ``false`` + (the default) no bounds overlap analysis is performed. If ``true``, labels will be + hidden if they exceed the axis range by more than 1 pixel. If this property is a + number, it specifies the pixel tolerance: the maximum amount by which a label + bounding box may exceed the axis range. + + **Default value:** ``false``. + labelColor + The color of the tick label, can be in hex color code or regular color name. + labelExpr + `Vega expression `__ for customizing + labels. + + **Note:** The label text and value can be assessed via the ``label`` and ``value`` + properties of the axis's backing ``datum`` object. + labelFlush + Indicates if the first and last axis labels should be aligned flush with the scale + range. Flush alignment for a horizontal axis will left-align the first label and + right-align the last label. For vertical axes, bottom and top text baselines are + applied instead. If this property is a number, it also indicates the number of + pixels by which to offset the first and last labels; for example, a value of 2 will + flush-align the first and last labels and also push them 2 pixels outward from the + center of the axis. The additional adjustment can sometimes help the labels better + visually group with corresponding axis ticks. + + **Default value:** ``true`` for axis of a continuous x-scale. Otherwise, ``false``. + labelFlushOffset + Indicates the number of pixels by which to offset flush-adjusted labels. For + example, a value of ``2`` will push flush-adjusted labels 2 pixels outward from the + center of the axis. Offsets can help the labels better visually group with + corresponding axis ticks. + + **Default value:** ``0``. + labelFont + The font of the tick label. + labelFontSize + The font size of the label, in pixels. + labelFontStyle + Font style of the title. + labelFontWeight + Font weight of axis tick labels. + labelLimit + Maximum allowed pixel width of axis tick labels. + + **Default value:** ``180`` + labelLineHeight + Line height in pixels for multi-line label text or label text with ``"line-top"`` or + ``"line-bottom"`` baseline. + labelOffset + Position offset in pixels to apply to labels, in addition to tickOffset. + + **Default value:** ``0`` + labelOpacity + The opacity of the labels. + labelOverlap + The strategy to use for resolving overlap of axis labels. If ``false`` (the + default), no overlap reduction is attempted. If set to ``true`` or ``"parity"``, a + strategy of removing every other label is used (this works well for standard linear + axes). If set to ``"greedy"``, a linear scan of the labels is performed, removing + any labels that overlaps with the last visible label (this often works better for + log-scaled axes). + + **Default value:** ``true`` for non-nominal fields with non-log scales; ``"greedy"`` + for log scales; otherwise ``false``. + labelPadding + The padding in pixels between labels and ticks. + + **Default value:** ``2`` + labelSeparation + The minimum separation that must be between label bounding boxes for them to be + considered non-overlapping (default ``0``). This property is ignored if + *labelOverlap* resolution is not enabled. + labels + A boolean flag indicating if labels should be included as part of the axis. + + **Default value:** ``true``. + maxExtent + The maximum extent in pixels that axis ticks and labels should use. This determines + a maximum offset value for axis titles. + + **Default value:** ``undefined``. + minExtent + The minimum extent in pixels that axis ticks and labels should use. This determines + a minimum offset value for axis titles. + + **Default value:** ``30`` for y-axis; ``undefined`` for x-axis. + offset + The offset, in pixels, by which to displace the axis from the edge of the enclosing + group or data rectangle. + + **Default value:** derived from the `axis config + `__'s + ``offset`` (``0`` by default) + orient + The orientation of the axis. One of ``"top"``, ``"bottom"``, ``"left"`` or + ``"right"``. The orientation can be used to further specialize the axis type (e.g., + a y-axis oriented towards the right edge of the chart). + + **Default value:** ``"bottom"`` for x-axes and ``"left"`` for y-axes. + position + The anchor position of the axis in pixels. For x-axes with top or bottom + orientation, this sets the axis group x coordinate. For y-axes with left or right + orientation, this sets the axis group y coordinate. + + **Default value**: ``0`` + style + A string or array of strings indicating the name of custom styles to apply to the + axis. A style is a named collection of axis property defined within the `style + configuration `__. If + style is an array, later styles will override earlier styles. + + **Default value:** (none) **Note:** Any specified style will augment the default + style. For example, an x-axis mark with ``"style": "foo"`` will use ``config.axisX`` + and ``config.style.foo`` (the specified style ``"foo"`` has higher precedence). + tickBand + For band scales, indicates if ticks and grid lines should be placed at the + ``"center"`` of a band (default) or at the band ``"extent"``s to indicate intervals + tickCap + The stroke cap for the tick lines' ending style. One of ``"butt"``, ``"round"`` or + ``"square"``. + + **Default value:** ``"butt"`` + tickColor + The color of the axis's tick. + + **Default value:** ``"gray"`` + tickCount + A desired number of ticks, for axes visualizing quantitative scales. The resulting + number may be different so that values are "nice" (multiples of 2, 5, 10) and lie + within the underlying scale's range. + + For scales of type ``"time"`` or ``"utc"``, the tick count can instead be a time + interval specifier. Legal string values are ``"millisecond"``, ``"second"``, + ``"minute"``, ``"hour"``, ``"day"``, ``"week"``, ``"month"``, and ``"year"``. + Alternatively, an object-valued interval specifier of the form ``{"interval": + "month", "step": 3}`` includes a desired number of interval steps. Here, ticks are + generated for each quarter (Jan, Apr, Jul, Oct) boundary. + + **Default value**: Determine using a formula ``ceil(width/40)`` for x and + ``ceil(height/40)`` for y. + tickDash + An array of alternating [stroke, space] lengths for dashed tick mark lines. + tickDashOffset + The pixel offset at which to start drawing with the tick mark dash array. + tickExtra + Boolean flag indicating if an extra axis tick should be added for the initial + position of the axis. This flag is useful for styling axes for ``band`` scales such + that ticks are placed on band boundaries rather in the middle of a band. Use in + conjunction with ``"bandPosition": 1`` and an axis ``"padding"`` value of ``0``. + tickMinStep + The minimum desired step between axis ticks, in terms of scale domain values. For + example, a value of ``1`` indicates that ticks should not be less than 1 unit apart. + If ``tickMinStep`` is specified, the ``tickCount`` value will be adjusted, if + necessary, to enforce the minimum step value. + tickOffset + Position offset in pixels to apply to ticks, labels, and gridlines. + tickOpacity + Opacity of the ticks. + tickRound + Boolean flag indicating if pixel position values should be rounded to the nearest + integer. + + **Default value:** ``true`` + tickSize + The size in pixels of axis ticks. + + **Default value:** ``5`` + tickWidth + The width, in pixels, of ticks. + + **Default value:** ``1`` + ticks + Boolean value that determines whether the axis should include ticks. + + **Default value:** ``true`` + title + A title for the field. If ``null``, the title will be removed. + + **Default value:** derived from the field's name and transformation function + (``aggregate``, ``bin`` and ``timeUnit``). If the field has an aggregate function, + the function is displayed as part of the title (e.g., ``"Sum of Profit"``). If the + field is binned or has a time unit applied, the applied function is shown in + parentheses (e.g., ``"Profit (binned)"``, ``"Transaction Date (year-month)"``). + Otherwise, the title is simply the field name. + + **Notes**: + + 1) You can customize the default field title format by providing the `fieldTitle + `__ property in + the `config `__ or `fieldTitle + function via the compile function's options + `__. + + 2) If both field definition's ``title`` and axis, header, or legend ``title`` are + defined, axis/header/legend title will be used. + titleAlign + Horizontal text alignment of axis titles. + titleAnchor + Text anchor position for placing axis titles. + titleAngle + Angle in degrees of axis titles. + titleBaseline + Vertical text baseline for axis titles. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, or ``"line-bottom"``. The + ``"line-top"`` and ``"line-bottom"`` values operate similarly to ``"top"`` and + ``"bottom"``, but are calculated relative to the *lineHeight* rather than *fontSize* + alone. + titleColor + Color of the title, can be in hex color code or regular color name. + titleFont + Font of the title. (e.g., ``"Helvetica Neue"``). + titleFontSize + Font size of the title. + titleFontStyle + Font style of the title. + titleFontWeight + Font weight of the title. This can be either a string (e.g ``"bold"``, ``"normal"``) + or a number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` + and ``"bold"`` = ``700``). + titleLimit + Maximum allowed pixel width of axis titles. + titleLineHeight + Line height in pixels for multi-line title text or title text with ``"line-top"`` or + ``"line-bottom"`` baseline. + titleOpacity + Opacity of the axis title. + titlePadding + The padding, in pixels, between title and axis. + titleX + X-coordinate of the axis title relative to the axis group. + titleY + Y-coordinate of the axis title relative to the axis group. + translate + Coordinate space translation offset for axis layout. By default, axes are translated + by a 0.5 pixel offset for both the x and y coordinates in order to align stroked + lines with the pixel grid. However, for vector graphics output these pixel-specific + adjustments may be undesirable, in which case translate can be changed (for example, + to zero). + + **Default value:** ``0.5`` + values + Explicitly set the visible axis tick values. + zindex + A non-negative integer indicating the z-index of the axis. If zindex is 0, axes + should be drawn behind all chart elements. To put them in front, set ``zindex`` to + ``1`` or more. + + **Default value:** ``0`` (behind the marks). + """ + + aria: bool + bandPosition: float + description: str + disable: bool + domain: bool + domainCap: StrokeCap_T + domainColor: None | ColorHex | ColorName_T + domainDash: Sequence[float] + domainDashOffset: float + domainOpacity: float + domainWidth: float + format: str + formatType: str + grid: bool + gridCap: StrokeCap_T + gridColor: None | ColorHex | ColorName_T + gridDash: Sequence[float] + gridDashOffset: float + gridOpacity: float + gridWidth: float + labelAlign: Align_T + labelAngle: float + labelBaseline: TextBaseline_T + labelBound: bool | float + labelColor: None | ColorHex | ColorName_T + labelExpr: str + labelFlush: bool | float + labelFlushOffset: float + labelFont: str + labelFontSize: float + labelFontStyle: str + labelFontWeight: FontWeight_T + labelLimit: float + labelLineHeight: float + labelOffset: float + labelOpacity: float + labelOverlap: bool | Literal["greedy", "parity"] + labelPadding: float + labelSeparation: float + labels: bool + maxExtent: float + minExtent: float + offset: float + orient: AxisOrient_T + position: float + style: str | Sequence[str] + tickBand: Literal["center", "extent"] + tickCap: StrokeCap_T + tickColor: None | ColorHex | ColorName_T + tickCount: float | TimeIntervalStepKwds | TimeInterval_T + tickDash: Sequence[float] + tickDashOffset: float + tickExtra: bool + tickMinStep: float + tickOffset: float + tickOpacity: float + tickRound: bool + tickSize: float + tickWidth: float + ticks: bool + title: str | None | Sequence[str] + titleAlign: Align_T + titleAnchor: TitleAnchor_T + titleAngle: float + titleBaseline: TextBaseline_T + titleColor: None | ColorHex | ColorName_T + titleFont: str + titleFontSize: float + titleFontStyle: str + titleFontWeight: FontWeight_T + titleLimit: float + titleLineHeight: float + titleOpacity: float + titlePadding: float + titleX: float + titleY: float + translate: float + values: Sequence[str] | Sequence[bool] | Sequence[float] | Sequence[DateTimeKwds] + zindex: float + + +class AxisResolveMapKwds(TypedDict, total=False): + """ + :class:`AxisResolveMap` ``TypedDict`` wrapper. + + Parameters + ---------- + x + + y + + """ + + x: ResolveMode_T + y: ResolveMode_T + + +class BarConfigKwds(TypedDict, total=False): + """ + :class:`BarConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + binSpacing + Offset between bars for binned field. The ideal value for this is either 0 + (preferred by statisticians) or 1 (Vega-Lite default, D3 example style). + + **Default value:** ``1`` + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + continuousBandSize + The default size of the bars on continuous scales. + + **Default value:** ``5`` + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusEnd + * For vertical bars, top-left and top-right corner radius. + + * For horizontal bars, top-right and bottom-right corner radius. + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + discreteBandSize + The default size of the bars with discrete dimensions. If unspecified, the default + size is ``step-2``, which provides 2 pixel offset between bars. + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + minBandSize + The minimum band size for bar and rectangle marks. **Default value:** ``0.25`` + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + baseline: TextBaseline_T + binSpacing: float + blend: Blend_T + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + continuousBandSize: float + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusEnd: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + discreteBandSize: float + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + lineBreak: str + lineHeight: float + minBandSize: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + radius: float + radius2: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + tension: float + text: str | Sequence[str] + theta: float + theta2: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + y: float | Literal["height"] + y2: float | Literal["height"] + + +class BindCheckboxKwds(TypedDict, total=False): + """ + :class:`BindCheckbox` ``TypedDict`` wrapper. + + Parameters + ---------- + input + + debounce + If defined, delays event handling until the specified milliseconds have elapsed + since the last event was fired. + element + An optional CSS selector string indicating the parent element to which the input + element should be added. By default, all input elements are added within the parent + container of the Vega view. + name + By default, the signal name is used to label input elements. This ``name`` property + can be used instead to specify a custom label for the bound signal. + """ + + input: Literal["checkbox"] + debounce: float + element: str + name: str + + +class BindDirectKwds(TypedDict, total=False): + """ + :class:`BindDirect` ``TypedDict`` wrapper. + + Parameters + ---------- + element + An input element that exposes a *value* property and supports the `EventTarget + `__ interface, or a + CSS selector string to such an element. When the element updates and dispatches an + event, the *value* property will be used as the new, bound signal value. When the + signal updates independent of the element, the *value* property will be set to the + signal value and a new event will be dispatched on the element. + debounce + If defined, delays event handling until the specified milliseconds have elapsed + since the last event was fired. + event + The event (default ``"input"``) to listen for to track changes on the external + element. + """ + + element: str + debounce: float + event: str + + +class BindInputKwds(TypedDict, total=False): + """ + :class:`BindInput` ``TypedDict`` wrapper. + + Parameters + ---------- + autocomplete + A hint for form autofill. See the `HTML autocomplete attribute + `__ for + additional information. + debounce + If defined, delays event handling until the specified milliseconds have elapsed + since the last event was fired. + element + An optional CSS selector string indicating the parent element to which the input + element should be added. By default, all input elements are added within the parent + container of the Vega view. + input + The type of input element to use. The valid values are ``"checkbox"``, ``"radio"``, + ``"range"``, ``"select"``, and any other legal `HTML form input type + `__. + name + By default, the signal name is used to label input elements. This ``name`` property + can be used instead to specify a custom label for the bound signal. + placeholder + Text that appears in the form control when it has no value set. + """ + + autocomplete: str + debounce: float + element: str + input: str + name: str + placeholder: str + + +class BindRadioSelectKwds(TypedDict, total=False): + """ + :class:`BindRadioSelect` ``TypedDict`` wrapper. + + Parameters + ---------- + input + + options + An array of options to select from. + debounce + If defined, delays event handling until the specified milliseconds have elapsed + since the last event was fired. + element + An optional CSS selector string indicating the parent element to which the input + element should be added. By default, all input elements are added within the parent + container of the Vega view. + labels + An array of label strings to represent the ``options`` values. If unspecified, the + ``options`` value will be coerced to a string and used as the label. + name + By default, the signal name is used to label input elements. This ``name`` property + can be used instead to specify a custom label for the bound signal. + """ + + input: Literal["radio", "select"] + options: Sequence[Any] + debounce: float + element: str + labels: Sequence[str] + name: str + + +class BindRangeKwds(TypedDict, total=False): + """ + :class:`BindRange` ``TypedDict`` wrapper. + + Parameters + ---------- + input + + debounce + If defined, delays event handling until the specified milliseconds have elapsed + since the last event was fired. + element + An optional CSS selector string indicating the parent element to which the input + element should be added. By default, all input elements are added within the parent + container of the Vega view. + max + Sets the maximum slider value. Defaults to the larger of the signal value and + ``100``. + min + Sets the minimum slider value. Defaults to the smaller of the signal value and + ``0``. + name + By default, the signal name is used to label input elements. This ``name`` property + can be used instead to specify a custom label for the bound signal. + step + Sets the minimum slider increment. If undefined, the step size will be automatically + determined based on the ``min`` and ``max`` values. + """ + + input: Literal["range"] + debounce: float + element: str + max: float + min: float + name: str + step: float + + +class BoxPlotConfigKwds(TypedDict, total=False): + """ + :class:`BoxPlotConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + box + + extent + The extent of the whiskers. Available options include: + + * ``"min-max"``: min and max are the lower and upper whiskers respectively. + * A number representing multiple of the interquartile range. This number will be + multiplied by the IQR to determine whisker boundary, which spans from the smallest + data to the largest data within the range *[Q1 - k * IQR, Q3 + k * IQR]* where + *Q1* and *Q3* are the first and third quartiles while *IQR* is the interquartile + range (*Q3-Q1*). + + **Default value:** ``1.5``. + median + + outliers + + rule + + size + Size of the box and median tick of a box plot + ticks + + """ + + box: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + extent: float | Literal["min-max"] + median: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + outliers: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + rule: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + size: float + ticks: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + + +class BrushConfigKwds(TypedDict, total=False): + """ + :class:`BrushConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + cursor + The mouse cursor used over the interval mark. Any valid `CSS cursor type + `__ can be used. + fill + The fill color of the interval mark. + + **Default value:** ``"#333333"`` + fillOpacity + The fill opacity of the interval mark (a value between ``0`` and ``1``). + + **Default value:** ``0.125`` + stroke + The stroke color of the interval mark. + + **Default value:** ``"#ffffff"`` + strokeDash + An array of alternating stroke and space lengths, for creating dashed or dotted + lines. + strokeDashOffset + The offset (in pixels) with which to begin drawing the stroke dash array. + strokeOpacity + The stroke opacity of the interval mark (a value between ``0`` and ``1``). + strokeWidth + The stroke width of the interval mark. + """ + + cursor: Cursor_T + fill: ColorHex | ColorName_T + fillOpacity: float + stroke: ColorHex | ColorName_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeOpacity: float + strokeWidth: float + + +class CompositionConfigKwds(TypedDict, total=False): + """ + :class:`CompositionConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + columns + The number of columns to include in the view composition layout. + + **Default value**: ``undefined`` -- An infinite number of columns (a single row) + will be assumed. This is equivalent to ``hconcat`` (for ``concat``) and to using the + ``column`` channel (for ``facet`` and ``repeat``). + + **Note**: + + 1) This property is only for: + + * the general (wrappable) ``concat`` operator (not ``hconcat``/``vconcat``) + * the ``facet`` and ``repeat`` operator with one field/repetition definition + (without row/column nesting) + + 2) Setting the ``columns`` to ``1`` is equivalent to ``vconcat`` (for ``concat``) + and to using the ``row`` channel (for ``facet`` and ``repeat``). + spacing + The default spacing in pixels between composed sub-views. + + **Default value**: ``20`` + """ + + columns: float + spacing: float + + +class ConfigKwds(TypedDict, total=False): + """ + :class:`Config` ``TypedDict`` wrapper. + + Parameters + ---------- + arc + Arc-specific Config + area + Area-Specific Config + aria + A boolean flag indicating if ARIA default attributes should be included for marks + and guides (SVG output only). If false, the ``"aria-hidden"`` attribute will be set + for all guides, removing them from the ARIA accessibility tree and Vega-Lite will + not generate default descriptions for marks. + + **Default value:** ``true``. + autosize + How the visualization size should be determined. If a string, should be one of + ``"pad"``, ``"fit"`` or ``"none"``. Object values can additionally specify + parameters for content sizing and automatic resizing. + + **Default value**: ``pad`` + axis + Axis configuration, which determines default properties for all ``x`` and ``y`` + `axes `__. For a full list of axis + configuration options, please see the `corresponding section of the axis + documentation `__. + axisBand + Config for axes with "band" scales. + axisBottom + Config for x-axis along the bottom edge of the chart. + axisDiscrete + Config for axes with "point" or "band" scales. + axisLeft + Config for y-axis along the left edge of the chart. + axisPoint + Config for axes with "point" scales. + axisQuantitative + Config for quantitative axes. + axisRight + Config for y-axis along the right edge of the chart. + axisTemporal + Config for temporal axes. + axisTop + Config for x-axis along the top edge of the chart. + axisX + X-axis specific config. + axisXBand + Config for x-axes with "band" scales. + axisXDiscrete + Config for x-axes with "point" or "band" scales. + axisXPoint + Config for x-axes with "point" scales. + axisXQuantitative + Config for x-quantitative axes. + axisXTemporal + Config for x-temporal axes. + axisY + Y-axis specific config. + axisYBand + Config for y-axes with "band" scales. + axisYDiscrete + Config for y-axes with "point" or "band" scales. + axisYPoint + Config for y-axes with "point" scales. + axisYQuantitative + Config for y-quantitative axes. + axisYTemporal + Config for y-temporal axes. + background + CSS color property to use as the background of the entire view. + + **Default value:** ``"white"`` + bar + Bar-Specific Config + boxplot + Box Config + circle + Circle-Specific Config + concat + Default configuration for all concatenation and repeat view composition operators + (``concat``, ``hconcat``, ``vconcat``, and ``repeat``) + countTitle + Default axis and legend title for count fields. + + **Default value:** ``'Count of Records``. + customFormatTypes + Allow the ``formatType`` property for text marks and guides to accept a custom + formatter function `registered as a Vega expression + `__. + errorband + ErrorBand Config + errorbar + ErrorBar Config + facet + Default configuration for the ``facet`` view composition operator + fieldTitle + Defines how Vega-Lite generates title for fields. There are three possible styles: + + * ``"verbal"`` (Default) - displays function in a verbal style (e.g., "Sum of + field", "Year-month of date", "field (binned)"). + * ``"function"`` - displays function using parentheses and capitalized texts (e.g., + "SUM(field)", "YEARMONTH(date)", "BIN(field)"). + * ``"plain"`` - displays only the field name without functions (e.g., "field", + "date", "field"). + font + Default font for all text marks, titles, and labels. + geoshape + Geoshape-Specific Config + header + Header configuration, which determines default properties for all `headers + `__. + + For a full list of header configuration options, please see the `corresponding + section of in the header documentation + `__. + headerColumn + Header configuration, which determines default properties for column `headers + `__. + + For a full list of header configuration options, please see the `corresponding + section of in the header documentation + `__. + headerFacet + Header configuration, which determines default properties for non-row/column facet + `headers `__. + + For a full list of header configuration options, please see the `corresponding + section of in the header documentation + `__. + headerRow + Header configuration, which determines default properties for row `headers + `__. + + For a full list of header configuration options, please see the `corresponding + section of in the header documentation + `__. + image + Image-specific Config + legend + Legend configuration, which determines default properties for all `legends + `__. For a full list of legend + configuration options, please see the `corresponding section of in the legend + documentation `__. + line + Line-Specific Config + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property provides a global default for text marks, which is + overridden by mark or style config settings, and by the lineBreak mark encoding + channel. If signal-valued, either string or regular expression (regexp) values are + valid. + locale + Locale definitions for string parsing and formatting of number and date values. The + locale object should contain ``number`` and/or ``time`` properties with `locale + definitions `__. Locale definitions + provided in the config block may be overridden by the View constructor locale + option. + mark + Mark Config + normalizedNumberFormat + If normalizedNumberFormatType is not specified, D3 number format for axis labels, + text marks, and tooltips of normalized stacked fields (fields with ``stack: + "normalize"``). For example ``"s"`` for SI units. Use `D3's number format pattern + `__. + + If ``config.normalizedNumberFormatType`` is specified and + ``config.customFormatTypes`` is ``true``, this value will be passed as ``format`` + alongside ``datum.value`` to the ``config.numberFormatType`` function. **Default + value:** ``%`` + normalizedNumberFormatType + `Custom format type + `__ for + ``config.normalizedNumberFormat``. + + **Default value:** ``undefined`` -- This is equilvalent to call D3-format, which is + exposed as `format in Vega-Expression + `__. **Note:** You must also + set ``customFormatTypes`` to ``true`` to use this feature. + numberFormat + If numberFormatType is not specified, D3 number format for guide labels, text marks, + and tooltips of non-normalized fields (fields *without* ``stack: "normalize"``). For + example ``"s"`` for SI units. Use `D3's number format pattern + `__. + + If ``config.numberFormatType`` is specified and ``config.customFormatTypes`` is + ``true``, this value will be passed as ``format`` alongside ``datum.value`` to the + ``config.numberFormatType`` function. + numberFormatType + `Custom format type + `__ for + ``config.numberFormat``. + + **Default value:** ``undefined`` -- This is equilvalent to call D3-format, which is + exposed as `format in Vega-Expression + `__. **Note:** You must also + set ``customFormatTypes`` to ``true`` to use this feature. + padding + The default visualization padding, in pixels, from the edge of the visualization + canvas to the data rectangle. If a number, specifies padding for all sides. If an + object, the value should have the format ``{"left": 5, "top": 5, "right": 5, + "bottom": 5}`` to specify padding for each side of the visualization. + + **Default value**: ``5`` + params + Dynamic variables or selections that parameterize a visualization. + point + Point-Specific Config + projection + Projection configuration, which determines default properties for all `projections + `__. For a full list of + projection configuration options, please see the `corresponding section of the + projection documentation + `__. + range + An object hash that defines default range arrays or schemes for using with scales. + For a full list of scale range configuration options, please see the `corresponding + section of the scale documentation + `__. + rect + Rect-Specific Config + rule + Rule-Specific Config + scale + Scale configuration determines default properties for all `scales + `__. For a full list of scale + configuration options, please see the `corresponding section of the scale + documentation `__. + selection + An object hash for defining default properties for each type of selections. + square + Square-Specific Config + style + An object hash that defines key-value mappings to determine default properties for + marks with a given `style + `__. The keys represent + styles names; the values have to be valid `mark configuration objects + `__. + text + Text-Specific Config + tick + Tick-Specific Config + timeFormat + Default time format for raw time values (without time units) in text marks, legend + labels and header labels. + + **Default value:** ``"%b %d, %Y"`` **Note:** Axes automatically determine the format + for each label automatically so this config does not affect axes. + timeFormatType + `Custom format type + `__ for + ``config.timeFormat``. + + **Default value:** ``undefined`` -- This is equilvalent to call D3-time-format, + which is exposed as `timeFormat in Vega-Expression + `__. **Note:** You must + also set ``customFormatTypes`` to ``true`` and there must *not* be a ``timeUnit`` + defined to use this feature. + title + Title configuration, which determines default properties for all `titles + `__. For a full list of title + configuration options, please see the `corresponding section of the title + documentation `__. + tooltipFormat + Define `custom format configuration + `__ for tooltips. If + unspecified, default format config will be applied. + trail + Trail-Specific Config + view + Default properties for `single view plots + `__. + """ + + arc: RectConfigKwds + area: AreaConfigKwds + aria: bool + autosize: AutoSizeParamsKwds | AutosizeType_T + axis: AxisConfigKwds + axisBand: AxisConfigKwds + axisBottom: AxisConfigKwds + axisDiscrete: AxisConfigKwds + axisLeft: AxisConfigKwds + axisPoint: AxisConfigKwds + axisQuantitative: AxisConfigKwds + axisRight: AxisConfigKwds + axisTemporal: AxisConfigKwds + axisTop: AxisConfigKwds + axisX: AxisConfigKwds + axisXBand: AxisConfigKwds + axisXDiscrete: AxisConfigKwds + axisXPoint: AxisConfigKwds + axisXQuantitative: AxisConfigKwds + axisXTemporal: AxisConfigKwds + axisY: AxisConfigKwds + axisYBand: AxisConfigKwds + axisYDiscrete: AxisConfigKwds + axisYPoint: AxisConfigKwds + axisYQuantitative: AxisConfigKwds + axisYTemporal: AxisConfigKwds + background: ColorHex | ColorName_T + bar: BarConfigKwds + boxplot: BoxPlotConfigKwds + circle: MarkConfigKwds + concat: CompositionConfigKwds + countTitle: str + customFormatTypes: bool + errorband: ErrorBandConfigKwds + errorbar: ErrorBarConfigKwds + facet: CompositionConfigKwds + fieldTitle: Literal["verbal", "functional", "plain"] + font: str + geoshape: MarkConfigKwds + header: HeaderConfigKwds + headerColumn: HeaderConfigKwds + headerFacet: HeaderConfigKwds + headerRow: HeaderConfigKwds + image: RectConfigKwds + legend: LegendConfigKwds + line: LineConfigKwds + lineBreak: str + locale: LocaleKwds + mark: MarkConfigKwds + normalizedNumberFormat: str + normalizedNumberFormatType: str + numberFormat: str + numberFormatType: str + padding: float | PaddingKwds + params: Sequence[VariableParameterKwds | TopLevelSelectionParameterKwds] + point: MarkConfigKwds + projection: ProjectionConfigKwds + range: RangeConfigKwds + rect: RectConfigKwds + rule: MarkConfigKwds + scale: ScaleConfigKwds + selection: SelectionConfigKwds + square: MarkConfigKwds + style: StyleConfigIndexKwds + text: MarkConfigKwds + tick: TickConfigKwds + timeFormat: str + timeFormatType: str + title: TitleConfigKwds + tooltipFormat: FormatConfigKwds + trail: LineConfigKwds + view: ViewConfigKwds + + +class DateTimeKwds(TypedDict, total=False): + """ + :class:`DateTime` ``TypedDict`` wrapper. + + Parameters + ---------- + date + Integer value representing the date (day of the month) from 1-31. + day + Value representing the day of a week. This can be one of: (1) integer value -- ``1`` + represents Monday; (2) case-insensitive day name (e.g., ``"Monday"``); (3) + case-insensitive, 3-character short day name (e.g., ``"Mon"``). + + **Warning:** A DateTime definition object with ``day``** should not be combined with + ``year``, ``quarter``, ``month``, or ``date``. + hours + Integer value representing the hour of a day from 0-23. + milliseconds + Integer value representing the millisecond segment of time. + minutes + Integer value representing the minute segment of time from 0-59. + month + One of: (1) integer value representing the month from ``1``-``12``. ``1`` represents + January; (2) case-insensitive month name (e.g., ``"January"``); (3) + case-insensitive, 3-character short month name (e.g., ``"Jan"``). + quarter + Integer value representing the quarter of the year (from 1-4). + seconds + Integer value representing the second segment (0-59) of a time value + utc + A boolean flag indicating if date time is in utc time. If false, the date time is in + local time + year + Integer value representing the year. + """ + + date: float + day: str | float + hours: float + milliseconds: float + minutes: float + month: str | float + quarter: float + seconds: float + utc: bool + year: float + + +class DerivedStreamKwds(TypedDict, total=False): + """ + :class:`DerivedStream` ``TypedDict`` wrapper. + + Parameters + ---------- + stream + + between + + consume + + debounce + + filter + + markname + + marktype + + throttle + + """ + + stream: MergedStreamKwds | DerivedStreamKwds + between: Sequence[MergedStreamKwds | DerivedStreamKwds] + consume: bool + debounce: float + filter: str | Sequence[str] + markname: str + marktype: MarkType_T + throttle: float + + +class ErrorBandConfigKwds(TypedDict, total=False): + """ + :class:`ErrorBandConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + band + + borders + + extent + The extent of the band. Available options include: + + * ``"ci"``: Extend the band to the confidence interval of the mean. + * ``"stderr"``: The size of band are set to the value of standard error, extending + from the mean. + * ``"stdev"``: The size of band are set to the value of standard deviation, + extending from the mean. + * ``"iqr"``: Extend the band to the q1 and q3. + + **Default value:** ``"stderr"``. + interpolate + The line interpolation method for the error band. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: a piecewise constant function (a step function) consisting of + alternating horizontal and vertical lines. The y-value changes at the midpoint of + each pair of adjacent x-values. + * ``"step-before"``: a piecewise constant function (a step function) consisting of + alternating horizontal and vertical lines. The y-value changes before the x-value. + * ``"step-after"``: a piecewise constant function (a step function) consisting of + alternating horizontal and vertical lines. The y-value changes after the x-value. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + tension + The tension parameter for the interpolation type of the error band. + """ + + band: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + borders: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + extent: ErrorBarExtent_T + interpolate: Interpolate_T + tension: float + + +class ErrorBarConfigKwds(TypedDict, total=False): + """ + :class:`ErrorBarConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + extent + The extent of the rule. Available options include: + + * ``"ci"``: Extend the rule to the confidence interval of the mean. + * ``"stderr"``: The size of rule are set to the value of standard error, extending + from the mean. + * ``"stdev"``: The size of rule are set to the value of standard deviation, + extending from the mean. + * ``"iqr"``: Extend the rule to the q1 and q3. + + **Default value:** ``"stderr"``. + rule + + size + Size of the ticks of an error bar + thickness + Thickness of the ticks and the bar of an error bar + ticks + + """ + + extent: ErrorBarExtent_T + rule: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + size: float + thickness: float + ticks: ( + bool + | BarConfigKwds + | AreaConfigKwds + | LineConfigKwds + | MarkConfigKwds + | RectConfigKwds + | TickConfigKwds + ) + + +class FeatureGeometryGeoJsonPropertiesKwds(TypedDict, total=False): + """ + :class:`FeatureGeometryGeoJsonProperties` ``TypedDict`` wrapper. + + Parameters + ---------- + geometry + The feature's geometry + properties + Properties associated with this feature. + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + id + A value that uniquely identifies this feature in a + https://tools.ietf.org/html/rfc7946#section-3.2. + """ + + geometry: ( + PointKwds + | PolygonKwds + | LineStringKwds + | MultiPointKwds + | MultiPolygonKwds + | MultiLineStringKwds + | GeometryCollectionKwds + ) + properties: None + type: Literal["Feature"] + bbox: Sequence[float] + id: str | float + + +class FormatConfigKwds(TypedDict, total=False): + """ + :class:`FormatConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + normalizedNumberFormat + If normalizedNumberFormatType is not specified, D3 number format for axis labels, + text marks, and tooltips of normalized stacked fields (fields with ``stack: + "normalize"``). For example ``"s"`` for SI units. Use `D3's number format pattern + `__. + + If ``config.normalizedNumberFormatType`` is specified and + ``config.customFormatTypes`` is ``true``, this value will be passed as ``format`` + alongside ``datum.value`` to the ``config.numberFormatType`` function. **Default + value:** ``%`` + normalizedNumberFormatType + `Custom format type + `__ for + ``config.normalizedNumberFormat``. + + **Default value:** ``undefined`` -- This is equilvalent to call D3-format, which is + exposed as `format in Vega-Expression + `__. **Note:** You must also + set ``customFormatTypes`` to ``true`` to use this feature. + numberFormat + If numberFormatType is not specified, D3 number format for guide labels, text marks, + and tooltips of non-normalized fields (fields *without* ``stack: "normalize"``). For + example ``"s"`` for SI units. Use `D3's number format pattern + `__. + + If ``config.numberFormatType`` is specified and ``config.customFormatTypes`` is + ``true``, this value will be passed as ``format`` alongside ``datum.value`` to the + ``config.numberFormatType`` function. + numberFormatType + `Custom format type + `__ for + ``config.numberFormat``. + + **Default value:** ``undefined`` -- This is equilvalent to call D3-format, which is + exposed as `format in Vega-Expression + `__. **Note:** You must also + set ``customFormatTypes`` to ``true`` to use this feature. + timeFormat + Default time format for raw time values (without time units) in text marks, legend + labels and header labels. + + **Default value:** ``"%b %d, %Y"`` **Note:** Axes automatically determine the format + for each label automatically so this config does not affect axes. + timeFormatType + `Custom format type + `__ for + ``config.timeFormat``. + + **Default value:** ``undefined`` -- This is equilvalent to call D3-time-format, + which is exposed as `timeFormat in Vega-Expression + `__. **Note:** You must + also set ``customFormatTypes`` to ``true`` and there must *not* be a ``timeUnit`` + defined to use this feature. + """ + + normalizedNumberFormat: str + normalizedNumberFormatType: str + numberFormat: str + numberFormatType: str + timeFormat: str + timeFormatType: str + + +class GeoJsonFeatureKwds(TypedDict, total=False): + """ + :class:`GeoJsonFeature` ``TypedDict`` wrapper. + + Parameters + ---------- + geometry + The feature's geometry + properties + Properties associated with this feature. + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + id + A value that uniquely identifies this feature in a + https://tools.ietf.org/html/rfc7946#section-3.2. + """ + + geometry: ( + PointKwds + | PolygonKwds + | LineStringKwds + | MultiPointKwds + | MultiPolygonKwds + | MultiLineStringKwds + | GeometryCollectionKwds + ) + properties: None + type: Literal["Feature"] + bbox: Sequence[float] + id: str | float + + +class GeoJsonFeatureCollectionKwds(TypedDict, total=False): + """ + :class:`GeoJsonFeatureCollection` ``TypedDict`` wrapper. + + Parameters + ---------- + features + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + features: Sequence[FeatureGeometryGeoJsonPropertiesKwds] + type: Literal["FeatureCollection"] + bbox: Sequence[float] + + +class GeometryCollectionKwds(TypedDict, total=False): + """ + :class:`GeometryCollection` ``TypedDict`` wrapper. + + Parameters + ---------- + geometries + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + geometries: Sequence[ + PointKwds + | PolygonKwds + | LineStringKwds + | MultiPointKwds + | MultiPolygonKwds + | MultiLineStringKwds + | GeometryCollectionKwds + ] + type: Literal["GeometryCollection"] + bbox: Sequence[float] + + +class GradientStopKwds(TypedDict, total=False): + """ + :class:`GradientStop` ``TypedDict`` wrapper. + + Parameters + ---------- + color + The color value at this point in the gradient. + offset + The offset fraction for the color stop, indicating its position within the gradient. + """ + + color: ColorHex | ColorName_T + offset: float + + +class HeaderConfigKwds(TypedDict, total=False): + """ + :class:`HeaderConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + format + When used with the default ``"number"`` and ``"time"`` format type, the text + formatting pattern for labels of guides (axes, legends, headers) and text marks. + + * If the format type is ``"number"`` (e.g., for quantitative fields), this is D3's + `number format pattern `__. + * If the format type is ``"time"`` (e.g., for temporal fields), this is D3's `time + format pattern `__. + + See the `format documentation `__ + for more examples. + + When used with a `custom formatType + `__, this + value will be passed as ``format`` alongside ``datum.value`` to the registered + function. + + **Default value:** Derived from `numberFormat + `__ config for number + format and from `timeFormat + `__ config for time + format. + formatType + The format type for labels. One of ``"number"``, ``"time"``, or a `registered custom + format type + `__. + + **Default value:** + + * ``"time"`` for temporal fields and ordinal and nominal fields with ``timeUnit``. + * ``"number"`` for quantitative fields as well as ordinal and nominal fields without + ``timeUnit``. + labelAlign + Horizontal text alignment of header labels. One of ``"left"``, ``"center"``, or + ``"right"``. + labelAnchor + The anchor position for placing the labels. One of ``"start"``, ``"middle"``, or + ``"end"``. For example, with a label orientation of top these anchor positions map + to a left-, center-, or right-aligned label. + labelAngle + The rotation angle of the header labels. + + **Default value:** ``0`` for column header, ``-90`` for row header. + labelBaseline + The vertical text baseline for the header labels. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, or ``"line-bottom"``. The + ``"line-top"`` and ``"line-bottom"`` values operate similarly to ``"top"`` and + ``"bottom"``, but are calculated relative to the ``titleLineHeight`` rather than + ``titleFontSize`` alone. + labelColor + The color of the header label, can be in hex color code or regular color name. + labelExpr + `Vega expression `__ for customizing + labels. + + **Note:** The label text and value can be assessed via the ``label`` and ``value`` + properties of the header's backing ``datum`` object. + labelFont + The font of the header label. + labelFontSize + The font size of the header label, in pixels. + labelFontStyle + The font style of the header label. + labelFontWeight + The font weight of the header label. + labelLimit + The maximum length of the header label in pixels. The text value will be + automatically truncated if the rendered size exceeds the limit. + + **Default value:** ``0``, indicating no limit + labelLineHeight + Line height in pixels for multi-line header labels or title text with ``"line-top"`` + or ``"line-bottom"`` baseline. + labelOrient + The orientation of the header label. One of ``"top"``, ``"bottom"``, ``"left"`` or + ``"right"``. + labelPadding + The padding, in pixel, between facet header's label and the plot. + + **Default value:** ``10`` + labels + A boolean flag indicating if labels should be included as part of the header. + + **Default value:** ``true``. + orient + Shortcut for setting both labelOrient and titleOrient. + title + Set to null to disable title for the axis, legend, or header. + titleAlign + Horizontal text alignment (to the anchor) of header titles. + titleAnchor + The anchor position for placing the title. One of ``"start"``, ``"middle"``, or + ``"end"``. For example, with an orientation of top these anchor positions map to a + left-, center-, or right-aligned title. + titleAngle + The rotation angle of the header title. + + **Default value:** ``0``. + titleBaseline + The vertical text baseline for the header title. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, or ``"line-bottom"``. The + ``"line-top"`` and ``"line-bottom"`` values operate similarly to ``"top"`` and + ``"bottom"``, but are calculated relative to the ``titleLineHeight`` rather than + ``titleFontSize`` alone. + + **Default value:** ``"middle"`` + titleColor + Color of the header title, can be in hex color code or regular color name. + titleFont + Font of the header title. (e.g., ``"Helvetica Neue"``). + titleFontSize + Font size of the header title. + titleFontStyle + The font style of the header title. + titleFontWeight + Font weight of the header title. This can be either a string (e.g ``"bold"``, + ``"normal"``) or a number (``100``, ``200``, ``300``, ..., ``900`` where + ``"normal"`` = ``400`` and ``"bold"`` = ``700``). + titleLimit + The maximum length of the header title in pixels. The text value will be + automatically truncated if the rendered size exceeds the limit. + + **Default value:** ``0``, indicating no limit + titleLineHeight + Line height in pixels for multi-line header title text or title text with + ``"line-top"`` or ``"line-bottom"`` baseline. + titleOrient + The orientation of the header title. One of ``"top"``, ``"bottom"``, ``"left"`` or + ``"right"``. + titlePadding + The padding, in pixel, between facet header's title and the label. + + **Default value:** ``10`` + """ + + format: str + formatType: str + labelAlign: Align_T + labelAnchor: TitleAnchor_T + labelAngle: float + labelBaseline: TextBaseline_T + labelColor: ColorHex | ColorName_T + labelExpr: str + labelFont: str + labelFontSize: float + labelFontStyle: str + labelFontWeight: FontWeight_T + labelLimit: float + labelLineHeight: float + labelOrient: Orient_T + labelPadding: float + labels: bool + orient: Orient_T + title: None + titleAlign: Align_T + titleAnchor: TitleAnchor_T + titleAngle: float + titleBaseline: TextBaseline_T + titleColor: ColorHex | ColorName_T + titleFont: str + titleFontSize: float + titleFontStyle: str + titleFontWeight: FontWeight_T + titleLimit: float + titleLineHeight: float + titleOrient: Orient_T + titlePadding: float + + +class IntervalSelectionConfigKwds(TypedDict, total=False): + """ + :class:`IntervalSelectionConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + type + Determines the default event processing and data query for the selection. Vega-Lite + currently supports two selection types: + + * ``"point"`` -- to select multiple discrete data values; the first value is + selected on ``click`` and additional values toggled on shift-click. + * ``"interval"`` -- to select a continuous range of data values on ``drag``. + clear + Clears the selection, emptying it of all values. This property can be a `Event + Stream `__ or ``false`` to disable + clear. + + **Default value:** ``dblclick``. + + **See also:** `clear examples + `__ in the + documentation. + encodings + An array of encoding channels. The corresponding data field values must match for a + data tuple to fall within the selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + fields + An array of field names whose values must match for a data tuple to fall within the + selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + mark + An interval selection also adds a rectangle mark to depict the extents of the + interval. The ``mark`` property can be used to customize the appearance of the mark. + + **See also:** `mark examples + `__ in the documentation. + on + A `Vega event stream `__ (object or + selector) that triggers the selection. For interval selections, the event stream + must specify a `start and end + `__. + + **See also:** `on examples + `__ in the documentation. + resolve + With layered and multi-view displays, a strategy that determines how selections' + data queries are resolved when applied in a filter transform, conditional encoding + rule, or scale domain. + + One of: + + * ``"global"`` -- only one brush exists for the entire SPLOM. When the user begins + to drag, any previous brushes are cleared, and a new one is constructed. + * ``"union"`` -- each cell contains its own brush, and points are highlighted if + they lie within *any* of these individual brushes. + * ``"intersect"`` -- each cell contains its own brush, and points are highlighted + only if they fall within *all* of these individual brushes. + + **Default value:** ``global``. + + **See also:** `resolve examples + `__ in the + documentation. + translate + When truthy, allows a user to interactively move an interval selection + back-and-forth. Can be ``true``, ``false`` (to disable panning), or a `Vega event + stream definition `__ which must + include a start and end event to trigger continuous panning. Discrete panning (e.g., + pressing the left/right arrow keys) will be supported in future versions. + + **Default value:** ``true``, which corresponds to ``[pointerdown, window:pointerup] + > window:pointermove!``. This default allows users to clicks and drags within an + interval selection to reposition it. + + **See also:** `translate examples + `__ in the + documentation. + zoom + When truthy, allows a user to interactively resize an interval selection. Can be + ``true``, ``false`` (to disable zooming), or a `Vega event stream definition + `__. Currently, only ``wheel`` + events are supported, but custom event streams can still be used to specify filters, + debouncing, and throttling. Future versions will expand the set of events that can + trigger this transformation. + + **Default value:** ``true``, which corresponds to ``wheel!``. This default allows + users to use the mouse wheel to resize an interval selection. + + **See also:** `zoom examples + `__ in the documentation. + """ + + type: Literal["interval"] + clear: str | bool | MergedStreamKwds | DerivedStreamKwds + encodings: Sequence[SingleDefUnitChannel_T] + fields: Sequence[str] + mark: BrushConfigKwds + on: str | MergedStreamKwds | DerivedStreamKwds + resolve: SelectionResolution_T + translate: str | bool + zoom: str | bool + + +class IntervalSelectionConfigWithoutTypeKwds(TypedDict, total=False): + """ + :class:`IntervalSelectionConfigWithoutType` ``TypedDict`` wrapper. + + Parameters + ---------- + clear + Clears the selection, emptying it of all values. This property can be a `Event + Stream `__ or ``false`` to disable + clear. + + **Default value:** ``dblclick``. + + **See also:** `clear examples + `__ in the + documentation. + encodings + An array of encoding channels. The corresponding data field values must match for a + data tuple to fall within the selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + fields + An array of field names whose values must match for a data tuple to fall within the + selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + mark + An interval selection also adds a rectangle mark to depict the extents of the + interval. The ``mark`` property can be used to customize the appearance of the mark. + + **See also:** `mark examples + `__ in the documentation. + on + A `Vega event stream `__ (object or + selector) that triggers the selection. For interval selections, the event stream + must specify a `start and end + `__. + + **See also:** `on examples + `__ in the documentation. + resolve + With layered and multi-view displays, a strategy that determines how selections' + data queries are resolved when applied in a filter transform, conditional encoding + rule, or scale domain. + + One of: + + * ``"global"`` -- only one brush exists for the entire SPLOM. When the user begins + to drag, any previous brushes are cleared, and a new one is constructed. + * ``"union"`` -- each cell contains its own brush, and points are highlighted if + they lie within *any* of these individual brushes. + * ``"intersect"`` -- each cell contains its own brush, and points are highlighted + only if they fall within *all* of these individual brushes. + + **Default value:** ``global``. + + **See also:** `resolve examples + `__ in the + documentation. + translate + When truthy, allows a user to interactively move an interval selection + back-and-forth. Can be ``true``, ``false`` (to disable panning), or a `Vega event + stream definition `__ which must + include a start and end event to trigger continuous panning. Discrete panning (e.g., + pressing the left/right arrow keys) will be supported in future versions. + + **Default value:** ``true``, which corresponds to ``[pointerdown, window:pointerup] + > window:pointermove!``. This default allows users to clicks and drags within an + interval selection to reposition it. + + **See also:** `translate examples + `__ in the + documentation. + zoom + When truthy, allows a user to interactively resize an interval selection. Can be + ``true``, ``false`` (to disable zooming), or a `Vega event stream definition + `__. Currently, only ``wheel`` + events are supported, but custom event streams can still be used to specify filters, + debouncing, and throttling. Future versions will expand the set of events that can + trigger this transformation. + + **Default value:** ``true``, which corresponds to ``wheel!``. This default allows + users to use the mouse wheel to resize an interval selection. + + **See also:** `zoom examples + `__ in the documentation. + """ + + clear: str | bool | MergedStreamKwds | DerivedStreamKwds + encodings: Sequence[SingleDefUnitChannel_T] + fields: Sequence[str] + mark: BrushConfigKwds + on: str | MergedStreamKwds | DerivedStreamKwds + resolve: SelectionResolution_T + translate: str | bool + zoom: str | bool + + +class LegendConfigKwds(TypedDict, total=False): + """ + :class:`LegendConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG group, removing the legend from the ARIA accessibility tree. + + **Default value:** ``true`` + clipHeight + The height in pixels to clip symbol legend entries and limit their size. + columnPadding + The horizontal padding in pixels between symbol legend entries. + + **Default value:** ``10``. + columns + The number of columns in which to arrange symbol legend entries. A value of ``0`` or + lower indicates a single row with one column per entry. + cornerRadius + Corner radius for the full legend. + description + A text description of this legend for `ARIA accessibility + `__ (SVG output + only). If the ``aria`` property is true, for SVG output the `"aria-label" attribute + `__ + will be set to this description. If the description is unspecified it will be + automatically generated. + direction + The direction of the legend, one of ``"vertical"`` or ``"horizontal"``. + + **Default value:** + + * For top-/bottom-``orient``ed legends, ``"horizontal"`` + * For left-/right-``orient``ed legends, ``"vertical"`` + * For top/bottom-left/right-``orient``ed legends, ``"horizontal"`` for gradient + legends and ``"vertical"`` for symbol legends. + disable + Disable legend by default + fillColor + Background fill color for the full legend. + gradientDirection + The default direction (``"horizontal"`` or ``"vertical"``) for gradient legends. + + **Default value:** ``"vertical"``. + gradientHorizontalMaxLength + Max legend length for a horizontal gradient when ``config.legend.gradientLength`` is + undefined. + + **Default value:** ``200`` + gradientHorizontalMinLength + Min legend length for a horizontal gradient when ``config.legend.gradientLength`` is + undefined. + + **Default value:** ``100`` + gradientLabelLimit + The maximum allowed length in pixels of color ramp gradient labels. + gradientLabelOffset + Vertical offset in pixels for color ramp gradient labels. + + **Default value:** ``2``. + gradientLength + The length in pixels of the primary axis of a color gradient. This value corresponds + to the height of a vertical gradient or the width of a horizontal gradient. + + **Default value:** ``200``. + gradientOpacity + Opacity of the color gradient. + gradientStrokeColor + The color of the gradient stroke, can be in hex color code or regular color name. + + **Default value:** ``"lightGray"``. + gradientStrokeWidth + The width of the gradient stroke, in pixels. + + **Default value:** ``0``. + gradientThickness + The thickness in pixels of the color gradient. This value corresponds to the width + of a vertical gradient or the height of a horizontal gradient. + + **Default value:** ``16``. + gradientVerticalMaxLength + Max legend length for a vertical gradient when ``config.legend.gradientLength`` is + undefined. + + **Default value:** ``200`` + gradientVerticalMinLength + Min legend length for a vertical gradient when ``config.legend.gradientLength`` is + undefined. + + **Default value:** ``100`` + gridAlign + The alignment to apply to symbol legends rows and columns. The supported string + values are ``"all"``, ``"each"`` (the default), and ``none``. For more information, + see the `grid layout documentation `__. + + **Default value:** ``"each"``. + labelAlign + The alignment of the legend label, can be left, center, or right. + labelBaseline + The position of the baseline of legend label, can be ``"top"``, ``"middle"``, + ``"bottom"``, or ``"alphabetic"``. + + **Default value:** ``"middle"``. + labelColor + The color of the legend label, can be in hex color code or regular color name. + labelFont + The font of the legend label. + labelFontSize + The font size of legend label. + + **Default value:** ``10``. + labelFontStyle + The font style of legend label. + labelFontWeight + The font weight of legend label. + labelLimit + Maximum allowed pixel width of legend tick labels. + + **Default value:** ``160``. + labelOffset + The offset of the legend label. + + **Default value:** ``4``. + labelOpacity + Opacity of labels. + labelOverlap + The strategy to use for resolving overlap of labels in gradient legends. If + ``false``, no overlap reduction is attempted. If set to ``true`` or ``"parity"``, a + strategy of removing every other label is used. If set to ``"greedy"``, a linear + scan of the labels is performed, removing any label that overlaps with the last + visible label (this often works better for log-scaled axes). + + **Default value:** ``"greedy"`` for ``log scales otherwise ``true`. + labelPadding + Padding in pixels between the legend and legend labels. + labelSeparation + The minimum separation that must be between label bounding boxes for them to be + considered non-overlapping (default ``0``). This property is ignored if + *labelOverlap* resolution is not enabled. + layout + + legendX + Custom x-position for legend with orient "none". + legendY + Custom y-position for legend with orient "none". + offset + The offset in pixels by which to displace the legend from the data rectangle and + axes. + + **Default value:** ``18``. + orient + The orientation of the legend, which determines how the legend is positioned within + the scene. One of ``"left"``, ``"right"``, ``"top"``, ``"bottom"``, ``"top-left"``, + ``"top-right"``, ``"bottom-left"``, ``"bottom-right"``, ``"none"``. + + **Default value:** ``"right"`` + padding + The padding between the border and content of the legend group. + + **Default value:** ``0``. + rowPadding + The vertical padding in pixels between symbol legend entries. + + **Default value:** ``2``. + strokeColor + Border stroke color for the full legend. + strokeDash + Border stroke dash pattern for the full legend. + strokeWidth + Border stroke width for the full legend. + symbolBaseFillColor + Default fill color for legend symbols. Only applied if there is no ``"fill"`` scale + color encoding for the legend. + + **Default value:** ``"transparent"``. + symbolBaseStrokeColor + Default stroke color for legend symbols. Only applied if there is no ``"fill"`` + scale color encoding for the legend. + + **Default value:** ``"gray"``. + symbolDash + An array of alternating [stroke, space] lengths for dashed symbol strokes. + symbolDashOffset + The pixel offset at which to start drawing with the symbol stroke dash array. + symbolDirection + The default direction (``"horizontal"`` or ``"vertical"``) for symbol legends. + + **Default value:** ``"vertical"``. + symbolFillColor + The color of the legend symbol, + symbolLimit + The maximum number of allowed entries for a symbol legend. Additional entries will + be dropped. + symbolOffset + Horizontal pixel offset for legend symbols. + + **Default value:** ``0``. + symbolOpacity + Opacity of the legend symbols. + symbolSize + The size of the legend symbol, in pixels. + + **Default value:** ``100``. + symbolStrokeColor + Stroke color for legend symbols. + symbolStrokeWidth + The width of the symbol's stroke. + + **Default value:** ``1.5``. + symbolType + The symbol shape. One of the plotting shapes ``circle`` (default), ``square``, + ``cross``, ``diamond``, ``triangle-up``, ``triangle-down``, ``triangle-right``, or + ``triangle-left``, the line symbol ``stroke``, or one of the centered directional + shapes ``arrow``, ``wedge``, or ``triangle``. Alternatively, a custom `SVG path + string `__ can be + provided. For correct sizing, custom shape paths should be defined within a square + bounding box with coordinates ranging from -1 to 1 along both the x and y + dimensions. + + **Default value:** ``"circle"``. + tickCount + The desired number of tick values for quantitative legends. + title + Set to null to disable title for the axis, legend, or header. + titleAlign + Horizontal text alignment for legend titles. + + **Default value:** ``"left"``. + titleAnchor + Text anchor position for placing legend titles. + titleBaseline + Vertical text baseline for legend titles. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, or ``"line-bottom"``. The + ``"line-top"`` and ``"line-bottom"`` values operate similarly to ``"top"`` and + ``"bottom"``, but are calculated relative to the *lineHeight* rather than *fontSize* + alone. + + **Default value:** ``"top"``. + titleColor + The color of the legend title, can be in hex color code or regular color name. + titleFont + The font of the legend title. + titleFontSize + The font size of the legend title. + titleFontStyle + The font style of the legend title. + titleFontWeight + The font weight of the legend title. This can be either a string (e.g ``"bold"``, + ``"normal"``) or a number (``100``, ``200``, ``300``, ..., ``900`` where + ``"normal"`` = ``400`` and ``"bold"`` = ``700``). + titleLimit + Maximum allowed pixel width of legend titles. + + **Default value:** ``180``. + titleLineHeight + Line height in pixels for multi-line title text or title text with ``"line-top"`` or + ``"line-bottom"`` baseline. + titleOpacity + Opacity of the legend title. + titleOrient + Orientation of the legend title. + titlePadding + The padding, in pixels, between title and legend. + + **Default value:** ``5``. + unselectedOpacity + The opacity of unselected legend entries. + + **Default value:** 0.35. + zindex + The integer z-index indicating the layering of the legend group relative to other + axis, mark, and legend groups. + """ + + aria: bool + clipHeight: float + columnPadding: float + columns: float + cornerRadius: float + description: str + direction: Orientation_T + disable: bool + fillColor: None | ColorHex | ColorName_T + gradientDirection: Orientation_T + gradientHorizontalMaxLength: float + gradientHorizontalMinLength: float + gradientLabelLimit: float + gradientLabelOffset: float + gradientLength: float + gradientOpacity: float + gradientStrokeColor: None | ColorHex | ColorName_T + gradientStrokeWidth: float + gradientThickness: float + gradientVerticalMaxLength: float + gradientVerticalMinLength: float + gridAlign: LayoutAlign_T + labelAlign: Align_T + labelBaseline: TextBaseline_T + labelColor: None | ColorHex | ColorName_T + labelFont: str + labelFontSize: float + labelFontStyle: str + labelFontWeight: FontWeight_T + labelLimit: float + labelOffset: float + labelOpacity: float + labelOverlap: bool | Literal["greedy", "parity"] + labelPadding: float + labelSeparation: float + layout: Map + legendX: float + legendY: float + offset: float + orient: LegendOrient_T + padding: float + rowPadding: float + strokeColor: None | ColorHex | ColorName_T + strokeDash: Sequence[float] + strokeWidth: float + symbolBaseFillColor: None | ColorHex | ColorName_T + symbolBaseStrokeColor: None | ColorHex | ColorName_T + symbolDash: Sequence[float] + symbolDashOffset: float + symbolDirection: Orientation_T + symbolFillColor: None | ColorHex | ColorName_T + symbolLimit: float + symbolOffset: float + symbolOpacity: float + symbolSize: float + symbolStrokeColor: None | ColorHex | ColorName_T + symbolStrokeWidth: float + symbolType: str + tickCount: float | TimeIntervalStepKwds | TimeInterval_T + title: None + titleAlign: Align_T + titleAnchor: TitleAnchor_T + titleBaseline: TextBaseline_T + titleColor: None | ColorHex | ColorName_T + titleFont: str + titleFontSize: float + titleFontStyle: str + titleFontWeight: FontWeight_T + titleLimit: float + titleLineHeight: float + titleOpacity: float + titleOrient: Orient_T + titlePadding: float + unselectedOpacity: float + zindex: float + + +class LegendResolveMapKwds(TypedDict, total=False): + """ + :class:`LegendResolveMap` ``TypedDict`` wrapper. + + Parameters + ---------- + angle + + color + + fill + + fillOpacity + + opacity + + shape + + size + + stroke + + strokeDash + + strokeOpacity + + strokeWidth + + """ + + angle: ResolveMode_T + color: ResolveMode_T + fill: ResolveMode_T + fillOpacity: ResolveMode_T + opacity: ResolveMode_T + shape: ResolveMode_T + size: ResolveMode_T + stroke: ResolveMode_T + strokeDash: ResolveMode_T + strokeOpacity: ResolveMode_T + strokeWidth: ResolveMode_T + + +class LegendStreamBindingKwds(TypedDict, total=False): + """ + :class:`LegendStreamBinding` ``TypedDict`` wrapper. + + Parameters + ---------- + legend + + """ + + legend: str | MergedStreamKwds | DerivedStreamKwds + + +class LineConfigKwds(TypedDict, total=False): + """ + :class:`LineConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + point + A flag for overlaying points on top of line or area marks, or an object defining the + properties of the overlayed points. + + * If this property is ``"transparent"``, transparent points will be used (for + enhancing tooltips and selections). + + * If this property is an empty object (``{}``) or ``true``, filled points with + default properties will be used. + + * If this property is ``false``, no points would be automatically added to line or + area marks. + + **Default value:** ``false``. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + baseline: TextBaseline_T + blend: Blend_T + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + lineBreak: str + lineHeight: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + point: bool | OverlayMarkDefKwds | Literal["transparent"] + radius: float + radius2: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + tension: float + text: str | Sequence[str] + theta: float + theta2: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + y: float | Literal["height"] + y2: float | Literal["height"] + + +class LineStringKwds(TypedDict, total=False): + """ + :class:`LineString` ``TypedDict`` wrapper. + + Parameters + ---------- + coordinates + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + coordinates: Sequence[Sequence[float]] + type: Literal["LineString"] + bbox: Sequence[float] + + +class LinearGradientKwds(TypedDict, total=False): + """ + :class:`LinearGradient` ``TypedDict`` wrapper. + + Parameters + ---------- + gradient + The type of gradient. Use ``"linear"`` for a linear gradient. + stops + An array of gradient stops defining the gradient color sequence. + id + + x1 + The starting x-coordinate, in normalized [0, 1] coordinates, of the linear gradient. + + **Default value:** ``0`` + x2 + The ending x-coordinate, in normalized [0, 1] coordinates, of the linear gradient. + + **Default value:** ``1`` + y1 + The starting y-coordinate, in normalized [0, 1] coordinates, of the linear gradient. + + **Default value:** ``0`` + y2 + The ending y-coordinate, in normalized [0, 1] coordinates, of the linear gradient. + + **Default value:** ``0`` + """ + + gradient: Literal["linear"] + stops: Sequence[GradientStopKwds] + id: str + x1: float + x2: float + y1: float + y2: float + + +class LocaleKwds(TypedDict, total=False): + """ + :class:`Locale` ``TypedDict`` wrapper. + + Parameters + ---------- + number + Locale definition for formatting numbers. + time + Locale definition for formatting dates and times. + """ + + number: NumberLocaleKwds + time: TimeLocaleKwds + + +class MarkConfigKwds(TypedDict, total=False): + """ + :class:`MarkConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + baseline: TextBaseline_T + blend: Blend_T + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + lineBreak: str + lineHeight: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + radius: float + radius2: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + tension: float + text: str | Sequence[str] + theta: float + theta2: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + y: float | Literal["height"] + y2: float | Literal["height"] + + +class MergedStreamKwds(TypedDict, total=False): + """ + :class:`MergedStream` ``TypedDict`` wrapper. + + Parameters + ---------- + merge + + between + + consume + + debounce + + filter + + markname + + marktype + + throttle + + """ + + merge: Sequence[MergedStreamKwds | DerivedStreamKwds] + between: Sequence[MergedStreamKwds | DerivedStreamKwds] + consume: bool + debounce: float + filter: str | Sequence[str] + markname: str + marktype: MarkType_T + throttle: float + + +class MultiLineStringKwds(TypedDict, total=False): + """ + :class:`MultiLineString` ``TypedDict`` wrapper. + + Parameters + ---------- + coordinates + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + coordinates: Sequence[Sequence[Sequence[float]]] + type: Literal["MultiLineString"] + bbox: Sequence[float] + + +class MultiPointKwds(TypedDict, total=False): + """ + :class:`MultiPoint` ``TypedDict`` wrapper. + + Parameters + ---------- + coordinates + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + coordinates: Sequence[Sequence[float]] + type: Literal["MultiPoint"] + bbox: Sequence[float] + + +class MultiPolygonKwds(TypedDict, total=False): + """ + :class:`MultiPolygon` ``TypedDict`` wrapper. + + Parameters + ---------- + coordinates + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + coordinates: Sequence[Sequence[Sequence[Sequence[float]]]] + type: Literal["MultiPolygon"] + bbox: Sequence[float] + + +class NumberLocaleKwds(TypedDict, total=False): + """ + :class:`NumberLocale` ``TypedDict`` wrapper. + + Parameters + ---------- + currency + The currency prefix and suffix (e.g., ["$", ""]). + decimal + The decimal point (e.g., "."). + grouping + The array of group sizes (e.g., [3]), cycled as needed. + thousands + The group separator (e.g., ","). + minus + The minus sign (defaults to hyphen-minus, "-"). + nan + The not-a-number value (defaults to "NaN"). + numerals + An array of ten strings to replace the numerals 0-9. + percent + The percent sign (defaults to "%"). + """ + + currency: Sequence[str] + decimal: str + grouping: Sequence[float] + thousands: str + minus: str + nan: str + numerals: Sequence[str] + percent: str + + +class OverlayMarkDefKwds(TypedDict, total=False): + """ + :class:`OverlayMarkDef` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + clip + Whether a mark be clipped to the enclosing group's width and height. + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + radius2Offset + Offset for radius2. + radiusOffset + Offset for radius. + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + style + A string or array of strings indicating the name of custom styles to apply to the + mark. A style is a named collection of mark property defaults defined within the + `style configuration + `__. If style is an + array, later styles will override earlier styles. Any `mark properties + `__ explicitly + defined within the ``encoding`` will override a style default. + + **Default value:** The mark's name. For example, a bar mark will have style + ``"bar"`` by default. **Note:** Any specified style will augment the default style. + For example, a bar mark with ``"style": "foo"`` will receive from + ``config.style.bar`` and ``config.style.foo`` (the specified style ``"foo"`` has + higher precedence). + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + theta2Offset + Offset for theta2. + thetaOffset + Offset for theta. + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2Offset + Offset for x2-position. + xOffset + Offset for x-position. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2Offset + Offset for y2-position. + yOffset + Offset for y-position. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + baseline: TextBaseline_T + blend: Blend_T + clip: bool + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + lineBreak: str + lineHeight: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + radius: float + radius2: float + radius2Offset: float + radiusOffset: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + style: str | Sequence[str] + tension: float + text: str | Sequence[str] + theta: float + theta2: float + theta2Offset: float + thetaOffset: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + x2Offset: float + xOffset: float + y: float | Literal["height"] + y2: float | Literal["height"] + y2Offset: float + yOffset: float + + +class PointKwds(TypedDict, total=False): + """ + :class:`Point` ``TypedDict`` wrapper. + + Parameters + ---------- + coordinates + A Position is an array of coordinates. + https://tools.ietf.org/html/rfc7946#section-3.1.1 Array should contain between two + and three elements. The previous GeoJSON specification allowed more elements (e.g., + which could be used to represent M values), but the current specification only + allows X, Y, and (optionally) Z to be defined. + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + coordinates: Sequence[float] + type: Literal["Point"] + bbox: Sequence[float] + + +class PointSelectionConfigKwds(TypedDict, total=False): + """ + :class:`PointSelectionConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + type + Determines the default event processing and data query for the selection. Vega-Lite + currently supports two selection types: + + * ``"point"`` -- to select multiple discrete data values; the first value is + selected on ``click`` and additional values toggled on shift-click. + * ``"interval"`` -- to select a continuous range of data values on ``drag``. + clear + Clears the selection, emptying it of all values. This property can be a `Event + Stream `__ or ``false`` to disable + clear. + + **Default value:** ``dblclick``. + + **See also:** `clear examples + `__ in the + documentation. + encodings + An array of encoding channels. The corresponding data field values must match for a + data tuple to fall within the selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + fields + An array of field names whose values must match for a data tuple to fall within the + selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + nearest + When true, an invisible voronoi diagram is computed to accelerate discrete + selection. The data value *nearest* the mouse cursor is added to the selection. + + **Default value:** ``false``, which means that data values must be interacted with + directly (e.g., clicked on) to be added to the selection. + + **See also:** `nearest examples + `__ documentation. + on + A `Vega event stream `__ (object or + selector) that triggers the selection. For interval selections, the event stream + must specify a `start and end + `__. + + **See also:** `on examples + `__ in the documentation. + resolve + With layered and multi-view displays, a strategy that determines how selections' + data queries are resolved when applied in a filter transform, conditional encoding + rule, or scale domain. + + One of: + + * ``"global"`` -- only one brush exists for the entire SPLOM. When the user begins + to drag, any previous brushes are cleared, and a new one is constructed. + * ``"union"`` -- each cell contains its own brush, and points are highlighted if + they lie within *any* of these individual brushes. + * ``"intersect"`` -- each cell contains its own brush, and points are highlighted + only if they fall within *all* of these individual brushes. + + **Default value:** ``global``. + + **See also:** `resolve examples + `__ in the + documentation. + toggle + Controls whether data values should be toggled (inserted or removed from a point + selection) or only ever inserted into point selections. + + One of: + + * ``true`` -- the default behavior, which corresponds to ``"event.shiftKey"``. As a + result, data values are toggled when the user interacts with the shift-key + pressed. + * ``false`` -- disables toggling behaviour; the selection will only ever contain a + single data value corresponding to the most recent interaction. + * A `Vega expression `__ which is + re-evaluated as the user interacts. If the expression evaluates to ``true``, the + data value is toggled into or out of the point selection. If the expression + evaluates to ``false``, the point selection is first cleared, and the data value + is then inserted. For example, setting the value to the Vega expression ``"true"`` + will toggle data values without the user pressing the shift-key. + + **Default value:** ``true`` + + **See also:** `toggle examples + `__ in the + documentation. + """ + + type: Literal["point"] + clear: str | bool | MergedStreamKwds | DerivedStreamKwds + encodings: Sequence[SingleDefUnitChannel_T] + fields: Sequence[str] + nearest: bool + on: str | MergedStreamKwds | DerivedStreamKwds + resolve: SelectionResolution_T + toggle: str | bool + + +class PointSelectionConfigWithoutTypeKwds(TypedDict, total=False): + """ + :class:`PointSelectionConfigWithoutType` ``TypedDict`` wrapper. + + Parameters + ---------- + clear + Clears the selection, emptying it of all values. This property can be a `Event + Stream `__ or ``false`` to disable + clear. + + **Default value:** ``dblclick``. + + **See also:** `clear examples + `__ in the + documentation. + encodings + An array of encoding channels. The corresponding data field values must match for a + data tuple to fall within the selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + fields + An array of field names whose values must match for a data tuple to fall within the + selection. + + **See also:** The `projection with encodings and fields section + `__ in the + documentation. + nearest + When true, an invisible voronoi diagram is computed to accelerate discrete + selection. The data value *nearest* the mouse cursor is added to the selection. + + **Default value:** ``false``, which means that data values must be interacted with + directly (e.g., clicked on) to be added to the selection. + + **See also:** `nearest examples + `__ documentation. + on + A `Vega event stream `__ (object or + selector) that triggers the selection. For interval selections, the event stream + must specify a `start and end + `__. + + **See also:** `on examples + `__ in the documentation. + resolve + With layered and multi-view displays, a strategy that determines how selections' + data queries are resolved when applied in a filter transform, conditional encoding + rule, or scale domain. + + One of: + + * ``"global"`` -- only one brush exists for the entire SPLOM. When the user begins + to drag, any previous brushes are cleared, and a new one is constructed. + * ``"union"`` -- each cell contains its own brush, and points are highlighted if + they lie within *any* of these individual brushes. + * ``"intersect"`` -- each cell contains its own brush, and points are highlighted + only if they fall within *all* of these individual brushes. + + **Default value:** ``global``. + + **See also:** `resolve examples + `__ in the + documentation. + toggle + Controls whether data values should be toggled (inserted or removed from a point + selection) or only ever inserted into point selections. + + One of: + + * ``true`` -- the default behavior, which corresponds to ``"event.shiftKey"``. As a + result, data values are toggled when the user interacts with the shift-key + pressed. + * ``false`` -- disables toggling behaviour; the selection will only ever contain a + single data value corresponding to the most recent interaction. + * A `Vega expression `__ which is + re-evaluated as the user interacts. If the expression evaluates to ``true``, the + data value is toggled into or out of the point selection. If the expression + evaluates to ``false``, the point selection is first cleared, and the data value + is then inserted. For example, setting the value to the Vega expression ``"true"`` + will toggle data values without the user pressing the shift-key. + + **Default value:** ``true`` + + **See also:** `toggle examples + `__ in the + documentation. + """ + + clear: str | bool | MergedStreamKwds | DerivedStreamKwds + encodings: Sequence[SingleDefUnitChannel_T] + fields: Sequence[str] + nearest: bool + on: str | MergedStreamKwds | DerivedStreamKwds + resolve: SelectionResolution_T + toggle: str | bool + + +class PolygonKwds(TypedDict, total=False): + """ + :class:`Polygon` ``TypedDict`` wrapper. + + Parameters + ---------- + coordinates + + type + Specifies the type of GeoJSON object. + bbox + Bounding box of the coordinate range of the object's Geometries, Features, or + Feature Collections. https://tools.ietf.org/html/rfc7946#section-5 + """ + + coordinates: Sequence[Sequence[Sequence[float]]] + type: Literal["Polygon"] + bbox: Sequence[float] + + +class ProjectionKwds(TypedDict, total=False): + """ + :class:`Projection` ``TypedDict`` wrapper. + + Parameters + ---------- + center + The projection's center, a two-element array of longitude and latitude in degrees. + + **Default value:** ``[0, 0]`` + clipAngle + The projection's clipping circle radius to the specified angle in degrees. If + ``null``, switches to `antimeridian `__ cutting + rather than small-circle clipping. + clipExtent + The projection's viewport clip extent to the specified bounds in pixels. The extent + bounds are specified as an array ``[[x0, y0], [x1, y1]]``, where ``x0`` is the + left-side of the viewport, ``y0`` is the top, ``x1`` is the right and ``y1`` is the + bottom. If ``null``, no viewport clipping is performed. + coefficient + The coefficient parameter for the ``hammer`` projection. + + **Default value:** ``2`` + distance + For the ``satellite`` projection, the distance from the center of the sphere to the + point of view, as a proportion of the sphere's radius. The recommended maximum clip + angle for a given ``distance`` is acos(1 / distance) converted to degrees. If tilt + is also applied, then more conservative clipping may be necessary. + + **Default value:** ``2.0`` + extent + + fit + + fraction + The fraction parameter for the ``bottomley`` projection. + + **Default value:** ``0.5``, corresponding to a sin(ψ) where ψ = π/6. + lobes + The number of lobes in projections that support multi-lobe views: ``berghaus``, + ``gingery``, or ``healpix``. The default value varies based on the projection type. + parallel + The parallel parameter for projections that support it: ``armadillo``, ``bonne``, + ``craig``, ``cylindricalEqualArea``, ``cylindricalStereographic``, + ``hammerRetroazimuthal``, ``loximuthal``, or ``rectangularPolyconic``. The default + value varies based on the projection type. + parallels + For conic projections, the `two standard parallels + `__ that define the map layout. + The default depends on the specific conic projection used. + pointRadius + The default radius (in pixels) to use when drawing GeoJSON ``Point`` and + ``MultiPoint`` geometries. This parameter sets a constant default value. To modify + the point radius in response to data, see the corresponding parameter of the GeoPath + and GeoShape transforms. + + **Default value:** ``4.5`` + precision + The threshold for the projection's `adaptive resampling + `__ to the specified value in pixels. This + value corresponds to the `Douglas-Peucker distance + `__. + If precision is not specified, returns the projection's current resampling precision + which defaults to ``√0.5 ≅ 0.70710…``. + radius + The radius parameter for the ``airy`` or ``gingery`` projection. The default value + varies based on the projection type. + ratio + The ratio parameter for the ``hill``, ``hufnagel``, or ``wagner`` projections. The + default value varies based on the projection type. + reflectX + Sets whether or not the x-dimension is reflected (negated) in the output. + reflectY + Sets whether or not the y-dimension is reflected (negated) in the output. + rotate + The projection's three-axis rotation to the specified angles, which must be a two- + or three-element array of numbers [``lambda``, ``phi``, ``gamma``] specifying the + rotation angles in degrees about each spherical axis. (These correspond to yaw, + pitch and roll.) + + **Default value:** ``[0, 0, 0]`` + scale + The projection's scale (zoom) factor, overriding automatic fitting. The default + scale is projection-specific. The scale factor corresponds linearly to the distance + between projected points; however, scale factor values are not equivalent across + projections. + size + Used in conjunction with fit, provides the width and height in pixels of the area to + which the projection should be automatically fit. + spacing + The spacing parameter for the ``lagrange`` projection. + + **Default value:** ``0.5`` + tilt + The tilt angle (in degrees) for the ``satellite`` projection. + + **Default value:** ``0``. + translate + The projection's translation offset as a two-element array ``[tx, ty]``. + type + The cartographic projection to use. This value is case-insensitive, for example + ``"albers"`` and ``"Albers"`` indicate the same projection type. You can find all + valid projection types `in the documentation + `__. + + **Default value:** ``equalEarth`` + """ + + center: Sequence[float] + clipAngle: float + clipExtent: Sequence[Sequence[float]] + coefficient: float + distance: float + extent: Sequence[Sequence[float]] + fit: ( + GeoJsonFeatureKwds + | GeoJsonFeatureCollectionKwds + | Sequence[GeoJsonFeatureKwds] + | Sequence[ + GeoJsonFeatureKwds + | GeoJsonFeatureCollectionKwds + | Sequence[GeoJsonFeatureKwds] + ] + ) + fraction: float + lobes: float + parallel: float + parallels: Sequence[float] + pointRadius: float + precision: float + radius: float + ratio: float + reflectX: bool + reflectY: bool + rotate: Sequence[float] + scale: float + size: Sequence[float] + spacing: float + tilt: float + translate: Sequence[float] + type: ProjectionType_T + + +class ProjectionConfigKwds(TypedDict, total=False): + """ + :class:`ProjectionConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + center + The projection's center, a two-element array of longitude and latitude in degrees. + + **Default value:** ``[0, 0]`` + clipAngle + The projection's clipping circle radius to the specified angle in degrees. If + ``null``, switches to `antimeridian `__ cutting + rather than small-circle clipping. + clipExtent + The projection's viewport clip extent to the specified bounds in pixels. The extent + bounds are specified as an array ``[[x0, y0], [x1, y1]]``, where ``x0`` is the + left-side of the viewport, ``y0`` is the top, ``x1`` is the right and ``y1`` is the + bottom. If ``null``, no viewport clipping is performed. + coefficient + The coefficient parameter for the ``hammer`` projection. + + **Default value:** ``2`` + distance + For the ``satellite`` projection, the distance from the center of the sphere to the + point of view, as a proportion of the sphere's radius. The recommended maximum clip + angle for a given ``distance`` is acos(1 / distance) converted to degrees. If tilt + is also applied, then more conservative clipping may be necessary. + + **Default value:** ``2.0`` + extent + + fit + + fraction + The fraction parameter for the ``bottomley`` projection. + + **Default value:** ``0.5``, corresponding to a sin(ψ) where ψ = π/6. + lobes + The number of lobes in projections that support multi-lobe views: ``berghaus``, + ``gingery``, or ``healpix``. The default value varies based on the projection type. + parallel + The parallel parameter for projections that support it: ``armadillo``, ``bonne``, + ``craig``, ``cylindricalEqualArea``, ``cylindricalStereographic``, + ``hammerRetroazimuthal``, ``loximuthal``, or ``rectangularPolyconic``. The default + value varies based on the projection type. + parallels + For conic projections, the `two standard parallels + `__ that define the map layout. + The default depends on the specific conic projection used. + pointRadius + The default radius (in pixels) to use when drawing GeoJSON ``Point`` and + ``MultiPoint`` geometries. This parameter sets a constant default value. To modify + the point radius in response to data, see the corresponding parameter of the GeoPath + and GeoShape transforms. + + **Default value:** ``4.5`` + precision + The threshold for the projection's `adaptive resampling + `__ to the specified value in pixels. This + value corresponds to the `Douglas-Peucker distance + `__. + If precision is not specified, returns the projection's current resampling precision + which defaults to ``√0.5 ≅ 0.70710…``. + radius + The radius parameter for the ``airy`` or ``gingery`` projection. The default value + varies based on the projection type. + ratio + The ratio parameter for the ``hill``, ``hufnagel``, or ``wagner`` projections. The + default value varies based on the projection type. + reflectX + Sets whether or not the x-dimension is reflected (negated) in the output. + reflectY + Sets whether or not the y-dimension is reflected (negated) in the output. + rotate + The projection's three-axis rotation to the specified angles, which must be a two- + or three-element array of numbers [``lambda``, ``phi``, ``gamma``] specifying the + rotation angles in degrees about each spherical axis. (These correspond to yaw, + pitch and roll.) + + **Default value:** ``[0, 0, 0]`` + scale + The projection's scale (zoom) factor, overriding automatic fitting. The default + scale is projection-specific. The scale factor corresponds linearly to the distance + between projected points; however, scale factor values are not equivalent across + projections. + size + Used in conjunction with fit, provides the width and height in pixels of the area to + which the projection should be automatically fit. + spacing + The spacing parameter for the ``lagrange`` projection. + + **Default value:** ``0.5`` + tilt + The tilt angle (in degrees) for the ``satellite`` projection. + + **Default value:** ``0``. + translate + The projection's translation offset as a two-element array ``[tx, ty]``. + type + The cartographic projection to use. This value is case-insensitive, for example + ``"albers"`` and ``"Albers"`` indicate the same projection type. You can find all + valid projection types `in the documentation + `__. + + **Default value:** ``equalEarth`` + """ + + center: Sequence[float] + clipAngle: float + clipExtent: Sequence[Sequence[float]] + coefficient: float + distance: float + extent: Sequence[Sequence[float]] + fit: ( + GeoJsonFeatureKwds + | GeoJsonFeatureCollectionKwds + | Sequence[GeoJsonFeatureKwds] + | Sequence[ + GeoJsonFeatureKwds + | GeoJsonFeatureCollectionKwds + | Sequence[GeoJsonFeatureKwds] + ] + ) + fraction: float + lobes: float + parallel: float + parallels: Sequence[float] + pointRadius: float + precision: float + radius: float + ratio: float + reflectX: bool + reflectY: bool + rotate: Sequence[float] + scale: float + size: Sequence[float] + spacing: float + tilt: float + translate: Sequence[float] + type: ProjectionType_T + + +class RadialGradientKwds(TypedDict, total=False): + """ + :class:`RadialGradient` ``TypedDict`` wrapper. + + Parameters + ---------- + gradient + The type of gradient. Use ``"radial"`` for a radial gradient. + stops + An array of gradient stops defining the gradient color sequence. + id + + r1 + The radius length, in normalized [0, 1] coordinates, of the inner circle for the + gradient. + + **Default value:** ``0`` + r2 + The radius length, in normalized [0, 1] coordinates, of the outer circle for the + gradient. + + **Default value:** ``0.5`` + x1 + The x-coordinate, in normalized [0, 1] coordinates, for the center of the inner + circle for the gradient. + + **Default value:** ``0.5`` + x2 + The x-coordinate, in normalized [0, 1] coordinates, for the center of the outer + circle for the gradient. + + **Default value:** ``0.5`` + y1 + The y-coordinate, in normalized [0, 1] coordinates, for the center of the inner + circle for the gradient. + + **Default value:** ``0.5`` + y2 + The y-coordinate, in normalized [0, 1] coordinates, for the center of the outer + circle for the gradient. + + **Default value:** ``0.5`` + """ + + gradient: Literal["radial"] + stops: Sequence[GradientStopKwds] + id: str + r1: float + r2: float + x1: float + x2: float + y1: float + y2: float + + +class RangeConfigKwds(TypedDict, total=False): + """ + :class:`RangeConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + category + Default `color scheme `__ for categorical + data. + diverging + Default `color scheme `__ for diverging + quantitative ramps. + heatmap + Default `color scheme `__ for + quantitative heatmaps. + ordinal + Default `color scheme `__ for + rank-ordered data. + ramp + Default `color scheme `__ for sequential + quantitative ramps. + symbol + Array of `symbol `__ names or paths + for the default shape palette. + """ + + category: ( + Sequence[ColorHex | ColorName_T] + | Sequence[str | bool | None | float | Sequence[float]] + | RangeEnum_T + ) + diverging: ( + Sequence[ColorHex | ColorName_T] + | Sequence[str | bool | None | float | Sequence[float]] + | RangeEnum_T + ) + heatmap: ( + Sequence[ColorHex | ColorName_T] + | Sequence[str | bool | None | float | Sequence[float]] + | RangeEnum_T + ) + ordinal: ( + Sequence[ColorHex | ColorName_T] + | Sequence[str | bool | None | float | Sequence[float]] + | RangeEnum_T + ) + ramp: ( + Sequence[ColorHex | ColorName_T] + | Sequence[str | bool | None | float | Sequence[float]] + | RangeEnum_T + ) + symbol: Sequence[str] + + +class RectConfigKwds(TypedDict, total=False): + """ + :class:`RectConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + binSpacing + Offset between bars for binned field. The ideal value for this is either 0 + (preferred by statisticians) or 1 (Vega-Lite default, D3 example style). + + **Default value:** ``1`` + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + continuousBandSize + The default size of the bars on continuous scales. + + **Default value:** ``5`` + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + discreteBandSize + The default size of the bars with discrete dimensions. If unspecified, the default + size is ``step-2``, which provides 2 pixel offset between bars. + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + minBandSize + The minimum band size for bar and rectangle marks. **Default value:** ``0.25`` + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + baseline: TextBaseline_T + binSpacing: float + blend: Blend_T + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + continuousBandSize: float + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + discreteBandSize: float + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + lineBreak: str + lineHeight: float + minBandSize: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + radius: float + radius2: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + tension: float + text: str | Sequence[str] + theta: float + theta2: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + y: float | Literal["height"] + y2: float | Literal["height"] + + +class ResolveKwds(TypedDict, total=False): + """ + :class:`Resolve` ``TypedDict`` wrapper. + + Parameters + ---------- + axis + + legend + + scale + + """ + + axis: AxisResolveMapKwds + legend: LegendResolveMapKwds + scale: ScaleResolveMapKwds + + +class ScaleConfigKwds(TypedDict, total=False): + """ + :class:`ScaleConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + bandPaddingInner + Default inner padding for ``x`` and ``y`` band scales. + + **Default value:** + + * ``nestedOffsetPaddingInner`` for x/y scales with nested x/y offset scales. + * ``barBandPaddingInner`` for bar marks (``0.1`` by default) + * ``rectBandPaddingInner`` for rect and other marks (``0`` by default) + bandPaddingOuter + Default outer padding for ``x`` and ``y`` band scales. + + **Default value:** ``paddingInner/2`` (which makes *width/height = number of unique + values * step*) + bandWithNestedOffsetPaddingInner + Default inner padding for ``x`` and ``y`` band scales with nested ``xOffset`` and + ``yOffset`` encoding. + + **Default value:** ``0.2`` + bandWithNestedOffsetPaddingOuter + Default outer padding for ``x`` and ``y`` band scales with nested ``xOffset`` and + ``yOffset`` encoding. + + **Default value:** ``0.2`` + barBandPaddingInner + Default inner padding for ``x`` and ``y`` band-ordinal scales of ``"bar"`` marks. + + **Default value:** ``0.1`` + clamp + If true, values that exceed the data domain are clamped to either the minimum or + maximum range value + continuousPadding + Default padding for continuous x/y scales. + + **Default:** The bar width for continuous x-scale of a vertical bar and continuous + y-scale of a horizontal bar.; ``0`` otherwise. + invalid + An object that defines scale outputs per channel for invalid values (nulls and NaNs + on a continuous scale). + + * The keys in this object are the scale channels. + * The values is either ``"zero-or-min"`` (use zero if the scale includes zero or min + value otherwise) or a value definition ``{value: ...}``. + + *Example:* Setting this ``config.scale.invalid`` property to ``{color: {value: + '#aaa'}}`` will make the visualization color all invalid values with '#aaa'. + + See [https://vega.github.io/vega-lite/docs/invalid-data.html](Invalid Data Docs) for + more details. + maxBandSize + The default max value for mapping quantitative fields to bar's size/bandSize. + + If undefined (default), we will use the axis's size (width or height) - 1. + maxFontSize + The default max value for mapping quantitative fields to text's size/fontSize scale. + + **Default value:** ``40`` + maxOpacity + Default max opacity for mapping a field to opacity. + + **Default value:** ``0.8`` + maxSize + Default max value for point size scale. + maxStrokeWidth + Default max strokeWidth for the scale of strokeWidth for rule and line marks and of + size for trail marks. + + **Default value:** ``4`` + minBandSize + The default min value for mapping quantitative fields to bar and tick's + size/bandSize scale. + + **Default value:** ``2`` + minFontSize + The default min value for mapping quantitative fields to text's size/fontSize scale. + + **Default value:** ``8`` + minOpacity + Default minimum opacity for mapping a field to opacity. + + **Default value:** ``0.3`` + minSize + Default minimum value for point size scale. + + **Default value:** ``9`` + minStrokeWidth + Default minimum strokeWidth for the scale of strokeWidth for rule and line marks and + of size for trail marks. + + **Default value:** ``1`` + offsetBandPaddingInner + Default padding inner for xOffset/yOffset's band scales. + + **Default Value:** ``0`` + offsetBandPaddingOuter + Default padding outer for xOffset/yOffset's band scales. + + **Default Value:** ``0`` + pointPadding + Default outer padding for ``x`` and ``y`` point-ordinal scales. + + **Default value:** ``0.5`` (which makes *width/height = number of unique values * + step*) + quantileCount + Default range cardinality for `quantile + `__ scale. + + **Default value:** ``4`` + quantizeCount + Default range cardinality for `quantize + `__ scale. + + **Default value:** ``4`` + rectBandPaddingInner + Default inner padding for ``x`` and ``y`` band-ordinal scales of ``"rect"`` marks. + + **Default value:** ``0`` + round + If true, rounds numeric output values to integers. This can be helpful for snapping + to the pixel grid. (Only available for ``x``, ``y``, and ``size`` scales.) + tickBandPaddingInner + Default inner padding for ``x`` and ``y`` band-ordinal scales of ``"tick"`` marks. + + **Default value:** ``0.25`` + useUnaggregatedDomain + Use the source data range before aggregation as scale domain instead of aggregated + data for aggregate axis. + + This is equivalent to setting ``domain`` to ``"unaggregate"`` for aggregated + *quantitative* fields by default. + + This property only works with aggregate functions that produce values within the raw + data domain (``"mean"``, ``"average"``, ``"median"``, ``"q1"``, ``"q3"``, ``"min"``, + ``"max"``). For other aggregations that produce values outside of the raw data + domain (e.g. ``"count"``, ``"sum"``), this property is ignored. + + **Default value:** ``false`` + xReverse + Reverse x-scale by default (useful for right-to-left charts). + zero + Default ``scale.zero`` for `continuous + `__ scales except for + (1) x/y-scales of non-ranged bar or area charts and (2) size scales. + + **Default value:** ``true`` + """ + + bandPaddingInner: float + bandPaddingOuter: float + bandWithNestedOffsetPaddingInner: float + bandWithNestedOffsetPaddingOuter: float + barBandPaddingInner: float + clamp: bool + continuousPadding: float + invalid: ScaleInvalidDataConfigKwds + maxBandSize: float + maxFontSize: float + maxOpacity: float + maxSize: float + maxStrokeWidth: float + minBandSize: float + minFontSize: float + minOpacity: float + minSize: float + minStrokeWidth: float + offsetBandPaddingInner: float + offsetBandPaddingOuter: float + pointPadding: float + quantileCount: float + quantizeCount: float + rectBandPaddingInner: float + round: bool + tickBandPaddingInner: float + useUnaggregatedDomain: bool + xReverse: bool + zero: bool + + +class ScaleInvalidDataConfigKwds(TypedDict, total=False): + """ + :class:`ScaleInvalidDataConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + angle + + color + + fill + + fillOpacity + + opacity + + radius + + shape + + size + + stroke + + strokeDash + + strokeOpacity + + strokeWidth + + theta + + x + + xOffset + + y + + yOffset + + """ + + angle: Value[float] | Literal["zero-or-min"] + color: ( + Literal["zero-or-min"] + | Value[ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T] + ) + fill: ( + Literal["zero-or-min"] + | Value[None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T] + ) + fillOpacity: Value[float] | Literal["zero-or-min"] + opacity: Value[float] | Literal["zero-or-min"] + radius: Value[float] | Literal["zero-or-min"] + shape: Value[str] | Literal["zero-or-min"] + size: Value[float] | Literal["zero-or-min"] + stroke: ( + Literal["zero-or-min"] + | Value[None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T] + ) + strokeDash: Literal["zero-or-min"] | Value[Sequence[float]] + strokeOpacity: Value[float] | Literal["zero-or-min"] + strokeWidth: Value[float] | Literal["zero-or-min"] + theta: Value[float] | Literal["zero-or-min"] + x: Literal["zero-or-min"] | Value[float | Literal["width"]] + xOffset: Value[float] | Literal["zero-or-min"] + y: Literal["zero-or-min"] | Value[float | Literal["height"]] + yOffset: Value[float] | Literal["zero-or-min"] + + +class ScaleResolveMapKwds(TypedDict, total=False): + """ + :class:`ScaleResolveMap` ``TypedDict`` wrapper. + + Parameters + ---------- + angle + + color + + fill + + fillOpacity + + opacity + + radius + + shape + + size + + stroke + + strokeDash + + strokeOpacity + + strokeWidth + + theta + + x + + xOffset + + y + + yOffset + + """ + + angle: ResolveMode_T + color: ResolveMode_T + fill: ResolveMode_T + fillOpacity: ResolveMode_T + opacity: ResolveMode_T + radius: ResolveMode_T + shape: ResolveMode_T + size: ResolveMode_T + stroke: ResolveMode_T + strokeDash: ResolveMode_T + strokeOpacity: ResolveMode_T + strokeWidth: ResolveMode_T + theta: ResolveMode_T + x: ResolveMode_T + xOffset: ResolveMode_T + y: ResolveMode_T + yOffset: ResolveMode_T + + +class SelectionConfigKwds(TypedDict, total=False): + """ + :class:`SelectionConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + interval + The default definition for an `interval + `__ selection. All + properties and transformations for an interval selection definition (except + ``type``) may be specified here. + + For instance, setting ``interval`` to ``{"translate": false}`` disables the ability + to move interval selections by default. + point + The default definition for a `point + `__ selection. All + properties and transformations for a point selection definition (except ``type``) + may be specified here. + + For instance, setting ``point`` to ``{"on": "dblclick"}`` populates point selections + on double-click by default. + """ + + interval: IntervalSelectionConfigWithoutTypeKwds + point: PointSelectionConfigWithoutTypeKwds + + +class StepKwds(TypedDict, closed=True, total=False): # type: ignore[call-arg] + """ + :class:`Step` ``TypedDict`` wrapper. + + Parameters + ---------- + step + The size (width/height) per discrete step. + + Notes + ----- + The following keys may be specified as string literals **only**: + + ['for'] + + See `PEP728`_ for type checker compatibility. + + .. _PEP728: + https://peps.python.org/pep-0728/#reference-implementation + """ + + step: float + __extra_items__: StepFor_T + + +class StyleConfigIndexKwds(TypedDict, closed=True, total=False): # type: ignore[call-arg] + """ + :class:`StyleConfigIndex` ``TypedDict`` wrapper. + + Parameters + ---------- + arc + Arc-specific Config + area + Area-Specific Config + bar + Bar-Specific Config + circle + Circle-Specific Config + geoshape + Geoshape-Specific Config + image + Image-specific Config + line + Line-Specific Config + mark + Mark Config + point + Point-Specific Config + rect + Rect-Specific Config + rule + Rule-Specific Config + square + Square-Specific Config + text + Text-Specific Config + tick + Tick-Specific Config + trail + Trail-Specific Config + + Notes + ----- + The following keys may be specified as string literals **only**: + + ['group-subtitle', 'group-title', 'guide-label', 'guide-title'] + + See `PEP728`_ for type checker compatibility. + + .. _PEP728: + https://peps.python.org/pep-0728/#reference-implementation + """ + + arc: RectConfigKwds + area: AreaConfigKwds + bar: BarConfigKwds + circle: MarkConfigKwds + geoshape: MarkConfigKwds + image: RectConfigKwds + line: LineConfigKwds + mark: MarkConfigKwds + point: MarkConfigKwds + rect: RectConfigKwds + rule: MarkConfigKwds + square: MarkConfigKwds + text: MarkConfigKwds + tick: TickConfigKwds + trail: LineConfigKwds + __extra_items__: MarkConfigKwds + + +class TickConfigKwds(TypedDict, total=False): + """ + :class:`TickConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + The horizontal alignment of the text or ranged marks (area, bar, image, rect, rule). + One of ``"left"``, ``"right"``, ``"center"``. + + **Note:** Expression reference is *not* supported for range marks. + angle + The rotation angle of the text, in degrees. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG element, removing the mark item from the ARIA accessibility tree. + ariaRole + Sets the type of user interface element of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "role" attribute. Warning: this + property is experimental and may be changed in the future. + ariaRoleDescription + A human-readable, author-localized description for the role of the mark item for + `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the "aria-roledescription" attribute. + Warning: this property is experimental and may be changed in the future. + aspect + Whether to keep aspect ratio of image marks. + bandSize + The width of the ticks. + + **Default value:** 3/4 of step (width step for horizontal ticks and height step for + vertical ticks). + baseline + For text marks, the vertical text baseline. One of ``"alphabetic"`` (default), + ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, ``"line-bottom"``, or an + expression reference that provides one of the valid values. The ``"line-top"`` and + ``"line-bottom"`` values operate similarly to ``"top"`` and ``"bottom"``, but are + calculated relative to the ``lineHeight`` rather than ``fontSize`` alone. + + For range marks, the vertical alignment of the marks. One of ``"top"``, + ``"middle"``, ``"bottom"``. + + **Note:** Expression reference is *not* supported for range marks. + blend + The color blend mode for drawing an item on its current background. Any valid `CSS + mix-blend-mode `__ + value can be used. + + __Default value:__ ``"source-over"`` + color + Default color. + + **Default value:** :raw-html:`` ■ :raw-html:`` + ``"#4682b4"`` + + **Note:** + + * This property cannot be used in a `style config + `__. + * The ``fill`` and ``stroke`` properties have higher precedence than ``color`` and + will override ``color``. + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cornerRadiusBottomLeft + The radius in pixels of rounded rectangles' bottom left corner. + + **Default value:** ``0`` + cornerRadiusBottomRight + The radius in pixels of rounded rectangles' bottom right corner. + + **Default value:** ``0`` + cornerRadiusTopLeft + The radius in pixels of rounded rectangles' top right corner. + + **Default value:** ``0`` + cornerRadiusTopRight + The radius in pixels of rounded rectangles' top left corner. + + **Default value:** ``0`` + cursor + The mouse cursor used over the mark. Any valid `CSS cursor type + `__ can be used. + description + A text description of the mark item for `ARIA accessibility + `__ (SVG output + only). If specified, this property determines the `"aria-label" attribute + `__. + dir + The direction of the text. One of ``"ltr"`` (left-to-right) or ``"rtl"`` + (right-to-left). This property determines on which side is truncated in response to + the limit parameter. + + **Default value:** ``"ltr"`` + dx + The horizontal offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + dy + The vertical offset, in pixels, between the text label and its anchor point. The + offset is applied after rotation by the *angle* property. + ellipsis + The ellipsis string for text truncated in response to the limit parameter. + + **Default value:** ``"…"`` + endAngle + The end angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + fill + Default fill color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove fill. + + **Default value:** (None) + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + filled + Whether the mark's color should be used as fill color instead of stroke color. + + **Default value:** ``false`` for all ``point``, ``line``, and ``rule`` marks as well + as ``geoshape`` marks for `graticule + `__ data sources; + otherwise, ``true``. + + **Note:** This property cannot be used in a `style config + `__. + font + The typeface to set the text in (e.g., ``"Helvetica Neue"``). + fontSize + The font size, in pixels. + + **Default value:** ``11`` + fontStyle + The font style (e.g., ``"italic"``). + fontWeight + The font weight. This can be either a string (e.g ``"bold"``, ``"normal"``) or a + number (``100``, ``200``, ``300``, ..., ``900`` where ``"normal"`` = ``400`` and + ``"bold"`` = ``700``). + height + Height of the marks. + href + A URL to load upon mouse click. If defined, the mark acts as a hyperlink. + innerRadius + The inner radius in pixels of arc marks. ``innerRadius`` is an alias for + ``radius2``. + + **Default value:** ``0`` + interpolate + The line interpolation method to use for line and area marks. One of the following: + + * ``"linear"``: piecewise linear segments, as in a polyline. + * ``"linear-closed"``: close the linear segments to form a polygon. + * ``"step"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"step-before"``: alternate between vertical and horizontal segments, as in a + step function. + * ``"step-after"``: alternate between horizontal and vertical segments, as in a step + function. + * ``"basis"``: a B-spline, with control point duplication on the ends. + * ``"basis-open"``: an open B-spline; may not intersect the start or end. + * ``"basis-closed"``: a closed B-spline, as in a loop. + * ``"cardinal"``: a Cardinal spline, with control point duplication on the ends. + * ``"cardinal-open"``: an open Cardinal spline; may not intersect the start or end, + but will intersect other control points. + * ``"cardinal-closed"``: a closed Cardinal spline, as in a loop. + * ``"bundle"``: equivalent to basis, except the tension parameter is used to + straighten the spline. + * ``"monotone"``: cubic interpolation that preserves monotonicity in y. + invalid + Invalid data mode, which defines how the marks and corresponding scales should + represent invalid values (``null`` and ``NaN`` in continuous scales *without* + defined output for invalid values). + + * ``"filter"`` — *Exclude* all invalid values from the visualization's *marks* and + *scales*. For path marks (for line, area, trail), this option will create paths + that connect valid points, as if the data rows with invalid values do not exist. + + * ``"break-paths-filter-domains"`` — Break path marks (for line, area, trail) at + invalid values. For non-path marks, this is equivalent to ``"filter"``. All + *scale* domains will *exclude* these filtered data points. + + * ``"break-paths-show-domains"`` — Break paths (for line, area, trail) at invalid + values. Hide invalid values for non-path marks. All *scale* domains will + *include* these filtered data points (for both path and non-path marks). + + * ``"show"`` or ``null`` — Show all data points in the marks and scale domains. Each + scale will use the output for invalid values defined in ``config.scale.invalid`` + or, if unspecified, by default invalid values will produce the same visual values + as zero (if the scale includes zero) or the minimum value (if the scale does not + include zero). + + * ``"break-paths-show-path-domains"`` (default) — This is equivalent to + ``"break-paths-show-domains"`` for path-based marks (line/area/trail) and + ``"filter"`` for non-path marks. + + **Note**: If any channel's scale has an output for invalid values defined in + ``config.scale.invalid``, all values for the scales will be considered "valid" since + they can produce a reasonable output for the scales. Thus, fields for such channels + will not be filtered and will not cause path breaks. + limit + The maximum length of the text mark in pixels. The text value will be automatically + truncated if the rendered size exceeds the limit. + + **Default value:** ``0`` -- indicating no limit + lineBreak + A delimiter, such as a newline character, upon which to break text strings into + multiple lines. This property is ignored if the text is array-valued. + lineHeight + The line height in pixels (the spacing between subsequent lines of text) for + multi-line text marks. + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + order + For line and trail marks, this ``order`` property can be set to ``null`` or + ``false`` to make the lines use the original order in the data sources. + orient + The orientation of a non-stacked bar, tick, area, and line charts. The value is + either horizontal (default) or vertical. + + * For bar, rule and tick, this determines whether the size of the bar and tick + should be applied to x or y dimension. + * For area, this property determines the orient property of the Vega output. + * For line and trail marks, this property determines the sort order of the points in + the line if ``config.sortLineBy`` is not specified. For stacked charts, this is + always determined by the orientation of the stack; therefore explicitly specified + value will be ignored. + outerRadius + The outer radius in pixels of arc marks. ``outerRadius`` is an alias for ``radius``. + + **Default value:** ``0`` + padAngle + The angular padding applied to sides of the arc, in radians. + radius + For arc mark, the primary (outer) radius in pixels. + + For text marks, polar coordinate radial offset, in pixels, of the text from the + origin determined by the ``x`` and ``y`` properties. + + **Default value:** ``min(plot_width, plot_height)/2`` + radius2 + The secondary (inner) radius in pixels of arc marks. + + **Default value:** ``0`` + shape + Shape of the point marks. Supported values include: + + * plotting shapes: ``"circle"``, ``"square"``, ``"cross"``, ``"diamond"``, + ``"triangle-up"``, ``"triangle-down"``, ``"triangle-right"``, or + ``"triangle-left"``. + * the line symbol ``"stroke"`` + * centered directional shapes ``"arrow"``, ``"wedge"``, or ``"triangle"`` + * a custom `SVG path string + `__ (For correct + sizing, custom shape paths should be defined within a square bounding box with + coordinates ranging from -1 to 1 along both the x and y dimensions.) + + **Default value:** ``"circle"`` + size + Default size for marks. + + * For ``point``/``circle``/``square``, this represents the pixel area of the marks. + Note that this value sets the area of the symbol; the side lengths will increase + with the square root of this value. + * For ``bar``, this represents the band size of the bar, in pixels. + * For ``text``, this represents the font size, in pixels. + + **Default value:** + + * ``30`` for point, circle, square marks; width/height's ``step`` + * ``2`` for bar marks with discrete dimensions; + * ``5`` for bar marks with continuous dimensions; + * ``11`` for text marks. + smooth + A boolean flag (default true) indicating if the image should be smoothed when + resized. If false, individual pixels should be scaled directly rather than + interpolated with smoothing. For SVG rendering, this option may not work in some + browsers due to lack of standardization. + startAngle + The start angle in radians for arc marks. A value of ``0`` indicates up (north), + increasing values proceed clockwise. + stroke + Default stroke color. This property has higher precedence than ``config.color``. Set + to ``null`` to remove stroke. + + **Default value:** (None) + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOffset + The offset in pixels at which to draw the group stroke and fill. If unspecified, the + default behavior is to dynamically offset stroked groups such that 1 pixel stroke + widths align with the pixel grid. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + tension + Depending on the interpolation type, sets the tension parameter (for line and area + marks). + text + Placeholder text if the ``text`` channel is not specified + theta + * For arc marks, the arc length in radians if theta2 is not specified, otherwise the + start arc angle. (A value of 0 indicates up or “north”, increasing values proceed + clockwise.) + + * For text marks, polar coordinate angle in radians. + theta2 + The end angle of arc marks in radians. A value of 0 indicates up or “north”, + increasing values proceed clockwise. + thickness + Thickness of the tick mark. + + **Default value:** ``1`` + timeUnitBandPosition + Default relative band position for a time unit. If set to ``0``, the marks will be + positioned at the beginning of the time unit band step. If set to ``0.5``, the marks + will be positioned in the middle of the time unit band step. + timeUnitBandSize + Default relative band size for a time unit. If set to ``1``, the bandwidth of the + marks will be equal to the time unit band step. If set to ``0.5``, bandwidth of the + marks will be half of the time unit band step. + tooltip + The tooltip text string to show upon mouse hover or an object defining which fields + should the tooltip be derived from. + + * If ``tooltip`` is ``true`` or ``{"content": "encoding"}``, then all fields from + ``encoding`` will be used. + * If ``tooltip`` is ``{"content": "data"}``, then all fields that appear in the + highlighted data point will be used. + * If set to ``null`` or ``false``, then no tooltip will be used. + + See the `tooltip `__ + documentation for a detailed discussion about tooltip in Vega-Lite. + + **Default value:** ``null`` + url + The URL of the image file for image marks. + width + Width of the marks. + x + X coordinates of the marks, or width of horizontal ``"bar"`` and ``"area"`` without + specified ``x2`` or ``width``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + x2 + X2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"width"`` for the width + of the plot. + y + Y coordinates of the marks, or height of vertical ``"bar"`` and ``"area"`` without + specified ``y2`` or ``height``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + y2 + Y2 coordinates for ranged ``"area"``, ``"bar"``, ``"rect"``, and ``"rule"``. + + The ``value`` of this channel can be a number or a string ``"height"`` for the + height of the plot. + """ + + align: Align_T + angle: float + aria: bool + ariaRole: str + ariaRoleDescription: str + aspect: bool + bandSize: float + baseline: TextBaseline_T + blend: Blend_T + color: ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + cornerRadius: float + cornerRadiusBottomLeft: float + cornerRadiusBottomRight: float + cornerRadiusTopLeft: float + cornerRadiusTopRight: float + cursor: Cursor_T + description: str + dir: TextDirection_T + dx: float + dy: float + ellipsis: str + endAngle: float + fill: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + fillOpacity: float + filled: bool + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + height: float + href: str + innerRadius: float + interpolate: Interpolate_T + invalid: None | MarkInvalidDataMode_T + limit: float + lineBreak: str + lineHeight: float + opacity: float + order: bool | None + orient: Orientation_T + outerRadius: float + padAngle: float + radius: float + radius2: float + shape: str + size: float + smooth: bool + startAngle: float + stroke: None | ColorHex | LinearGradientKwds | RadialGradientKwds | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOffset: float + strokeOpacity: float + strokeWidth: float + tension: float + text: str | Sequence[str] + theta: float + theta2: float + thickness: float + timeUnitBandPosition: float + timeUnitBandSize: float + tooltip: str | bool | None | float | TooltipContentKwds + url: str + width: float + x: float | Literal["width"] + x2: float | Literal["width"] + y: float | Literal["height"] + y2: float | Literal["height"] + + +class TimeIntervalStepKwds(TypedDict, total=False): + """ + :class:`TimeIntervalStep` ``TypedDict`` wrapper. + + Parameters + ---------- + interval + + step + + """ + + interval: TimeInterval_T + step: float + + +class TimeLocaleKwds(TypedDict, total=False): + """ + :class:`TimeLocale` ``TypedDict`` wrapper. + + Parameters + ---------- + date + The date (%x) format specifier (e.g., "%m/%d/%Y"). + dateTime + The date and time (%c) format specifier (e.g., "%a %b %e %X %Y"). + days + The full names of the weekdays, starting with Sunday. + months + The full names of the months (starting with January). + periods + The A.M. and P.M. equivalents (e.g., ["AM", "PM"]). + shortDays + The abbreviated names of the weekdays, starting with Sunday. + shortMonths + The abbreviated names of the months (starting with January). + time + The time (%X) format specifier (e.g., "%H:%M:%S"). + """ + + date: str + dateTime: str + days: Sequence[str] + months: Sequence[str] + periods: Sequence[str] + shortDays: Sequence[str] + shortMonths: Sequence[str] + time: str + + +class TitleConfigKwds(TypedDict, total=False): + """ + :class:`TitleConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + align + Horizontal text alignment for title text. One of ``"left"``, ``"center"``, or + ``"right"``. + anchor + The anchor position for placing the title and subtitle text. One of ``"start"``, + ``"middle"``, or ``"end"``. For example, with an orientation of top these anchor + positions map to a left-, center-, or right-aligned title. + angle + Angle in degrees of title and subtitle text. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG group, removing the title from the ARIA accessibility tree. + + **Default value:** ``true`` + baseline + Vertical text baseline for title and subtitle text. One of ``"alphabetic"`` + (default), ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, or + ``"line-bottom"``. The ``"line-top"`` and ``"line-bottom"`` values operate similarly + to ``"top"`` and ``"bottom"``, but are calculated relative to the *lineHeight* + rather than *fontSize* alone. + color + Text color for title text. + dx + Delta offset for title and subtitle text x-coordinate. + dy + Delta offset for title and subtitle text y-coordinate. + font + Font name for title text. + fontSize + Font size in pixels for title text. + fontStyle + Font style for title text. + fontWeight + Font weight for title text. This can be either a string (e.g ``"bold"``, + ``"normal"``) or a number (``100``, ``200``, ``300``, ..., ``900`` where + ``"normal"`` = ``400`` and ``"bold"`` = ``700``). + frame + The reference frame for the anchor position, one of ``"bounds"`` (to anchor relative + to the full bounding box) or ``"group"`` (to anchor relative to the group width or + height). + limit + The maximum allowed length in pixels of title and subtitle text. + lineHeight + Line height in pixels for multi-line title text or title text with ``"line-top"`` or + ``"line-bottom"`` baseline. + offset + The orthogonal offset in pixels by which to displace the title group from its + position along the edge of the chart. + orient + Default title orientation (``"top"``, ``"bottom"``, ``"left"``, or ``"right"``) + subtitleColor + Text color for subtitle text. + subtitleFont + Font name for subtitle text. + subtitleFontSize + Font size in pixels for subtitle text. + subtitleFontStyle + Font style for subtitle text. + subtitleFontWeight + Font weight for subtitle text. This can be either a string (e.g ``"bold"``, + ``"normal"``) or a number (``100``, ``200``, ``300``, ..., ``900`` where + ``"normal"`` = ``400`` and ``"bold"`` = ``700``). + subtitleLineHeight + Line height in pixels for multi-line subtitle text. + subtitlePadding + The padding in pixels between title and subtitle text. + zindex + The integer z-index indicating the layering of the title group relative to other + axis, mark, and legend groups. + + **Default value:** ``0``. + """ + + align: Align_T + anchor: TitleAnchor_T + angle: float + aria: bool + baseline: TextBaseline_T + color: None | ColorHex | ColorName_T + dx: float + dy: float + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + frame: str | TitleFrame_T + limit: float + lineHeight: float + offset: float + orient: TitleOrient_T + subtitleColor: None | ColorHex | ColorName_T + subtitleFont: str + subtitleFontSize: float + subtitleFontStyle: str + subtitleFontWeight: FontWeight_T + subtitleLineHeight: float + subtitlePadding: float + zindex: float + + +class TitleParamsKwds(TypedDict, total=False): + """ + :class:`TitleParams` ``TypedDict`` wrapper. + + Parameters + ---------- + text + The title text. + align + Horizontal text alignment for title text. One of ``"left"``, ``"center"``, or + ``"right"``. + anchor + The anchor position for placing the title. One of ``"start"``, ``"middle"``, or + ``"end"``. For example, with an orientation of top these anchor positions map to a + left-, center-, or right-aligned title. + + **Default value:** ``"middle"`` for `single + `__ and `layered + `__ views. ``"start"`` for other + composite views. + + **Note:** `For now `__, ``anchor`` is + only customizable only for `single + `__ and `layered + `__ views. For other composite + views, ``anchor`` is always ``"start"``. + angle + Angle in degrees of title and subtitle text. + aria + A boolean flag indicating if `ARIA attributes + `__ should be + included (SVG output only). If ``false``, the "aria-hidden" attribute will be set on + the output SVG group, removing the title from the ARIA accessibility tree. + + **Default value:** ``true`` + baseline + Vertical text baseline for title and subtitle text. One of ``"alphabetic"`` + (default), ``"top"``, ``"middle"``, ``"bottom"``, ``"line-top"``, or + ``"line-bottom"``. The ``"line-top"`` and ``"line-bottom"`` values operate similarly + to ``"top"`` and ``"bottom"``, but are calculated relative to the *lineHeight* + rather than *fontSize* alone. + color + Text color for title text. + dx + Delta offset for title and subtitle text x-coordinate. + dy + Delta offset for title and subtitle text y-coordinate. + font + Font name for title text. + fontSize + Font size in pixels for title text. + fontStyle + Font style for title text. + fontWeight + Font weight for title text. This can be either a string (e.g ``"bold"``, + ``"normal"``) or a number (``100``, ``200``, ``300``, ..., ``900`` where + ``"normal"`` = ``400`` and ``"bold"`` = ``700``). + frame + The reference frame for the anchor position, one of ``"bounds"`` (to anchor relative + to the full bounding box) or ``"group"`` (to anchor relative to the group width or + height). + limit + The maximum allowed length in pixels of title and subtitle text. + lineHeight + Line height in pixels for multi-line title text or title text with ``"line-top"`` or + ``"line-bottom"`` baseline. + offset + The orthogonal offset in pixels by which to displace the title group from its + position along the edge of the chart. + orient + Default title orientation (``"top"``, ``"bottom"``, ``"left"``, or ``"right"``) + style + A `mark style property `__ + to apply to the title text mark. + + **Default value:** ``"group-title"``. + subtitle + The subtitle Text. + subtitleColor + Text color for subtitle text. + subtitleFont + Font name for subtitle text. + subtitleFontSize + Font size in pixels for subtitle text. + subtitleFontStyle + Font style for subtitle text. + subtitleFontWeight + Font weight for subtitle text. This can be either a string (e.g ``"bold"``, + ``"normal"``) or a number (``100``, ``200``, ``300``, ..., ``900`` where + ``"normal"`` = ``400`` and ``"bold"`` = ``700``). + subtitleLineHeight + Line height in pixels for multi-line subtitle text. + subtitlePadding + The padding in pixels between title and subtitle text. + zindex + The integer z-index indicating the layering of the title group relative to other + axis, mark and legend groups. + + **Default value:** ``0``. + """ + + text: str | Sequence[str] + align: Align_T + anchor: TitleAnchor_T + angle: float + aria: bool + baseline: TextBaseline_T + color: None | ColorHex | ColorName_T + dx: float + dy: float + font: str + fontSize: float + fontStyle: str + fontWeight: FontWeight_T + frame: str | TitleFrame_T + limit: float + lineHeight: float + offset: float + orient: TitleOrient_T + style: str | Sequence[str] + subtitle: str | Sequence[str] + subtitleColor: None | ColorHex | ColorName_T + subtitleFont: str + subtitleFontSize: float + subtitleFontStyle: str + subtitleFontWeight: FontWeight_T + subtitleLineHeight: float + subtitlePadding: float + zindex: float + + +class TooltipContentKwds(TypedDict, total=False): + """ + :class:`TooltipContent` ``TypedDict`` wrapper. + + Parameters + ---------- + content + + """ + + content: Literal["encoding", "data"] + + +class TopLevelSelectionParameterKwds(TypedDict, total=False): + """ + :class:`TopLevelSelectionParameter` ``TypedDict`` wrapper. + + Parameters + ---------- + name + Required. A unique name for the selection parameter. Selection names should be valid + JavaScript identifiers: they should contain only alphanumeric characters (or "$", or + "_") and may not start with a digit. Reserved keywords that may not be used as + parameter names are "datum", "event", "item", and "parent". + select + Determines the default event processing and data query for the selection. Vega-Lite + currently supports two selection types: + + * ``"point"`` -- to select multiple discrete data values; the first value is + selected on ``click`` and additional values toggled on shift-click. + * ``"interval"`` -- to select a continuous range of data values on ``drag``. + bind + When set, a selection is populated by input elements (also known as dynamic query + widgets) or by interacting with the corresponding legend. Direct manipulation + interaction is disabled by default; to re-enable it, set the selection's `on + `__ + property. + + Legend bindings are restricted to selections that only specify a single field or + encoding. + + Query widget binding takes the form of Vega's `input element binding definition + `__ or can be a mapping between + projected field/encodings and binding definitions. + + **See also:** `bind `__ + documentation. + value + Initialize the selection with a mapping between `projected channels or field names + `__ and initial + values. + + **See also:** `init `__ + documentation. + views + By default, top-level selections are applied to every view in the visualization. If + this property is specified, selections will only be applied to views with the given + names. + """ + + name: str + select: PointSelectionConfigKwds | IntervalSelectionConfigKwds | SelectionType_T + bind: ( + BindInputKwds + | BindRangeKwds + | BindDirectKwds + | BindCheckboxKwds + | BindRadioSelectKwds + | LegendStreamBindingKwds + | Literal["legend", "scales"] + ) + value: str | bool | None | float | DateTimeKwds | Sequence[Map] + views: Sequence[str] + + +class VariableParameterKwds(TypedDict, total=False): + """ + :class:`VariableParameter` ``TypedDict`` wrapper. + + Parameters + ---------- + name + A unique name for the variable parameter. Parameter names should be valid JavaScript + identifiers: they should contain only alphanumeric characters (or "$", or "_") and + may not start with a digit. Reserved keywords that may not be used as parameter + names are "datum", "event", "item", and "parent". + bind + Binds the parameter to an external input element such as a slider, selection list or + radio button group. + expr + An expression for the value of the parameter. This expression may include other + parameters, in which case the parameter will automatically update in response to + upstream parameter changes. + react + A boolean flag (default ``true``) indicating if the update expression should be + automatically re-evaluated when any upstream signal dependencies update. If + ``false``, the update expression will not register any dependencies on other + signals, even for initialization. + + **Default value:** ``true`` + value + The `initial value `__ of the + parameter. + + **Default value:** ``undefined`` + """ + + name: str + bind: ( + BindInputKwds + | BindRangeKwds + | BindDirectKwds + | BindCheckboxKwds + | BindRadioSelectKwds + ) + expr: str + react: bool + value: Any + + +class ViewBackgroundKwds(TypedDict, total=False): + """ + :class:`ViewBackground` ``TypedDict`` wrapper. + + Parameters + ---------- + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cursor + The mouse cursor used over the view. Any valid `CSS cursor type + `__ can be used. + fill + The fill color. + + **Default value:** ``undefined`` + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + stroke + The stroke color. + + **Default value:** ``"#ddd"`` + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + style + A string or array of strings indicating the name of custom styles to apply to the + view background. A style is a named collection of mark property defaults defined + within the `style configuration + `__. If style is an + array, later styles will override earlier styles. + + **Default value:** ``"cell"`` **Note:** Any specified view background properties + will augment the default style. + """ + + cornerRadius: float + cursor: Cursor_T + fill: None | ColorHex | ColorName_T + fillOpacity: float + opacity: float + stroke: None | ColorHex | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOpacity: float + strokeWidth: float + style: str | Sequence[str] + + +class ViewConfigKwds(TypedDict, total=False): + """ + :class:`ViewConfig` ``TypedDict`` wrapper. + + Parameters + ---------- + clip + Whether the view should be clipped. + continuousHeight + The default height when the plot has a continuous y-field for x or latitude, or has + arc marks. + + **Default value:** ``200`` + continuousWidth + The default width when the plot has a continuous field for x or longitude, or has + arc marks. + + **Default value:** ``200`` + cornerRadius + The radius in pixels of rounded rectangles or arcs' corners. + + **Default value:** ``0`` + cursor + The mouse cursor used over the view. Any valid `CSS cursor type + `__ can be used. + discreteHeight + The default height when the plot has non arc marks and either a discrete y-field or + no y-field. The height can be either a number indicating a fixed height or an object + in the form of ``{step: number}`` defining the height per discrete step. + + **Default value:** a step size based on ``config.view.step``. + discreteWidth + The default width when the plot has non-arc marks and either a discrete x-field or + no x-field. The width can be either a number indicating a fixed width or an object + in the form of ``{step: number}`` defining the width per discrete step. + + **Default value:** a step size based on ``config.view.step``. + fill + The fill color. + + **Default value:** ``undefined`` + fillOpacity + The fill opacity (value between [0,1]). + + **Default value:** ``1`` + opacity + The overall opacity (value between [0,1]). + + **Default value:** ``0.7`` for non-aggregate plots with ``point``, ``tick``, + ``circle``, or ``square`` marks or layered ``bar`` charts and ``1`` otherwise. + step + Default step size for x-/y- discrete fields. + stroke + The stroke color. + + **Default value:** ``"#ddd"`` + strokeCap + The stroke cap for line ending style. One of ``"butt"``, ``"round"``, or + ``"square"``. + + **Default value:** ``"butt"`` + strokeDash + An array of alternating stroke, space lengths for creating dashed or dotted lines. + strokeDashOffset + The offset (in pixels) into which to begin drawing with the stroke dash array. + strokeJoin + The stroke line join method. One of ``"miter"``, ``"round"`` or ``"bevel"``. + + **Default value:** ``"miter"`` + strokeMiterLimit + The miter limit at which to bevel a line join. + strokeOpacity + The stroke opacity (value between [0,1]). + + **Default value:** ``1`` + strokeWidth + The stroke width, in pixels. + """ + + clip: bool + continuousHeight: float + continuousWidth: float + cornerRadius: float + cursor: Cursor_T + discreteHeight: float + discreteWidth: float + fill: None | ColorHex | ColorName_T + fillOpacity: float + opacity: float + step: float + stroke: None | ColorHex | ColorName_T + strokeCap: StrokeCap_T + strokeDash: Sequence[float] + strokeDashOffset: float + strokeJoin: StrokeJoin_T + strokeMiterLimit: float + strokeOpacity: float + strokeWidth: float + + +class ThemeConfig(TypedDict, total=False): + """ + Top-Level Configuration ``TypedDict`` for creating a consistent theme. + + Parameters + ---------- + align + The alignment to apply to grid rows and columns. The supported string values are + ``"all"``, ``"each"``, and ``"none"``. + + * For ``"none"``, a flow layout will be used, in which adjacent subviews are simply + placed one after the other. + * For ``"each"``, subviews will be aligned into a clean grid structure, but each row + or column may be of variable size. + * For ``"all"``, subviews will be aligned and each row or column will be sized + identically based on the maximum observed size. String values for this property + will be applied to both grid rows and columns. + + Alternatively, an object value of the form ``{"row": string, "column": string}`` can + be used to supply different alignments for rows and columns. + + **Default value:** ``"all"``. + autosize + How the visualization size should be determined. If a string, should be one of + ``"pad"``, ``"fit"`` or ``"none"``. Object values can additionally specify + parameters for content sizing and automatic resizing. + + **Default value**: ``pad`` + background + CSS color property to use as the background of the entire view. + + **Default value:** ``"white"`` + bounds + The bounds calculation method to use for determining the extent of a sub-plot. One + of ``full`` (the default) or ``flush``. + + * If set to ``full``, the entire calculated bounds (including axes, title, and + legend) will be used. + * If set to ``flush``, only the specified width and height values for the sub-view + will be used. The ``flush`` setting can be useful when attempting to place + sub-plots without axes or legends into a uniform grid structure. + + **Default value:** ``"full"`` + center + Boolean flag indicating if subviews should be centered relative to their respective + rows or columns. + + An object value of the form ``{"row": boolean, "column": boolean}`` can be used to + supply different centering values for rows and columns. + + **Default value:** ``false`` + config + Vega-Lite configuration object. This property can only be defined at the top-level + of a specification. + description + Description of this mark for commenting purpose. + height + The height of a visualization. + + * For a plot with a continuous y-field, height should be a number. + * For a plot with either a discrete y-field or no y-field, height can be either a + number indicating a fixed height or an object in the form of ``{step: number}`` + defining the height per discrete step. (No y-field is equivalent to having one + discrete step.) + * To enable responsive sizing on height, it should be set to ``"container"``. + + **Default value:** Based on ``config.view.continuousHeight`` for a plot with a + continuous y-field and ``config.view.discreteHeight`` otherwise. + + **Note:** For plots with `row and column channels + `__, this represents the + height of a single view and the ``"container"`` option cannot be used. + + **See also:** `height `__ + documentation. + name + Name of the visualization for later reference. + padding + The default visualization padding, in pixels, from the edge of the visualization + canvas to the data rectangle. If a number, specifies padding for all sides. If an + object, the value should have the format ``{"left": 5, "top": 5, "right": 5, + "bottom": 5}`` to specify padding for each side of the visualization. + + **Default value**: ``5`` + params + An array of parameters that may either be simple variables, or more complex + selections that map user input to data queries. + projection + An object defining properties of geographic projection, which will be applied to + ``shape`` path for ``"geoshape"`` marks and to ``latitude`` and ``"longitude"`` + channels for other marks. + resolve + Scale, axis, and legend resolutions for view composition specifications. + spacing + The spacing in pixels between sub-views of the composition operator. An object of + the form ``{"row": number, "column": number}`` can be used to set different spacing + values for rows and columns. + + **Default value**: Depends on ``"spacing"`` property of `the view composition + configuration `__ + (``20`` by default) + title + Title for the plot. + usermeta + Optional metadata that will be passed to Vega. This object is completely ignored by + Vega and Vega-Lite and can be used for custom metadata. + view + An object defining the view background's fill and stroke. + + **Default value:** none (transparent) + width + The width of a visualization. + + * For a plot with a continuous x-field, width should be a number. + * For a plot with either a discrete x-field or no x-field, width can be either a + number indicating a fixed width or an object in the form of ``{step: number}`` + defining the width per discrete step. (No x-field is equivalent to having one + discrete step.) + * To enable responsive sizing on width, it should be set to ``"container"``. + + **Default value:** Based on ``config.view.continuousWidth`` for a plot with a + continuous x-field and ``config.view.discreteWidth`` otherwise. + + **Note:** For plots with `row and column channels + `__, this represents the + width of a single view and the ``"container"`` option cannot be used. + + **See also:** `width `__ + documentation. + """ + + align: RowColKwds[LayoutAlign_T] | LayoutAlign_T + autosize: AutoSizeParamsKwds | AutosizeType_T + background: ColorHex | ColorName_T + bounds: Literal["full", "flush"] + center: bool | RowColKwds[bool] + config: ConfigKwds + description: str + height: float | StepKwds | Literal["container"] + name: str + padding: float | PaddingKwds + params: Sequence[VariableParameterKwds | TopLevelSelectionParameterKwds] + projection: ProjectionKwds + resolve: ResolveKwds + spacing: float | RowColKwds[float] + title: str | Sequence[str] | TitleParamsKwds + usermeta: Map + view: ViewBackgroundKwds + width: float | StepKwds | Literal["container"] diff --git a/altair/vegalite/v5/schema/_typing.py b/altair/vegalite/v5/schema/_typing.py index aa19be511..e2ea00ed5 100644 --- a/altair/vegalite/v5/schema/_typing.py +++ b/altair/vegalite/v5/schema/_typing.py @@ -1,11 +1,42 @@ # The contents of this file are automatically written by # tools/generate_schema_wrapper.py. Do not modify directly. - from __future__ import annotations -from typing import Any, Literal, Mapping, Sequence, TypeVar, Union -from typing_extensions import TypeAlias, TypeAliasType +import re +import sys +from typing import Any, Generic, Literal, Mapping, Sequence, TypeVar, Union + +if sys.version_info >= (3, 14): # https://peps.python.org/pep-0728/ + from typing import TypedDict +else: + from typing_extensions import TypedDict + +if sys.version_info >= (3, 13): + from typing import TypeIs +else: + from typing_extensions import TypeIs + +if sys.version_info >= (3, 12): + from typing import TypeAliasType +else: + from typing_extensions import TypeAliasType + +if sys.version_info >= (3, 11): + from typing import LiteralString +else: + from typing_extensions import LiteralString + +if sys.version_info >= (3, 10): + from typing import TypeAlias +else: + from typing_extensions import TypeAlias + +if sys.version_info >= (3, 9): + from typing import Annotated, get_args +else: + from typing_extensions import Annotated, get_args + __all__ = [ "AggregateOp_T", @@ -16,6 +47,7 @@ "BinnedTimeUnit_T", "Blend_T", "BoxPlot_T", + "ColorHex", "ColorName_T", "ColorScheme_T", "CompositeMark_T", @@ -39,9 +71,11 @@ "OneOrSeq", "Orient_T", "Orientation_T", + "PaddingKwds", "ProjectionType_T", "RangeEnum_T", "ResolveMode_T", + "RowColKwds", "ScaleInterpolateEnum_T", "ScaleType_T", "SelectionResolution_T", @@ -53,6 +87,7 @@ "SortOrder_T", "StackOffset_T", "StandardType_T", + "StepFor_T", "StrokeCap_T", "StrokeJoin_T", "TextBaseline_T", @@ -65,14 +100,17 @@ "Type_T", "UtcMultiTimeUnit_T", "UtcSingleTimeUnit_T", + "Value", "VegaThemes", "WindowOnlyOp_T", + "is_color_hex", ] T = TypeVar("T") OneOrSeq = TypeAliasType("OneOrSeq", Union[T, Sequence[T]], type_params=(T,)) -"""One of ``T`` specified type(s), or a `Sequence` of such. +""" +One of ``T`` specified type(s), or a `Sequence` of such. Examples -------- @@ -86,6 +124,83 @@ def func( ): ... """ + +class Value(TypedDict, Generic[T]): + """ + A `Generic`_ single item ``dict``. + + Parameters + ---------- + value: T + Wrapped value. + + .. _Generic: + https://typing.readthedocs.io/en/latest/spec/generics.html#generics + """ + + value: T + + +ColorHex = Annotated[ + LiteralString, + re.compile(r"#[0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2}([0-9a-f]{2})?", re.IGNORECASE), +] +""" +A `hexadecimal`_ color code. + +Corresponds to the ``json-schema`` string format: + + {"format": "color-hex", "type": "string"} + +Examples +-------- +: + + "#f0f8ff" + "#7fffd4" + "#000000" + "#0000FF" + "#0000ff80" + +.. _hexadecimal: + https://www.w3schools.com/html/html_colors_hex.asp +""" + + +def is_color_hex(obj: Any) -> TypeIs[ColorHex]: + """Return ``True`` if the object is a hexadecimal color code.""" + # NOTE: Extracts compiled pattern from metadata, + # to avoid defining in multiple places. + it = iter(get_args(ColorHex)) + next(it) + pattern: re.Pattern[str] = next(it) + return bool(pattern.fullmatch(obj)) + + +class RowColKwds(TypedDict, Generic[T], total=False): + """ + A `Generic`_ two-item ``dict``. + + Parameters + ---------- + column: T + row: T + + .. _Generic: + https://typing.readthedocs.io/en/latest/spec/generics.html#generics + """ + + column: T + row: T + + +class PaddingKwds(TypedDict, total=False): + bottom: float + left: float + right: float + top: float + + VegaThemes: TypeAlias = Literal[ "carbong10", "carbong100", @@ -1069,6 +1184,7 @@ def func( SortOrder_T: TypeAlias = Literal["ascending", "descending"] StackOffset_T: TypeAlias = Literal["zero", "center", "normalize"] StandardType_T: TypeAlias = Literal["quantitative", "ordinal", "temporal", "nominal"] +StepFor_T: TypeAlias = Literal["position", "offset"] StrokeCap_T: TypeAlias = Literal["butt", "round", "square"] StrokeJoin_T: TypeAlias = Literal["miter", "round", "bevel"] TextBaseline_T: TypeAlias = Literal[ diff --git a/altair/vegalite/v5/schema/channels.py b/altair/vegalite/v5/schema/channels.py index ac645fd85..c978330a5 100644 --- a/altair/vegalite/v5/schema/channels.py +++ b/altair/vegalite/v5/schema/channels.py @@ -1,6 +1,8 @@ # The contents of this file are automatically written by # tools/generate_schema_wrapper.py. Do not modify directly. +from __future__ import annotations + # These errors need to be ignored as they come from the overload methods # which trigger two kind of errors in mypy: # * all of them do not have an implementation in this file @@ -8,12 +10,13 @@ # sense if there are multiple ones # However, we need these overloads due to how the propertysetter works # mypy: disable-error-code="no-overload-impl, empty-body, misc" - -from __future__ import annotations - +import sys from typing import TYPE_CHECKING, Any, Literal, Sequence, TypedDict, Union, overload -from typing_extensions import TypeAlias +if sys.version_info >= (3, 10): + from typing import TypeAlias +else: + from typing_extensions import TypeAlias import narwhals.stable.v1 as nw from altair.utils import infer_encoding_types as _infer_encoding_types @@ -23,14 +26,17 @@ from . import core from ._typing import * # noqa: F403 -# ruff: noqa: F405 if TYPE_CHECKING: - from typing_extensions import Self - + # ruff: noqa: F405 from altair import Parameter, SchemaBase from altair.typing import Optional from altair.vegalite.v5.api import IntoCondition + if sys.version_info >= (3, 11): + from typing import Self + else: + from typing_extensions import Self + __all__ = [ "X2", diff --git a/altair/vegalite/v5/schema/core.py b/altair/vegalite/v5/schema/core.py index 0d6dd47e0..623b27ee5 100644 --- a/altair/vegalite/v5/schema/core.py +++ b/altair/vegalite/v5/schema/core.py @@ -14,8 +14,8 @@ _subclasses, ) -# ruff: noqa: F405 if TYPE_CHECKING: + # ruff: noqa: F405 from altair import Parameter from altair.typing import Optional diff --git a/altair/vegalite/v5/schema/mixins.py b/altair/vegalite/v5/schema/mixins.py index 2e7048719..572014afa 100644 --- a/altair/vegalite/v5/schema/mixins.py +++ b/altair/vegalite/v5/schema/mixins.py @@ -3,25 +3,23 @@ from __future__ import annotations -import sys from typing import TYPE_CHECKING, Literal, Sequence -from altair.utils import use_signature -from altair.utils.schemapi import Undefined +from altair.utils import Undefined, use_signature from . import core if TYPE_CHECKING: from altair import Parameter, SchemaBase -if sys.version_info >= (3, 11): - from typing import Self -else: - from typing_extensions import Self - - -# ruff: noqa: F405 if TYPE_CHECKING: + # ruff: noqa: F405 + import sys + + if sys.version_info >= (3, 11): + from typing import Self + else: + from typing_extensions import Self from altair.typing import Optional from ._typing import * # noqa: F403 diff --git a/altair/vegalite/v5/schema/vega-themes.json b/altair/vegalite/v5/schema/vega-themes.json index 22d8664b8..10ad14d5d 100644 --- a/altair/vegalite/v5/schema/vega-themes.json +++ b/altair/vegalite/v5/schema/vega-themes.json @@ -28,12 +28,6 @@ "circle": { "fill": "#6929c4" }, - "group": { - "fill": "#ffffff" - }, - "path": { - "stroke": "#6929c4" - }, "range": { "category": [ "#6929c4", @@ -85,9 +79,6 @@ "rect": { "fill": "#6929c4" }, - "shape": { - "stroke": "#6929c4" - }, "style": { "guide-label": { "fill": "#525252", @@ -100,9 +91,6 @@ "fontWeight": 400 } }, - "symbol": { - "stroke": "#6929c4" - }, "title": { "anchor": "start", "color": "#161616", @@ -145,12 +133,6 @@ "circle": { "fill": "#d4bbff" }, - "group": { - "fill": "#161616" - }, - "path": { - "stroke": "#d4bbff" - }, "range": { "category": [ "#8a3ffc", @@ -202,9 +184,6 @@ "rect": { "fill": "#d4bbff" }, - "shape": { - "stroke": "#d4bbff" - }, "style": { "guide-label": { "fill": "#c6c6c6", @@ -217,9 +196,6 @@ "fontWeight": 400 } }, - "symbol": { - "stroke": "#d4bbff" - }, "title": { "anchor": "start", "color": "#f4f4f4", @@ -262,12 +238,6 @@ "circle": { "fill": "#d4bbff" }, - "group": { - "fill": "#161616" - }, - "path": { - "stroke": "#d4bbff" - }, "range": { "category": [ "#8a3ffc", @@ -319,9 +289,6 @@ "rect": { "fill": "#d4bbff" }, - "shape": { - "stroke": "#d4bbff" - }, "style": { "guide-label": { "fill": "#c6c6c6", @@ -334,9 +301,6 @@ "fontWeight": 400 } }, - "symbol": { - "stroke": "#d4bbff" - }, "title": { "anchor": "start", "color": "#f4f4f4", @@ -379,12 +343,6 @@ "circle": { "fill": "#6929c4" }, - "group": { - "fill": "#ffffff" - }, - "path": { - "stroke": "#6929c4" - }, "range": { "category": [ "#6929c4", @@ -436,9 +394,6 @@ "rect": { "fill": "#6929c4" }, - "shape": { - "stroke": "#6929c4" - }, "style": { "guide-label": { "fill": "#525252", @@ -451,9 +406,6 @@ "fontWeight": 400 } }, - "symbol": { - "stroke": "#6929c4" - }, "title": { "anchor": "start", "color": "#161616", @@ -522,9 +474,6 @@ "stroke": "#4572a7", "strokeWidth": 2 }, - "path": { - "stroke": "#4572a7" - }, "range": { "category": [ "#4572a7", @@ -541,14 +490,6 @@ }, "rect": { "fill": "#4572a7" - }, - "shape": { - "stroke": "#4572a7" - }, - "symbol": { - "fill": "#4572a7", - "size": 50, - "strokeWidth": 1.5 } }, "fivethirtyeight": { @@ -581,9 +522,6 @@ "fill": "#30a2da", "stroke": null }, - "group": { - "fill": "#f0f0f0" - }, "legend": { "labelColor": "#333", "labelFontSize": 11, @@ -598,10 +536,6 @@ "stroke": "#30a2da", "strokeWidth": 2 }, - "path": { - "stroke": "#30a2da", - "strokeWidth": 0.5 - }, "point": { "filled": true, "shape": "circle" @@ -640,9 +574,6 @@ "rect": { "fill": "#30a2da" }, - "shape": { - "stroke": "#30a2da" - }, "title": { "anchor": "start", "fontSize": 24, @@ -669,9 +600,6 @@ "titleFontSize": 16, "titleFontWeight": "normal" }, - "group": { - "fill": "#e5e5e5" - }, "legend": { "labelBaseline": "middle", "labelFontSize": 11, @@ -680,9 +608,6 @@ "line": { "stroke": "#000" }, - "path": { - "stroke": "#000" - }, "range": { "category": [ "#000000", @@ -699,13 +624,6 @@ }, "rect": { "fill": "#000" - }, - "shape": { - "stroke": "#000" - }, - "symbol": { - "fill": "#000", - "size": 40 } }, "googlecharts": { @@ -731,9 +649,6 @@ "right": 10, "top": 10 }, - "path": { - "stroke": "#3366CC" - }, "range": { "category": [ "#4285F4", @@ -758,9 +673,6 @@ "rect": { "fill": "#3366CC" }, - "shape": { - "stroke": "#3366CC" - }, "style": { "group-title": { "font": "Arial, sans-serif", @@ -775,9 +687,6 @@ "fontSize": 12 } }, - "symbol": { - "stroke": "#3366CC" - }, "title": { "anchor": "start", "dy": -3, @@ -829,9 +738,6 @@ "stroke": "#82c6df", "strokeWidth": 2 }, - "path": { - "stroke": "#82c6df" - }, "range": { "category": [ "#ec8431", @@ -880,13 +786,6 @@ "rect": { "fill": "#82c6df" }, - "shape": { - "stroke": "#82c6df" - }, - "symbol": { - "fill": "#82c6df", - "size": 30 - }, "title": { "anchor": "start", "color": "#000000", @@ -963,9 +862,6 @@ "strokeJoin": "round", "strokeWidth": 3 }, - "path": { - "stroke": "#118DFF" - }, "point": { "fill": "#118DFF", "filled": true, @@ -1006,14 +902,6 @@ "rect": { "fill": "#118DFF" }, - "shape": { - "stroke": "#118DFF" - }, - "symbol": { - "fill": "#118DFF", - "size": 50, - "strokeWidth": 1.5 - }, "text": { "fill": "#605E5C", "font": "Segoe UI", @@ -1061,9 +949,6 @@ "line": { "stroke": "#ab5787" }, - "path": { - "stroke": "#ab5787" - }, "range": { "category": [ "#ab5787", @@ -1080,13 +965,6 @@ }, "rect": { "fill": "#ab5787" - }, - "shape": { - "stroke": "#ab5787" - }, - "symbol": { - "fill": "#ab5787", - "size": 30 } }, "urbaninstitute": { @@ -1143,10 +1021,6 @@ "stroke": "#1696d2", "strokeWidth": 5 }, - "path": { - "stroke": "#1696d2", - "strokeWidth": 0.5 - }, "point": { "filled": true }, @@ -1201,19 +1075,12 @@ "rect": { "fill": "#1696d2" }, - "shape": { - "stroke": "#1696d2" - }, "style": { "bar": { "fill": "#1696d2", "stroke": null } }, - "symbol": { - "fill": "#1696d2", - "size": 30 - }, "text": { "align": "center", "color": "#1696d2", @@ -1273,9 +1140,6 @@ "line": { "stroke": "#3e5c69" }, - "path": { - "stroke": "#3e5c69" - }, "range": { "category": [ "#3e5c69", @@ -1290,12 +1154,6 @@ }, "rect": { "fill": "#3e5c69" - }, - "shape": { - "stroke": "#3e5c69" - }, - "symbol": { - "fill": "#3e5c69" } } } \ No newline at end of file diff --git a/altair/vegalite/v5/theme.py b/altair/vegalite/v5/theme.py index 2e438679b..ba5a5ab9a 100644 --- a/altair/vegalite/v5/theme.py +++ b/altair/vegalite/v5/theme.py @@ -4,9 +4,10 @@ import sys from functools import wraps -from typing import TYPE_CHECKING, Any, Callable, Dict, Final, Literal, TypeVar, get_args +from typing import TYPE_CHECKING, Callable, Final, Literal, get_args from altair.utils.theme import ThemeRegistry +from altair.vegalite.v5.schema._config import ThemeConfig from altair.vegalite.v5.schema._typing import VegaThemes if sys.version_info >= (3, 10): @@ -16,6 +17,8 @@ if TYPE_CHECKING: + from altair.utils.plugin_registry import Plugin + if sys.version_info >= (3, 11): from typing import LiteralString else: @@ -26,7 +29,6 @@ from typing_extensions import TypeAlias P = ParamSpec("P") -R = TypeVar("R", bound=Dict[str, Any]) AltairThemes: TypeAlias = Literal["default", "opaque"] VEGA_THEMES: list[LiteralString] = list(get_args(VegaThemes)) @@ -37,7 +39,7 @@ class VegaTheme: def __init__(self, theme: str) -> None: self.theme = theme - def __call__(self) -> dict[str, dict[str, dict[str, str | int]]]: + def __call__(self) -> ThemeConfig: return { "usermeta": {"embedOptions": {"theme": self.theme}}, "config": {"view": {"continuousWidth": 300, "continuousHeight": 300}}, @@ -66,7 +68,7 @@ def __repr__(self) -> str: } }, ) -themes.register("none", dict) +themes.register("none", ThemeConfig) for theme in VEGA_THEMES: themes.register(theme, VegaTheme(theme)) @@ -78,7 +80,7 @@ def __repr__(self) -> str: # https://github.com/vega/altair/pull/3526#discussion_r1743350127 def register_theme( name: LiteralString, *, enable: bool -) -> Callable[[Callable[P, R]], Callable[P, R]]: +) -> Callable[[Plugin[ThemeConfig]], Plugin[ThemeConfig]]: """ Decorator for registering a theme function. @@ -93,14 +95,12 @@ def register_theme( -------- Register and enable a theme:: - from __future__ import annotations - - from typing import Any import altair as alt + from altair.typing import ThemeConfig @alt.register_theme("param_font_size", enable=True) - def custom_theme() -> dict[str, Any]: + def custom_theme() -> ThemeConfig: sizes = 12, 14, 16, 18, 20 return { "autosize": {"contains": "content", "resize": True}, @@ -134,13 +134,13 @@ def custom_theme() -> dict[str, Any]: """ - def decorate(func: Callable[P, R], /) -> Callable[P, R]: + def decorate(func: Plugin[ThemeConfig], /) -> Plugin[ThemeConfig]: themes.register(name, func) if enable: themes.enable(name) @wraps(func) - def wrapper(*args: P.args, **kwargs: P.kwargs) -> R: + def wrapper(*args: P.args, **kwargs: P.kwargs) -> ThemeConfig: return func(*args, **kwargs) return wrapper diff --git a/doc/user_guide/api.rst b/doc/user_guide/api.rst index eaa9cb602..9000bce99 100644 --- a/doc/user_guide/api.rst +++ b/doc/user_guide/api.rst @@ -689,5 +689,7 @@ Typing ChartType EncodeKwds Optional + ThemeConfig is_chart_type + theme diff --git a/pyproject.toml b/pyproject.toml index 6901364a3..bc9cdf220 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -112,7 +112,7 @@ installer = "uv" [tool.hatch.envs.default.scripts] generate-schema-wrapper = [ - "mypy tools/schemapi/schemapi.py", + "mypy tools", "python tools/generate_schema_wrapper.py", "test" ] @@ -439,7 +439,7 @@ module = [ "ibis.*", # This refers to schemapi in the tools folder which is imported # by the tools scripts such as generate_schema_wrapper.py - "schemapi.*" + # "schemapi.*" ] ignore_missing_imports = true diff --git a/tests/vegalite/v5/test_theme.py b/tests/vegalite/v5/test_theme.py index fa6be95ac..97d2fb42e 100644 --- a/tests/vegalite/v5/test_theme.py +++ b/tests/vegalite/v5/test_theme.py @@ -1,13 +1,26 @@ from __future__ import annotations +from typing import TYPE_CHECKING, Any, Callable, cast + import pytest import altair.vegalite.v5 as alt +from altair.typing import ThemeConfig +from altair.vegalite.v5.schema._config import ConfigKwds +from altair.vegalite.v5.schema._typing import is_color_hex from altair.vegalite.v5.theme import VEGA_THEMES, register_theme, themes +if TYPE_CHECKING: + import sys + + if sys.version_info >= (3, 11): + from typing import LiteralString + else: + from typing_extensions import LiteralString + @pytest.fixture -def chart(): +def chart() -> alt.Chart: return alt.Chart("data.csv").mark_bar().encode(x="x:Q") @@ -23,10 +36,951 @@ def test_vega_themes(chart) -> None: def test_register_theme_decorator() -> None: @register_theme("unique name", enable=True) - def custom_theme() -> dict[str, int]: + def custom_theme() -> ThemeConfig: return {"height": 400, "width": 700} assert themes.active == "unique name" registered = themes.get() assert registered is not None assert registered() == {"height": 400, "width": 700} == custom_theme() + + +@pytest.mark.parametrize( + ("color_code", "valid"), + [ + ("#FFFFFF", True), + ("##ff6347", False), + ("#EE82EE", True), + ("#1ec9a0", True), + ("#19B_71", False), + ("#00#761", False), + ("123455", False), + ("#6a5acd ", False), + ("#f8f8f899", True), + ("#6a5acd6E", True), + ], +) +def test_is_color_hex(color_code: Any, *, valid: bool) -> None: + assert is_color_hex(color_code) == valid + + +def carbonwhite_theme() -> ThemeConfig: + """ + Only including **1/4** of `carbon`_ , which gives sufficient structural coverage. + + .. _carbon: + https://github.com/vega/vega-themes/blob/5f1a5c5b22cc462cf3d46894212152b71cfe964f/src/carbongen.ts + """ + return ThemeConfig( + config={ + "arc": {"fill": "#6929c4"}, + "area": {"fill": "#6929c4"}, + "axis": { + "grid": True, + "gridColor": "#e0e0e0", + "labelAngle": 0, + "labelColor": "#525252", + "labelFont": 'IBM Plex Sans Condensed, system-ui, -apple-system, BlinkMacSystemFont, ".SFNSText-Regular", sans-serif', + "labelFontSize": 12, + "labelFontWeight": 400, + "titleColor": "#161616", + "titleFontSize": 12, + "titleFontWeight": 600, + }, + "axisX": {"titlePadding": 10}, + "axisY": {"titlePadding": 2.5}, + "background": "#ffffff", + "circle": {"fill": "#6929c4"}, + "range": { + "category": [ + "#6929c4", + "#1192e8", + "#005d5d", + "#9f1853", + "#fa4d56", + "#570408", + "#198038", + "#002d9c", + "#ee538b", + "#b28600", + "#009d9a", + "#012749", + "#8a3800", + "#a56eff", + ], + "diverging": [ + "#750e13", + "#a2191f", + "#da1e28", + "#fa4d56", + "#ff8389", + "#ffb3b8", + "#ffd7d9", + "#fff1f1", + "#e5f6ff", + "#bae6ff", + "#82cfff", + "#33b1ff", + "#1192e8", + "#0072c3", + "#00539a", + "#003a6d", + ], + "heatmap": [ + "#f6f2ff", + "#e8daff", + "#d4bbff", + "#be95ff", + "#a56eff", + "#8a3ffc", + "#6929c4", + "#491d8b", + "#31135e", + "#1c0f30", + ], + }, + "rect": {"fill": "#6929c4"}, + "style": { + "guide-label": { + "fill": "#525252", + "font": 'IBM Plex Sans,system-ui,-apple-system,BlinkMacSystemFont,".sfnstext-regular",sans-serif', + "fontWeight": 400, + }, + "guide-title": { + "fill": "#525252", + "font": 'IBM Plex Sans,system-ui,-apple-system,BlinkMacSystemFont,".sfnstext-regular",sans-serif', + "fontWeight": 400, + }, + }, # type: ignore[typeddict-unknown-key] + "title": { + "anchor": "start", + "color": "#161616", + "dy": -15, + "font": 'IBM Plex Sans,system-ui,-apple-system,BlinkMacSystemFont,".sfnstext-regular",sans-serif', + "fontSize": 16, + "fontWeight": 600, + }, + "view": {"fill": "#ffffff", "stroke": "#ffffff"}, + } + ) + + +def dark_theme() -> ThemeConfig: + return ThemeConfig( + config=ConfigKwds( + axis={"domainColor": "#fff", "gridColor": "#888", "tickColor": "#fff"}, + background="#333", + style={ + "guide-label": {"fill": "#fff"}, + "guide-title": {"fill": "#fff"}, + }, # type: ignore[typeddict-unknown-key] + title={"color": "#fff", "subtitleColor": "#fff"}, + view={"stroke": "#888"}, + ) + ) + + +def excel_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#4572a7"}, + "area": {"fill": "#4572a7"}, + "axis": { + "bandPosition": 0.5, + "grid": True, + "gridColor": "#000000", + "gridOpacity": 1, + "gridWidth": 0.5, + "labelPadding": 10, + "tickSize": 5, + "tickWidth": 0.5, + }, + "axisBand": {"grid": False, "tickExtra": True}, + "background": "#fff", + "legend": { + "labelBaseline": "middle", + "labelFontSize": 11, + "symbolSize": 50, + "symbolType": "square", + }, + "line": {"stroke": "#4572a7", "strokeWidth": 2}, + "range": { + "category": [ + "#4572a7", + "#aa4643", + "#8aa453", + "#71598e", + "#4598ae", + "#d98445", + "#94aace", + "#d09393", + "#b9cc98", + "#a99cbc", + ] + }, + "rect": {"fill": "#4572a7"}, + } + } + + +def fivethirtyeight_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#30a2da"}, + "area": {"fill": "#30a2da"}, + "axis": { + "domainColor": "#cbcbcb", + "grid": True, + "gridColor": "#cbcbcb", + "gridWidth": 1, + "labelColor": "#999", + "labelFontSize": 10, + "labelPadding": 4, + "tickColor": "#cbcbcb", + "tickSize": 10, + "titleColor": "#333", + "titleFontSize": 14, + "titlePadding": 10, + }, + "axisBand": {"grid": False}, + "background": "#f0f0f0", + "bar": {"binSpacing": 2, "fill": "#30a2da", "stroke": None}, + "legend": { + "labelColor": "#333", + "labelFontSize": 11, + "padding": 1, + "symbolSize": 30, + "symbolType": "square", + "titleColor": "#333", + "titleFontSize": 14, + "titlePadding": 10, + }, + "line": {"stroke": "#30a2da", "strokeWidth": 2}, + "point": {"filled": True, "shape": "circle"}, + "range": { + "category": [ + "#30a2da", + "#fc4f30", + "#e5ae38", + "#6d904f", + "#8b8b8b", + "#b96db8", + "#ff9e27", + "#56cc60", + "#52d2ca", + "#52689e", + "#545454", + "#9fe4f8", + ], + "diverging": [ + "#cc0020", + "#e77866", + "#f6e7e1", + "#d6e8ed", + "#91bfd9", + "#1d78b5", + ], + "heatmap": ["#d6e8ed", "#cee0e5", "#91bfd9", "#549cc6", "#1d78b5"], + }, + "rect": {"fill": "#30a2da"}, + "title": { + "anchor": "start", + "fontSize": 24, + "fontWeight": 600, + "offset": 20, + }, + } + } + + +def ggplot2_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#000"}, + "area": {"fill": "#000"}, + "axis": { + "domain": False, + "grid": True, + "gridColor": "#FFFFFF", + "gridOpacity": 1, + "labelColor": "#7F7F7F", + "labelPadding": 4, + "tickColor": "#7F7F7F", + "tickSize": 5.67, + "titleFontSize": 16, + "titleFontWeight": "normal", + }, + "legend": { + "labelBaseline": "middle", + "labelFontSize": 11, + "symbolSize": 40, + }, + "line": {"stroke": "#000"}, + "range": { + "category": [ + "#000000", + "#7F7F7F", + "#1A1A1A", + "#999999", + "#333333", + "#B0B0B0", + "#4D4D4D", + "#C9C9C9", + "#666666", + "#DCDCDC", + ] + }, + "rect": {"fill": "#000"}, + } + } + + +def googlecharts_theme() -> ThemeConfig: + """``Padding`` definition `float | Map` needs to be stricter.""" + return { + "config": { + "arc": {"fill": "#3366CC"}, + "area": {"fill": "#3366CC"}, + "axis": { + "domain": False, + "grid": True, + "gridColor": "#ccc", + "tickColor": "#ccc", + }, + "background": "#fff", + "circle": {"fill": "#3366CC"}, + "padding": { + "bottom": 10, + "left": 10, + "right": 10, + "top": 10, + }, + "range": { + "category": [ + "#4285F4", + "#DB4437", + "#F4B400", + "#0F9D58", + "#AB47BC", + "#00ACC1", + "#FF7043", + "#9E9D24", + "#5C6BC0", + "#F06292", + "#00796B", + "#C2185B", + ], + "heatmap": ["#c6dafc", "#5e97f6", "#2a56c6"], + }, + "rect": {"fill": "#3366CC"}, + "style": { + "group-title": {"font": "Arial, sans-serif", "fontSize": 12}, + "guide-label": {"font": "Arial, sans-serif", "fontSize": 12}, + "guide-title": {"font": "Arial, sans-serif", "fontSize": 12}, + }, # type: ignore[typeddict-unknown-key] + "title": { + "anchor": "start", + "dy": -3, + "font": "Arial, sans-serif", + "fontSize": 14, + "fontWeight": "bold", + }, + } + } + + +def latimes_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#82c6df"}, + "area": {"fill": "#82c6df"}, + "axis": { + "labelFont": "Benton Gothic, sans-serif", + "labelFontSize": 11.5, + "labelFontWeight": "normal", + "titleFont": "Benton Gothic Bold, sans-serif", + "titleFontSize": 13, + "titleFontWeight": "normal", + }, + "axisX": {"labelAngle": 0, "labelPadding": 4, "tickSize": 3}, + "axisY": { + "labelBaseline": "middle", + "maxExtent": 45, + "minExtent": 45, + "tickSize": 2, + "titleAlign": "left", + "titleAngle": 0, + "titleX": -45, + "titleY": -11, + }, + "background": "#ffffff", + "legend": { + "labelFont": "Benton Gothic, sans-serif", + "labelFontSize": 11.5, + "symbolType": "square", + "titleFont": "Benton Gothic Bold, sans-serif", + "titleFontSize": 13, + "titleFontWeight": "normal", + }, + "line": {"stroke": "#82c6df", "strokeWidth": 2}, + "range": { + "category": [ + "#ec8431", + "#829eb1", + "#c89d29", + "#3580b1", + "#adc839", + "#ab7fb4", + ], + "diverging": [ + "#e68a4f", + "#f4bb6a", + "#f9e39c", + "#dadfe2", + "#a6b7c6", + "#849eae", + ], + "heatmap": [ + "#fbf2c7", + "#f9e39c", + "#f8d36e", + "#f4bb6a", + "#e68a4f", + "#d15a40", + "#ab4232", + ], + "ordinal": [ + "#fbf2c7", + "#f9e39c", + "#f8d36e", + "#f4bb6a", + "#e68a4f", + "#d15a40", + "#ab4232", + ], + "ramp": [ + "#fbf2c7", + "#f9e39c", + "#f8d36e", + "#f4bb6a", + "#e68a4f", + "#d15a40", + "#ab4232", + ], + }, + "rect": {"fill": "#82c6df"}, + "title": { + "anchor": "start", + "color": "#000000", + "font": "Benton Gothic Bold, sans-serif", + "fontSize": 22, + "fontWeight": "normal", + }, + } + } + + +def powerbi_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#118DFF"}, + "area": {"fill": "#118DFF", "line": True, "opacity": 0.6}, + "axis": { + "domain": False, + "grid": False, + "labelColor": "#605E5C", + "labelFontSize": 12, + "ticks": False, + "titleColor": "#252423", + "titleFont": "wf_standard-font, helvetica, arial, sans-serif", + "titleFontSize": 16, + "titleFontWeight": "normal", + }, + "axisBand": {"tickExtra": True}, + "axisQuantitative": { + "grid": True, + "gridColor": "#C8C6C4", + "gridDash": [1, 5], + "labelFlush": False, + "tickCount": 3, + }, + "axisX": {"labelPadding": 5}, + "axisY": {"labelPadding": 10}, + "background": "transparent", + "bar": {"fill": "#118DFF"}, + "font": "Segoe UI", + "header": { + "labelColor": "#605E5C", + "labelFont": "Segoe UI", + "labelFontSize": 13.333333333333332, + "titleColor": "#252423", + "titleFont": "wf_standard-font, helvetica, arial, sans-serif", + "titleFontSize": 16, + }, + "legend": { + "labelColor": "#605E5C", + "labelFont": "Segoe UI", + "labelFontSize": 13.333333333333332, + "symbolSize": 75, + "symbolType": "circle", + "titleColor": "#605E5C", + "titleFont": "Segoe UI", + "titleFontWeight": "bold", + }, + "line": { + "stroke": "#118DFF", + "strokeCap": "round", + "strokeJoin": "round", + "strokeWidth": 3, + }, + "point": {"fill": "#118DFF", "filled": True, "size": 75}, + "range": { + "category": [ + "#118DFF", + "#12239E", + "#E66C37", + "#6B007B", + "#E044A7", + "#744EC2", + "#D9B300", + "#D64550", + ], + "diverging": ["#DEEFFF", "#118DFF"], + "heatmap": ["#DEEFFF", "#118DFF"], + "ordinal": [ + "#DEEFFF", + "#c7e4ff", + "#b0d9ff", + "#9aceff", + "#83c3ff", + "#6cb9ff", + "#55aeff", + "#3fa3ff", + "#2898ff", + "#118DFF", + ], + }, + "rect": {"fill": "#118DFF"}, + "text": {"fill": "#605E5C", "font": "Segoe UI", "fontSize": 12}, + "view": {"stroke": "transparent"}, + } + } + + +def quartz_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#ab5787"}, + "area": {"fill": "#ab5787"}, + "axis": { + "domainColor": "#979797", + "domainWidth": 0.5, + "gridWidth": 0.2, + "labelColor": "#979797", + "tickColor": "#979797", + "tickWidth": 0.2, + "titleColor": "#979797", + }, + "axisBand": {"grid": False}, + "axisX": {"grid": True, "tickSize": 10}, + "axisY": {"domain": False, "grid": True, "tickSize": 0}, + "background": "#f9f9f9", + "legend": { + "labelFontSize": 11, + "padding": 1, + "symbolSize": 30, + "symbolType": "square", + }, + "line": {"stroke": "#ab5787"}, + "range": { + "category": [ + "#ab5787", + "#51b2e5", + "#703c5c", + "#168dd9", + "#d190b6", + "#00609f", + "#d365ba", + "#154866", + "#666666", + "#c4c4c4", + ] + }, + "rect": {"fill": "#ab5787"}, + } + } + + +def urbaninstitute_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#1696d2"}, + "area": {"fill": "#1696d2"}, + "axisX": { + "domain": True, + "domainColor": "#000000", + "domainWidth": 1, + "grid": False, + "labelAngle": 0, + "labelFont": "Lato", + "labelFontSize": 12, + "tickColor": "#000000", + "tickSize": 5, + "titleFont": "Lato", + "titleFontSize": 12, + "titlePadding": 10, + }, + "axisY": { + "domain": False, + "domainWidth": 1, + "grid": True, + "gridColor": "#DEDDDD", + "gridWidth": 1, + "labelFont": "Lato", + "labelFontSize": 12, + "labelPadding": 8, + "ticks": False, + "titleAngle": 0, + "titleFont": "Lato", + "titleFontSize": 12, + "titlePadding": 10, + "titleX": 18, + "titleY": -10, + }, + "background": "#FFFFFF", + "legend": { + "labelFont": "Lato", + "labelFontSize": 12, + "offset": 10, + "orient": "right", + "symbolSize": 100, + "titleFont": "Lato", + "titleFontSize": 12, + "titlePadding": 10, + }, + "line": {"color": "#1696d2", "stroke": "#1696d2", "strokeWidth": 5}, + "point": {"filled": True}, + "range": { + "category": [ + "#1696d2", + "#ec008b", + "#fdbf11", + "#000000", + "#d2d2d2", + "#55b748", + ], + "diverging": [ + "#ca5800", + "#fdbf11", + "#fdd870", + "#fff2cf", + "#cfe8f3", + "#73bfe2", + "#1696d2", + "#0a4c6a", + ], + "heatmap": [ + "#ca5800", + "#fdbf11", + "#fdd870", + "#fff2cf", + "#cfe8f3", + "#73bfe2", + "#1696d2", + "#0a4c6a", + ], + "ordinal": [ + "#cfe8f3", + "#a2d4ec", + "#73bfe2", + "#46abdb", + "#1696d2", + "#12719e", + ], + "ramp": [ + "#CFE8F3", + "#A2D4EC", + "#73BFE2", + "#46ABDB", + "#1696D2", + "#12719E", + "#0A4C6A", + "#062635", + ], + }, + "rect": {"fill": "#1696d2"}, + "style": {"bar": {"fill": "#1696d2", "stroke": None}}, + "text": { + "align": "center", + "color": "#1696d2", + "font": "Lato", + "fontSize": 11, + "fontWeight": 400, + "size": 11, + }, + "title": {"anchor": "start", "font": "Lato", "fontSize": 18}, + "trail": { + "color": "#1696d2", + "size": 1, + "stroke": "#1696d2", + "strokeWidth": 0, + }, + "view": {"stroke": "transparent"}, + } + } + + +def vox_theme() -> ThemeConfig: + return { + "config": { + "arc": {"fill": "#3e5c69"}, + "area": {"fill": "#3e5c69"}, + "axis": { + "domainWidth": 0.5, + "grid": True, + "labelPadding": 2, + "tickSize": 5, + "tickWidth": 0.5, + "titleFontWeight": "normal", + }, + "axisBand": {"grid": False}, + "axisX": {"gridWidth": 0.2}, + "axisY": {"gridDash": [3], "gridWidth": 0.4}, + "background": "#fff", + "legend": {"labelFontSize": 11, "padding": 1, "symbolType": "square"}, + "line": {"stroke": "#3e5c69"}, + "range": { + "category": [ + "#3e5c69", + "#6793a6", + "#182429", + "#0570b0", + "#3690c0", + "#74a9cf", + "#a6bddb", + "#e2ddf2", + ] + }, + "rect": {"fill": "#3e5c69"}, + } + } + + +def binste_altair_theme() -> ThemeConfig: + """Copied from https://gist.github.com/binste/b4042fa76a89d72d45cbbb9355ec6906.""" + return ThemeConfig( + config={ + "axis": { + "labelFontSize": 16, + "titleFontSize": 16, + "titleFontWeight": "normal", + "gridColor": "lightGray", + "labelAngle": 0, + "labelFlush": False, + "labelPadding": 5, + }, + "axisY": { + "domain": False, + "ticks": False, + "labelPadding": 10, + "titleAngle": 0, + "titleY": -20, + "titleAlign": "left", + "titlePadding": 0, + }, + "axisTemporal": {"grid": False}, + "axisDiscrete": {"ticks": False, "labelPadding": 10, "grid": False}, + "scale": {"barBandPaddingInner": 0.2}, + "header": {"labelFontSize": 16, "titleFontSize": 16}, + "legend": { + "labelFontSize": 16, + "titleFontSize": 16, + "titleFontWeight": "normal", + }, + "title": { + "fontSize": 20, + "fontStyle": "normal", + "align": "left", + "anchor": "start", + "orient": "top", + "fontWeight": 600, + "offset": 10, + "subtitlePadding": 3, + "subtitleFontSize": 16, + }, + "view": { + "strokeWidth": 0, + "continuousHeight": 350, + "continuousWidth": 600, + "step": 50, + }, + "line": {"strokeWidth": 3.5}, + "text": {"fontSize": 16}, + "circle": {"size": 60}, + "point": {"size": 60}, + "square": {"size": 60}, + } + ) + + +def husky_theme() -> ThemeConfig: + """ + Adapted from https://github.com/deppen8/husky-altair-theme/blob/46f680532ee38c44e656903d3f1affe11b9982bb/husky_theme.py. + + Keeps 2 errors present in the original (marked by `# type: ignore[...]`). + """ + PURPLE = "#4b2e83" + GOLD = "#b7a57a" + METALLIC_GOLD = "#85754d" + LIGHT_GRAY = "#d9d9d9" + DARK_GRAY = "#444444" + BLACK = "#000000" + + HEADER_FONT = "EncodeSans-Regular" + BODY_FONT = "OpenSans-Regular" + BODY_FONT_BOLD = "OpenSans-Bold" + + return ThemeConfig( + config={ + "title": { + "fontSize": 18, + "font": HEADER_FONT, + "anchor": "start", + "color": PURPLE, + }, + "axisX": { + "domain": True, + "domainColor": DARK_GRAY, + "domainWidth": 1, + "grid": True, + "gridColor": LIGHT_GRAY, + "gridWidth": 0.5, + "labelFont": BODY_FONT, + "labelFontSize": 12, + "labelColor": DARK_GRAY, + "labelAngle": 0, + "tickColor": DARK_GRAY, + "tickSize": 5, + "titleFont": BODY_FONT_BOLD, + "titleFontSize": 12, + }, + "axisY": { + "domain": True, + "domainColor": DARK_GRAY, + "grid": True, + "gridColor": LIGHT_GRAY, + "gridWidth": 0.5, + "labelFont": BODY_FONT, + "labelFontSize": 12, + "labelAngle": 0, + "ticks": True, + "titleFont": BODY_FONT_BOLD, + "titleFontSize": 12, + }, + "header": { + "labelFont": BODY_FONT, + "labelFontSize": 16, + "titleFont": BODY_FONT_BOLD, + "titleFontSize": 16, + }, + "range": { + "category": [ + PURPLE, + GOLD, + LIGHT_GRAY, + METALLIC_GOLD, + BLACK, + DARK_GRAY, + ], + "diverging": [PURPLE, "#c2a5cf", LIGHT_GRAY, GOLD, METALLIC_GOLD], + }, + "legend": { + "labelFont": BODY_FONT, + "labelFontSize": 12, + "symbolSize": 100, + "titleFont": BODY_FONT_BOLD, + "titleFontSize": 12, + }, + "area": { + "fill": PURPLE, + }, + "circle": {"fill": PURPLE, "size": 40}, + "line": { + "color": PURPLE, + "stroke": PURPLE, + "strokeWidth": 3, + }, + "trail": { + "color": PURPLE, + "stroke": PURPLE, + "strokeWidth": 0, + "size": 1, + }, + "path": { + "stroke": PURPLE, + "strokeWidth": 0.5, + }, # type: ignore[typeddict-unknown-key] + "point": {"color": PURPLE, "size": 40}, + "text": { + "font": BODY_FONT, + "color": PURPLE, + "fontSize": 11, + "align": "right", + "size": 14, + }, + "bar": { + "size": 10, + "binSpacing": 1, + "continuousBandSize": 10, + "fill": PURPLE, + "stroke": False, # type: ignore[typeddict-item] + }, + "tick": {"color": PURPLE}, + }, + ) + + +known_themes: pytest.MarkDecorator = pytest.mark.parametrize( + "theme_func", + [ + carbonwhite_theme, + dark_theme, + excel_theme, + fivethirtyeight_theme, + ggplot2_theme, + googlecharts_theme, + latimes_theme, + powerbi_theme, + quartz_theme, + urbaninstitute_theme, + vox_theme, + binste_altair_theme, + husky_theme, + ], +) +""" +``pytest.mark.parametrize`` decorator. + +Provides themes from `vega-themes`_ and `other sources`_. + +Notes +----- +These are **redefined by hand** to run through a type checker. + +.. _vega-themes: + https://vega.github.io/vega-themes/ +.. _other sources: + https://github.com/vega/altair/issues/3519#issuecomment-2292010192 +""" + + +@known_themes +def test_theme_config(theme_func: Callable[[], ThemeConfig], chart) -> None: + """ + Simple-minded extra safety for themes. + + See ``(test_vega_themes|test_register_theme_decorator)`` for comprehensive suite. + """ + name = cast("LiteralString", theme_func.__qualname__) + register_theme(name, enable=True) + assert chart.to_dict(validate=True) diff --git a/tools/generate_schema_wrapper.py b/tools/generate_schema_wrapper.py index b3598c1c9..a0fa08e72 100644 --- a/tools/generate_schema_wrapper.py +++ b/tools/generate_schema_wrapper.py @@ -5,42 +5,62 @@ import argparse import copy import json -import re import sys import textwrap +from collections import deque from dataclasses import dataclass from itertools import chain +from operator import attrgetter from pathlib import Path -from typing import Final, Iterable, Iterator, Literal +from typing import TYPE_CHECKING, Any, Final, Iterable, Iterator, Literal from urllib import request import vl_convert as vlc sys.path.insert(0, str(Path.cwd())) -from tools.schemapi import CodeSnippet, SchemaInfo, codegen + + +from tools.schemapi import ( # noqa: F401 + CodeSnippet, + SchemaInfo, + arg_invalid_kwds, + arg_kwds, + arg_required_kwds, + codegen, +) from tools.schemapi.utils import ( + SchemaProperties, TypeAliasTracer, + finalize_type_reprs, get_valid_identifier, + import_type_checking, + import_typing_extensions, indent_docstring, resolve_references, - rst_parse, rst_syntax_for_class, ruff_format_py, ruff_write_lint_format_str, spell_literal, ) +if TYPE_CHECKING: + from tools.schemapi.codegen import ArgInfo, AttrGetter + SCHEMA_VERSION: Final = "v5.20.1" -reLink = re.compile(r"(?<=\[)([^\]]+)(?=\]\([^\)]+\))", re.MULTILINE) -reSpecial = re.compile(r"[*_]{2,3}|`", re.MULTILINE) -HEADER: Final = """\ +HEADER_COMMENT = """\ # The contents of this file are automatically written by # tools/generate_schema_wrapper.py. Do not modify directly. """ +HEADER: Final = f"""{HEADER_COMMENT} +from __future__ import annotations\n +""" + SCHEMA_URL_TEMPLATE: Final = "https://vega.github.io/schema/{library}/{version}.json" +SCHEMA_FILE = "vega-lite-schema.json" +THEMES_FILE = "vega-themes.json" CHANNEL_MYPY_IGNORE_STATEMENTS: Final = """\ # These errors need to be ignored as they come from the overload methods @@ -181,11 +201,17 @@ def to_dict( ) """ +MARK_MIXIN: Final = ''' +class MarkMethodMixin: + """A mixin class that defines mark methods""" + +{methods} +''' + MARK_METHOD: Final = ''' -def mark_{mark}({def_arglist}) -> Self: - """Set the chart's mark to '{mark}' (see :class:`{mark_def}`) - """ - kwds = dict({dict_arglist}) +def mark_{mark}(self, {method_args}, **kwds) -> Self: + """Set the chart's mark to '{mark}' (see :class:`{mark_def}`).""" + kwds = dict({dict_args}, **kwds) copy = self.copy(deep=False) # type: ignore[attr-defined] if any(val is not Undefined for val in kwds.values()): copy.mark = core.{mark_def}(type="{mark}", **kwds) @@ -211,10 +237,43 @@ def configure_{prop}(self, *args, **kwargs) -> Self: copy.config["{prop}"] = core.{classname}(*args, **kwargs) return copy """ +UNIVERSAL_TYPED_DICT = ''' +class {name}(TypedDict{metaclass_kwds}):{comment} + """ + {summary} + + Parameters + ---------- + {doc}""" + + {td_args} +''' +ENCODE_KWDS: Literal["EncodeKwds"] = "EncodeKwds" +THEME_CONFIG: Literal["ThemeConfig"] = "ThemeConfig" +PADDING_KWDS: Literal["PaddingKwds"] = "PaddingKwds" +ROW_COL_KWDS: Literal["RowColKwds"] = "RowColKwds" +ENCODE_KWDS_SUMMARY: Final = ( + "Encoding channels map properties of the data to visual properties of the chart." +) +THEME_CONFIG_SUMMARY: Final = ( + "Top-Level Configuration ``TypedDict`` for creating a consistent theme." +) +EXTRA_ITEMS_MESSAGE: Final = """\ + Notes + ----- + The following keys may be specified as string literals **only**: + + {invalid_kwds} + + See `PEP728`_ for type checker compatibility. + + .. _PEP728: + https://peps.python.org/pep-0728/#reference-implementation +""" ENCODE_METHOD: Final = ''' class _EncodingMixin: - def encode({method_args}) -> Self: + def encode(self, *args: Any, {method_args}) -> Self: """Map properties of the data to visual properties of the chart (see :class:`FacetedEncoding`) {docstring}""" # Compat prep for `infer_encoding_types` signature @@ -238,20 +297,14 @@ def encode({method_args}) -> Self: return copy ''' -ENCODE_TYPED_DICT: Final = ''' -class EncodeKwds(TypedDict, total=False): - """Encoding channels map properties of the data to visual properties of the chart. - {docstring}""" - {channels} - -''' # NOTE: Not yet reasonable to generalize `TypeAliasType`, `TypeVar` # Revisit if this starts to become more common TYPING_EXTRA: Final = ''' T = TypeVar("T") OneOrSeq = TypeAliasType("OneOrSeq", Union[T, Sequence[T]], type_params=(T,)) -"""One of ``T`` specified type(s), or a `Sequence` of such. +""" +One of ``T`` specified type(s), or a `Sequence` of such. Examples -------- @@ -264,8 +317,84 @@ def func( long: Union[str, bool, float, Sequence[Union[str, bool, float]], ): ... """ + +class Value(TypedDict, Generic[T]): + """ + A `Generic`_ single item ``dict``. + + Parameters + ---------- + value: T + Wrapped value. + + .. _Generic: + https://typing.readthedocs.io/en/latest/spec/generics.html#generics + """ + + value: T + + +ColorHex = Annotated[ + LiteralString, + re.compile(r"#[0-9a-f]{2}[0-9a-f]{2}[0-9a-f]{2}([0-9a-f]{2})?", re.IGNORECASE), +] +""" +A `hexadecimal`_ color code. + +Corresponds to the ``json-schema`` string format: + + {"format": "color-hex", "type": "string"} + +Examples +-------- +: + + "#f0f8ff" + "#7fffd4" + "#000000" + "#0000FF" + "#0000ff80" + +.. _hexadecimal: + https://www.w3schools.com/html/html_colors_hex.asp +""" + +def is_color_hex(obj: Any) -> TypeIs[ColorHex]: + """Return ``True`` if the object is a hexadecimal color code.""" + # NOTE: Extracts compiled pattern from metadata, + # to avoid defining in multiple places. + it = iter(get_args(ColorHex)) + next(it) + pattern: re.Pattern[str] = next(it) + return bool(pattern.fullmatch(obj)) + + + +class RowColKwds(TypedDict, Generic[T], total=False): + """ + A `Generic`_ two-item ``dict``. + + Parameters + ---------- + column: T + row: T + + .. _Generic: + https://typing.readthedocs.io/en/latest/spec/generics.html#generics + """ + + column: T + row: T + + +class PaddingKwds(TypedDict, total=False): + bottom: float + left: float + right: float + top: float ''' +_ChannelType = Literal["field", "datum", "value"] INTO_CONDITION: Literal["IntoCondition"] = "IntoCondition" @@ -280,28 +409,6 @@ class {classname}({basename}): ''' ) - @staticmethod - def _process_description(description: str) -> str: - return process_description(description) - - -def process_description(description: str) -> str: - # remove formatting from links - description = "".join( - [ - reSpecial.sub("", d) if i % 2 else d - for i, d in enumerate(reLink.split(description)) - ] - ) - description = rst_parse(description) - # Some entries in the Vega-Lite schema miss the second occurence of '__' - description = description.replace("__Default value: ", "__Default value:__ ") - # Fixing ambiguous unicode, RUF001 produces RUF002 in docs - description = description.replace("’", "'") # noqa: RUF001 [RIGHT SINGLE QUOTATION MARK] - description = description.replace("–", "-") # noqa: RUF001 [EN DASH] - description = description.replace(" ", " ") # noqa: RUF001 [NO-BREAK SPACE] - return description.strip() - class FieldSchemaGenerator(SchemaGenerator): schema_class_template = textwrap.dedent( @@ -365,7 +472,7 @@ def download_schemafile( url = schema_url(version=version) schemadir = Path(schemapath) schemadir.mkdir(parents=True, exist_ok=True) - fp = schemadir / "vega-lite-schema.json" + fp = schemadir / SCHEMA_FILE if not skip_download: request.urlretrieve(url, fp) elif not fp.exists(): @@ -374,8 +481,19 @@ def download_schemafile( return fp +def _vega_lite_props_only( + themes: dict[str, dict[str, Any]], props: SchemaProperties, / +) -> Iterator[tuple[str, dict[str, Any]]]: + """Removes properties that are allowed in `Vega` but not `Vega-Lite` from theme definitions.""" + keep = props.keys() + for name, theme_spec in themes.items(): + yield name, {k: v for k, v in theme_spec.items() if k in keep} + + def update_vega_themes(fp: Path, /, indent: str | int | None = 2) -> None: - themes = vlc.get_themes() + root = load_schema(fp.parent / SCHEMA_FILE) + vl_props = SchemaInfo.from_refname("Config", root).properties + themes = dict(_vega_lite_props_only(vlc.get_themes(), vl_props)) data = json.dumps(themes, indent=indent, sort_keys=True) fp.write_text(data, encoding="utf8") @@ -383,36 +501,33 @@ def update_vega_themes(fp: Path, /, indent: str | int | None = 2) -> None: TypeAliasTracer.update_aliases(("VegaThemes", spell_literal(theme_names))) -def load_schema_with_shorthand_properties(schemapath: Path) -> dict: - with schemapath.open(encoding="utf8") as f: - schema = json.load(f) - - schema = _add_shorthand_property_to_field_encodings(schema) - return schema +def load_schema(fp: Path, /) -> dict[str, Any]: + """Reads and returns the root schema from ``fp``.""" + with fp.open(encoding="utf8") as f: + root_schema = json.load(f) + return root_schema -def _add_shorthand_property_to_field_encodings(schema: dict) -> dict: +def load_schema_with_shorthand_properties(fp: Path, /) -> dict[str, Any]: + schema = load_schema(fp) encoding_def = "FacetedEncoding" - encoding = SchemaInfo(schema["definitions"][encoding_def], rootschema=schema) - - for _, propschema in encoding.properties.items(): + shorthand = { + "anyOf": [ + {"type": "string"}, + {"type": "array", "items": {"type": "string"}}, + {"$ref": "#/definitions/RepeatRef"}, + ], + "description": "shorthand for field, aggregate, and type", + } + for propschema in encoding.properties.values(): def_dict = get_field_datum_value_defs(propschema, schema) - - field_ref = def_dict.get("field") - if field_ref is not None: - defschema = {"$ref": field_ref} + if field_ref := def_dict.get("field", None): + defschema: dict[str, Any] = {"$ref": field_ref} defschema = copy.deepcopy(resolve_references(defschema, schema)) # For Encoding field definitions, we patch the schema by adding the # shorthand property. - defschema["properties"]["shorthand"] = { - "anyOf": [ - {"type": "string"}, - {"type": "array", "items": {"type": "string"}}, - {"$ref": "#/definitions/RepeatRef"}, - ], - "description": "shorthand for field, aggregate, and type", - } + defschema["properties"]["shorthand"] = shorthand if "required" not in defschema: defschema["required"] = ["shorthand"] elif "shorthand" not in defschema["required"]: @@ -431,7 +546,7 @@ def copy_schemapi_util() -> None: with source_fp.open(encoding="utf8") as source, destination_fp.open( "w", encoding="utf8" ) as dest: - dest.write(HEADER) + dest.write(HEADER_COMMENT) dest.writelines(source.readlines()) if sys.platform == "win32": ruff_format_py(destination_fp) @@ -453,9 +568,14 @@ def recursive_dict_update(schema: dict, root: dict, def_dict: dict) -> None: recursive_dict_update(sub_schema, root, def_dict) -def get_field_datum_value_defs(propschema: SchemaInfo, root: dict) -> dict[str, str]: - def_dict: dict[str, str | None] = dict.fromkeys(("field", "datum", "value")) - schema = propschema.schema +def get_field_datum_value_defs( + propschema: SchemaInfo, root: dict[str, Any] +) -> dict[_ChannelType, str]: + def_dict: dict[_ChannelType, str | None] = dict.fromkeys( + ("field", "datum", "value") + ) + _schema = propschema.schema + schema = _schema if isinstance(_schema, dict) else dict(_schema) if propschema.is_reference() and "properties" in schema: if "field" in schema["properties"]: def_dict["field"] = propschema.ref @@ -499,14 +619,13 @@ def visit(nodes): return stack -def generate_vegalite_schema_wrapper(schema_file: Path) -> str: +def generate_vegalite_schema_wrapper(fp: Path, /) -> str: """Generate a schema wrapper at the given path.""" # TODO: generate simple tests for each wrapper basename = "VegaLiteSchema" - - rootschema = load_schema_with_shorthand_properties(schema_file) - + rootschema = load_schema_with_shorthand_properties(fp) definitions: dict[str, SchemaGenerator] = {} + graph: dict[str, list[str]] = {} for name in rootschema["definitions"]: defschema = {"$ref": "#/definitions/" + name} @@ -520,9 +639,6 @@ def generate_vegalite_schema_wrapper(schema_file: Path) -> str: basename=basename, rootschemarepr=CodeSnippet(f"{basename}._rootschema"), ) - - graph: dict[str, list[str]] = {} - for name, schema in definitions.items(): graph[name] = [] for child_name in schema.subclasses(): @@ -542,22 +658,20 @@ def generate_vegalite_schema_wrapper(schema_file: Path) -> str: EXCLUDE = {"Color", "Text", "LookupData", "Dict", "FacetMapping"} it = (c for c in definitions.keys() - EXCLUDE if not c.startswith("_")) all_ = [*sorted(it), "Root", "VegaLiteSchema", "SchemaBase", "load_schema"] - contents = [ HEADER, - "from __future__ import annotations\n" "from typing import Any, Literal, Union, Protocol, Sequence, List, Iterator, TYPE_CHECKING", "import pkgutil", "import json\n", "from narwhals.dependencies import is_pandas_dataframe as _is_pandas_dataframe", "from altair.utils.schemapi import SchemaBase, Undefined, UndefinedType, _subclasses # noqa: F401\n", - _type_checking_only_imports( + import_type_checking( "from altair import Parameter", "from altair.typing import Optional", "from ._typing import * # noqa: F403", ), "\n" f"__all__ = {all_}\n", - LOAD_SCHEMA.format(schemafile="vega-lite-schema.json"), + LOAD_SCHEMA.format(schemafile=SCHEMA_FILE), BASE_SCHEMA.format(basename=basename), schema_class( "Root", @@ -574,14 +688,6 @@ def generate_vegalite_schema_wrapper(schema_file: Path) -> str: return "\n".join(contents) -def _type_checking_only_imports(*imports: str) -> str: - return ( - "\n# ruff: noqa: F405\nif TYPE_CHECKING:\n" - + "\n".join(f" {s}" for s in imports) - + "\n" - ) - - @dataclass class ChannelInfo: supports_arrays: bool @@ -611,22 +717,15 @@ def non_field_names(self) -> Iterator[str]: yield self.value_class_name -def generate_vegalite_channel_wrappers( - schemafile: Path, version: str, imports: list[str] | None = None -) -> str: - schema = load_schema_with_shorthand_properties(schemafile) - +def generate_vegalite_channel_wrappers(fp: Path, /) -> str: + schema = load_schema_with_shorthand_properties(fp) encoding_def = "FacetedEncoding" - encoding = SchemaInfo(schema["definitions"][encoding_def], rootschema=schema) - channel_infos: dict[str, ChannelInfo] = {} - - class_defs = [] + class_defs: list[Any] = [] for prop, propschema in encoding.properties.items(): def_dict = get_field_datum_value_defs(propschema, schema) - supports_arrays = any( schema_info.is_array() for schema_info in propschema.anyOf ) @@ -643,7 +742,7 @@ def generate_vegalite_channel_wrappers( gen: SchemaGenerator defschema = {"$ref": definition} - kwds = { + kwds: dict[str, Any] = { "basename": basename, "schema": defschema, "rootschema": schema, @@ -660,6 +759,8 @@ def generate_vegalite_channel_wrappers( temp_name = f"{classname}Value" channel_info.value_class_name = temp_name gen = ValueSchemaGenerator(temp_name, nodefault=["value"], **kwds) + else: + raise NotImplementedError class_defs.append(gen.schema_class()) @@ -672,14 +773,12 @@ def generate_vegalite_channel_wrappers( "ValueChannelMixin", "with_property_setters", ) - it = chain.from_iterable(info.all_names for info in channel_infos.values()) all_ = list(chain(it, COMPAT_EXPORTS)) - - imports = imports or [ - "from __future__ import annotations\n", + imports = [ + "import sys", "from typing import Any, overload, Sequence, List, Literal, Union, TYPE_CHECKING, TypedDict", - "from typing_extensions import TypeAlias", + import_typing_extensions((3, 10), "TypeAlias"), "import narwhals.stable.v1 as nw", "from altair.utils.schemapi import Undefined, with_property_setters", "from altair.utils import infer_encoding_types as _infer_encoding_types", @@ -691,109 +790,215 @@ def generate_vegalite_channel_wrappers( HEADER, CHANNEL_MYPY_IGNORE_STATEMENTS, *imports, - _type_checking_only_imports( + import_type_checking( "from altair import Parameter, SchemaBase", "from altair.typing import Optional", - "from typing_extensions import Self", f"from altair.vegalite.v5.api import {INTO_CONDITION}", + textwrap.indent(import_typing_extensions((3, 11), "Self"), " "), ), "\n" f"__all__ = {sorted(all_)}\n", CHANNEL_MIXINS, *class_defs, - *generate_encoding_artifacts(channel_infos, ENCODE_METHOD, ENCODE_TYPED_DICT), + *generate_encoding_artifacts( + channel_infos, ENCODE_METHOD, facet_encoding=encoding + ), ] return "\n".join(contents) -def generate_vegalite_mark_mixin( - schemafile: Path, markdefs: dict[str, str] -) -> tuple[list[str], str]: - with schemafile.open(encoding="utf8") as f: - schema = json.load(f) - - class_name = "MarkMethodMixin" - - imports = [ - "from typing import Any, Sequence, List, Literal, Union", - "", - "from altair.utils.schemapi import Undefined, UndefinedType", - "from . import core", - ] - - code = [ - f"class {class_name}:", - ' """A mixin class that defines mark methods"""', - ] +def generate_vegalite_mark_mixin(fp: Path, /, markdefs: dict[str, str]) -> str: + schema = load_schema(fp) + code: list[str] = [] for mark_enum, mark_def in markdefs.items(): - if "enum" in schema["definitions"][mark_enum]: - marks = schema["definitions"][mark_enum]["enum"] - else: - marks = [schema["definitions"][mark_enum]["const"]] - info = SchemaInfo({"$ref": f"#/definitions/{mark_def}"}, rootschema=schema) - - # adapted from SchemaInfo.init_code - arg_info = codegen.get_args(info) - arg_info.required -= {"type"} - arg_info.kwds -= {"type"} - - def_args = ["self"] + [ - f"{p}: " - + info.properties[p].get_python_type_representation( - for_type_hints=True, - additional_type_hints=["UndefinedType"], - ) - + " = Undefined" - for p in (sorted(arg_info.required) + sorted(arg_info.kwds)) - ] - dict_args = [ - f"{p}={p}" for p in (sorted(arg_info.required) + sorted(arg_info.kwds)) - ] - - if arg_info.additional or arg_info.invalid_kwds: - def_args.append("**kwds") - dict_args.append("**kwds") + _def = schema["definitions"][mark_enum] + marks: list[Any] = _def["enum"] if "enum" in _def else [_def["const"]] + info = SchemaInfo.from_refname(mark_def, rootschema=schema) + mark_args = generate_mark_args(info) for mark in marks: # TODO: only include args relevant to given type? - mark_method = MARK_METHOD.format( - mark=mark, - mark_def=mark_def, - def_arglist=", ".join(def_args), - dict_arglist=", ".join(dict_args), - ) + mark_method = MARK_METHOD.format(mark=mark, mark_def=mark_def, **mark_args) code.append("\n ".join(mark_method.splitlines())) - return imports, "\n".join(code) + return MARK_MIXIN.format(methods="\n".join(code)) -def generate_vegalite_config_mixin(schemafile: Path) -> tuple[list[str], str]: - imports = [ - "from . import core", - "from altair.utils import use_signature", - ] +def generate_mark_args( + info: SchemaInfo, / +) -> dict[Literal["method_args", "dict_args"], str]: + args = codegen.get_args(info) + method_args: deque[str] = deque() + dict_args: deque[str] = deque() + for p, p_info in args.iter_args(arg_required_kwds, exclude="type"): + dict_args.append(f"{p}={p}") + method_args.append( + f"{p}: {p_info.to_type_repr(target='annotation', use_undefined=True)} = Undefined" + ) + return {"method_args": ", ".join(method_args), "dict_args": ", ".join(dict_args)} - class_name = "ConfigMethodMixin" +def generate_typed_dict( + info: SchemaInfo, + name: str, + *, + summary: str | None = None, + groups: Iterable[str] | AttrGetter[ArgInfo, set[str]] = arg_required_kwds, + exclude: str | Iterable[str] | None = None, + override_args: Iterable[str] | None = None, +) -> str: + """ + Return a fully typed & documented ``TypedDict``. + + Parameters + ---------- + info + JSON Schema wrapper. + name + Full target class name. + Include a pre/post-fix if ``SchemaInfo.title`` already exists. + summary + When provided, used instead of generated summary line. + groups + A subset of ``ArgInfo``, or a callable that can derive one. + exclude + Property name(s) to omit if they appear during iteration. + override_args + When provided, used instead of any ``ArgInfo`` related handling. + + .. note:: + See ``EncodeKwds``. + + Notes + ----- + - Internally handles keys that are not valid python identifiers + - The union of their types will be added to ``__extra_items__`` + """ + TARGET: Literal["annotation"] = "annotation" + arg_info = codegen.get_args(info) + metaclass_kwds = ", total=False" + comment = "" + args_it: Iterable[str] = ( + ( + f"{p}: {p_info.to_type_repr(target=TARGET, use_concrete=True)}" + for p, p_info in arg_info.iter_args(groups, exclude=exclude) + ) + if override_args is None + else override_args + ) + args = "\n ".join(args_it) + doc = indent_docstring( + chain.from_iterable( + (p, f" {p_info.deep_description}") + for p, p_info in arg_info.iter_args(groups, exclude=exclude) + ), + indent_level=4, + ) + # NOTE: The RHS eager eval is used to skip `invalid_kwds`, + # if they have been marked for exclusion + if (kwds := arg_info.invalid_kwds) and list( + arg_info.iter_args(kwds, exclude=exclude) + ): + metaclass_kwds = f", closed=True{metaclass_kwds}" + comment = " # type: ignore[call-arg]" + kwds_all_tps = chain.from_iterable( + info.to_type_repr(as_str=False, target=TARGET, use_concrete=True) + for _, info in arg_info.iter_args(kwds, exclude=exclude) + ) + args = ( + f"{args}\n " + f"__extra_items__: {finalize_type_reprs(kwds_all_tps, target=TARGET)}" + ) + doc = ( + f"{doc}\n" f"{EXTRA_ITEMS_MESSAGE.format(invalid_kwds=repr(sorted(kwds)))}" + ) + + return UNIVERSAL_TYPED_DICT.format( + name=name, + metaclass_kwds=metaclass_kwds, + comment=comment, + summary=summary or f"{rst_syntax_for_class(info.title)} ``TypedDict`` wrapper.", + doc=doc, + td_args=args, + ) + + +def generate_config_typed_dicts(fp: Path, /) -> Iterator[str]: + KWDS: Literal["Kwds"] = "Kwds" + CONFIG: Literal["Config"] = "Config" + TOP_LEVEL: Literal["TopLevelUnitSpec"] = "TopLevelUnitSpec" + TOP_LEVEL_EXTRAS = ( + "Step", + "Projection", + "Resolve", + "TitleParams", + "ViewBackground", + ) + TOP_LEVEL_EXCLUDE = {"$schema", "data", "datasets", "encoding", "transform"} + root = load_schema(fp) + config = SchemaInfo.from_refname(CONFIG, root) + theme_targets = find_theme_config_targets(config) + for name in TOP_LEVEL_EXTRAS: + theme_targets.update( + find_theme_config_targets(SchemaInfo.from_refname(name, root)) + ) + + relevant: dict[str, SchemaInfo] = { + x.title: x for x in sorted(theme_targets, key=attrgetter("refname")) + } + + SchemaInfo._remap_title.update( + {"HexColor": ("ColorHex",), "Padding": ("float", PADDING_KWDS)} + ) + SchemaInfo._remap_title.update((k, (f"{k}{KWDS}",)) for k in relevant) + config_sub: Iterator[str] = ( + generate_typed_dict(info, name=f"{info.title}{KWDS}") + for info in relevant.values() + ) + config_sub_names = (f"{nm}{KWDS}" for nm in relevant) + yield f"__all__ = {[*config_sub_names, PADDING_KWDS, ROW_COL_KWDS, THEME_CONFIG]}\n\n" + yield "\n".join(config_sub) + yield generate_typed_dict( + SchemaInfo.from_refname(TOP_LEVEL, root), + THEME_CONFIG, + summary=THEME_CONFIG_SUMMARY, + groups=arg_kwds, + exclude=TOP_LEVEL_EXCLUDE, + ) + + +def find_theme_config_targets(info: SchemaInfo, depth: int = 0, /) -> set[SchemaInfo]: + """Equivalent to `get_all_objects`.""" + MAX_DEPTH = 6 + seen: set[SchemaInfo] = set() + if info.is_theme_config_target() and info not in seen: + seen.add(info) + if depth < MAX_DEPTH: + for prop_info in info.iter_descendants(): + seen.update(find_theme_config_targets(prop_info, depth + 1)) + return seen + + +def generate_vegalite_config_mixin(fp: Path, /) -> str: + class_name = "ConfigMethodMixin" + CONFIG: Literal["Config"] = "Config" code = [ f"class {class_name}:", ' """A mixin class that defines config methods"""', ] - with schemafile.open(encoding="utf8") as f: - schema = json.load(f) - info = SchemaInfo({"$ref": "#/definitions/Config"}, rootschema=schema) + info = SchemaInfo.from_refname(CONFIG, rootschema=load_schema(fp)) # configure() method - method = CONFIG_METHOD.format(classname="Config", method="configure") + method = CONFIG_METHOD.format(classname=CONFIG, method="configure") code.append("\n ".join(method.splitlines())) # configure_prop() methods for prop, prop_info in info.properties.items(): classname = prop_info.refname - if classname and classname.endswith("Config"): + if classname and classname.endswith(CONFIG): method = CONFIG_PROP_METHOD.format(classname=classname, prop=prop) code.append("\n ".join(method.splitlines())) - return imports, "\n".join(code) + return "\n".join(code) def vegalite_main(skip_download: bool = False) -> None: @@ -807,7 +1012,7 @@ def vegalite_main(skip_download: bool = False) -> None: skip_download=skip_download, ) - fp_themes = schemapath / "vega-themes.json" + fp_themes = schemapath / THEMES_FILE print(f"Updating themes\n {schemafile!s}\n ->{fp_themes!s}") update_vega_themes(fp_themes) @@ -834,33 +1039,31 @@ def vegalite_main(skip_download: bool = False) -> None: # Generate the channel wrappers fp_channels = schemapath / "channels.py" print(f"Generating\n {schemafile!s}\n ->{fp_channels!s}") - files[fp_channels] = generate_vegalite_channel_wrappers(schemafile, version=version) + files[fp_channels] = generate_vegalite_channel_wrappers(schemafile) # generate the mark mixin markdefs = {k: f"{k}Def" for k in ["Mark", "BoxPlot", "ErrorBar", "ErrorBand"]} fp_mixins = schemapath / "mixins.py" print(f"Generating\n {schemafile!s}\n ->{fp_mixins!s}") - mark_imports, mark_mixin = generate_vegalite_mark_mixin(schemafile, markdefs) - config_imports, config_mixin = generate_vegalite_config_mixin(schemafile) - try_except_imports = [ - "if sys.version_info >= (3, 11):", - " from typing import Self", - "else:", - " from typing_extensions import Self", - ] - stdlib_imports = ["from __future__ import annotations\n", "import sys"] + mixins_imports = ( + "from typing import Any, Sequence, List, Literal, Union", + "from altair.utils import use_signature, Undefined", + "from . import core", + ) + + mark_mixin = generate_vegalite_mark_mixin(schemafile, markdefs) + config_mixin = generate_vegalite_config_mixin(schemafile) content_mixins = [ HEADER, - "\n".join(stdlib_imports), - "\n\n", - "\n".join(sorted({*mark_imports, *config_imports})), "\n\n", - "\n".join(try_except_imports), + "\n".join(mixins_imports), "\n\n", - _type_checking_only_imports( - "from altair import Parameter, SchemaBase", + import_type_checking( + "import sys", + textwrap.indent(import_typing_extensions((3, 11), "Self"), " "), "from altair.typing import Optional", "from ._typing import * # noqa: F403", + "from altair import Parameter, SchemaBase", ), "\n\n\n", mark_mixin, @@ -869,6 +1072,20 @@ def vegalite_main(skip_download: bool = False) -> None: ] files[fp_mixins] = content_mixins + # Generate theme-related Config hierarchy of TypedDict + fp_theme_config: Path = schemapath / "_config.py" + content_theme_config = [ + HEADER, + "from typing import Any, TYPE_CHECKING, Literal, Sequence, TypedDict, Union", + import_typing_extensions((3, 14), "TypedDict", include_sys=True), + f"from ._typing import {ROW_COL_KWDS}, {PADDING_KWDS}", + "\n\n", + import_type_checking("from ._typing import * # noqa: F403"), + "\n\n", + *generate_config_typed_dicts(schemafile), + ] + files[fp_theme_config] = content_theme_config + # Write `_typing.py` TypeAlias, for import in generated modules fp_typing = schemapath / "_typing.py" msg = ( @@ -877,7 +1094,15 @@ def vegalite_main(skip_download: bool = False) -> None: ) print(msg) TypeAliasTracer.write_module( - fp_typing, "OneOrSeq", header=HEADER, extra=TYPING_EXTRA + fp_typing, + "OneOrSeq", + "Value", + "ColorHex", + "is_color_hex", + ROW_COL_KWDS, + PADDING_KWDS, + header=HEADER, + extra=TYPING_EXTRA, ) # Write the pre-generated modules for fp, contents in files.items(): @@ -886,7 +1111,10 @@ def vegalite_main(skip_download: bool = False) -> None: def generate_encoding_artifacts( - channel_infos: dict[str, ChannelInfo], fmt_method: str, fmt_typed_dict: str + channel_infos: dict[str, ChannelInfo], + fmt_method: str, + *, + facet_encoding: SchemaInfo, ) -> Iterator[str]: """ Generate ``Chart.encode()`` and related typing structures. @@ -905,12 +1133,11 @@ def generate_encoding_artifacts( """ PREFIX_INTERNAL = "Any" PREFIX_EXPORT = "Channel" - signature_args: list[str] = ["self", "*args: Any"] + signature_args: list[str] = [] internal_aliases: list[str] = [] export_aliases: list[str] = [] typed_dict_args: list[str] = [] signature_doc_params: list[str] = ["", "Parameters", "----------"] - typed_dict_doc_params: list[str] = ["", "Parameters", "----------"] for channel, info in channel_infos.items(): channel_name = f"{channel[0].upper()}{channel[1:]}" @@ -945,18 +1172,19 @@ def generate_encoding_artifacts( typed_dict_args.append(f"{channel}: {tp_inner}") signature_args.append(f"{channel}: Optional[{tp_inner}] = Undefined") - description: str = f" {process_description(info.deep_description)}" + description: str = f" {info.deep_description}" signature_doc_params.extend((f"{channel} : {doc_types_flat}", description)) - typed_dict_doc_params.extend((f"{channel}", description)) method: str = fmt_method.format( method_args=", ".join(signature_args), docstring=indent_docstring(signature_doc_params, indent_level=8, lstrip=False), ) - typed_dict: str = fmt_typed_dict.format( - channels="\n ".join(typed_dict_args), - docstring=indent_docstring(typed_dict_doc_params, indent_level=4, lstrip=False), + typed_dict = generate_typed_dict( + facet_encoding, + ENCODE_KWDS, + summary=ENCODE_KWDS_SUMMARY, + override_args=typed_dict_args, ) artifacts: Iterable[str] = ( *internal_aliases, diff --git a/tools/schemapi/__init__.py b/tools/schemapi/__init__.py index 023a9a2af..55c5f4148 100644 --- a/tools/schemapi/__init__.py +++ b/tools/schemapi/__init__.py @@ -1,8 +1,24 @@ """schemapi: tools for generating Python APIs from JSON schemas.""" from tools.schemapi import codegen, utils -from tools.schemapi.codegen import CodeSnippet +from tools.schemapi.codegen import ( + CodeSnippet, + arg_invalid_kwds, + arg_kwds, + arg_required_kwds, +) from tools.schemapi.schemapi import SchemaBase, Undefined -from tools.schemapi.utils import SchemaInfo +from tools.schemapi.utils import OneOrSeq, SchemaInfo -__all__ = ["CodeSnippet", "SchemaBase", "SchemaInfo", "Undefined", "codegen", "utils"] +__all__ = [ + "CodeSnippet", + "OneOrSeq", + "SchemaBase", + "SchemaInfo", + "Undefined", + "arg_invalid_kwds", + "arg_kwds", + "arg_required_kwds", + "codegen", + "utils", +] diff --git a/tools/schemapi/codegen.py b/tools/schemapi/codegen.py index cf8ea81ba..5e6d3107b 100644 --- a/tools/schemapi/codegen.py +++ b/tools/schemapi/codegen.py @@ -3,9 +3,12 @@ from __future__ import annotations import re +import sys import textwrap from dataclasses import dataclass -from typing import Final +from itertools import chain +from operator import attrgetter +from typing import Any, Callable, Final, Iterable, Iterator, TypeVar, Union from .utils import ( SchemaInfo, @@ -14,9 +17,27 @@ indent_docstring, is_valid_identifier, jsonschema_to_python_types, + process_description, spell_literal, ) +if sys.version_info >= (3, 12): + from typing import TypeAliasType +else: + from typing_extensions import TypeAliasType + + +T1 = TypeVar("T1") +T2 = TypeVar("T2") +AttrGetter = TypeAliasType( + "AttrGetter", Callable[[T1], Union[T2, "tuple[T2, ...]"]], type_params=(T1, T2) +) +""" +Intended to model the signature of ``operator.attrgetter``. + +Spelled more generically to support future extension. +""" + class CodeSnippet: """Object whose repr() is a string of code.""" @@ -35,6 +56,64 @@ class ArgInfo: kwds: set[str] invalid_kwds: set[str] additional: bool + schema_info: SchemaInfo + + def iter_args( + self, + group: Iterable[str] | AttrGetter[ArgInfo, set[str]], + *more_groups: Iterable[str] | AttrGetter[ArgInfo, set[str]], + exclude: str | Iterable[str] | None = None, + ) -> Iterator[tuple[str, SchemaInfo]]: + r""" + Yields (property_name, property_info). + + Useful for signatures and docstrings. + + Parameters + ---------- + group, \*more_groups + Each group will independently sorted, and chained. + exclude + Property name(s) to omit if they appear during iteration. + """ + props = self.schema_info.properties + it = chain.from_iterable( + sorted(g) for g in self._normalize_groups(group, *more_groups) + ) + if exclude is not None: + exclude = {exclude} if isinstance(exclude, str) else set(exclude) + for p in it: + if p not in exclude: + yield p, props[p] + else: + for p in it: + yield p, props[p] + + def _normalize_groups( + self, *groups: Iterable[str] | AttrGetter[ArgInfo, set[str]] + ) -> Iterator[set[str]]: + for group in groups: + if isinstance(group, set): + yield group + elif isinstance(group, Iterable): + yield set(group) + elif callable(group): + result = group(self) + if isinstance(result, set): + yield result + else: + yield from result + else: + msg = ( + f"Expected all cases to be reducible to a `set[str]`," + f" but got {type(group).__name__!r}" + ) + raise TypeError(msg) + + +arg_required_kwds: AttrGetter[ArgInfo, set[str]] = attrgetter("required", "kwds") +arg_invalid_kwds: AttrGetter[ArgInfo, set[str]] = attrgetter("invalid_kwds") +arg_kwds: AttrGetter[ArgInfo, set[str]] = attrgetter("kwds") def get_args(info: SchemaInfo) -> ArgInfo: @@ -46,22 +125,9 @@ def get_args(info: SchemaInfo) -> ArgInfo: invalid_kwds: set[str] = set() # TODO: specialize for anyOf/oneOf? - - if info.is_allOf(): - # recursively call function on all children - arginfo = [get_args(child) for child in info.allOf] - nonkeyword = all(args.nonkeyword for args in arginfo) - required = set.union(set(), *(args.required for args in arginfo)) - kwds = set.union(set(), *(args.kwds for args in arginfo)) - kwds -= required - invalid_kwds = set.union(set(), *(args.invalid_kwds for args in arginfo)) - additional = all(args.additional for args in arginfo) - elif info.is_empty() or info.is_compound(): + if info.is_empty() or info.is_anyOf(): nonkeyword = True additional = True - elif info.is_value(): - nonkeyword = True - additional = False elif info.is_object(): invalid_kwds = {p for p in info.required if not is_valid_identifier(p)} | { p for p in info.properties if not is_valid_identifier(p) @@ -73,8 +139,19 @@ def get_args(info: SchemaInfo) -> ArgInfo: additional = True # additional = info.additionalProperties or info.patternProperties else: - msg = "Schema object not understood" - raise ValueError(msg) + nonkeyword = True + additional = False + if info.is_allOf(): + # recursively call function on all children + msg = f"Branch is reachable with:\n{info.raw_schema!r}" + raise NotImplementedError(msg) + arginfo: list[ArgInfo] = [get_args(child) for child in info.allOf] + nonkeyword = all(args.nonkeyword for args in arginfo) + required = {args.required for args in arginfo} + kwds = {args.kwds for args in arginfo} + kwds -= required + invalid_kwds = {args.invalid_kwds for args in arginfo} + additional = all(args.additional for args in arginfo) return ArgInfo( nonkeyword=nonkeyword, @@ -82,6 +159,7 @@ def get_args(info: SchemaInfo) -> ArgInfo: kwds=kwds, invalid_kwds=invalid_kwds, additional=additional, + schema_info=info, ) @@ -129,13 +207,10 @@ def __init__({arglist}): """ ).lstrip() - def _process_description(self, description: str): - return description - def __init__( self, classname: str, - schema: dict, + schema: dict[str, Any], rootschema: dict | None = None, basename: str | list[str] = "SchemaBase", schemarepr: object | None = None, @@ -154,19 +229,24 @@ def __init__( self.haspropsetters = haspropsetters self.kwargs = kwargs - def subclasses(self) -> list[str]: - """Return a list of subclass names, if any.""" - info = SchemaInfo(self.schema, self.rootschema) - return [child.refname for child in info.anyOf if child.is_reference()] + def subclasses(self) -> Iterator[str]: + """ + Return an Iterator over subclass names, if any. + + NOTE + ---- + *Does not represent subclasses**. + + Represents a ``Union`` of schemas (``SchemaInfo.anyOf``). + """ + for child in SchemaInfo(self.schema, self.rootschema).anyOf: + if child.is_reference(): + yield child.refname def schema_class(self) -> str: """Generate code for a schema class.""" - rootschema: dict = ( - self.rootschema if self.rootschema is not None else self.schema - ) - schemarepr: object = ( - self.schemarepr if self.schemarepr is not None else self.schema - ) + rootschema: dict = self.rootschema or self.schema + schemarepr: object = self.schemarepr or self.schema rootschemarepr = self.rootschemarepr if rootschemarepr is None: if rootschema is self.schema: @@ -204,7 +284,7 @@ def docstring(self, indent: int = 0) -> str: # https://numpydoc.readthedocs.io/en/latest/format.html#extended-summary # Remove condition from description desc: str = re.sub(r"\n\{\n(\n|.)*\n\}", "", info.description) - ext_summary: list[str] = self._process_description(desc).splitlines() + ext_summary: list[str] = process_description(desc).splitlines() # Remove lines which contain the "raw-html" directive which cannot be processed # by Sphinx at this level of the docstring. It works for descriptions # of attributes which is why we do not do the same below. The removed @@ -217,17 +297,13 @@ def docstring(self, indent: int = 0) -> str: if info.properties: arg_info = self.arg_info - doc += ["", "Parameters", "----------", ""] - for prop in ( - sorted(arg_info.required) - + sorted(arg_info.kwds) - + sorted(arg_info.invalid_kwds) - ): - propinfo = info.properties[prop] - doc += [ - f"{prop} : {propinfo.get_python_type_representation()}", - f" {self._process_description(propinfo.deep_description)}", - ] + it = chain.from_iterable( + (f"{p} : {p_info.to_type_repr()}", f" {p_info.deep_description}") + for p, p_info in arg_info.iter_args( + arg_info.required, arg_kwds, arg_invalid_kwds + ) + ) + doc.extend(chain(["", "Parameters", "----------", ""], it)) return indent_docstring(doc, indent_level=indent, width=100, lstrip=True) def init_code(self, indent: int = 0) -> str: @@ -243,10 +319,7 @@ def init_code(self, indent: int = 0) -> str: initfunc = ("\n" + indent * " ").join(initfunc.splitlines()) return initfunc - def init_args( - self, additional_types: list[str] | None = None - ) -> tuple[list[str], list[str]]: - additional_types = additional_types or [] + def init_args(self) -> tuple[list[str], list[str]]: info = self.info arg_info = self.arg_info @@ -257,32 +330,23 @@ def init_args( args: list[str] = ["self"] super_args: list[str] = [] - self.init_kwds = sorted(arg_info.kwds) + self.init_kwds: list[str] = sorted(arg_info.kwds) + init_required: list[str] = sorted(arg_info.required) + _nodefault: list[str] = sorted(nodefault) if nodefault: - args.extend(sorted(nodefault)) + args.extend(_nodefault) elif arg_info.nonkeyword: args.append("*args") super_args.append("*args") - args.extend( - f"{p}: Optional[Union[" - + ", ".join( - [ - *additional_types, - *info.properties[p].get_python_type_representation( - for_type_hints=True, return_as_str=False - ), - ] - ) - + "]] = Undefined" - for p in sorted(arg_info.required) + sorted(arg_info.kwds) + it = ( + f"{p}: {info.properties[p].to_type_repr(target='annotation', use_undefined=True)} = Undefined" + for p in chain(init_required, self.init_kwds) ) + args.extend(it) super_args.extend( - f"{p}={p}" - for p in sorted(nodefault) - + sorted(arg_info.required) - + sorted(arg_info.kwds) + f"{p}={p}" for p in chain(_nodefault, init_required, self.init_kwds) ) if arg_info.additional: @@ -302,16 +366,10 @@ def get_args(self, si: SchemaInfo) -> list[str]: if prop_infos: contents.extend( - [ - f"{p}: " - + info.get_python_type_representation( - for_type_hints=True, additional_type_hints=["UndefinedType"] - ) - + " = Undefined" - for p, info in prop_infos.items() - ] + f"{p}: {info.to_type_repr(target='annotation', use_undefined=True)} = Undefined" + for p, info in prop_infos.items() ) - elif si.type: + elif isinstance(si.type, str): py_type = jsonschema_to_python_types[si.type] if py_type == "list": # Try to get a type hint like "List[str]" which is more specific @@ -375,6 +433,6 @@ def method_code(self, indent: int = 0) -> str | None: if not self.haspropsetters: return None args = self.init_kwds - type_hints = [hint for a in args for hint in self.setter_hint(a, indent)] + type_hints = (hint for a in args for hint in self.setter_hint(a, indent)) return ("\n" + indent * " ").join(type_hints) diff --git a/tools/schemapi/utils.py b/tools/schemapi/utils.py index 3fa304925..5c4a84f9c 100644 --- a/tools/schemapi/utils.py +++ b/tools/schemapi/utils.py @@ -2,22 +2,28 @@ from __future__ import annotations -import keyword +import json import re import subprocess +import sys import textwrap -import urllib +import urllib.parse from html import unescape from itertools import chain +from keyword import iskeyword from operator import itemgetter from typing import ( TYPE_CHECKING, Any, - Final, + ClassVar, Iterable, Iterator, Literal, + Mapping, + MutableSequence, Sequence, + TypeVar, + Union, overload, ) @@ -27,14 +33,39 @@ from tools.schemapi.schemapi import _resolve_references as resolve_references if TYPE_CHECKING: + from _collections_abc import KeysView from pathlib import Path - from typing_extensions import LiteralString + from re import Pattern from mistune import BlockState -EXCLUDE_KEYS: Final = ("definitions", "title", "description", "$schema", "id") - -jsonschema_to_python_types = { +if sys.version_info >= (3, 12): + from typing import TypeAliasType +else: + from typing_extensions import TypeAliasType +if sys.version_info >= (3, 11): + from typing import LiteralString, Never +else: + from typing_extensions import LiteralString, Never +if sys.version_info >= (3, 10): + from typing import TypeAlias +else: + from typing_extensions import TypeAlias + +T = TypeVar("T") + +OneOrSeq = TypeAliasType("OneOrSeq", Union[T, Sequence[T]], type_params=(T,)) +TargetType: TypeAlias = Literal["annotation", "doc"] + +EXCLUDE_KEYS: frozenset[ + Literal["definitions", "title", "description", "$schema", "id"] +] = frozenset(("definitions", "title", "description", "$schema", "id")) +COMPOUND_KEYS: tuple[Literal["anyOf"], Literal["oneOf"], Literal["allOf"]] = ( + "anyOf", + "oneOf", + "allOf", +) +jsonschema_to_python_types: dict[str, str] = { "string": "str", "number": "float", "integer": "int", @@ -44,6 +75,14 @@ "null": "None", } +_VALID_IDENT: Pattern[str] = re.compile(r"^[^\d\W]\w*\Z", re.ASCII) +_RE_LINK: Pattern[str] = re.compile(r"(?<=\[)([^\]]+)(?=\]\([^\)]+\))", re.MULTILINE) +_RE_SPECIAL: Pattern[str] = re.compile(r"[*_]{2,3}|`", re.MULTILINE) +_RE_LIST_MISSING_ASTERISK: Pattern[str] = re.compile(r"^-(?=[ `\"a-z])", re.MULTILINE) +_RE_LIST_MISSING_WHITESPACE: Pattern[str] = re.compile(r"^\*(?=[`\"a-z])", re.MULTILINE) + +_HASH_ENCODER = json.JSONEncoder(sort_keys=True, separators=(",", ":")) + class _TypeAliasTracer: """ @@ -89,8 +128,17 @@ def __init__( self._aliases: dict[str, str] = {} self._imports: Sequence[str] = ( "from __future__ import annotations\n", - "from typing import Any, Literal, Mapping, TypeVar, Sequence, Union", - "from typing_extensions import TypeAlias, TypeAliasType", + "import sys", + "from typing import Any, Generic, Literal, Mapping, TypeVar, Sequence, Union", + "import re", + import_typing_extensions( + (3, 14), "TypedDict", reason="https://peps.python.org/pep-0728/" + ), + import_typing_extensions((3, 13), "TypeIs"), + import_typing_extensions((3, 12), "TypeAliasType"), + import_typing_extensions((3, 11), "LiteralString"), + import_typing_extensions((3, 10), "TypeAlias"), + import_typing_extensions((3, 9), "Annotated", "get_args"), ) self._cmd_check: list[str] = ["--fix"] self._cmd_format: Sequence[str] = ruff_format or () @@ -118,7 +166,7 @@ def add_literal( self._update_literals(alias, tp) if replace: tp = alias - elif (alias := self._literals_invert.get(tp)) and replace: + elif (alias := self._literals_invert.get(tp, "")) and replace: tp = alias elif replace and info.is_union_literal(): # Handles one very specific edge case `WindowFieldDef` @@ -153,13 +201,15 @@ def generate_aliases(self) -> Iterator[str]: for name, statement in self._aliases.items(): yield f"{name}: TypeAlias = {statement}" - def is_cached(self, tp: str, /) -> bool: + def is_cached(self, tp: str, /, *, include_concrete: bool = False) -> bool: """ Applies to both docstring and type hints. Currently used as a sort key, to place literals/aliases last. """ - return tp in self._literals_invert or tp in self._literals or tp in self._aliases # fmt: skip + return ( + tp in self._literals_invert or tp in self._literals or tp in self._aliases + ) or (include_concrete and self.fmt.format(tp) in self._literals) def write_module( self, fp: Path, *extra_all: str, header: LiteralString, extra: LiteralString @@ -178,10 +228,13 @@ def write_module( extra `tools.generate_schema_wrapper.TYPING_EXTRA`. """ - ruff_format = ["ruff", "format", fp] + ruff_format: MutableSequence[str | Path] = ["ruff", "format", fp] if self._cmd_format: ruff_format.extend(self._cmd_format) - commands = (["ruff", "check", fp, *self._cmd_check], ruff_format) + commands: tuple[Sequence[str | Path], ...] = ( + ["ruff", "check", fp, *self._cmd_check], + ruff_format, + ) static = (header, "\n", *self._imports, "\n\n") self.update_aliases(*sorted(self._literals.items(), key=itemgetter(0))) all_ = [*iter(self._aliases), *extra_all] @@ -201,18 +254,6 @@ def n_entries(self) -> int: return len(self._literals) -TypeAliasTracer: _TypeAliasTracer = _TypeAliasTracer("{}_T", "I001", "I002") -"""An instance of `_TypeAliasTracer`. - -Collects a cache of unique `Literal` types used globally. - -These are then converted to `TypeAlias` statements, written to another module. - -Allows for a single definition to be reused multiple times, -rather than repeating long literals in every method definition. -""" - - def get_valid_identifier( prop: str, replacement_character: str = "", @@ -271,25 +312,14 @@ def get_valid_identifier( valid = "_" + valid # if the result is a reserved keyword, then add an underscore at the end - if keyword.iskeyword(valid): + if iskeyword(valid): valid += "_" return valid -def is_valid_identifier(var: str, allow_unicode: bool = False): - """ - Return true if var contains a valid Python identifier. - - Parameters - ---------- - val : string - identifier to check - allow_unicode : bool (default: False) - if True, then allow Python 3 style unicode identifiers. - """ - flags = re.UNICODE if allow_unicode else re.ASCII - is_valid = re.match(r"^[^\d\W]\w*\Z", var, flags) - return is_valid and not keyword.iskeyword(var) +def is_valid_identifier(s: str, /) -> bool: + """Return ``True`` if ``s`` contains a valid Python identifier.""" + return _VALID_IDENT.match(s) is not None and not iskeyword(s) class SchemaProperties: @@ -297,13 +327,13 @@ class SchemaProperties: def __init__( self, - properties: dict[str, Any], - schema: dict, - rootschema: dict | None = None, + properties: Mapping[str, Any], + schema: Mapping[str, Any], + rootschema: Mapping[str, Any] | None = None, ) -> None: - self._properties = properties - self._schema = schema - self._rootschema = rootschema or schema + self._properties: Mapping[str, Any] = properties + self._schema: Mapping[str, Any] = schema + self._rootschema: Mapping[str, Any] = rootschema or schema def __bool__(self) -> bool: return bool(self._properties) @@ -311,46 +341,78 @@ def __bool__(self) -> bool: def __dir__(self) -> list[str]: return list(self._properties.keys()) - def __getattr__(self, attr): - try: - return self[attr] - except KeyError: - return super().__getattr__(attr) + def __getattr__(self, attr) -> SchemaInfo: + return self[attr] - def __getitem__(self, attr): + def __getitem__(self, attr) -> SchemaInfo: dct = self._properties[attr] if "definitions" in self._schema and "definitions" not in dct: dct = dict(definitions=self._schema["definitions"], **dct) return SchemaInfo(dct, self._rootschema) - def __iter__(self): + def __iter__(self) -> Iterator[str]: return iter(self._properties) - def items(self): + def __len__(self) -> int: + return len(self._properties) + + def items(self) -> Iterator[tuple[str, SchemaInfo]]: return ((key, self[key]) for key in self) - def keys(self): + def keys(self) -> KeysView[str]: return self._properties.keys() - def values(self): + def values(self) -> Iterator[SchemaInfo]: return (self[key] for key in self) class SchemaInfo: """A wrapper for inspecting a JSON schema.""" + _remap_title: ClassVar[dict[str, Sequence[str]]] = {} + def __init__( - self, schema: dict[str, Any], rootschema: dict[str, Any] | None = None + self, schema: Mapping[str, Any], rootschema: Mapping[str, Any] | None = None ) -> None: if not rootschema: rootschema = schema - self.raw_schema = schema - self.rootschema = rootschema - self.schema = resolve_references(schema, rootschema) - - def child(self, schema: dict) -> SchemaInfo: + self.raw_schema: Mapping[str, Any] + self.rootschema: Mapping[str, Any] + self.schema: Mapping[str, Any] + object.__setattr__(self, "raw_schema", schema) + object.__setattr__(self, "rootschema", rootschema) + object.__setattr__(self, "schema", resolve_references(schema, rootschema)) # type: ignore + + @classmethod + def from_refname(cls, refname: str, /, rootschema: Mapping[str, Any]) -> SchemaInfo: + return cls({"$ref": f"#/definitions/{refname}"}, rootschema) + + def __setattr__(self, name: str, value: Any) -> Never: + msg = f"{type(self).__name__!r} is immutable.\nCould not assign self.{name} = {value}" + raise TypeError(msg) + + def __hash__(self) -> int: + return hash(_HASH_ENCODER.encode(self.schema)) + + def __eq__(self, value: object) -> bool: + if isinstance(value, SchemaInfo): + if self.ref: + return self.ref == value.ref + return self.schema == value.schema + return False + + def child(self, schema: dict[str, Any]) -> SchemaInfo: return self.__class__(schema, rootschema=self.rootschema) + def iter_descendants(self) -> Iterator[SchemaInfo]: + """Yields `properties`, `anyOf`, `items`.""" + if "properties" in self.schema: + yield from self.properties.values() + if "anyOf" in self.schema: + yield from self.anyOf + if self.items: + yield self.child(self.items) + def __repr__(self) -> str: keys = [] for key in sorted(self.schema.keys()): @@ -373,140 +435,160 @@ def title(self) -> str: return "" @overload - def get_python_type_representation( + def to_type_repr( self, - for_type_hints: bool = ..., - return_as_str: Literal[True] = ..., - additional_type_hints: list[str] | None = ..., + *, + as_str: Literal[True] = ..., + target: TargetType = ..., + use_concrete: bool = ..., + use_undefined: bool = ..., ) -> str: ... @overload - def get_python_type_representation( + def to_type_repr( self, - for_type_hints: bool = ..., - return_as_str: Literal[False] = ..., - additional_type_hints: list[str] | None = ..., + *, + as_str: Literal[False], + target: TargetType = ..., + use_concrete: bool = ..., + use_undefined: bool = ..., ) -> list[str]: ... - def get_python_type_representation( # noqa: C901 + def to_type_repr( # noqa: C901 self, - for_type_hints: bool = False, - return_as_str: bool = True, - additional_type_hints: list[str] | None = None, + *, + as_str: bool = True, + target: TargetType = "doc", + use_concrete: bool = False, + use_undefined: bool = False, ) -> str | list[str]: - type_representations: list[str] = [] """ - All types which can be used for the current `SchemaInfo`. - Including `altair` classes, standard `python` types, etc. + Return the python type representation of ``SchemaInfo``. + + Includes `altair` classes, standard `python` types, etc. + + Parameters + ---------- + as_str + Return as a string. + Should only be ``False`` during internal recursive calls. + target: {"annotation", "doc"} + Where the representation will be used. + use_concrete + Avoid base classes/wrappers that don't provide type info. + use_undefined + Wrap the result in ``altair.typing.Optional``. """ + tps: set[str] = set() + FOR_TYPE_HINTS: bool = target == "annotation" if self.title: - if for_type_hints: - # To keep type hints simple, we only use the SchemaBase class - # as the type hint for all classes which inherit from it. - class_names = ["SchemaBase"] - if self.title in {"ExprRef", "ParameterExtent"}: - class_names.append("Parameter") - # In these cases, a value parameter is also always accepted. - # It would be quite complex to further differentiate - # between a value and a selection parameter based on - # the type system (one could - # try to check for the type of the Parameter.param attribute - # but then we would need to write some overload signatures for - # api.param). - - type_representations.extend(class_names) - else: - # use RST syntax for generated sphinx docs - type_representations.append(rst_syntax_for_class(self.title)) + if target == "annotation": + tps.update(self.title_to_type_reprs(use_concrete=use_concrete)) + elif target == "doc": + tps.add(rst_syntax_for_class(self.title)) if self.is_empty(): - type_representations.append("Any") + tps.add("Any") elif self.is_literal(): tp_str = spell_literal(self.literal) - if for_type_hints: + if FOR_TYPE_HINTS: tp_str = TypeAliasTracer.add_literal(self, tp_str, replace=True) - type_representations.append(tp_str) - elif for_type_hints and self.is_union_literal(): + tps.add(tp_str) + elif FOR_TYPE_HINTS and self.is_union_literal(): it = chain.from_iterable(el.literal for el in self.anyOf) tp_str = TypeAliasTracer.add_literal(self, spell_literal(it), replace=True) - type_representations.append(tp_str) + tps.add(tp_str) elif self.is_anyOf(): - it = ( - s.get_python_type_representation( - for_type_hints=for_type_hints, return_as_str=False - ) + it_nest = ( + s.to_type_repr(target=target, as_str=False, use_concrete=use_concrete) for s in self.anyOf ) - type_representations.extend(maybe_rewrap_literal(chain.from_iterable(it))) + tps.update(maybe_rewrap_literal(chain.from_iterable(it_nest))) elif isinstance(self.type, list): - options = [] - subschema = SchemaInfo(dict(**self.schema)) - for typ_ in self.type: - subschema.schema["type"] = typ_ - # We always use title if possible for nested objects - options.append( - subschema.get_python_type_representation( - for_type_hints=for_type_hints - ) + # We always use title if possible for nested objects + tps.update( + SchemaInfo(dict(self.schema, type=tp)).to_type_repr( + target=target, use_concrete=use_concrete ) - type_representations.extend(options) - elif self.is_object() and not for_type_hints: - type_representations.append("dict") + for tp in self.type + ) elif self.is_array(): - # A list is invariant in its type parameter. This means that e.g. - # List[str] is not a subtype of List[Union[core.FieldName, str]] - # and hence we would need to explicitly write out the combinations, - # so in this case: - # List[core.FieldName], List[str], List[core.FieldName, str] - # However, this can easily explode to too many combinations. - # Furthermore, we would also need to add additional entries - # for e.g. int wherever a float is accepted which would lead to very - # long code. - # As suggested in the mypy docs, - # https://mypy.readthedocs.io/en/stable/common_issues.html#variance, - # we revert to using Sequence which works as well for lists and also - # includes tuples which are also supported by the SchemaBase.to_dict - # method. However, it is not entirely accurate as some sequences - # such as e.g. a range are not supported by SchemaBase.to_dict but - # this tradeoff seems worth it. - s = self.child(self.items).get_python_type_representation( - for_type_hints=for_type_hints + tps.add( + spell_nested_sequence(self, target=target, use_concrete=use_concrete) ) - type_representations.append(f"Sequence[{s}]") elif self.type in jsonschema_to_python_types: - type_representations.append(jsonschema_to_python_types[self.type]) + if self.is_object() and use_concrete: + ... # HACK: Fall-through case to avoid `dict` added to `TypedDict` + elif self.is_object() and target == "doc": + tps.add("dict") + else: + tps.add(jsonschema_to_python_types[self.type]) else: msg = "No Python type representation available for this schema" raise ValueError(msg) - # Shorter types are usually the more relevant ones, e.g. `str` instead - # of `SchemaBase`. Output order from set is non-deterministic -> If - # types have same length names, order would be non-deterministic as it is - # returned from sort. Hence, we sort as well by type name as a tie-breaker, - # see https://docs.python.org/3.10/howto/sorting.html#sort-stability-and-complex-sorts - # for more infos. - # Using lower as we don't want to prefer uppercase such as "None" over - it = sorted(set(flatten(type_representations)), key=str.lower) # Tertiary sort - it = sorted(it, key=len) # Secondary sort - type_representations = sorted(it, key=TypeAliasTracer.is_cached) # Primary sort - if additional_type_hints: - type_representations.extend(additional_type_hints) - - if return_as_str: - type_representations_str = ", ".join(type_representations) - # If it's not for_type_hints but instead for the docstrings, we don't want - # to include Union as it just clutters the docstrings. - if len(type_representations) > 1 and for_type_hints: - # Use parameterised `TypeAlias` instead of exposing `UndefinedType` - # `Union` is collapsed by `ruff` later - if type_representations_str.endswith(", UndefinedType"): - s = type_representations_str.replace(", UndefinedType", "") - s = f"Optional[Union[{s}]]" - else: - s = f"Union[{type_representations_str}]" - return s - return type_representations_str - else: - return type_representations + if use_concrete: + if tps >= {"ColorHex", TypeAliasTracer.fmt.format("ColorName"), "str"}: + # HACK: Remove regular `str` if HEX & CSS color codes are present as well + tps.discard("str") + elif len(tps) == 0 and as_str: + # HACK: There is a single case that ends up empty here + # See: https://github.com/vega/altair/pull/3536#discussion_r1714344162 + tps = {"Map"} + return ( + finalize_type_reprs(tps, target=target, use_undefined=use_undefined) + if as_str + else sort_type_reprs(tps) + ) + + def title_to_type_reprs(self, *, use_concrete: bool) -> set[str]: + """ + Possibly use ``self.title`` as a type, or provide alternative(s). + + Parameters + ---------- + use_concrete + Avoid base classes/wrappers that don't provide type info. + """ + tp_param: set[str] = {"ExprRef", "ParameterExtent"} + # In these cases, a `VariableParameter` is also always accepted. + # It could be difficult to differentiate `(Variable|Selection)Parameter`, with typing. + # TODO: A solution could be defining `Parameter` as generic over either `param` or `param_type`. + # - Rewriting the init logic to not use an `Undefined` default. + # - Any narrowing logic could be factored-out into `is_(selection|variable)_parameter` guards. + EXCLUDE_TITLE: set[str] = tp_param | {"RelativeBandSize"} + """ + `RelativeBandSize` excluded as it has a single property `band`, + but all instances also accept `float`. + """ + REMAP_TITLE = SchemaInfo._remap_title + title: str = self.title + tps: set[str] = set() + if not use_concrete: + tps.add("SchemaBase") + # NOTE: To keep type hints simple, we annotate with `SchemaBase` for all subclasses. + if title in tp_param: + tps.add("Parameter") + elif self.is_value(): + value = self.properties["value"] + t = value.to_type_repr(target="annotation", use_concrete=use_concrete) + tps.add(f"Value[{t}]") + elif self.is_rowcol(): + row = self.properties["row"] + t = row.to_type_repr(target="annotation", use_concrete=use_concrete) + tps.add(f"RowColKwds[{t}]") + elif title in REMAP_TITLE: + tps.update(REMAP_TITLE[title]) + elif ( + (title not in EXCLUDE_TITLE) + and not TypeAliasTracer.is_cached(title, include_concrete=use_concrete) + and not self.is_union() + and not self.is_format() + and not self.is_array() + and not self.is_type_alias() + and not self.additionalProperties + ): + tps.add(title) + return tps @property def properties(self) -> SchemaProperties: @@ -521,11 +603,11 @@ def definitions(self) -> SchemaProperties: ) @property - def required(self) -> list: + def required(self) -> list[str]: return self.schema.get("required", []) @property - def patternProperties(self) -> dict: + def patternProperties(self) -> dict[str, Any]: return self.schema.get("patternProperties", {}) @property @@ -533,27 +615,30 @@ def additionalProperties(self) -> bool: return self.schema.get("additionalProperties", True) @property - def type(self) -> str | list[Any] | None: - return self.schema.get("type", None) + def type(self) -> str | list[Any]: + return self.schema.get("type", "") @property - def anyOf(self) -> list[SchemaInfo]: - return [self.child(s) for s in self.schema.get("anyOf", [])] + def anyOf(self) -> Iterator[SchemaInfo]: + for s in self.schema.get("anyOf", []): + yield self.child(s) @property - def oneOf(self) -> list[SchemaInfo]: - return [self.child(s) for s in self.schema.get("oneOf", [])] + def oneOf(self) -> Iterator[SchemaInfo]: + for s in self.schema.get("oneOf", []): + yield self.child(s) @property - def allOf(self) -> list[SchemaInfo]: - return [self.child(s) for s in self.schema.get("allOf", [])] + def allOf(self) -> Iterator[SchemaInfo]: + for s in self.schema.get("allOf", []): + yield self.child(s) @property def not_(self) -> SchemaInfo: return self.child(self.schema.get("not", {})) @property - def items(self) -> dict: + def items(self) -> dict[str, Any]: return self.schema.get("items", {}) @property @@ -573,8 +658,8 @@ def refname(self) -> str: return self.raw_schema.get("$ref", "#/").split("/")[-1] @property - def ref(self) -> str | None: - return self.raw_schema.get("$ref", None) + def ref(self) -> str: + return self.raw_schema.get("$ref", "") @property def description(self) -> str: @@ -582,7 +667,7 @@ def description(self) -> str: @property def deep_description(self) -> str: - return self._get_description(include_sublevels=True) + return process_description(self._get_description(include_sublevels=True)) def _get_description(self, include_sublevels: bool = False) -> str: desc = self.raw_schema.get("description", self.schema.get("description", "")) @@ -613,10 +698,10 @@ def is_literal(self) -> bool: return not ({"enum", "const"}.isdisjoint(self.schema)) def is_empty(self) -> bool: - return not (set(self.schema.keys()) - set(EXCLUDE_KEYS)) + return not (self.schema.keys() - EXCLUDE_KEYS) def is_compound(self) -> bool: - return any(key in self.schema for key in ["anyOf", "allOf", "oneOf"]) + return any(key in self.schema for key in COMPOUND_KEYS) def is_anyOf(self) -> bool: return "anyOf" in self.schema @@ -633,13 +718,13 @@ def is_not(self) -> bool: def is_object(self) -> bool: if self.type == "object": return True - elif self.type is not None: + elif self.type: return False elif ( self.properties or self.required - or self.patternProperties or self.additionalProperties + or self.patternProperties ): return True else: @@ -647,7 +732,15 @@ def is_object(self) -> bool: raise ValueError(msg) def is_value(self) -> bool: - return not self.is_object() + return self.is_object() and self.properties.keys() == {"value"} + + def is_rowcol(self) -> bool: + props = self.properties + return ( + self.is_object() + and props.keys() == {"column", "row"} + and props["column"] == props["row"] + ) def is_array(self) -> bool: return self.type == "array" @@ -658,7 +751,7 @@ def is_union(self) -> bool: Not a real class. """ - return self.is_anyOf() and self.type is None + return self.is_anyOf() and not self.type def is_union_literal(self) -> bool: """ @@ -668,129 +761,71 @@ def is_union_literal(self) -> bool: """ return self.is_union() and all(el.is_literal() for el in self.anyOf) + def is_format(self) -> bool: + """ + Represents a string format specifier. -class RSTRenderer(_RSTRenderer): - def __init__(self) -> None: - super().__init__() + These do not currently produce useful classes (e.g. ``HexColor``, ``URI``). - def inline_html(self, token: dict[str, Any], state: BlockState) -> str: - html = token["raw"] - return rf"\ :raw-html:`{html}`\ " + See Also + -------- + [python-jsonschema](https://python-jsonschema.readthedocs.io/en/latest/faq/#my-schema-specifies-format-validation-why-do-invalid-instances-seem-valid) + """ + return (self.schema.keys() == {"format", "type"}) and self.type == "string" + def is_type_alias(self) -> bool: + """ + Represents a name assigned to a literal type. -class RSTParse(mistune.Markdown): - def __init__( - self, - renderer: mistune.BaseRenderer, - block: mistune.BlockParser | None = None, - inline: mistune.InlineParser | None = None, - plugins=None, - ) -> None: - super().__init__(renderer, block, inline, plugins) + At the time of writing, most of these are: - def __call__(self, s: str) -> str: - s = super().__call__(s) - return unescape(s).replace(r"\ ,", ",").replace(r"\ ", " ") + SchemaInfo.schema = {"type": "string"} + The resulting annotation then becomes, e.g. ``FieldName``: -rst_parse: RSTParse = RSTParse(RSTRenderer()) + arg: str | FieldName + Where both of the above represent: -def indent_docstring( # noqa: C901 - lines: list[str], indent_level: int, width: int = 100, lstrip=True -) -> str: - """Indent a docstring for use in generated code.""" - final_lines = [] - if len(lines) > 1: - lines += [""] + arg = "name 1" + arg = FieldName("name 1") - for i, line in enumerate(lines): - stripped = line.lstrip() - if stripped: - leading_space = len(line) - len(stripped) - indent = indent_level + leading_space - wrapper = textwrap.TextWrapper( - width=width - indent, - initial_indent=indent * " ", - subsequent_indent=indent * " ", - break_long_words=False, - break_on_hyphens=False, - drop_whitespace=True, - ) - list_wrapper = textwrap.TextWrapper( - width=width - indent, - initial_indent=indent * " " + "* ", - subsequent_indent=indent * " " + " ", - break_long_words=False, - break_on_hyphens=False, - drop_whitespace=True, - ) - for line in stripped.split("\n"): - line_stripped = line.lstrip() - line_stripped = fix_docstring_issues(line_stripped) - if line_stripped == "": - final_lines.append("") - elif line_stripped.startswith("* "): - final_lines.extend(list_wrapper.wrap(line_stripped[2:])) - # Matches lines where an attribute is mentioned followed by the accepted - # types (lines starting with a character sequence that - # does not contain white spaces or '*' followed by ' : '). - # It therefore matches 'condition : anyOf(...' but not '**Notes** : ...' - # These lines should not be wrapped at all but appear on one line - elif re.match(r"[^\s*]+ : ", line_stripped): - final_lines.append(indent * " " + line_stripped) - else: - final_lines.extend(wrapper.wrap(line_stripped)) + The latter is not useful and adds noise. - # If this is the last line, put in an indent - elif i + 1 == len(lines): - final_lines.append(indent_level * " ") - # If it's not the last line, this is a blank line that should not indent. - else: - final_lines.append("") - # Remove any trailing whitespaces on the right side - stripped_lines = [] - for i, line in enumerate(final_lines): - if i + 1 == len(final_lines): - stripped_lines.append(line) - else: - stripped_lines.append(line.rstrip()) - # Join it all together - wrapped = "\n".join(stripped_lines) - if lstrip: - wrapped = wrapped.lstrip() - return wrapped - - -def fix_docstring_issues(docstring: str) -> str: - # All lists should start with '*' followed by a whitespace. Fixes the ones - # which either do not have a whitespace or/and start with '-' by first replacing - # "-" with "*" and then adding a whitespace where necessary - docstring = re.sub( - r"^-(?=[ `\"a-z])", - "*", - docstring, - flags=re.MULTILINE, - ) - # Now add a whitespace where an asterisk is followed by one of the characters - # in the square brackets of the regex pattern - docstring = re.sub( - r"^\*(?=[`\"a-z])", - "* ", - docstring, - flags=re.MULTILINE, - ) + ``Dict`` is very similar case, with a *slightly* different schema: - # Links to the vega-lite documentation cannot be relative but instead need to - # contain the full URL. - docstring = docstring.replace( - "types#datetime", "https://vega.github.io/vega-lite/docs/datetime.html" - ) - return docstring + SchemaInfo.schema = {"additionalProperties": {}, "type": "object"} + """ + TP = "type" + ADDITIONAL = "additionalProperties" + keys = self.schema.keys() + return ( + ( + (keys == {TP}) + or (keys == {TP, ADDITIONAL} and self.schema[ADDITIONAL] == {}) + ) + and isinstance(self.type, str) + and self.type in jsonschema_to_python_types + ) + def is_theme_config_target(self) -> bool: + """ + Return `True` for candidates classes in ``ThemeConfig`` hierarchy of ``TypedDict``(s). -def rst_syntax_for_class(class_name: str) -> str: - return f":class:`{class_name}`" + Satisfying these rules ensures: + - we generate meaningful annotations + - they improve autocompletion, without overwhelming the UX + """ + EXCLUDE = {"ExprRef", "ParameterPredicate", "RelativeBandSize"} + return bool( + self.ref + and self.refname not in EXCLUDE + and self.properties + and self.type == "object" + and not self.is_value() + and "field" not in self.required + and not (iskeyword(next(iter(self.required), ""))) + ) def flatten(container: Iterable) -> Iterable: @@ -806,6 +841,128 @@ def flatten(container: Iterable) -> Iterable: yield i +def finalize_type_reprs( + tps: Iterable[str], + /, + *, + target: TargetType, + use_undefined: bool = False, +) -> str: + """ + Deduplicates, sorts, and returns ``tps`` as a single string. + + Parameters + ---------- + tps + Collected type representations. + target + Destination for the type. + + .. note:: + `"doc"` skips ``(Union|Optional)`` wrappers. + + use_undefined + Wrap the result in `altair.typing.Optional`. + Avoids exposing `UndefinedType`. + """ + return _collapse_type_repr( + sort_type_reprs(tps), target=target, use_undefined=use_undefined + ) + + +def _collapse_type_repr( + tps: Iterable[str], + /, + *, + target: TargetType, + use_undefined: bool = False, +) -> str: + """ + Flatten unique types into a single string. + + See Also + -------- + - ``utils.finalize_type_reprs`` + """ + tp_str = ", ".join(tps) + if target == "doc": + return tp_str + elif target == "annotation": + if "," in tp_str: + tp_str = f"Union[{tp_str}]" + return f"Optional[{tp_str}]" if use_undefined else tp_str + else: + msg = f"Unexpected {target=}.\nUse one of {['annotation', 'doc']!r}" + raise TypeError(msg) + + +def sort_type_reprs(tps: Iterable[str], /) -> list[str]: + """ + Shorter types are usually the more relevant ones, e.g. `str` instead of `SchemaBase`. + + We use `set`_ for unique elements, but the lack of ordering requires additional sorts: + - If types have same length names, order would still be non-deterministic + - Hence, we sort as well by type name as a tie-breaker, see `sort-stability`_. + - Using ``str.lower`` gives priority to `builtins`_ over ``None``. + - Lowest priority is given to generated aliases from ``TypeAliasTracer``. + - These are purely to improve autocompletion + + Related + ------- + - https://github.com/vega/altair/pull/3573#discussion_r1747121600 + + .. _set: + https://docs.python.org/3/tutorial/datastructures.html#sets + .. _sort-stability: + https://docs.python.org/3/howto/sorting.html#sort-stability-and-complex-sorts + .. _builtins: + https://docs.python.org/3/library/functions.html + """ + dedup = tps if isinstance(tps, set) else set(tps) + it = sorted(dedup, key=str.lower) # Tertiary sort + it = sorted(it, key=len) # Secondary sort + return sorted(it, key=TypeAliasTracer.is_cached) # Primary sort + + +def spell_nested_sequence( + info: SchemaInfo, *, target: TargetType, use_concrete: bool +) -> str: + """ + Return a type representation for an array. + + Notes + ----- + A list is invariant in its type parameter. + + This means that ``list[str]`` is not a subtype of ``list[FieldName | str]`` + and hence we would need to explicitly write out the combinations, + so in this case: + + Accepted: list[FieldName] | list[str] | list[FieldName | str] + + However, this can easily explode to too many combinations. + + Furthermore, we would also need to add additional entries + for e.g. ``int`` wherever a ``float`` is accepted which would lead to very + long code. + + As suggested in the `mypy docs`_ we revert to using ``Sequence``. + + This includes ``list``, ``tuple`` and many others supported by ``SchemaBase.to_dict``. + + The original example becomes: + + Accepted: Sequence[FieldName | str] + + .. _mypy docs: + https://mypy.readthedocs.io/en/stable/common_issues.html#variance + + """ + child: SchemaInfo = info.child(info.items) + s = child.to_type_repr(target=target, use_concrete=use_concrete) + return f"Sequence[{s}]" + + def spell_literal(it: Iterable[str], /, *, quote: bool = True) -> str: """ Combine individual ``str`` type reprs into a single ``Literal``. @@ -845,20 +1002,6 @@ def unwrap_literal(tp: str, /) -> str: return re.sub(r"Literal\[(.+)\]", r"\g<1>", tp) -def ruff_format_str(code: str | list[str]) -> str: - if isinstance(code, list): - code = "\n".join(code) - - r = subprocess.run( - # Name of the file does not seem to matter but ruff requires one - ["ruff", "format", "--stdin-filename", "placeholder.py"], - input=code.encode(), - check=True, - capture_output=True, - ) - return r.stdout.decode() - - def ruff_format_py(fp: Path, /, *extra_args: str) -> None: """ Format an existing file. @@ -868,7 +1011,7 @@ def ruff_format_py(fp: Path, /, *extra_args: str) -> None: ruff format --diff --check . ``` """ - cmd = ["ruff", "format", fp] + cmd: MutableSequence[str | Path] = ["ruff", "format", fp] if extra_args: cmd.extend(extra_args) r = subprocess.run(cmd, check=True) @@ -889,7 +1032,7 @@ def ruff_write_lint_format_str( - Encoding set as default - `I001/2` are `isort` rules, to sort imports. """ - commands = ( + commands: Iterable[Sequence[str | Path]] = ( ["ruff", "check", fp, "--fix"], ["ruff", "check", fp, "--fix", "--select", "I001", "--select", "I002"], ) @@ -900,3 +1043,180 @@ def ruff_write_lint_format_str( r = subprocess.run(cmd, check=True) r.check_returncode() ruff_format_py(fp) + + +def import_type_checking(*imports: str) -> str: + """Write an `if TYPE_CHECKING` block.""" + imps = "\n".join(f" {s}" for s in imports) + return f"\nif TYPE_CHECKING:\n # ruff: noqa: F405\n{imps}\n" + + +def import_typing_extensions( + version_added: tuple[float, float], + /, + *symbol_names: str, + reason: str | None = None, + include_sys: bool = False, +) -> str: + major, minor = version_added + names = ", ".join(symbol_names) + line_1 = "import sys\n" if include_sys else "\n" + comment = f" # {reason}" if reason else "" + return ( + f"{line_1}" + f"if sys.version_info >= ({major}, {minor}):{comment}\n " + f"from typing import {names}\n" + f"else:\n " + f"from typing_extensions import {names}" + ) + + +TypeAliasTracer: _TypeAliasTracer = _TypeAliasTracer("{}_T", "I001", "I002") +"""An instance of `_TypeAliasTracer`. + +Collects a cache of unique `Literal` types used globally. + +These are then converted to `TypeAlias` statements, written to another module. + +Allows for a single definition to be reused multiple times, +rather than repeating long literals in every method definition. +""" + + +class RSTRenderer(_RSTRenderer): + def __init__(self) -> None: + super().__init__() + + def inline_html(self, token: dict[str, Any], state: BlockState) -> str: + html = token["raw"] + return rf"\ :raw-html:`{html}`\ " + + +class RSTParse(mistune.Markdown): + def __init__( + self, + renderer: mistune.BaseRenderer, + block: mistune.BlockParser | None = None, + inline: mistune.InlineParser | None = None, + plugins=None, + ) -> None: + super().__init__(renderer, block, inline, plugins) + + def __call__(self, s: str) -> str: + s = super().__call__(s) # pyright: ignore[reportAssignmentType] + return unescape(s).replace(r"\ ,", ",").replace(r"\ ", " ") + + +def indent_docstring( # noqa: C901 + lines: Iterable[str], indent_level: int, width: int = 100, lstrip=True +) -> str: + """Indent a docstring for use in generated code.""" + final_lines = [] + if not isinstance(lines, list): + lines = list(lines) + if len(lines) > 1: + lines += [""] + + for i, line in enumerate(lines): + stripped = line.lstrip() + if stripped: + leading_space = len(line) - len(stripped) + indent = indent_level + leading_space + wrapper = textwrap.TextWrapper( + width=width - indent, + initial_indent=indent * " ", + subsequent_indent=indent * " ", + break_long_words=False, + break_on_hyphens=False, + drop_whitespace=True, + ) + list_wrapper = textwrap.TextWrapper( + width=width - indent, + initial_indent=indent * " " + "* ", + subsequent_indent=indent * " " + " ", + break_long_words=False, + break_on_hyphens=False, + drop_whitespace=True, + ) + for line in stripped.split("\n"): + line_stripped = line.lstrip() + line_stripped = fix_docstring_issues(line_stripped) + if line_stripped == "": + final_lines.append("") + elif line_stripped.startswith("* "): + final_lines.extend(list_wrapper.wrap(line_stripped[2:])) + # Matches lines where an attribute is mentioned followed by the accepted + # types (lines starting with a character sequence that + # does not contain white spaces or '*' followed by ' : '). + # It therefore matches 'condition : anyOf(...' but not '**Notes** : ...' + # These lines should not be wrapped at all but appear on one line + elif re.match(r"[^\s*]+ : ", line_stripped): + final_lines.append(indent * " " + line_stripped) + else: + final_lines.extend(wrapper.wrap(line_stripped)) + + # If this is the last line, put in an indent + elif i + 1 == len(lines): + final_lines.append(indent_level * " ") + # If it's not the last line, this is a blank line that should not indent. + else: + final_lines.append("") + # Remove any trailing whitespaces on the right side + stripped_lines = [] + for i, line in enumerate(final_lines): + if i + 1 == len(final_lines): + stripped_lines.append(line) + else: + stripped_lines.append(line.rstrip()) + # Join it all together + wrapped = "\n".join(stripped_lines) + if lstrip: + wrapped = wrapped.lstrip() + return wrapped + + +def fix_docstring_issues(docstring: str) -> str: + """ + All lists should start with `"* "`. + + 1. Fixes the ones which either do not have `" "` and/or start with `"-"` replacing `"-"` -> `"*"` and then adding `" "` where necessary. + 2. Now add a `" "` where a `"*"` is followed by one of the characters in the square brackets of the regex pattern. + + Parameters + ---------- + docstring + A processed docstring line. + """ + return _RE_LIST_MISSING_WHITESPACE.sub( + "* ", _RE_LIST_MISSING_ASTERISK.sub("*", docstring) + ) + + +def rst_syntax_for_class(class_name: str) -> str: + return f":class:`{class_name}`" + + +rst_parse: RSTParse = RSTParse(RSTRenderer()) + + +# TODO: Investigate `mistune.Markdown.(before|after)_render_hooks`. +def process_description(description: str) -> str: + """Parse a JSON encoded markdown description into an `RST` string.""" + # remove formatting from links + description = "".join( + _RE_SPECIAL.sub("", d) if i % 2 else d + for i, d in enumerate(_RE_LINK.split(description)) + ) + description = rst_parse(description) + # Some entries in the Vega-Lite schema miss the second occurence of '__' + description = description.replace("__Default value: ", "__Default value:__ ") + # Links to the vega-lite documentation cannot be relative but instead need to + # contain the full URL. + description = description.replace( + "types#datetime", "https://vega.github.io/vega-lite/docs/datetime.html" + ) + # Fixing ambiguous unicode, RUF001 produces RUF002 in docs + description = description.replace("’", "'") # noqa: RUF001 [RIGHT SINGLE QUOTATION MARK] + description = description.replace("–", "-") # noqa: RUF001 [EN DASH] + description = description.replace(" ", " ") # noqa: RUF001 [NO-BREAK SPACE] + return description.strip()