Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I get thousands separator with center label on hover with ApexCharts donut chart?

I am building a donut chart using ApexCharts for Vue JS 3 Composition API. My goal is to have the data displayed with a thousand separator. So far, the chart correctly applies a separator to the total displayed in the middle of the donut, but when you hover over either data series and the middle text changes to them, the values are not shown with a separator:

Total displayed with separator

On hover over a series, center text is NOT formatted with separator

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

How do I have the center text display the series data with a separator as well?

Initially, This post helped me in formatting the total in the middle of the chart

I’ve tried adding a formatter function returning value.toLocaleString() to plotOptions.donut.labels.value but it has no effect on the values displayed in the center when hovering over the donut sections. I have replicated the chart itself in this CodePen

Chart options:

const options = {
  series: [12039, 1899],
  chart: {
    type: "donut"
  },
  title: {
    text: "Customers Within Standards",
    align: "center",
    style: {
      fontSize: "14px"
    }
  },
  labels: ["Within Standards", "Not Within Standards"],
  dataLabels: {
    enabled: false
  },
  dataLabels: {
    enabled: false
  },
  plotOptions: {
    pie: {
      customScale: 0.8,
      expandOnClick: false,
      dataLabels: {
        enabled: false
      },
      donut: {
        size: "60%",
        labels: {
          show: true,
          value: {
            formatter: function (value) {
              return value.toLocaleString(); // doesn't appear to apply to text
            }
          },
          total: {
            show: true,
            formatter: function (value) {
              let total = value.globals.seriesTotals.reduce((a, b) => a + b, 0);
              return total.toLocaleString();
            }
          }
        }
      }
    }
  },
  legend: {
    position: "bottom",
    offsetY: -20
  },
  tooltip: {
    enabled: false
  },

>Solution :

Issue

When you compute an aggregated total the value type is number, but the input value value type is string. All objects inherit a toLocaleString method from Object.prptotype, but only certain other types implement or override this method. See Object toLocaleString for details. Strings just return strings.

console.log("123456.78".toLocaleString());         // "123456.78"
console.log(Number("123456.78").toLocaleString()); // "123,456.78"

Solution

Cast the value in the label formatter to a number first so that internationalization can format it properly as a number.

plotOptions: {
  pie: {
    customScale: 0.8,
    expandOnClick: false,
    dataLabels: {
      enabled: false
    },
    donut: {
      size: "60%",
      labels: {
        show: true,
        value: {
          formatter: function (value) {
            return Number(value).toLocaleString(); // <-- Cast to number
          }
        },
        total: {
          show: true,
          formatter: function (value) {
            let total = value.globals.seriesTotals.reduce((a, b) => a + b, 0);
            return total.toLocaleString();
          }
        }
      }
    }
  }
},
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading