# Faceted Sparkline > Compact line trends split into small multiples by category, laid out in a responsive grid that fills the widget. Faceted Sparkline shows the same metric's trend for many categories side by side, one compact panel per category. Use it when a single multi-line chart turns into spaghetti: tracking revenue trend per region, sign-ups per marketing channel, or a KPI's health across teams. Because each panel scales independently, you compare the shape of each trend (growing, flat, seasonal, declining) rather than absolute values. Hovering shows a crosshair at the same date in every panel, with each panel's header showing the values at that date (color-coded by series) next to the date, so you can check how all categories were doing at one moment in time. Hovering a line highlights that series across all panels. ```aml CustomChartDef faceted_sparkline { label: 'Faceted Sparkline' description: 'Use this chart to show a compact line trend split into small multiples by category, with optional series coloring and tooltip control.' fields { field date_dimension { label: 'Date' type: 'dimension' data_type: 'date' sort { apply_order: 1 direction: 'asc' } } field value { label: 'Value' type: 'measure' data_type: 'number' sort { apply_order: 2 direction: 'asc' } } field facet { label: 'Facet' type: 'dimension' sort { apply_order: 3 direction: 'asc' } } field series_color { label: 'Series Color Group' type: 'dimension' sort { apply_order: 4 direction: 'asc' } } } options { option show_tooltip { label: 'Show tooltip' type: 'toggle' default_value: true } option facet_columns { label: 'Facet columns' type: 'number-input' default_value: 4 } option color_scheme { label: 'Color scheme' type: 'select' options: ['tableau10', 'category10', 'accent', 'dark2', 'paired', 'set2'] default_value: 'tableau10' } } template: @vg { "$schema": "https://vega.github.io/schema/vega/v5.json", "description": "Responsive faceted sparklines in a signal-computed grid.", "autosize": "none", "padding": 0, "signals": [ { "name": "width", "init": "containerSize()[0]", "on": [{ "events": "window:resize", "update": "containerSize()[0]" }] }, { "name": "height", "init": "containerSize()[1]", "on": [{ "events": "window:resize", "update": "containerSize()[1]" }] }, {"name": "columns", "update": "max(1, @{options.facet_columns.value})"}, {"name": "rows", "update": "max(1, ceil(length(data('facets')) / columns))"}, {"name": "cellW", "update": "width / columns"}, {"name": "cellH", "update": "height / rows"}, {"name": "headerH", "value": 22}, {"name": "plotW", "update": "max(10, cellW - 16)"}, {"name": "plotH", "update": "max(10, cellH - headerH - 12)"}, { "name": "cursorX", "value": null, "on": [ {"events": "@hoverRect:mousemove, @sparkline:mousemove", "update": "clamp(x(group()), 0, plotW)"}, {"events": "@hoverRect:mouseout", "update": "null"} ] }, {"name": "hoverDate", "update": "cursorX === null ? null : invert('x', cursorX)"}, { "name": "hoveredSeries", "value": null, "on": [ {"events": "@sparkline:mouseover", "update": "datum.series_value"}, {"events": "@sparkline:mouseout", "update": "null"} ] } ], "data": [ { "name": "source", "values": @{values}, "transform": [ {"type": "formula", "expr": "toDate(datum['@{fields.date_dimension.name}'])", "as": "date_value"}, {"type": "formula", "expr": "datum['@{fields.value.name}']", "as": "amount"}, {"type": "formula", "expr": "datum['@{fields.facet.name}']", "as": "facet_value"}, {"type": "formula", "expr": "datum['@{fields.series_color.name}']", "as": "series_value"}, {"type": "filter", "expr": "datum.amount != null"}, {"type": "collect", "sort": {"field": "date_value"}} ] }, { "name": "facets", "source": "source", "transform": [ {"type": "aggregate", "groupby": ["facet_value"]}, {"type": "collect", "sort": {"field": "facet_value"}}, {"type": "window", "ops": ["row_number"], "as": ["index"]}, {"type": "formula", "expr": "(datum.index - 1) % columns", "as": "col"}, {"type": "formula", "expr": "floor((datum.index - 1) / columns)", "as": "row"} ] }, { "name": "plot", "source": "source", "transform": [ { "type": "lookup", "from": "facets", "key": "facet_value", "fields": ["facet_value"], "values": ["col", "row"], "as": ["col", "row"] } ] }, { "name": "hover_points", "source": "plot", "transform": [ {"type": "filter", "expr": "hoverDate != null"}, {"type": "formula", "expr": "abs(datum.date_value - time(hoverDate))", "as": "dist"}, { "type": "joinaggregate", "ops": ["min"], "fields": ["dist"], "as": ["min_dist"], "groupby": ["facet_value", "series_value"] }, {"type": "filter", "expr": "datum.dist === datum.min_dist"}, {"type": "collect", "sort": {"field": "series_value"}}, {"type": "window", "ops": ["row_number"], "as": ["sidx"], "groupby": ["facet_value"]} ] } ], "scales": [ { "name": "x", "type": "time", "domain": {"data": "plot", "field": "date_value"}, "range": [0, {"signal": "plotW"}] }, { "name": "color", "type": "ordinal", "domain": {"data": "plot", "field": "series_value"}, "range": {"scheme": @{options.color_scheme.value}} } ], "marks": [ { "type": "group", "from": { "facet": {"name": "cell", "data": "plot", "groupby": ["facet_value", "col", "row"]} }, "encode": { "update": { "x": {"signal": "datum.col * cellW + 8"}, "y": {"signal": "datum.row * cellH"}, "width": {"signal": "plotW"}, "height": {"signal": "cellH"} } }, "scales": [ { "name": "yscale", "type": "linear", "nice": true, "domain": {"data": "cell", "field": "amount"}, "range": [{"signal": "headerH + plotH"}, {"signal": "headerH"}] } ], "marks": [ { "type": "rect", "name": "hoverRect", "encode": { "update": { "x": {"value": 0}, "y": {"value": 0}, "width": {"signal": "plotW"}, "height": {"signal": "cellH"}, "fill": {"value": "transparent"} } } }, { "type": "text", "interactive": false, "encode": { "update": { "x": {"value": 0}, "y": {"value": 12}, "text": {"signal": "parent.facet_value"}, "limit": {"signal": "plotW * 0.4"}, "fontSize": {"value": 12}, "fontWeight": {"value": 600}, "fill": {"value": "#374151"} } } }, { "type": "rule", "interactive": false, "encode": { "update": { "x": {"signal": "cursorX === null ? 0 : cursorX"}, "y": {"signal": "headerH"}, "y2": {"signal": "headerH + plotH"}, "stroke": {"value": "#9ba1a6"}, "strokeDash": {"value": [3, 3]}, "opacity": {"signal": "cursorX === null ? 0 : 0.6"} } } }, { "type": "text", "interactive": false, "encode": { "update": { "x": {"signal": "plotW"}, "y": {"value": 12}, "align": {"value": "right"}, "text": {"signal": "hoverDate === null ? '' : timeFormat(hoverDate, '%b %d, %Y')"}, "fontSize": {"value": 11}, "fill": {"value": "#6b7280"} } } }, { "type": "symbol", "interactive": false, "from": {"data": "hover_points"}, "encode": { "update": { "x": {"scale": "x", "field": "date_value"}, "y": {"scale": "yscale", "field": "amount"}, "fill": {"scale": "color", "field": "series_value"}, "stroke": {"value": "white"}, "strokeWidth": {"value": 1}, "size": {"value": 50}, "opacity": {"signal": "datum.facet_value === parent.facet_value ? 1 : 0"} } } }, { "type": "text", "interactive": false, "from": {"data": "hover_points"}, "encode": { "update": { "x": {"signal": "plotW * 0.45 + (datum.sidx - 1) * 60"}, "y": {"value": 12}, "align": {"value": "left"}, "text": {"signal": "format(datum.amount, ',')"}, "fontSize": {"value": 11}, "fontWeight": {"value": 600}, "fill": {"scale": "color", "field": "series_value"}, "opacity": {"signal": "datum.facet_value === parent.facet_value ? 1 : 0"} } } }, { "type": "group", "from": { "facet": {"name": "series_split", "data": "cell", "groupby": "series_value"} }, "marks": [ { "type": "line", "name": "sparkline", "from": {"data": "series_split"}, "encode": { "update": { "x": {"scale": "x", "field": "date_value"}, "y": {"scale": "yscale", "field": "amount"}, "stroke": {"scale": "color", "field": "series_value"}, "strokeWidth": {"signal": "hoveredSeries === datum.series_value ? 2.5 : 1.5"}, "opacity": {"signal": "hoveredSeries === null || hoveredSeries === datum.series_value ? 1 : 0.25"}, "interpolate": {"value": "monotone"}, "tooltip": { "signal": "@{options.show_tooltip.value} ? {'Facet': datum.facet_value, 'Date': timeFormat(datum.date_value, '%Y-%m-%d'), 'Value': format(datum.amount, ',')} : null" } } } } ] } ] } ] };; } ```