# Bullet Chart > A bullet chart shows a measure against a target and qualitative ranges, packing KPI-versus-goal context into a compact bar. A bullet chart shows a measure against a target and qualitative ranges, packing KPI-versus-goal context into a compact bar. ```aml CustomChartDef bullet_chart { label: 'Bullet Chart' description: 'Use this chart to compare target, pace, and current values across categories in a compact bullet chart layout.' fields { field category { label: 'Category' type: 'dimension' data_type: 'string' sort { apply_order: 1 direction: 'asc' } } field target { label: 'Target' type: 'measure' data_type: 'number' sort { apply_order: 2 direction: 'desc' } } field pace { label: 'Pace' type: 'measure' data_type: 'number' sort { apply_order: 3 direction: 'desc' } } field current { label: 'Current' type: 'measure' data_type: 'number' sort { apply_order: 4 direction: 'desc' } } } options { option show_tooltip { label: 'Show tooltip' type: 'toggle' default_value: true } option current_bar_height { label: 'Current bar height' type: 'number-input' default_value: 8 } option target_tick_thickness { label: 'Target tick thickness' type: 'number-input' default_value: 2 } } template: @vgl { "$schema": "https://vega.github.io/schema/vega-lite/v5.json", "description": "A reusable target-vs-pace-vs-current bullet-style comparison chart.", "data": {"values": @{values}}, "width": "container", "height": "container", "transform": [ { "calculate": "datum['@{fields.target.name}']", "as": "target_value" }, { "calculate": "datum['@{fields.pace.name}']", "as": "pace_value" }, { "calculate": "datum['@{fields.current.name}']", "as": "current_value" }, { "calculate": "datum['@{fields.category.name}']", "as": "category_value" }, { "fold": ["target_value", "pace_value", "current_value"], "as": ["series_key", "series_value"] }, { "calculate": "{'target_value':'Target','pace_value':'Pace','current_value':'Current'}[datum.series_key]", "as": "series_label" }, { "calculate": "indexof(['Target','Pace','Current'], datum.series_label)", "as": "series_order" } ], "encoding": { "y": { "field": "category_value", "type": "ordinal", "title": null, "axis": { "labelOverlap": true, "domain": false, "ticks": false, "grid": false, "labelPadding": 8 } }, "x": { "field": "series_value", "type": "quantitative", "stack": null, "axis": { "title": null, "domain": false, "tickColor": "#E5E7EB", "grid": true, "gridColor": "#F3F4F6", "gridOpacity": 1 } }, "order": { "field": "series_order", "type": "quantitative", "sort": "ascending" }, "tooltip": [ { "field": "category_value", "type": "nominal", "title": "Category" }, { "field": "current_value", "type": "quantitative", "title": "Current" }, { "field": "pace_value", "type": "quantitative", "title": "Pace" }, { "field": "target_value", "type": "quantitative", "title": "Target" } ] }, "layer": [ { "mark": "bar", "params": [ { "name": "series_hover", "select": { "type": "point", "fields": ["series_label"] }, "bind": {"legend": "pointerover"} } ], "encoding": { "color": { "field": "series_label", "type": "nominal", "legend": { "title": null, "orient": "top", "direction": "horizontal", "symbolType": "square", "symbolSize": 80, "labelLimit": 140, "symbolOpacity": 1 }, "scale": { "domain": ["Target", "Pace", "Current"], "range": ["#9CA3AF", "#E5E7EB", "#4F46E5"] } }, "opacity": { "value": 0 } } }, { "transform": [ { "filter": "datum.series_label === 'Pace'" } ], "mark": { "type": "bar", "tooltip": @{options.show_tooltip.value} }, "encoding": { "color": { "field": "series_label", "type": "nominal", "legend": null, "scale": { "domain": ["Target", "Pace", "Current"], "range": ["#9CA3AF", "#E5E7EB", "#4F46E5"] } }, "opacity": { "condition": { "param": "series_hover", "value": 1 }, "value": 0.25 } } }, { "transform": [ { "filter": "datum.series_label === 'Current'" } ], "mark": { "type": "bar", "height": @{options.current_bar_height.value}, "tooltip": @{options.show_tooltip.value} }, "encoding": { "color": { "field": "series_label", "type": "nominal", "legend": null, "scale": { "domain": ["Target", "Pace", "Current"], "range": ["#9CA3AF", "#E5E7EB", "#4F46E5"] } }, "opacity": { "condition": { "param": "series_hover", "value": 1 }, "value": 0.25 } } }, { "transform": [ { "filter": "datum.series_label === 'Target'" } ], "mark": { "type": "tick", "thickness": @{options.target_tick_thickness.value}, "tooltip": @{options.show_tooltip.value} }, "encoding": { "color": { "field": "series_label", "type": "nominal", "legend": null, "scale": { "domain": ["Target", "Pace", "Current"], "range": ["#9CA3AF", "#E5E7EB", "#4F46E5"] } }, "opacity": { "condition": { "param": "series_hover", "value": 1 }, "value": 0.25 } } } ], "config": { "background": null, "view": { "stroke": null }, "axis": { "labelFontSize": 12, "titleFontSize": 12, "labelFontWeight": 400, "titleFontWeight": 500 }, "legend": { "labelFontSize": 12, "titleFontSize": 12, "labelFontWeight": 400, "symbolStrokeWidth": 0 }, "bar": { "cornerRadius": 2 }, "tick": { "thickness": 2, "size": 22 } } };; } ```