Label text on amCharts5 pie-chart cannot be accessed in adapter

275 Views Asked by At

I'm labelling sectors of a pie-chart in amCharts5 with the 'category' value. I want to change the label text to 'Unknown' on any sector which has an empty category value.

I've written an adapter but I get the following error:

"Uncaught TypeError: Cannot read properties of undefined (reading 'get')"

It looks like dataItem is not being instantiated. I don't understand why not.

How might I check for empty labels and replace them with 'Unknown'?

// Create pie-chart series

var series = chart.series.push(am5percent.PieSeries.new(root, {
   valueField: "eventCount",
   categoryField: "category"
}));

// Add adapter to change label on empty sectors to 'Unknown'.

series.labels.template.adapters.add("text", function(text, target) {
   return target.dataItem.get("category").length > 0 ? text : 'Unknown';
});
1

There are 1 best solutions below

0
On

You have to check if dataItem is defined, then access the category through dataContext.

Your code should look like this:

series.labels.template.adapters.add("text", (text, target) => {
  if (target.dataItem?.dataContext.category === "") {
    return "Unknown: {valuePercentTotal}%";
  }
    
  return text;
});

Here is a full example:

am5.ready(() => {

  let root = am5.Root.new("chartdiv");

  let chart = root.container.children.push(
    am5percent.PieChart.new(root, {})
  );

  let series = chart.series.push(
    am5percent.PieSeries.new(root, {
      valueField: "value",
      categoryField: "category"
    })
  );
  
  series.labels.template.set("text", "{category}: {valuePercentTotal}%");
  
  series.labels.template.adapters.add("text", (text, target) => {
    if (target.dataItem?.dataContext.category === "") {
      return "Unknown: {valuePercentTotal}%";
    }
    
    return text;
  });
  
  series.slices.template.set("tooltipText", "");

  series.data.setAll([
    {
      category: "Foo",
      value: 30
    },
    {
      category: "",
      value: 60
    },
    {
      category: "Baz",
      value: 10
    }
  ]);

});
#chartdiv {
  width: 100%;
  height: 350px;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/index.min.js"></script>
<script src="https://cdn.amcharts.com/lib/5/index.js"></script>
<script src="https://cdn.amcharts.com/lib/5/percent.js"></script>

<div id="chartdiv"></div>

Warning: my code above uses optional chaining (?.) for which you may need a polyfill. If you do not want that, you can do this instead:

if (target.dataItem && target.dataItem.dataContext.category === "") {
  // ...
}