---
name: bricks-chart-widgets
description: Bricks frameworks ECharts chart widgets reference (ChartBar, ChartPie, ChartScatter) with pitfalls and usage patterns
tags: [bricks, echarts, chart, frontend, visualization]
related_skills: [bricks-framework]
---
# Bricks ECharts Chart Widgets
## Available Widget Types
Bricks includes native ECharts-based chart widgets in `bricks/bricks/*.js`:
`ChartBar`, `ChartPie`, `ChartScatter`, `ChartLine`, `ChartRadar`, `ChartMap`, `ChartHeatmap`, `ChartKLine`.
All extend `bricks.EchartsExt` (extends `bricks.VBox`). ECharts bundled at `bricks/dist/3parties/echarts.min.js`.
## ChartBar / ChartLine
```json
{
"widgettype": "ChartBar",
"options": {
"height": "180px",
"data_url": "/module/api/endpoint.dspy",
"nameField": "category_field",
"valueFields": ["value1", "value2"]
}
}
```
- `nameField`: x-axis category labels from data rows
- `valueFields`: array of numeric fields, each = one bar/line series
- Auto-fetches `data_url` via `HttpJson` → `render_data()` → `setup_options()` → `chart.setOption()`
- Supports `refresh_period` (seconds) for auto-refresh
## ChartPie
```json
{
"widgettype": "ChartPie",
"options": {
"height": "200px",
"data_url": "/module/api/endpoint.dspy",
"nameField": "currency",
"valueFields": ["call_count"],
"pie_options": {"type": "pie", "radius": "60%"}
}
}
```
### CRITICAL: `pie_options` Required
ChartPie **requires** `pie_options: {"type": "pie"}`. Without it, `s_opts` = `{}` (no `type`), ECharts defaults to `type: "line"` → chart renders invisible — **no error, just blank space**. Symptom: empty area under chart title with no visible chart elements.
## ChartScatter
```json
{
"widgettype": "ChartScatter",
"options": {
"height": "240px",
"data_url": "/module/api/endpoint.dspy",
"nameField": "model",
"xField": "unit_price",
"yField": "avg_ttft_ms",
"sizeField": "total_calls",
"categoryField": "provider_name"
}
}
```
**ChartScatter does NOT use `valueFields`** — uses `xField`, `yField`, `sizeField` (bubble size), `nameField` (tooltip label), `categoryField` (color grouping). Tooltip shows nameField value (from `p.value[2]`) + xField/yField.
### series0 Legend Fix
Default tooltip shows `seriesName` ("series0"). To show nameField and hide meaningless legend, patch `bricks/bricks/scatter.js`:
```javascript
formatter: function(params) {
const p = params[0];
const name = p.value[2] ? p.value[2] + '
' : '';
return name + xAxisName + ': ' + p.value[0] + '
' + yAxisName + ': ' + p.value[1];
}
legend: { show: false }
```
After patching: `cd bricks && bash build.sh` → copy `dist/bricks.js` to Sage.
## Pitfalls
1. **`WebWidget` does NOT exist** in bricks. Use native chart widgets, not `WebWidget`.
2. **ChartPie needs `pie_options`** with `type:"pie"` or renders blank.
3. **ChartScatter uses `xField`/`yField`** not `valueFields`.
4. **`entire_url` unavailable** in RefreshWidget sub-pages → use absolute paths for `data_url`.
5. **CSS-only fallback**: For simple bars without ECharts, use `VBox` with `width:"75%"` + `bgcolor` as progress bars.
6. **`actiontype: "urldata"` crashes without `status_of`** — `_buildDataHandler` needs `desc.status_of[data.status]`. For ChartBar period buttons, use `actiontype: "method"` with `method: "render_urldata"` (inherited from `EchartsExt`). Chart uses `data_params` for defaults, buttons pass params:
```json
{"data_url": ".../api/chart.dspy", "data_params": {"period": "all"}}
{"actiontype": "method", "target": "chart_id", "method": "render_urldata", "params": {"period": "year"}}
```
## i18n Pattern — `merge_i18n.py` + `msg.txt`
Sage i18n uses repo-root `i18n/{lang}/msg.txt` in `key: value` line format, NOT per-package JSON. `merge_i18n.py` consolidates into `wwwroot/i18n/`. Bricks Tabular built-in strings must be in `bricks/i18n/{lang}/msg.txt`; bricks must be LAST in merge priority.
```jinja2
// WRONG — non-admin gets trailing comma: },]
{ "shared": "section" },
{% if is_admin %}
{ "admin": "only" },
{% endif %}
// CORRECT — comma only rendered when block fires
{ "shared": "section" }
{% if is_admin %},
{ "admin": "only" }
{% endif %}
```
## i18n Pattern
Use `otext` + `"i18n": true` (NOT `text`). Files in `MODULE/i18n/{zh,en,jp,ko}/i18n.json`. Requires `pip install .` to deploy (i18n files are in package, not wwwroot).
## Jinja2 Async Function Fallback
```jinja2
{% set is_distributor = false %}
{% if j2_is_distributor is defined %}
{% set is_distributor = j2_is_distributor(request) %}
{% endif %}
```
Prevents UndefinedError → black screen when function not registered in current deployment.