Repository navigation
Graphical Charts
The Graphical Charts report (ASIDE → Reports → Charts) displays overall execution metrics as client-side rendered charts (pie + stacked bar) instead of the legacy server-side pChart PNG images. It replaces the legacy 1.9.20 lib/results/charts.php with a modern Dashio-styled page backed by a plain-PHP REST BFF.
Path: ASIDE menu → Reports → Charts
URL: gui/templates/results/charts.html?tproject_id=<id>&tplan_id=<id>
BFF API: api/reports/index.php — GET ?action=charts_data&tproject_id=&tplan_id=
Rights: testplan_metrics
Tracking issue: #690
The header carries the test plan context; the toolbar shows the test project name and elapsed time. The screen renders up to 4 chart sections using Chart.js (client-side, no GD/pChart dependency):
| Section | Chart Type | Data Source | Condition |
|---|---|---|---|
| Overall Metrics | Pie | getExecCountersByExecStatus() |
Always shown (if data exists) |
| Overall Metrics by Platform | One pie per platform | getStatusTotalsByPlatformForRender() |
Only when plan has linked platforms |
| Results by Keyword | Stacked bar | getStatusTotalsByKeywordForRender() |
Only when keywords are linked |
| Results by Top-Level Test Suite | Stacked bar | getStatusTotalsByTopLevelTestSuiteForRender() |
Always shown (if data exists) |
- No chart data — "No chart data available for this test plan." with a chart icon.
- Individual sections hide automatically when their data source returns empty.
- Client-side rendering — Chart.js replaces server-side pChart + GD PNG generation
-
No GD dependency — the legacy
checkLibGd()guard is irrelevant - Single BFF call — one AJAX request returns all chart data as JSON (vs 5 separate PHP scripts generating images)
- Interactive — charts support hover tooltips with percentage breakdowns
- Responsive — charts resize with the viewport
GET /api/reports/index.php?action=charts_data&tproject_id=1&tplan_id=2
Response:
{
"status": "ok",
"tproject_name": "My Project",
"tplan_name": "My Plan",
"charts": {
"overall": { "labels": ["Not Run", "Passed", "Failed"], "values": [5, 3, 1], "colors": ["#000", "#006400", "#B22222"] },
"platforms": [{ "name": "Platform A", "labels": [...], "values": [...], "colors": [...] }],
"by_keyword": { "labels": ["K1", "K2"], "datasets": [{"label":"Not Run","data":[2,3],"backgroundColor":"#000"}] },
"by_suite": { "labels": ["Suite A"], "datasets": [{"label":"Passed","data":[5],"backgroundColor":"#006400"}] }
},
"elapsed_time": 0.02
}The BFF calls the same tlTestPlanMetrics methods the legacy pChart scripts used, serializes the data as JSON, and the frontend renders it with Chart.js. Status colors come from $tlCfg->results['charts']['status_colour'] (cfg/const.inc.php).
Mirroring the legacy charts.php:79-112 init_args() and the results_flat/metrics_general precedent (#1220/#1246), the BFF charts_data action accepts the legacy apikey argument:
-
32-char — remote access for the owning user (
setUpEnvForRemoteAccess+testplan_metricsrights). -
longer (64-char) — anonymous/public read-only access tied to the test plan or test project carrying that key (
setUpEnvForAnonymousAccess,addOpAccess=false); the contextual rights re-check is skipped.
The screen forwards its own apikey query param to every BFF request, so a public link such as:
gui/templates/results/charts.html?tproject_id=1&tplan_id=2&apikey=<plan-or-project-key>
renders the full chart report without any login. The apikey allow-list in the BFF is limited to results_flat, metrics_general and charts_data; all other report actions keep session-only auth. Unknown keys → 401.
| # | Test | Result |
|---|---|---|
| 1 | Aside link switches to modernized page | PASS |
| 2 | Header shows plan/project names | PASS |
| 3 | Overall Metrics pie chart renders | PASS |
| 4 | BFF returns correct JSON structure | PASS |
| 5 | BFF data matches executions | PASS |
| 6 | Colors match TestLink config | PASS |
| 7 | Locale switcher works | PASS |
| 8 | No console errors | PASS |
| 9 | No network errors | PASS |
| 10 | Empty plan shows graceful handling | PASS |
| 11 | getRootTestSuites crash guard | PASS |
| 12 | Rights gate enforced | PASS |
| 13 | Event Viewer clean | PASS |
Actual result: 13/13 PASS.
Bug fixed: lib/functions/testplan.class.php — getRootTestSuites() now returns early on empty $items/$tlnodes instead of generating invalid WHERE id IN () SQL. The BFF also wraps the call in try/catch as a safety net.