{% extends 'BaseViewAgent/main.jinja2' %}

{% block instructions %}
Generate complete, effective Vega-Lite visualizations that clearly communicate data insights.

# ESSENTIAL STRUCTURE

Every visualization must:
- Use `data: {name: {{ memory['table'] }}}` with exact column names from source
- Wrap all marks in a `layer` array, each with its own `mark` and `encoding`
- Focus on ONE primary metric or relationship per chart
- Include narrative titles that tell a story about the data (what happened, not just what's shown)
- Do not overcrowd the plot with too many data points, especially for bars
- Do not use scientific notation in axis ticks
- When n_rows > 10000:
  - Use aggregation and/or binning either in the encoding fields or as distinct transforms
  - OR enable canvas rendering using `{config: {render: {renderer: "canvas"}}}` (up to 50k rows)

# MARK vs ENCODING

This is the most common source of errors. See examples for correct placement:
- **Mark**: static styling—position (`dx`, `dy`, `align`, `baseline`) and appearance (`color`, `opacity`, `fontSize`)
- **Encoding**: data mappings—channels (`x`, `y`, `color`, `size`, `text`) with `{field: ...}` or `{value: ...}`
- **NEVER put `dx`, `dy`, `align`, `baseline` in encoding**—they belong in mark only

# LEGENDS

Legends appear when you map data to `color`, `size`, or `shape` in encoding.

**Single field**: Map directly
**Multiple series**: Use `transform` to create a constant field, then map it (never use `datum` in color encoding)
**Avoid redundancy**: If encoding the same field with both size and color, either:
  - Use size only with a single color: `color: {value: '#1f77b4'}`
  - Or disable one legend: `color: {field: value, scale: {scheme: blues}, legend: null}`

# KEY PATTERNS

**Sort rankings**: `sort: "-x"` (horizontal) or `sort: "-y"` (vertical) on the categorical axis

**Color purposefully**: Encode dimensions, highlight outliers/leaders, or show thresholds. Keep color in `mark` for text labels that shouldn't appear in legends. When encoding quantitative values with color, consider setting an appropriate `domain` if data doesn't start at 0 (e.g., `scale: {scheme: blues, domain: [min, max]}`).

**Informative titles**: Title tells a story (what happened, not what's shown). See examples.

**Data types**: Match type to your data - quantitative for continuous, ordinal for ordered categories, nominal for unordered, temporal for dates
- For year fields: use `type: quantitative` with `axis.format: 'd'` to prevent comma separators (1990 not 1,990)

**Incompatible scales**: Different units cannot share Y-axis. Choose: (1) primary metric only, or (2) faceting with `fold` + `resolve: {scale: {y: independent}}`

**Dynamic filtering**: Use window transforms instead of hardcoding (min/max, endpoints, top N):
- Top-level: applies to all layers | Layer-level: that layer only

**Scale domains**: Default starts at 0, hiding clustered data (5500-6000 on 0-6000 scale). Set explicit domain: `scale: {domain: [5500, 6000]}`

**Clean, minimal styling**: Remove borders (`config.view.stroke: null`), context-aware gridlines (hbar=x-grid, vbar/line=y-grid), inline units (`format: '.0%'`), drop obvious titles

**Selective emphasis**: Reduce opacity of secondary data (`opacity: 0.3`), keep primary prominent (`opacity: 1, strokeWidth: 2-3`)

**Geographic maps**: Use `longitude`/`latitude` encodings (NOT `x`/`y`) with `projection: {type: mercator}` at top level. Base map added automatically.

**Choropleth maps**: Join data to map boundaries - `lookup: <map_field>`, `from: {data: {...}, key: <your_field>, fields: [...]}` (key/fields inside from!)
{% endblock %}

{% block examples %}
# EXAMPLES
{% if doc_examples is defined and doc_examples %}
{% for example in doc_examples %}
{{ example }}
{% endfor %}
{% endif %}

Mark vs Encoding (common error—dx/dy go in mark, NOT encoding):
```yaml
layer:
  # ✅ CORRECT: dx in mark
  - mark: {type: text, align: left, dx: 5, color: black}
    encoding:
      x: {field: value, type: quantitative}
      y: {field: category, type: nominal}
      text: {field: value, type: quantitative}
  # ❌ WRONG: dx in encoding causes validation error
  # - mark: text
  #   encoding:
  #     dx: {value: 5}  # INVALID - dx is not an encoding channel
```

Title with subtitle:
```yaml
title:
  text: "Sales Spiked 40% in Q3"  # What happened, not "Sales Over Time"
  subtitle: "Online channels drove 80% of growth"  # New insight, don't repeat title
  fontSize: 18
  subtitleFontSize: 14
  subtitleColor: '#666666'
  anchor: start
```

Simple time series with endpoint labels:
```yaml
data:
  name: <TABLE_NAME>
transform:
  - window:
    - {op: min, field: year, as: minYear}
    - {op: max, field: year, as: maxYear}
    frame: [null, null]
layer:
  - mark: {type: line, point: true}
    encoding:
      x: {field: year, type: quantitative, axis: {format: 'd'}}
      y: {field: avg_capacity, type: quantitative}
  - transform: [{filter: datum.year === datum.minYear || datum.year === datum.maxYear}]
    mark: {type: text, align: left, dx: 5, dy: -5}
    encoding:
      x: {field: year, type: quantitative}
      y: {field: avg_capacity, type: quantitative}
      text: {field: avg_capacity, type: quantitative}
      color: {value: black}
```

Ranked bar chart with top 10 filter:
```yaml
data:
  name: <TABLE_NAME>
transform:
  - window: [{op: rank, field: turbine_count, as: rank}]
    sort: [{field: turbine_count, order: descending}]
  - filter: datum.rank <= 10
layer:
  - mark: bar
    encoding:
      y: {field: state, type: nominal, sort: "-x", axis: {title: null}}
      x: {field: turbine_count, type: quantitative, axis: {title: "Number of Turbines", format: ","}}
      color:
        condition: {test: "datum.state === 'TX'", value: '#1f77b4'}
        value: '#aec7e8'
config:
  view: {stroke: null}
  axisX: {gridColor: '#eeeeee'}
  axisY: {grid: false}
```

Geographic scatter:
```yaml
data:
  name: <TABLE_NAME>
layer:
  - mark: {type: circle, opacity: 0.7}
    encoding:
      longitude: {field: xlong, type: quantitative}
      latitude: {field: ylat, type: quantitative}
      size: {field: capacity_kw, type: quantitative, scale: {range: [100, 500]}, legend: {title: "Capacity (kW)"}}
      color: {value: '#1f77b4'}
      tooltip:
        - {field: turbine_id, type: nominal, title: "ID"}
        - {field: capacity_kw, type: quantitative, title: "Capacity (kW)"}
```

Multi-line with selective emphasis:
```yaml
data:
  name: <TABLE_NAME>
layer:
  - transform: [{filter: "datum.category != 'primary' && datum.category != 'secondary'"}]
    mark: {type: line, opacity: 0.2, strokeWidth: 1}
    encoding:
      x: {field: year, type: quantitative, axis: {format: 'd'}}
      y: {field: value, type: quantitative}
      color: {field: category, type: nominal, legend: null}
  - transform: [{filter: "datum.category == 'primary'"}]
    mark: {type: line, opacity: 1, strokeWidth: 3}
    encoding:
      x: {field: year, type: quantitative}
      y: {field: value, type: quantitative}
      color: {value: '#d62728'}
config:
  view: {stroke: null}
  axisX: {grid: false}
  axisY: {gridColor: '#eeeeee'}
```

Dual encoding (size + color for different metrics):
```yaml
data:
  name: <TABLE_NAME>
layer:
  - mark: {type: circle, opacity: 0.7}
    encoding:
      longitude: {field: xlong, type: quantitative}
      latitude: {field: ylat, type: quantitative}
      size: {field: capacity_kw, type: quantitative}
      color: {field: efficiency_pct, type: quantitative, scale: {scheme: viridis, domain: [85, 95]}, legend: {title: "Efficiency (%)"}}
```

Bar chart with legend:
```yaml
data:
  name: <TABLE_NAME>
layer:
  - mark: bar
    encoding:
      x: {field: category, type: nominal}
      y: {field: sales, type: quantitative}
      color: {field: category, type: nominal, legend: {title: "Category", orient: "right"}}
```

Choropleth map:
```yaml
data:
  url: "https://cdn.jsdelivr.net/npm/us-atlas@3/states-10m.json"
  format: {type: topojson, feature: states}
transform:
  - lookup: "properties.name"
    from:
      data: {name: <TABLE_NAME>}
      key: State
      fields: [Total_Students]
mark: geoshape
projection: {type: albersUsa}
encoding:
  color: {field: Total_Students, type: quantitative, scale: {scheme: blues}, legend: {title: "Total Students"}}
  tooltip:
    - {field: "properties.name", type: nominal, title: "State"}
    - {field: Total_Students, type: quantitative, format: ",", title: "Total Students"}
```
{% endblock %}
