Pie with Resolved Label Overlapping
Documentation
In the PieChart, series may include a large number of points, which may result in point label overlapping. This demo illustrates the resolveLabelOverlapping property that allows you to specify how the component must behave when point labels overlap.
www.wikipedia.org
Feel free to share demo-related thoughts here.
If you have technical questions, please create a support ticket in the DevExpress Support Center.
Thank you for the feedback!
If you have technical questions, please create a support ticket in the DevExpress Support Center.
Backend API
import React, { useCallback, useState } from 'react';
import SelectBox, { SelectBoxTypes } from 'devextreme-react/select-box';
import PieChart, {
Series,
Label,
Margin,
Export,
Legend,
Animation,
IPieChartOptions,
} from 'devextreme-react/pie-chart';
import { dataSource, resolutionModeLabel } from './data.ts';
const resolveModes: (IPieChartOptions['resolveLabelOverlapping'])[] = ['shift', 'hide', 'none'];
function formatText(arg: { argumentText: string; percentText: string; }) {
return `${arg.argumentText} (${arg.percentText})`;
}
function App() {
const [resolveMode, setResolveMode] = useState(resolveModes[0]);
const handleResolveModeChange = useCallback((data: SelectBoxTypes.ValueChangedEvent) => {
setResolveMode(data.value);
}, [setResolveMode]);
return (
<React.Fragment>
<PieChart
id="pie"
dataSource={dataSource}
palette="Bright"
title="Olympic Medals in 2008"
resolveLabelOverlapping={resolveMode}
>
<Series
argumentField="country"
valueField="medals"
>
<Label visible={true} customizeText={formatText} />
</Series>
<Margin bottom={20} />
<Export enabled={true} />
<Legend visible={false} />
<Animation enabled={false} />
</PieChart>
<div className="options">
<div className="caption">Options</div>
<div className="option">
<span>Label Overlapping Resolution Mode </span>
<SelectBox
dataSource={resolveModes}
inputAttr={resolutionModeLabel}
value={resolveMode}
onValueChanged={handleResolveModeChange}
/>
</div>
</div>
</React.Fragment>
);
}
export default App;
import React, { useCallback, useState } from 'react';
import SelectBox from 'devextreme-react/select-box';
import PieChart, {
Series,
Label,
Margin,
Export,
Legend,
Animation,
} from 'devextreme-react/pie-chart';
import { dataSource, resolutionModeLabel } from './data.js';
const resolveModes = ['shift', 'hide', 'none'];
function formatText(arg) {
return `${arg.argumentText} (${arg.percentText})`;
}
function App() {
const [resolveMode, setResolveMode] = useState(resolveModes[0]);
const handleResolveModeChange = useCallback(
(data) => {
setResolveMode(data.value);
},
[setResolveMode],
);
return (
<React.Fragment>
<PieChart
id="pie"
dataSource={dataSource}
palette="Bright"
title="Olympic Medals in 2008"
resolveLabelOverlapping={resolveMode}
>
<Series
argumentField="country"
valueField="medals"
>
<Label
visible={true}
customizeText={formatText}
/>
</Series>
<Margin bottom={20} />
<Export enabled={true} />
<Legend visible={false} />
<Animation enabled={false} />
</PieChart>
<div className="options">
<div className="caption">Options</div>
<div className="option">
<span>Label Overlapping Resolution Mode </span>
<SelectBox
dataSource={resolveModes}
inputAttr={resolutionModeLabel}
value={resolveMode}
onValueChanged={handleResolveModeChange}
/>
</div>
</div>
</React.Fragment>
);
}
export default App;
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.tsx';
ReactDOM.render(
<App />,
document.getElementById('app'),
);
export const dataSource = [{
country: 'USA',
medals: 112,
}, {
country: 'China',
medals: 100,
}, {
country: 'Russia',
medals: 60,
}, {
country: 'Britain',
medals: 49,
}, {
country: 'Australia',
medals: 46,
}, {
country: 'France',
medals: 43,
}, {
country: 'Germany',
medals: 41,
}, {
country: 'South Korea',
medals: 32,
}, {
country: 'Cuba',
medals: 29,
}, {
country: 'Italy',
medals: 27,
}, {
country: 'Japan',
medals: 25,
}, {
country: 'Ukraine',
medals: 22,
}, {
country: 'Canada',
medals: 20,
}, {
country: 'Spain',
medals: 19,
}];
export const resolutionModeLabel = { 'aria-label': 'Resolution Mode' };
window.exports = window.exports || {};
window.config = {
transpiler: 'ts',
typescriptOptions: {
module: 'system',
emitDecoratorMetadata: true,
experimentalDecorators: true,
jsx: 'react',
},
meta: {
'react': {
'esModule': true,
},
'typescript': {
'exports': 'ts',
},
'devextreme/time_zone_utils.js': {
'esModule': true,
},
'devextreme/localization.js': {
'esModule': true,
},
'devextreme/viz/palette.js': {
'esModule': true,
},
},
paths: {
'npm:': 'https://unpkg.com/',
},
defaultExtension: 'js',
map: {
'ts': 'npm:plugin-typescript@4.2.4/lib/plugin.js',
'typescript': 'npm:typescript@4.2.4/lib/typescript.js',
'react': 'npm:react@17.0.2/umd/react.development.js',
'react-dom': 'npm:react-dom@17.0.2/umd/react-dom.development.js',
'prop-types': 'npm:prop-types@15.8.1/prop-types.js',
'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js',
'luxon': 'npm:luxon@1.28.1/build/global/luxon.min.js',
'es6-object-assign': 'npm:es6-object-assign@1.1.0',
'devextreme': 'npm:devextreme@23.2.5/cjs',
'devextreme-react': 'npm:devextreme-react@23.2.5/cjs',
'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js',
'devextreme-quill': 'npm:devextreme-quill@1.6.4/dist/dx-quill.min.js',
'devexpress-diagram': 'npm:devexpress-diagram@2.2.5/dist/dx-diagram.js',
'devexpress-gantt': 'npm:devexpress-gantt@4.1.51/dist/dx-gantt.js',
'@devextreme/runtime': 'npm:@devextreme/runtime@3.0.12',
'inferno': 'npm:inferno@7.4.11/dist/inferno.min.js',
'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js',
'inferno-create-element': 'npm:inferno-create-element@7.4.11/dist/inferno-create-element.min.js',
'inferno-dom': 'npm:inferno-dom/dist/inferno-dom.min.js',
'inferno-hydrate': 'npm:inferno-hydrate@7.4.11/dist/inferno-hydrate.min.js',
'inferno-clone-vnode': 'npm:inferno-clone-vnode/dist/inferno-clone-vnode.min.js',
'inferno-create-class': 'npm:inferno-create-class/dist/inferno-create-class.min.js',
'inferno-extras': 'npm:inferno-extras/dist/inferno-extras.min.js',
'devextreme-cldr-data': 'npm:devextreme-cldr-data@1.0.3',
// SystemJS plugins
'plugin-babel': 'npm:systemjs-plugin-babel@0.0.25/plugin-babel.js',
'systemjs-babel-build': 'npm:systemjs-plugin-babel@0.0.25/systemjs-babel-browser.js',
// Prettier
'prettier/standalone': 'npm:prettier@2.8.4/standalone.js',
'prettier/parser-html': 'npm:prettier@2.8.4/parser-html.js',
},
packages: {
'devextreme': {
defaultExtension: 'js',
},
'devextreme-react': {
main: 'index.js',
},
'devextreme/events/utils': {
main: 'index',
},
'devextreme/localization/messages': {
format: 'json',
defaultExtension: '',
},
'devextreme/events': {
main: 'index',
},
'es6-object-assign': {
main: './index.js',
defaultExtension: 'js',
},
},
packageConfigPaths: [
'npm:@devextreme/*/package.json',
'npm:@devextreme/runtime@3.0.12/inferno/package.json',
],
babelOptions: {
sourceMaps: false,
stage0: true,
react: true,
},
};
System.config(window.config);
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('app'));
export const dataSource = [
{
country: 'USA',
medals: 112,
},
{
country: 'China',
medals: 100,
},
{
country: 'Russia',
medals: 60,
},
{
country: 'Britain',
medals: 49,
},
{
country: 'Australia',
medals: 46,
},
{
country: 'France',
medals: 43,
},
{
country: 'Germany',
medals: 41,
},
{
country: 'South Korea',
medals: 32,
},
{
country: 'Cuba',
medals: 29,
},
{
country: 'Italy',
medals: 27,
},
{
country: 'Japan',
medals: 25,
},
{
country: 'Ukraine',
medals: 22,
},
{
country: 'Canada',
medals: 20,
},
{
country: 'Spain',
medals: 19,
},
];
export const resolutionModeLabel = { 'aria-label': 'Resolution Mode' };
<!DOCTYPE html>
<html>
<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=1.0" />
<link rel="stylesheet" type="text/css" href="https://cdn3.devexpress.com/jslib/23.2.5/css/dx.light.css" />
<link rel="stylesheet" type="text/css" href="styles.css" />
<script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script>
<script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script>
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript">
System.import("./index.tsx");
</script>
</head>
<body class="dx-viewport">
<div class="demo-container">
<div id="app"></div>
</div>
</body>
</html>
.options {
padding: 20px;
background-color: rgba(191, 191, 191, 0.15);
margin-top: 20px;
}
.option {
margin-top: 10px;
display: flex;
align-items: center;
}
.caption {
font-size: 18px;
font-weight: 500;
}
.option > span {
margin-right: 10px;
}
.option > .dx-widget {
display: inline-block;
vertical-align: middle;
}