If you have technical questions, please create a support ticket in the DevExpress Support Center.
import React from 'react';
import {
Chart, Series, CommonSeriesSettings, Legend, ValueAxis, Title, Export, Tooltip, Border,
} from 'devextreme-react/chart';
import service from './data.ts';
const dataSource = service.getMaleAgeData();
function customizeItems(items) {
const sortedItems = [];
items.forEach((item) => {
const startIndex = item.series.stack === 'male' ? 0 : 3;
sortedItems.splice(startIndex, 0, item);
});
return sortedItems;
}
function App() {
return (
<Chart
id="chart"
title="Population: Age Structure"
dataSource={dataSource}
>
<CommonSeriesSettings argumentField="state" type="stackedbar" />
<Series
valueField="maleyoung"
name="Male: 0-14"
stack="male"
/>
<Series
valueField="malemiddle"
name="Male: 15-64"
stack="male"
/>
<Series
valueField="maleolder"
name="Male: 65 and older"
stack="male"
/>
<Series
valueField="femaleyoung"
name="Female: 0-14"
stack="female"
/>
<Series
valueField="femalemiddle"
name="Female: 15-64"
stack="female"
/>
<Series
valueField="femaleolder"
name="Female: 65 and older"
stack="female"
/>
<ValueAxis>
<Title text="Populations, millions" />
</ValueAxis>
<Legend position="inside"
columnCount={2}
customizeItems={customizeItems}
horizontalAlignment="right">
<Border visible={true} />
</Legend>
<Export enabled={true} />
<Tooltip enabled={true} />
</Chart>
);
}
export default App;
xxxxxxxxxx
import React from 'react';
import {
Chart,
Series,
CommonSeriesSettings,
Legend,
ValueAxis,
Title,
Export,
Tooltip,
Border,
} from 'devextreme-react/chart';
import service from './data.js';
const dataSource = service.getMaleAgeData();
function customizeItems(items) {
const sortedItems = [];
items.forEach((item) => {
const startIndex = item.series.stack === 'male' ? 0 : 3;
sortedItems.splice(startIndex, 0, item);
});
return sortedItems;
}
function App() {
return (
<Chart
id="chart"
title="Population: Age Structure"
dataSource={dataSource}
>
<CommonSeriesSettings
argumentField="state"
type="stackedbar"
/>
<Series
valueField="maleyoung"
name="Male: 0-14"
stack="male"
/>
<Series
valueField="malemiddle"
name="Male: 15-64"
stack="male"
/>
<Series
valueField="maleolder"
name="Male: 65 and older"
stack="male"
/>
<Series
valueField="femaleyoung"
name="Female: 0-14"
stack="female"
/>
<Series
valueField="femalemiddle"
name="Female: 15-64"
stack="female"
/>
<Series
valueField="femaleolder"
name="Female: 65 and older"
stack="female"
/>
<ValueAxis>
<Title text="Populations, millions" />
</ValueAxis>
<Legend
position="inside"
columnCount={2}
customizeItems={customizeItems}
horizontalAlignment="right"
>
<Border visible={true} />
</Legend>
<Export enabled={true} />
<Tooltip enabled={true} />
</Chart>
);
}
export default App;
xxxxxxxxxx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.tsx';
ReactDOM.render(
<App />,
document.getElementById('app'),
);
xxxxxxxxxx
const maleAgeData = [{
state: 'USA',
maleyoung: 29.956,
malemiddle: 90.354,
maleolder: 14.472,
femaleyoung: 28.597,
femalemiddle: 91.827,
femaleolder: 20.362,
}, {
state: 'Brazil',
maleyoung: 25.607,
malemiddle: 55.793,
maleolder: 3.727,
femaleyoung: 24.67,
femalemiddle: 57.598,
femaleolder: 5.462,
}, {
state: 'Russia',
maleyoung: 13.493,
malemiddle: 48.983,
maleolder: 5.802,
femaleyoung: 12.971,
femalemiddle: 52.14,
femaleolder: 12.61,
}, {
state: 'Japan',
maleyoung: 9.575,
malemiddle: 43.363,
maleolder: 9.024,
femaleyoung: 9.105,
femalemiddle: 42.98,
femaleolder: 12.501,
}, {
state: 'Mexico',
maleyoung: 17.306,
malemiddle: 30.223,
maleolder: 1.927,
femaleyoung: 16.632,
femalemiddle: 31.868,
femaleolder: 2.391,
}, {
state: 'Germany',
maleyoung: 6.679,
malemiddle: 28.638,
maleolder: 5.133,
femaleyoung: 6.333,
femalemiddle: 27.693,
femaleolder: 8.318,
}, {
state: 'United Kindom',
maleyoung: 5.816,
malemiddle: 19.622,
maleolder: 3.864,
femaleyoung: 5.519,
femalemiddle: 19.228,
femaleolder: 5.459,
}];
export default {
getMaleAgeData() {
return maleAgeData;
},
};
xxxxxxxxxx
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,
},
'openai': {
'esModule': true,
},
},
paths: {
'npm:': 'https://unpkg.com/',
'bundles:': 'bundles/',
'externals:': 'bundles/externals/',
},
defaultExtension: 'js',
map: {
'ts': 'npm:plugin-typescript@8.0.0/lib/plugin.js',
'typescript': 'npm:typescript@4.2.4/lib/typescript.js',
'jszip': 'npm:jszip@3.10.1/dist/jszip.min.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/prop-types.js',
'rrule': 'npm:rrule@2.6.4/dist/es5/rrule.js',
'luxon': 'npm:luxon@3.4.4/build/global/luxon.min.js',
'es6-object-assign': 'npm:es6-object-assign',
'devextreme': 'npm:devextreme@link:../../packages/devextreme/artifacts/npm/devextreme/cjs',
'devextreme-react': 'npm:devextreme-react@link:../../packages/devextreme-react/npm/cjs',
'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js',
'devexpress-diagram': 'npm:devexpress-diagram@2.2.5/dist/dx-diagram.js',
'devexpress-gantt': 'npm:devexpress-gantt@4.1.54/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/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.8/standalone.js',
'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js',
},
packages: {
'devextreme': {
defaultExtension: 'js',
},
'devextreme-react': {
main: 'index.js',
},
'devextreme/events/utils': {
main: 'index',
},
'devextreme/localization/messages': {
format: 'json',
defaultExtension: 'json',
},
'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);
xxxxxxxxxx
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App.js';
ReactDOM.render(<App />, document.getElementById('app'));
xxxxxxxxxx
const maleAgeData = [
{
state: 'USA',
maleyoung: 29.956,
malemiddle: 90.354,
maleolder: 14.472,
femaleyoung: 28.597,
femalemiddle: 91.827,
femaleolder: 20.362,
},
{
state: 'Brazil',
maleyoung: 25.607,
malemiddle: 55.793,
maleolder: 3.727,
femaleyoung: 24.67,
femalemiddle: 57.598,
femaleolder: 5.462,
},
{
state: 'Russia',
maleyoung: 13.493,
malemiddle: 48.983,
maleolder: 5.802,
femaleyoung: 12.971,
femalemiddle: 52.14,
femaleolder: 12.61,
},
{
state: 'Japan',
maleyoung: 9.575,
malemiddle: 43.363,
maleolder: 9.024,
femaleyoung: 9.105,
femalemiddle: 42.98,
femaleolder: 12.501,
},
{
state: 'Mexico',
maleyoung: 17.306,
malemiddle: 30.223,
maleolder: 1.927,
femaleyoung: 16.632,
femalemiddle: 31.868,
femaleolder: 2.391,
},
{
state: 'Germany',
maleyoung: 6.679,
malemiddle: 28.638,
maleolder: 5.133,
femaleyoung: 6.333,
femalemiddle: 27.693,
femaleolder: 8.318,
},
{
state: 'United Kindom',
maleyoung: 5.816,
malemiddle: 19.622,
maleolder: 3.864,
femaleyoung: 5.519,
femalemiddle: 19.228,
femaleolder: 5.459,
},
];
export default {
getMaleAgeData() {
return maleAgeData;
},
};
xxxxxxxxxx
<html lang="en">
<head></head>
<body class="dx-viewport">
<div class="demo-container">
<div id="app"></div>
</div>
</body>
</html>
xxxxxxxxxx
#chart {
height: 440px;
}
Bind Chart to Data
The side-by-side stacked bar chart contains series with the same argument field. In this demo, the data source array consists of the objects with the same field structure. Assign the state
field to the argumentField property of the commonSeriesSettings object to specify the common argument for the series. Then, define the series array of objects. In each object, specify the valueField property and use the stack property to group the series in stacks depending on the stack property values.
Customize Side-By-Side Stacked Bar Chart
Customize Chart Legend
Use the verticalAlignment and horizontalAlignment properties of the legend object to specify the legend layout.
The customizeLegend function allows you to change the order, text, and visibility of legend items. This demo uses the array.splice method in the customizeItems function to sort the legend items. If you want to customize the legend border, use properties collected in the border object.
To distribute all legend items between multiple columns (in a vertically-oriented legend) or rows (in a horizontally-oriented legend), specify the columnCount or rowCount property, respectively.
Configure Tooltips
To configure tooltips in the chart, use the tooltip object. To enable the tooltips, assign true to the enabled property of this object.
Export Chart
To allow users to export your side-by-side stacked bar chart into a PNG, JPEG, PDF, and SVG file or print the chart, set the export.enabled property to true. Since the export functionality is enabled in this demo, you can click the hamburger button in the chart to invoke a drop-down menu with export and print commands.