Problem/Motivation

Charts can render an accessible HTML "data table" alongside the chart (the "View data table" option). For pie and doughnut charts with the Chart.js library, that table is malformed:

  • The Label column ("My Category") shows generic Slice 1, Slice 2, … instead of the real category names.
  • The Value column ("My Value") shows the category name and the number together in a single cell, e.g. Legend 1, 17.

So the one column that should hold a clean number holds "name, value", and the column meant for the name holds a placeholder. This defeats the point of the accessible table (screen-reader users get "Slice 3 — Legend 1, 17" instead of "Legend 1 — 17").

Steps to reproduce

  1. Build a pie or doughnut chart with the Chart.js library and enable the data table ("View data table" / data_markup).
  2. View the data table under the chart.
  3. Observe: rows are labelled Slice N, and each value cell contains "name, value" instead of just the value.

Root cause

For pie/doughnut, each data point arrives as a [name, value] pair (the same shape behind Issue 1). In ChartTableBuilder::buildStandardTableData(), the single-axis branch treats each point as a scalar and has no separate labels array to draw the row header from:

if ($single_axis) {
  $data_points = $series_data[0]['data'] ?? [];
  $labels = !empty($series_data[0]['labels']) ? $series_data[0]['labels'] : $categories;

  foreach ($data_points as $index => $point) {
    // $labels is empty for pie/doughnut → falls back to "Slice N"
    $row_label = $labels[$index] ?? $this->t('Slice @n', ['@n' => $index + 1]);
    $rows[] = [
      ['data' => $row_label, 'header' => TRUE, 'scope' => 'row'],
      // $point is the whole [name, value] pair → rendered as "name, value"
      $this->processDataPoint($point),
    ];
  }
}

Because $series_data[0]['labels'] (and $categories) are empty for pie/doughnut, every row label falls back to Slice N; and because $point is the [name, value] pair rather than a scalar, the value cell renders the name and the number together.

Proposed resolution

When a point is a two-element list [scalar, numeric], split it: use the first element as the row label and the second as the value. This is fully backward-compatible — scalar points (line/bar/column single-axis) are untouched, since the guard only fires on the pie/doughnut pair shape.

foreach ($data_points as $index => $point) {
  $row_label = $labels[$index] ?? NULL;
  $value = $point;
  // Pie/doughnut points arrive as [label, value] with no separate labels
  // array; split them so the label and value land in their own columns.
  if (is_array($point) && array_is_list($point) && count($point) === 2 && is_scalar($point[0]) && is_numeric($point[1])) {
    $row_label ??= $point[0];
    $value = $point[1];
  }
  $row_label ??= $this->t('Slice @n', ['@n' => $index + 1]);
  $rows[] = [
    ['data' => $row_label, 'header' => TRUE, 'scope' => 'row'],
    $this->processDataPoint($value),
  ];
}

After the change, the pie/doughnut data table has the category name in the Label column and the plain number in the Value column; the Slice N fallback still applies only when no label is available at all.

Issue fork charts-3611409

Command icon Show commands

Start within a Git clone of the project using the version control instructions.

Or, if you do not have SSH keys set up on git.drupalcode.org:

Comments

jrochate created an issue. See original summary.

andileco made their first commit to this issue’s fork.

andileco’s picture

Status: Active » Needs review

Your patch didn't properly handle NULL (point) values. Please try this. I also need to check around more, but at least the tests pass.

jrochate’s picture

I have tested on my use case (pie and doughnut) and it works great.
I have tested with one result, OK. Also tried with no label, and got Slice N as label.

Also tested against other type of charts, and they still shows the table correctly.

At least on my multivalued 2-dim charts, is working fine.

Thanks.

  • andileco committed 33dd453f on 5.2.x
    fix: #3611409 chartjs pie/doughnut "View data table" merges name and...
andileco’s picture

Status: Needs review » Fixed

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.