Pie dough nut in EJ2 TypeScript Accumulation chart control

8 May 202324 minutes to read

Pie Chart

To render a pie series, use the series type as Pie and inject the PieSeries module using AccumulationChart.Inject(PieSeries) method. If the PieSeries module is not injected, this module will be loaded by default.

import { AccumulationChart, PieSeries } from '@syncfusion/ej2-charts';
AccumulationChart.Inject(PieSeries);

let piechart: AccumulationChart = new AccumulationChart({
    series: [
        {
            dataSource: [{ x: 'Jan', y: 3 }, { x: 'Feb', y: 3.5 }, { x: 'Mar', y: 7 }, { x: 'Apr', y: 13.5 },{ x: 'May', y: 19 }, { x: 'Jun', y: 23.5 }, { x: 'Jul', y: 26 }, { x: 'Aug', y: 25 },
            { x: 'Sep', y: 21 }, { x: 'Oct', y: 15 }],
            type:'Pie',
            xName: 'x',
            yName: 'y'
        }
    ]
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Radius Customization

By default, radius of the pie series will be 80% of the size (minimum of chart width and height). You can customize this using radius property of the series.

import { AccumulationChart } from '@syncfusion/ej2-charts';
import { data } from './datasource.ts';
let piechart: AccumulationChart = new AccumulationChart({
    series: [
        {
            dataSource: data,
            radius: '100%',
            xName: 'x',
            yName: 'y'
        }
    ]
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Pie Center

The center position of the pie can be changed by Center X and Center Y. By default, center value of the pie series x and y is 50%. You can customize this using center property of the series.

import { AccumulationChart, PieSeries } from '@syncfusion/ej2-charts';
AccumulationChart.Inject(PieSeries);

let piechart: AccumulationChart = new AccumulationChart({
  // Initialize the chart series
        series: [
            {
                dataSource: [
                    { 'x': 'Chrome', y: 37, text: '37%' }, { 'x': 'UC Browser', y: 17, text: '17%' },
                    { 'x': 'iPhone', y: 19, text: '19%' },
                    { 'x': 'Others', y: 4, text: '4%' }, { 'x': 'Opera', y: 11, text: '11%' },
                    { 'x': 'Android', y: 12, text: '12%' }
                ],
                dataLabel: {
                    visible: true, position: 'Inside', name: 'text', font: { fontWeight: '600' }
                },
                radius: '70%', xName: 'x', yName: 'y', name: 'Browser'
            }
        ],
        center: { x: '60%', y: '60%' },
        enableSmartLabels: true,
        enableAnimation: false,
        legendSettings: { visible: false },
        // Initialize tht tooltip
        tooltip: { enable: true, format: '${point.x} : <b>${point.y}%</b>' },
        title: 'Mobile Browser Statistics'

}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Various Radius Pie Chart

You can use radius mapping to render the slice with different radius pie and also use border , fill properties to customize the point. dataLabel is used to represent individual data and its value.

import { AccumulationChart, AccumulationLegend, PieSeries, AccumulationDataLabel } from '@syncfusion/ej2-charts';
AccumulationChart.Inject(AccumulationChart, AccumulationLegend, PieSeries, AccumulationDataLabel );

let piechart: AccumulationChart = new AccumulationChart({
   series: [
            {

                dataSource: [
                    { x: 'Argentina', y: 505370, r: '100' },
                    { x: 'Belgium', y: 551500, r: '118.7' },
                    { x: 'Cuba', y: 312685, r: '124.6' },
                    { x: 'Dominican Republic', y: 350000, r: '137.5' },
                    { x: 'Egypt', y: 301000, r: '150.8' },
                    { x: 'Kazakhstan', y: 300000, r: '155.5' },
                    { x: 'Somalia', y: 357022, r: '160.6' }

                ],
                dataLabel: {
                    visible: true, position: 'Outside',
                    name: 'x'

                },
                radius: 'r', xName: 'x',
                yName: 'y', innerRadius: '20%'
            },

        ],
        enableSmartLabels: true,
        legendSettings: {
            visible: true,
        },
        enableAnimation: true,
        title: 'Countries compared by population density and total area'
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Doughnut Chart

To achieve a doughnut in pie series, customize the innerRadius property of the series. By setting value greater than 0%, a doughnut will appear. The innerRadius property takes value from 0% to 100% of the pie radius.

import { AccumulationChart } from '@syncfusion/ej2-charts';
import { data } from './datasource.ts';
let piechart: AccumulationChart = new AccumulationChart({
    series: [
        {
            dataSource: data,
            innerRadius: '40%',
            xName: 'x',
            yName: 'y'
        }
    ]
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Start and End angles

You can customize the start and end angle of the pie series using the startAngle and endAngle properties. The default value of startAngle is 0 degree, and endAngle is 360 degrees. By customizing this, you can achieve a semi pie series.

import { AccumulationChart, AccumulationDataLabel  } from '@syncfusion/ej2-charts';
import { dataMapping } from './datasource.ts';
AccumulationChart.Inject(AccumulationDataLabel);

let piechart: AccumulationChart = new AccumulationChart({
    series: [
        {
            dataSource: dataMapping,
            startAngle: 270,
            endAngle: 90,
            xName: 'x',
            yName: 'y'
        }
    ]
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Color & Text Mapping

The fill color and the text in the data source can be mapped to the chart using pointColorMapping in series and name in datalabel respectively.

import { AccumulationChart, AccumulationDataLabel  } from '@syncfusion/ej2-charts';
import { dataMapping } from './datasource.ts';
AccumulationChart.Inject(AccumulationDataLabel);

let piechart: AccumulationChart = new AccumulationChart({
    series: [
        {
            dataSource:dataMapping ,
            //Map the fill color from data source
            pointColorMapping: 'fill',
            //Map the fill color from data source
            name: ''
            xName: 'x',
            yName: 'y',
            dataLabel: { visible: true, name:'text' }
        }
    ]
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Customization

Individual points can be customized using the pointRender event.

import { AccumulationChart, AccumulationDataLabel, IAccPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { dataMapping } from './datasource.ts';
AccumulationChart.Inject(AccumulationDataLabel);
let piechart: AccumulationChart = new AccumulationChart({
    series: [
        {
            dataSource: dataMapping,
            xName: 'x',
            yName: 'y',
            border: { color: 'white', width: 1 },
        }
    ],
    pointRender: (args: IAccPointRenderEventArgs) => {
        if ((args.point.x as string).indexOf('Apr') > -1) {
            args.fill = '#f4bc42';
        }
        else {
            args.fill = '#597cf9';
        }
    },
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Hide pie or doughnut border

By default, the border will appear in the pie/doughnut chart while mouse hover on the chart. You can disable the the border by setting enableBorderOnMouseMove property is false.

import { AccumulationChart, AccumulationDataLabel, IAccPointRenderEventArgs } from '@syncfusion/ej2-charts';
import { dataMapping } from './datasource.ts';
AccumulationChart.Inject(AccumulationDataLabel);
let piechart: AccumulationChart = new AccumulationChart({
    enableBorderOnMouseMove: false,
    series: [
        {
            dataSource: dataMapping,
            xName: 'x',
            yName: 'y',
        }
    ]
}, '#element');
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div id='container'>
        <div id='element'></div>
    </div>
</body>

</html>

Multi-level pie chart

You can achieve a multi-level drill down in pie and doughnut charts using pointClick event. If user clicks any point in the chart, that corresponding data will be shown in the next level and so on based on point clicked.

You can also achieve drill-up (back to the initial state) by using chartMouseClick event. In below sample, you can drill-up by clicking back button in the center of the chart.

import {
    AccumulationTheme, getElement, AccumulationChart, AccumulationLegend, PieSeries,
    AccumulationTooltip, IAccLoadedEventArgs, IAccTextRenderEventArgs,
    chartMouseClick, IMouseEventArgs, Index, indexFinder, AccumulationDataLabel,
    AccumulationChartModel, AccumulationAnnotation
} from '@syncfusion/ej2-charts';
import { EmitType } from '@syncfusion/ej2-base';
AccumulationChart.Inject(AccumulationLegend, PieSeries, AccumulationTooltip, AccumulationDataLabel, AccumulationAnnotation);
/**
 * Sample fro Drill Down in Pie chart
 */
//tslint:disable:max-func-body-length

let suvs: Object = [{ x: 'Toyota', y: 8 }, { x: 'Ford', y: 12 }, { x: 'GM', y: 17 }, { x: 'Renault', y: 6 }, { x: 'Fiat', y: 3 },
{ x: 'Hyundai', y: 16 }, { x: 'Honda', y: 8 }, { x: 'Maruthi', y: 10 }, { x: 'BMW', y: 20 }];
let cars: Object = [{ x: 'Toyota', y: 7 }, { x: 'Chrysler', y: 12 }, { x: 'Nissan', y: 9 }, { x: 'Ford', y: 15 }, { x: 'Tata', y: 10 },
{ x: 'Mahindra', y: 7 }, { x: 'Renault', y: 8 }, { x: 'Skoda', y: 5 }, { x: 'Volkswagen', y: 15 }, { x: 'Fiat', y: 3 }];
let pickups: Object = [{ x: 'Nissan', y: 9 }, { x: 'Chrysler', y: 4 }, { x: 'Ford', y: 7 }, { x: 'Toyota', y: 20 },
{ x: 'Suzuki', y: 13 }, { x: 'Lada', y: 12 }, { x: 'Bentley', y: 6 }, { x: 'Volvo', y: 10 }, { x: 'Audi', y: 19 }];
let minivans: Object = [{ x: 'Hummer', y: 11 }, { x: 'Ford', y: 5 }, { x: 'GM', y: 12 }, { x: 'Chrysler', y: 3 }, { x: 'Jaguar', y: 9 },
{ x: 'Fiat', y: 8 }, { x: 'Honda', y: 15 }, { x: 'Hyundai', y: 4 }, { x: 'Scion', y: 11 }, { x: 'Toyota', y: 17 }];
let clickInstance: AccumulationChartModel = {
    series: [{
        type: 'Pie', dataSource: suvs, xName: 'x', yName: 'y',
        dataLabel: { visible: true, position: 'Outside' }, innerRadius: '30%',
    }
    ], textRender: (args: IAccTextRenderEventArgs) => {
        args.text = args.point.x + ' ' + args.point.y + ' %';
    }, annotations: [{
        content: '<div id="back" style="cursor:pointer;padding:3px;width:30px; height:30px;">' +
            '<img src="//ej2.syncfusion.com/demos/src/chart/images/back.png" id="back" />', region: 'Series', x: '50%', y: '50%'
    }], chartMouseClick: (args: IMouseEventArgs) => {
        if (args.target.indexOf('back') > -1) {
            let tooltip: Element = document.getElementsByClassName('e-tooltip-wrap')[0];
            if (tooltip) { tooltip.remove(); }
            pie.destroy(); pie.removeSvg(); pie = null; pie = new AccumulationChart(instance);
            pie.appendTo('#container');
            (getElement('category') as HTMLButtonElement).style.visibility = 'hidden';
            (getElement('symbol') as HTMLElement).style.visibility = 'hidden';
            (<HTMLElement>getElement('text')).style.visibility = 'hidden';
        }
    },
    legendSettings: { visible: false }, enableSmartLabels: true,
    tooltip: { enable: false, format: '${point.x} <br> ${point.y} %' },

};
let pointClick: EmitType<IMouseEventArgs> = (args: IMouseEventArgs) => {
    let index: Index = indexFinder(args.target);
    if (getElement(pie.element.id + '_Series_' + index.series + '_Point_' + index.point)) {
        let tooltip: Element = document.getElementsByClassName('e-tooltip-wrap')[0];
        if (tooltip) { tooltip.remove(); }
        pie.destroy(); pie.removeSvg(); pie = null;
        switch (index.point) {
            case 0:
                clickInstance.series[0].dataSource = suvs; getElement('text').innerHTML = 'SUV';
                clickInstance.title = 'Automobile Sales in the SUV Segment';
                break;
            case 1:
                clickInstance.series[0].dataSource = cars; getElement('text').innerHTML = 'Car';
                clickInstance.title = 'Automobile Sales in the Car Segment';
                break;
            case 2:
                clickInstance.series[0].dataSource = pickups; getElement('text').innerHTML = 'Pickup';
                clickInstance.title = 'Automobile Sales in the Pickup Segment';
                break;
            case 3:
                clickInstance.series[0].dataSource = minivans; getElement('text').innerHTML = 'Minivan';
                clickInstance.title = 'Automobile Sales in the Minivan Segment';
                break;
        }
        pie = new AccumulationChart(clickInstance); pie.appendTo('#container');
        (<HTMLElement>getElement('symbol')).style.visibility = 'visible';
        (<HTMLElement>getElement('category')).style.visibility = 'visible';
        (<HTMLElement>getElement('text')).style.visibility = 'visible';
    }
};
let instance: AccumulationChartModel = {
    series: [
        {
            dataSource: [{ x: 'SUV', y: 25 }, { x: 'Car', y: 37 }, { x: 'Pickup', y: 15 }, { x: 'Minivan', y: 23 }],
            dataLabel: {
                visible: true, position: 'Inside', connectorStyle: { type: 'Curve', length: '10%' },
                font: { fontWeight: '600', color: 'white' }
            },
            radius: '70%', xName: 'x', yName: 'y', startAngle: 0, endAngle: 360, innerRadius: '0%',
            explode: false
        }
    ], enableSmartLabels: false, legendSettings: { visible: false }, chartMouseClick: pointClick,
    textRender: (args: IAccTextRenderEventArgs) => { args.text = args.point.x + ' ' + args.point.y + ' %'; },
    tooltip: { enable: false, format: '${point.x} <br> ${point.y} %' },
    title: 'Automobile Sales by Category',
    load: (args: IAccLoadedEventArgs) => {
        let selectedTheme: string = location.hash.split('/')[1];
        selectedTheme = selectedTheme ? selectedTheme : 'Material';
        args.accumulation.theme = <AccumulationTheme>(selectedTheme.charAt(0).toUpperCase() +
            selectedTheme.slice(1)).replace(/-dark/i, 'Dark').replace(/contrast/i, 'Contrast');
    }
};
let pie: AccumulationChart = new AccumulationChart(instance); pie.appendTo('#container');
(getElement('category') as HTMLElement).onclick = (e: MouseEvent) => {
    let tooltip: Element = document.getElementsByClassName('e-tooltip-wrap')[0];
    if (tooltip) { tooltip.remove(); }
    pie.destroy(); pie.removeSvg(); pie = null; pie = new AccumulationChart(instance);
    pie.appendTo('#container');
    (e.target as HTMLButtonElement).style.visibility = 'hidden';
    (getElement('symbol') as HTMLElement).style.visibility = 'hidden';
    (getElement('text') as HTMLElement).style.visibility = 'hidden';
};
<!DOCTYPE html>
<html lang="en">

<head>
    <title>EJ2 Animation</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript UI Controls" />
    <meta name="author" content="Syncfusion" />
    <link href="https://cdn.syncfusion.com/ej2/material.css" rel="stylesheet" rel="stylesheet">
    <link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
    <script src="systemjs.config.js"></script>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>

<body>
    <div id='loader'>Loading....</div>
    <div class="control-section">
      <div id="link">
          <a id="category" style="visibility:hidden; display:inline-block">
            Sales by Category 
      </a>
          <p style="visibility:hidden; display:inline-block" id="symbol">&nbsp;&gt;&gt;&nbsp;</p>
          <p id="text" style="display:inline-block;"></p>
      </div>
      <div id="container"></div>
  </div>
  
</body> 
</html>

See Also