DevExtreme v26.1 is now available.

Explore our newest features/capabilities and share your thoughts with us.

Your search did not match any results.

Angular Charts - Center Label Customization

To customize the doughnut's center, declare the SVG markup in the centerTemplate. This template accepts the PieChart instance. Use this instance to call PieChart methods. For example, call the getInnerRaduis() method to get the radius of the doughnut hole.

Backend API
<div> <div class="long-title"><h3>Energy Production (GWh, 2024)</h3></div> <div class="pies-container"> @for(country of countries; track country) { <dx-pie-chart class="pie" sizeGroup="piesGroup" [dataSource]="service.getData(country)" [animation]="false" resolveLabelOverlapping="shift" type="doughnut" centerTemplate="centerTemplate" [innerRadius]="0.65" > <dxi-pie-chart-series argumentField="commodity" valueField="total"> <dxo-pie-chart-label backgroundColor="none" [visible]="true" format="fixedPoint" [customizeText]="customizeLabel" > <dxo-pie-chart-connector [visible]="true"></dxo-pie-chart-connector> </dxo-pie-chart-label> </dxi-pie-chart-series> <dxo-pie-chart-legend [visible]="false"> </dxo-pie-chart-legend> <svg *dxTemplate="let pieChart of 'centerTemplate'"> <circle cx="100" cy="100" [attr.r]="pieChart.getInnerRadius() - 6" fill="#eee" ></circle> <image attr.href="{{ getImagePath(country) }}" x="70" y="58" width="60" height="40" /> <text class="center-label" text-anchor="middle" x="100" y="120" fill="#494949" > <tspan x="100">{{ country }}</tspan> <!-- display: inline --> <tspan class="center-label-total" x="100" dy="20px">{{ calculateTotal(pieChart) }}</tspan> </text> </svg> </dx-pie-chart> } </div> </div>
import { bootstrapApplication } from '@angular/platform-browser'; import { Component, enableProdMode, provideZoneChangeDetection } from '@angular/core'; import { DxPieChartModule } from 'devextreme-angular'; import { DecimalPipe } from '@angular/common'; import { Service } from './app.service'; if (!/localhost/.test(document.location.host)) { enableProdMode(); } @Component({ selector: 'demo-app', templateUrl: './app.component.html', styleUrls: ['./app.component.css'], providers: [Service], imports: [ DxPieChartModule, ], }) export class AppComponent { service: Service; countries: Iterable<string>; pipe = new DecimalPipe('en-US'); constructor(service: Service) { this.service = service; this.countries = new Set(service.getData().map((item) => item.country)); } customizeLabel(e) { return `${e.argumentText}\n${e.valueText}`; } calculateTotal(pieChart) { const totalValue = pieChart.getAllSeries()[0].getVisiblePoints().reduce((s, p) => s + p.originalValue, 0); return this.pipe.transform(totalValue, '1.0-0'); } getImagePath(country) { return `../../../../images/flags/${country.replace(/\s/, '').toLowerCase()}.svg`; } } bootstrapApplication(AppComponent, { providers: [ provideZoneChangeDetection({ eventCoalescing: true, runCoalescing: true }), ], });
::ng-deep .pies-container { margin: auto; width: 800px; } ::ng-deep .pies-container > .pie { width: 400px; margin-top: -50px; float: left; } ::ng-deep .long-title h3 { font-weight: 200; font-size: 28px; text-align: center; margin-bottom: 20px; } ::ng-deep .center-label { font-size: 18px; } ::ng-deep .center-label-total { font-weight: 600; }
import { Injectable, } from '@angular/core'; export class DataItem { country: string; commodity: string; total: number; } const data: DataItem[] = [ { country: 'France', commodity: 'Nuclear', total: 360000 }, { country: 'France', commodity: 'Thermal', total: 52000 }, { country: 'Germany', commodity: 'Thermal', total: 210000 }, { country: 'France', commodity: 'Wind', total: 50000 }, { country: 'Germany', commodity: 'Wind', total: 140000 }, { country: 'France', commodity: 'Solar', total: 23000 }, { country: 'Germany', commodity: 'Solar', total: 70000 }, { country: 'Germany', commodity: 'Hydro', total: 20000 }, { country: 'France', commodity: 'Hydro', total: 65000 }, { country: 'Germany', commodity: 'Biomass', total: 45000 }, ]; const cache = {}; @Injectable() export class Service { getData(country?: string): DataItem[] { if (country) { if (!cache[country]) { cache[country] = data.filter((item) => item.country === country); } return cache[country]; } return data; } }
<!DOCTYPE html> <html lang="en"> <head> <title>DevExtreme Demo</title> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" /> <link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/26.1.5/css/dx.light.css" /> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> <script src="https://cdn.jsdelivr.net/npm/zone.js@0.16.2/bundles/zone.umd.js"></script> <script src="./bundle.js" type="module"></script> </body> </html>