--- 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.