{"$schema":"https://json-schema.org/draft/2020-12/schema","$id":"https://github.com/zinnoberHaus/quartile/schema.json","title":"Quartile component spec","description":"A single component spec, or a Dashboard of them. Specs reference datasets by name and fields by column name; SpecView renders them.","oneOf":[{"$ref":"#/$defs/Spec"},{"$ref":"#/$defs/Dashboard"}],"$defs":{"Field":{"type":"string","minLength":1,"description":"A field (column) name."},"FieldRef":{"description":"A field name, or a field with display overrides.","oneOf":[{"$ref":"#/$defs/Field"},{"type":"object","properties":{"field":{"$ref":"#/$defs/Field"},"type":{"enum":["temporal","quantitative","nominal"],"description":"How the field behaves on a scale."},"label":{"type":"string","description":"Human label for axes, legends and headers."},"format":{"$ref":"#/$defs/Format","description":"Display format."},"axisFormat":{"$ref":"#/$defs/Format","description":"Axis-only format; table values retain format."},"tooltipFormat":{"$ref":"#/$defs/Format","description":"Tooltip-only format; table values retain format."},"description":{"type":"string","description":"Plain-text field definition or caveat."},"timeZone":{"type":"string","minLength":1,"description":"Intl time zone identifier. Changes display, not data bucketing.","x-quartile-time-zone":true},"currency":{"type":"string","pattern":"^[A-Za-z]{3}$","description":"Three-letter currency code, e.g. USD or JPY."},"unit":{"type":"string","description":"Short unit badge, not a numeric conversion."}},"required":["field"],"additionalProperties":false}]},"Measure":{"description":"A field, optionally aggregated across rows that share the other encodings.","oneOf":[{"$ref":"#/$defs/Field"},{"type":"object","properties":{"field":{"$ref":"#/$defs/Field"},"aggregate":{"enum":["sum","count","mean"],"description":"How rows combine."},"type":{"enum":["temporal","quantitative","nominal"],"description":"How the field behaves on a scale."},"label":{"type":"string","description":"Human label for axes, legends and headers."},"format":{"$ref":"#/$defs/Format","description":"Display format."},"axisFormat":{"$ref":"#/$defs/Format","description":"Axis-only format; table values retain format."},"tooltipFormat":{"$ref":"#/$defs/Format","description":"Tooltip-only format; table values retain format."},"description":{"type":"string","description":"Plain-text field definition or caveat."},"timeZone":{"type":"string","minLength":1,"description":"Intl time zone identifier. Changes display, not data bucketing.","x-quartile-time-zone":true},"currency":{"type":"string","pattern":"^[A-Za-z]{3}$","description":"Three-letter currency code, e.g. USD or JPY."},"unit":{"type":"string","description":"Short unit badge, not a numeric conversion."}},"required":["field"],"additionalProperties":false}]},"Format":{"description":"A named format, Intl number options, or a typed format descriptor. Callbacks are React-only.","oneOf":[{"enum":["text","number","integer","compact","scientific","engineering","bytes","bytes-binary","duration","currency","currency-compact","percent","pt","date","date-short","month","weekday","datetime","time"]},{"$ref":"#/$defs/NumberOptions"},{"$ref":"#/$defs/NumberFormat"},{"$ref":"#/$defs/DateFormat"},{"$ref":"#/$defs/BytesFormat"},{"$ref":"#/$defs/DurationFormat"}]},"NumberOptions":{"type":"object","properties":{"localeMatcher":{"enum":["lookup","best fit"],"description":"Locale matching algorithm."},"numberingSystem":{"type":"string","description":"Unicode numbering system identifier."},"style":{"enum":["decimal","currency","percent","unit"],"description":"Numeric display style."},"currency":{"type":"string","pattern":"^[A-Za-z]{3}$","description":"Three-letter currency code, e.g. USD or JPY."},"currencyDisplay":{"enum":["symbol","narrowSymbol","code","name"],"description":"Currency label."},"currencySign":{"enum":["standard","accounting"],"description":"Negative currency convention."},"unit":{"type":"string","description":"Intl sanctioned unit, optionally compounded with -per-."},"unitDisplay":{"enum":["short","narrow","long"],"description":"Unit label length."},"notation":{"enum":["standard","scientific","engineering","compact"],"description":"Numeric notation."},"compactDisplay":{"enum":["short","long"],"description":"Compact suffix length."},"useGrouping":{"enum":[true,false,"auto","always","min2"],"description":"Digit grouping."},"signDisplay":{"enum":["auto","always","exceptZero","negative","never"],"description":"Sign policy."},"minimumIntegerDigits":{"type":"integer","minimum":1,"maximum":21,"description":"Minimum integer digits."},"minimumFractionDigits":{"type":"integer","minimum":0,"maximum":100,"description":"Minimum fractional places."},"maximumFractionDigits":{"type":"integer","minimum":0,"maximum":100,"description":"Maximum fractional places."},"minimumSignificantDigits":{"type":"integer","minimum":1,"maximum":21,"description":"Minimum significant digits."},"maximumSignificantDigits":{"type":"integer","minimum":1,"maximum":21,"description":"Maximum significant digits."},"roundingPriority":{"enum":["auto","morePrecision","lessPrecision"],"description":"Precision precedence."},"roundingIncrement":{"enum":[1,2,5,10,20,25,50,100,200,250,500,1000,2000,2500,5000],"description":"Rounding increment. Subject to Intl precision constraints."},"roundingMode":{"enum":["ceil","floor","expand","trunc","halfCeil","halfFloor","halfExpand","halfTrunc","halfEven"],"description":"Rounding rule."},"trailingZeroDisplay":{"enum":["auto","stripIfInteger"],"description":"Trailing fractional zeros."}},"additionalProperties":false,"x-quartile-format":"bare-number"},"NumberFormat":{"type":"object","properties":{"type":{"const":"number"},"locale":{"type":"string","minLength":1,"description":"BCP 47 locale identifier."},"missing":{"type":"string","description":"Text for missing or invalid values; defaults to an em dash."},"localeMatcher":{"enum":["lookup","best fit"],"description":"Locale matching algorithm."},"numberingSystem":{"type":"string","description":"Unicode numbering system identifier."},"style":{"enum":["decimal","currency","percent","unit"],"description":"Numeric display style."},"currency":{"type":"string","pattern":"^[A-Za-z]{3}$","description":"Three-letter currency code, e.g. USD or JPY."},"currencyDisplay":{"enum":["symbol","narrowSymbol","code","name"],"description":"Currency label."},"currencySign":{"enum":["standard","accounting"],"description":"Negative currency convention."},"unit":{"type":"string","description":"Intl sanctioned unit, optionally compounded with -per-."},"unitDisplay":{"enum":["short","narrow","long"],"description":"Unit label length."},"notation":{"enum":["standard","scientific","engineering","compact"],"description":"Numeric notation."},"compactDisplay":{"enum":["short","long"],"description":"Compact suffix length."},"useGrouping":{"enum":[true,false,"auto","always","min2"],"description":"Digit grouping."},"signDisplay":{"enum":["auto","always","exceptZero","negative","never"],"description":"Sign policy."},"minimumIntegerDigits":{"type":"integer","minimum":1,"maximum":21,"description":"Minimum integer digits."},"minimumFractionDigits":{"type":"integer","minimum":0,"maximum":100,"description":"Minimum fractional places."},"maximumFractionDigits":{"type":"integer","minimum":0,"maximum":100,"description":"Maximum fractional places."},"minimumSignificantDigits":{"type":"integer","minimum":1,"maximum":21,"description":"Minimum significant digits."},"maximumSignificantDigits":{"type":"integer","minimum":1,"maximum":21,"description":"Maximum significant digits."},"roundingPriority":{"enum":["auto","morePrecision","lessPrecision"],"description":"Precision precedence."},"roundingIncrement":{"enum":[1,2,5,10,20,25,50,100,200,250,500,1000,2000,2500,5000],"description":"Rounding increment. Subject to Intl precision constraints."},"roundingMode":{"enum":["ceil","floor","expand","trunc","halfCeil","halfFloor","halfExpand","halfTrunc","halfEven"],"description":"Rounding rule."},"trailingZeroDisplay":{"enum":["auto","stripIfInteger"],"description":"Trailing fractional zeros."},"prefix":{"type":"string","description":"Literal prefix, outside the localized number."},"suffix":{"type":"string","description":"Literal suffix, outside the localized number."},"scale":{"type":"number","description":"Finite display-only multiplier; percent already multiplies ratios by 100."}},"required":["type"],"additionalProperties":false,"x-quartile-format":"number"},"DateFormat":{"type":"object","properties":{"type":{"const":"date"},"locale":{"type":"string","minLength":1,"description":"BCP 47 locale identifier."},"missing":{"type":"string","description":"Text for missing or invalid values; defaults to an em dash."},"localeMatcher":{"enum":["lookup","best fit"],"description":"Locale matching algorithm."},"calendar":{"type":"string","description":"Unicode calendar identifier."},"numberingSystem":{"type":"string","description":"Unicode numbering system identifier."},"timeZone":{"type":"string","minLength":1,"description":"Intl time zone identifier. Changes display, not data bucketing.","x-quartile-time-zone":true},"hour12":{"type":"boolean","description":"Use a 12-hour clock."},"hourCycle":{"enum":["h11","h12","h23","h24"],"description":"Hour cycle."},"formatMatcher":{"enum":["basic","best fit"],"description":"Date component matching algorithm."},"dateStyle":{"enum":["full","long","medium","short"],"description":"Date style; excludes component options."},"timeStyle":{"enum":["full","long","medium","short"],"description":"Time style; excludes component options."},"weekday":{"enum":["long","short","narrow"],"description":"Weekday label."},"era":{"enum":["long","short","narrow"],"description":"Era label."},"year":{"enum":["numeric","2-digit"],"description":"Year label."},"month":{"enum":["numeric","2-digit","long","short","narrow"],"description":"Month label."},"day":{"enum":["numeric","2-digit"],"description":"Day label."},"dayPeriod":{"enum":["long","short","narrow"],"description":"Day-period label."},"hour":{"enum":["numeric","2-digit"],"description":"Hour label."},"minute":{"enum":["numeric","2-digit"],"description":"Minute label."},"second":{"enum":["numeric","2-digit"],"description":"Second label."},"fractionalSecondDigits":{"type":"integer","minimum":1,"maximum":3,"description":"Fractional second places."},"timeZoneName":{"enum":["long","short","shortOffset","longOffset","shortGeneric","longGeneric"],"description":"Time-zone label."}},"required":["type"],"additionalProperties":false,"x-quartile-format":"date"},"BytesFormat":{"type":"object","properties":{"type":{"const":"bytes"},"locale":{"type":"string","minLength":1,"description":"BCP 47 locale identifier."},"missing":{"type":"string","description":"Text for missing or invalid values; defaults to an em dash."},"base":{"enum":[1000,1024],"description":"Decimal kB/MB or binary KiB/MiB."},"maximumFractionDigits":{"type":"integer","minimum":0,"maximum":20,"description":"Maximum fractional places."}},"required":["type"],"additionalProperties":false,"x-quartile-format":"bytes"},"DurationFormat":{"type":"object","properties":{"type":{"const":"duration"},"locale":{"type":"string","minLength":1,"description":"BCP 47 locale identifier."},"missing":{"type":"string","description":"Text for missing or invalid values; defaults to an em dash."},"unit":{"enum":["millisecond","second"],"description":"Unit of the elapsed numeric observation; default millisecond."},"maximumFractionDigits":{"type":"integer","minimum":0,"maximum":20,"description":"Maximum fractional second places."}},"required":["type"],"additionalProperties":false,"x-quartile-format":"duration"},"Column":{"type":"object","description":"A DataTable column.","properties":{"field":{"$ref":"#/$defs/Field"},"key":{"type":"string","description":"Unique column id; defaults to the field. Required when two columns share a field."},"label":{"type":"string","description":"Header text."},"description":{"type":"string","description":"Plain-text field definition; overrides dataset field description."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"align":{"enum":["left","center","right"],"description":"Alignment."},"width":{"type":["number","string"],"description":"Grid track: px, or a CSS track such as \"minmax(160px, 2fr)\"."},"cell":{"enum":["text","number","bar","sparkline","delta","badge","status"],"description":"How the value renders."},"sortable":{"type":"boolean","description":"Sort by clicking the header."},"secondary":{"$ref":"#/$defs/Field","description":"Text cells: a second mono line from this field."},"tones":{"type":"object","description":"Badge and status cells: tone per value.","additionalProperties":{"enum":["neutral","signal","positive","warning","negative"]}},"deltaKind":{"enum":["percent","pt","number"],"description":"Delta cells: unit of change."},"deltaDigits":{"type":"integer","minimum":0,"maximum":20,"description":"Delta cells: fraction digits for the displayed change."},"invert":{"type":"boolean","description":"Delta cells: down is good."},"share":{"type":"boolean","description":"Bar cells: label shows the share of the column total."},"aggregate":{"enum":["sum","count","mean","min","max"],"description":"With groupBy: how the field combines."},"over":{"$ref":"#/$defs/Field","description":"With groupBy: sparkline and delta series over this field."}},"required":["field"],"additionalProperties":false},"LineChart":{"title":"LineChart","description":"Trends over a continuous x. One line per measure, or per value of `color`.","type":"object","properties":{"component":{"const":"LineChart"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"x":{"$ref":"#/$defs/FieldRef","description":"Continuous field for the horizontal axis; dates are detected."},"y":{"description":"A measure, or several fields for several lines.","oneOf":[{"$ref":"#/$defs/Measure"},{"type":"array","items":{"$ref":"#/$defs/Field"},"minItems":1}]},"color":{"$ref":"#/$defs/Field","description":"Splits rows into one line per value of this field."},"compare":{"$ref":"#/$defs/Field","description":"Field with comparison values, drawn dashed."},"compareLabel":{"type":"string","description":"Label for the comparison line."},"curve":{"enum":["linear","monotone","step"],"description":"Interpolation between points."},"area":{"type":"boolean","description":"Fill under the line."},"points":{"enum":[true,false,"hover"],"description":"Mark every point, none, or only the hovered one."},"brush":{"type":"boolean","description":"Drag to select a range of x and publish it to the selection."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"xFormat":{"$ref":"#/$defs/Format","description":"Axis format for x."},"legend":{"type":"boolean","description":"Show a legend above the plot."}},"required":["component","data","x","y"],"additionalProperties":false},"AreaChart":{"title":"AreaChart","description":"Filled trends; stack several series to show a total and its parts.","type":"object","properties":{"component":{"const":"AreaChart"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"x":{"$ref":"#/$defs/FieldRef","description":"Continuous field for the horizontal axis."},"y":{"description":"A measure, or several fields for several areas.","oneOf":[{"$ref":"#/$defs/Measure"},{"type":"array","items":{"$ref":"#/$defs/Field"},"minItems":1}]},"color":{"$ref":"#/$defs/Field","description":"Splits rows into one area per value of this field."},"stack":{"type":"boolean","description":"Stack series on top of each other."},"curve":{"enum":["linear","monotone","step"],"description":"Interpolation between points."},"brush":{"type":"boolean","description":"Drag to select a range of x and publish it to the selection."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"xFormat":{"$ref":"#/$defs/Format","description":"Axis format for x."},"legend":{"type":"boolean","description":"Show a legend."}},"required":["component","data","x","y"],"additionalProperties":false},"BarChart":{"title":"BarChart","description":"Compares values across categories or dates. Rows sharing an x are summed.","type":"object","properties":{"component":{"const":"BarChart"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"x":{"$ref":"#/$defs/FieldRef","description":"Category or date field, one bar per value."},"y":{"description":"A measure, or several fields for grouped bars.","oneOf":[{"$ref":"#/$defs/Measure"},{"type":"array","items":{"$ref":"#/$defs/Field"},"minItems":1}]},"group":{"$ref":"#/$defs/Field","description":"Splits each bar by this field."},"color":{"$ref":"#/$defs/Field","description":"Alias of `group`."},"stack":{"type":"boolean","description":"Stack groups into one bar."},"orientation":{"enum":["vertical","horizontal"],"description":"Bar direction."},"sort":{"enum":["desc","asc","none"],"description":"Ranking order."},"select":{"type":"boolean","description":"Click a bar to toggle its x value in the selection."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"xFormat":{"$ref":"#/$defs/Format","description":"Category label format."},"legend":{"type":"boolean","description":"Show a legend."}},"required":["component","data","x","y"],"additionalProperties":false},"BarList":{"title":"BarList","description":"A ranked list with inline bars; raw rows are aggregated per category.","type":"object","properties":{"component":{"const":"BarList"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"category":{"$ref":"#/$defs/FieldRef","description":"Field whose values become the rows."},"value":{"$ref":"#/$defs/Measure","description":"Measure to aggregate; omit to count rows."},"sort":{"enum":["desc","asc","none"],"description":"Ranking order."},"limit":{"type":"integer","minimum":1,"description":"Show at most this many rows."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"delta":{"$ref":"#/$defs/Field","description":"Field holding each row’s change as a ratio."},"invertDelta":{"type":"boolean","description":"A fall in the delta is good."},"variant":{"enum":["bar","fill"],"description":"Bar under the label, or a soft fill behind it."},"select":{"type":"boolean","description":"Click a row to toggle its category in the selection."}},"required":["component","data","category"],"additionalProperties":false},"DonutChart":{"title":"DonutChart","description":"Parts of a whole, for a handful of categories.","type":"object","properties":{"component":{"const":"DonutChart"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"category":{"$ref":"#/$defs/FieldRef","description":"Field whose values become the slices."},"value":{"$ref":"#/$defs/Measure","description":"Measure to aggregate; omit to count rows."},"sort":{"enum":["desc","asc","none"],"description":"Ranking order."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"centerValue":{"type":"string","description":"Text in the middle; defaults to the total."},"centerLabel":{"type":"string","description":"Caption under the center value."},"legend":{"type":"boolean","description":"Show a legend."},"size":{"type":"number","minimum":40,"description":"Diameter in px."},"thickness":{"type":"number","minimum":2,"description":"Ring thickness in px."},"select":{"type":"boolean","description":"Click a slice to toggle its category in the selection."}},"required":["component","data","category"],"additionalProperties":false},"Funnel":{"title":"Funnel","description":"Conversion through ordered steps.","type":"object","properties":{"component":{"const":"Funnel"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"step":{"$ref":"#/$defs/Field","description":"Field naming each step, in order."},"value":{"$ref":"#/$defs/Field","description":"Count at each step."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"align":{"enum":["start","center"],"description":"Bar alignment."},"overall":{"type":"boolean","description":"Show the overall conversion."}},"required":["component","data","step","value"],"additionalProperties":false},"Sparkline":{"title":"Sparkline","description":"A small line without axes.","type":"object","properties":{"component":{"const":"Sparkline"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"x":{"$ref":"#/$defs/Field","description":"Field to order points by."},"y":{"$ref":"#/$defs/Field","description":"Values to draw."},"compare":{"$ref":"#/$defs/Field","description":"Comparison values, drawn dashed."},"area":{"type":"boolean","description":"Fill under the line."},"curve":{"enum":["linear","monotone","step"],"description":"Interpolation between points."},"format":{"$ref":"#/$defs/Format","description":"Value format for the accessible summary."}},"required":["component","data","y"],"additionalProperties":false},"Histogram":{"title":"Histogram","description":"The distribution of a quantitative field, or counts per day, week or month.","type":"object","properties":{"component":{"const":"Histogram"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"x":{"$ref":"#/$defs/FieldRef","description":"Field to bin."},"bins":{"type":"integer","minimum":1,"description":"Number of equal-width bins."},"interval":{"enum":["day","week","month"],"description":"Calendar bucket for a date x."},"value":{"$ref":"#/$defs/Field","description":"Sum this field per bin instead of counting rows."},"format":{"$ref":"#/$defs/Format","description":"Format for x."},"valueFormat":{"$ref":"#/$defs/Format","description":"Format for counts or sums."},"countLabel":{"type":"string","description":"Label for counts in the tooltip."},"brush":{"type":"boolean","description":"Drag across bins to publish a range of x."},"median":{"type":"boolean","description":"Mark the median."}},"required":["component","data","x"],"additionalProperties":false},"ScatterPlot":{"title":"ScatterPlot","description":"The relationship between two measures.","type":"object","properties":{"component":{"const":"ScatterPlot"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"renderer":{"type":"string","enum":["svg","canvas","webgl"],"description":"Scatter point renderer. Defaults to SVG; WebGL falls back to Canvas, then SVG when unavailable."},"x":{"$ref":"#/$defs/FieldRef","description":"Horizontal measure."},"y":{"$ref":"#/$defs/FieldRef","description":"Vertical measure."},"size":{"$ref":"#/$defs/Field","description":"Point size by this field."},"color":{"$ref":"#/$defs/Field","description":"Point color by this field."},"label":{"$ref":"#/$defs/Field","description":"Field naming each point."},"format":{"$ref":"#/$defs/Format","description":"Format for y."},"xFormat":{"$ref":"#/$defs/Format","description":"Format for x."},"select":{"description":"Click a point to toggle a value in the selection: true uses `color` (or `label`), a field name uses that field.","oneOf":[{"type":"boolean"},{"$ref":"#/$defs/Field"}]},"legend":{"type":"boolean","description":"Show a legend."},"xTitle":{"type":"string","description":"Horizontal axis title."},"yTitle":{"type":"string","description":"Vertical axis title."}},"required":["component","data","x","y"],"additionalProperties":false},"Heatmap":{"title":"Heatmap","description":"A value across two categorical or time dimensions.","type":"object","properties":{"component":{"const":"Heatmap"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"x":{"$ref":"#/$defs/FieldRef","description":"Columns."},"y":{"$ref":"#/$defs/FieldRef","description":"Rows."},"value":{"$ref":"#/$defs/Measure","description":"Measure per cell; omit to count rows."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"xFormat":{"$ref":"#/$defs/Format","description":"Column label format."},"yFormat":{"$ref":"#/$defs/Format","description":"Row label format."},"cellHeight":{"type":"number","minimum":4,"description":"Row height in px."},"peak":{"type":"boolean","description":"Mark the highest cell."},"countLabel":{"type":"string","description":"Label for counts in the tooltip when `value` is not set."},"legend":{"type":"boolean","description":"Show the color legend."}},"required":["component","data","x","y"],"additionalProperties":false},"CalendarHeatmap":{"title":"CalendarHeatmap","description":"One cell per day, arranged by week.","type":"object","properties":{"component":{"const":"CalendarHeatmap"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"date":{"$ref":"#/$defs/FieldRef","description":"Date field."},"value":{"$ref":"#/$defs/Measure","description":"Measure per day; omit to count rows."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"weeks":{"type":"integer","minimum":1,"description":"Number of weeks to show."},"weekStart":{"enum":[0,1],"description":"First day of the week: 0 Sunday, 1 Monday."},"dayLabels":{"type":"boolean","description":"Show weekday labels."},"countLabel":{"type":"string","description":"Label for counts in the tooltip when `value` is not set."},"legend":{"type":"boolean","description":"Show the color legend."},"select":{"type":"boolean","description":"Click a day to select it."}},"required":["component","data","date"],"additionalProperties":false},"Sankey":{"title":"Sankey","description":"Flows between stages; rows are aggregated per from → to pair.","type":"object","properties":{"component":{"const":"Sankey"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"from":{"$ref":"#/$defs/Field","description":"Where a flow starts."},"to":{"$ref":"#/$defs/Field","description":"Where a flow ends. A name used in both fields links the stages."},"value":{"$ref":"#/$defs/Field","description":"Flow size; counts rows when omitted."},"format":{"$ref":"#/$defs/Format","description":"Flow size format."},"nodeWidth":{"type":"number","minimum":2,"description":"Node bar width in px."},"nodePadding":{"type":"number","minimum":0,"description":"Vertical gap between nodes in px."},"select":{"type":"boolean","description":"Click a node to toggle it in the selection."}},"required":["component","data","from","to"],"additionalProperties":false},"BoxPlot":{"title":"BoxPlot","description":"Quartiles and outliers of a measure per category.","type":"object","properties":{"component":{"const":"BoxPlot"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"height":{"type":"number","minimum":40,"maximum":2000,"description":"Plot height in px."},"tooltipNote":{"type":"string","description":"Plain-text chart context, included in accessible descriptions and supported hover tooltips."},"category":{"$ref":"#/$defs/FieldRef","description":"One box per value of this field."},"value":{"$ref":"#/$defs/Field","description":"Measure to summarize."},"orientation":{"enum":["horizontal","vertical"],"description":"Box direction."},"whiskers":{"enum":["tukey","minmax"],"description":"Whisker rule."},"zero":{"type":"boolean","description":"Start the value axis at zero."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"select":{"type":"boolean","description":"Click a box to select its category."}},"required":["component","data","category","value"],"additionalProperties":false},"KPI":{"title":"KPI","description":"A headline number with its comparison, aggregated from the rows the selection lets through.","type":"object","properties":{"component":{"const":"KPI"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"label":{"type":"string","description":"What the number is."},"value":{"$ref":"#/$defs/Measure","description":"Measure to aggregate; `{ \"field\": …, \"aggregate\": \"count\" }` counts rows."},"compareValue":{"$ref":"#/$defs/Field","description":"Field with comparison values; the delta is computed against it."},"trendBy":{"$ref":"#/$defs/Field","description":"Draw a sparkline of the value per distinct value of this field."},"format":{"$ref":"#/$defs/Format","description":"Value format."},"unit":{"type":"string","description":"Mono tag in the corner, e.g. \"USD\"."},"currency":{"type":"string","pattern":"^[A-Za-z]{3}$","description":"Three-letter currency code, e.g. USD or JPY."},"comparison":{"type":"string","description":"What the delta is measured against, e.g. \"vs. previous 30 days\"."},"deltaKind":{"enum":["percent","pt"],"description":"Ratio change or percentage points."},"deltaDigits":{"type":"integer","minimum":0,"maximum":20,"description":"Fraction digits for the displayed change."},"invert":{"type":"boolean","description":"Down is good."},"compare":{"type":"boolean","description":"Show this period and the previous one as two bars."},"target":{"type":"object","description":"Progress toward a goal.","properties":{"value":{"type":"number","description":"The goal."},"label":{"type":"string","description":"Name of the goal."},"expected":{"type":"number","minimum":0,"maximum":1,"description":"Share of the goal expected by now."}},"required":["value"],"additionalProperties":false}},"required":["component","data","label","value"],"additionalProperties":false},"DataTable":{"title":"DataTable","description":"Rows with typed cells. Optionally grouped, sorted, limited and selectable.","type":"object","properties":{"component":{"const":"DataTable"},"data":{"type":"string","description":"Name of a dataset passed to SpecView in `data`."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"columns":{"type":"array","items":{"$ref":"#/$defs/Column"},"minItems":1,"description":"Columns in order."},"groupBy":{"$ref":"#/$defs/Field","description":"One row per value of this field; columns aggregate."},"sort":{"type":"string","pattern":"^-?[^-].*$","description":"Column key to sort by; prefix \"-\" for descending."},"limit":{"type":"integer","minimum":1,"description":"Keep the first N rows after sorting."},"pageSize":{"type":"integer","minimum":1,"description":"Rows per page."},"select":{"$ref":"#/$defs/Field","description":"Field published to the selection when a row is clicked."},"multiple":{"type":"boolean","description":"Allow several selected rows."},"rank":{"type":"boolean","description":"Leading rank column."},"caption":{"type":"string","description":"Line under the title."},"noun":{"type":"string","description":"Plural noun for the page label."},"height":{"type":"number","minimum":120,"description":"Scroller height in px."}},"required":["component","data","columns"],"additionalProperties":false},"FilterBar":{"title":"FilterBar","description":"Chips that mirror the selection, with menus to set values.","type":"object","properties":{"component":{"const":"FilterBar"},"data":{"type":"string","description":"Optional dataset name, used for derived options."},"title":{"type":"string","description":"Card title. Charts render it above the plot and use it as their accessible name."},"description":{"type":"string","description":"One line under the title."},"span":{"type":"integer","minimum":1,"maximum":12,"description":"Columns this item spans in a Dashboard layout (12-column grid)."},"fields":{"type":"array","minItems":1,"description":"Fields offered as chips.","items":{"type":"object","properties":{"field":{"$ref":"#/$defs/Field","description":"Field to filter."},"label":{"type":"string","description":"Chip label."},"pinned":{"type":"boolean","description":"Always show the chip."},"multiple":{"type":"boolean","description":"Allow several values."},"options":{"type":"array","description":"Values offered; derived from the dataset when omitted.","items":{"type":"object","properties":{"value":{"type":["string","number","boolean"]},"label":{"type":"string","description":"Display text."},"meta":{"type":"string","description":"Right-aligned detail."}},"required":["value"],"additionalProperties":false}}},"required":["field"],"additionalProperties":false}},"label":{"type":"string","description":"Leading label; defaults to \"Filters\"."}},"required":["component","fields"],"additionalProperties":false},"Spec":{"description":"One component, chosen by `component`.","oneOf":[{"$ref":"#/$defs/LineChart"},{"$ref":"#/$defs/AreaChart"},{"$ref":"#/$defs/BarChart"},{"$ref":"#/$defs/BarList"},{"$ref":"#/$defs/DonutChart"},{"$ref":"#/$defs/Funnel"},{"$ref":"#/$defs/Sparkline"},{"$ref":"#/$defs/Histogram"},{"$ref":"#/$defs/ScatterPlot"},{"$ref":"#/$defs/Heatmap"},{"$ref":"#/$defs/CalendarHeatmap"},{"$ref":"#/$defs/Sankey"},{"$ref":"#/$defs/BoxPlot"},{"$ref":"#/$defs/KPI"},{"$ref":"#/$defs/DataTable"},{"$ref":"#/$defs/FilterBar"}]},"Dashboard":{"type":"object","description":"Components laid out on a 12-column grid and linked by one selection.","properties":{"title":{"type":"string","description":"Dashboard title."},"description":{"type":"string","description":"One line under the title."},"selection":{"type":"string","pattern":"^[A-Za-z][\\w-]*$","description":"Selection id the components share."},"layout":{"type":"array","items":{"$ref":"#/$defs/Spec"},"minItems":1,"description":"Items in order."}},"required":["layout"],"additionalProperties":false}}}