Backend API
<template>
<div>
<DxChart
id="chart"
:customize-point="customizePoint"
:class="isFirstLevel ? 'pointer-on-bars' : ''"
:data-source="dataSource"
title="The Most Populated Countries by Continents"
@point-click="onPointClick"
>
<DxSeries type="bar"/>
<DxValueAxis :show-zero="false"/>
<DxLegend :visible="false"/>
</DxChart>
<DxButton
:visible="!isFirstLevel"
class="button-container"
text="Back"
icon="chevronleft"
@click="onButtonClick"
/>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import {
DxChart,
DxSeries,
DxValueAxis,
DxLegend,
type DxChartTypes,
} from 'devextreme-vue/chart';
import { DxButton } from 'devextreme-vue/button';
import { type SeriesPoint } from 'devextreme-vue/common/charts';
import service from './data.ts';
const isFirstLevel = ref(true);
const dataSource = ref(service.filterData(''));
const colors = ['#6babac', '#e55253'];
function customizePoint(): SeriesPoint {
return {
color: colors[Number(isFirstLevel.value)],
hoverStyle: {
...!isFirstLevel.value ? { hatching: 'none' } : {},
}
} as SeriesPoint;
}
function onPointClick({ target }: DxChartTypes.PointClickEvent): void {
if (isFirstLevel.value) {
isFirstLevel.value = false;
dataSource.value = service.filterData(target.originalArgument as string);
}
}
function onButtonClick(): void {
if (!isFirstLevel.value) {
isFirstLevel.value = true;
dataSource.value = service.filterData('');
}
}
</script>
<style>
#chart {
height: 440px;
width: 100%;
}
#chart.pointer-on-bars .dxc-series rect {
cursor: pointer;
}
.button-container {
text-align: center;
height: 40px;
position: absolute;
top: 7px;
left: 0;
}
</style>
window.exports = window.exports || {};
window.config = {
transpiler: 'plugin-babel',
meta: {
'*.vue': {
loader: 'vue-loader',
},
'*.ts': {
loader: 'demo-ts-loader',
},
'*.svg': {
loader: 'svg-loader',
},
'devextreme/time_zone_utils.js': {
'esModule': true,
},
'devextreme/localization.js': {
'esModule': true,
},
'devextreme/viz/palette.js': {
'esModule': true,
},
'openai': {
'esModule': true,
},
},
paths: {
'project:': '../../../../',
'npm:': 'https://cdn.jsdelivr.net/npm/',
'bundles:': '../../../../bundles/',
'externals:': '../../../../bundles/externals/',
},
map: {
'vue': 'npm:vue@3.4.27/dist/vue.esm-browser.js',
'@vue/shared': 'npm:@vue/shared@3.4.27/dist/shared.cjs.prod.js',
'vue-loader': 'npm:dx-systemjs-vue-browser@1.1.2/index.js',
'demo-ts-loader': 'project:utils/demo-ts-loader.js',
'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js',
'svg-loader': 'project:utils/svg-loader.js',
'mitt': 'npm:mitt/dist/mitt.umd.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-vue': 'npm:devextreme-vue@link:../../packages/devextreme-vue/npm/cjs',
'devextreme-quill': 'npm:devextreme-quill@1.7.6/dist/dx-quill.min.js',
'devexpress-diagram': 'npm:devexpress-diagram@2.2.24/dist/dx-diagram.js',
'devexpress-gantt': 'npm:devexpress-gantt@4.1.64/dist/dx-gantt.js',
'inferno': 'npm:inferno@8.2.3/dist/inferno.min.js',
'inferno-compat': 'npm:inferno-compat/dist/inferno-compat.min.js',
'inferno-create-element': 'npm:inferno-create-element@8.2.3/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',
'@preact/signals-core': 'npm:@preact/signals-core@1.8.0/dist/signals-core.min.js',
'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-vue': {
main: 'index.js',
},
'devextreme-vue/common': {
main: 'index.js',
},
'devextreme': {
defaultExtension: 'js',
},
'devextreme/events/utils': {
main: 'index',
},
'devextreme/common/core/events/utils': {
main: 'index',
},
'devextreme/events': {
main: 'index',
},
'es6-object-assign': {
main: './index.js',
defaultExtension: 'js',
},
},
packageConfigPaths: [
'npm:@devextreme/*/package.json',
],
babelOptions: {
sourceMaps: false,
stage0: true,
},
};
System.config(window.config);
// eslint-disable-next-line
const useTgzInCSB = ['openai'];
interface DataItem {
arg: string;
val: number;
parentID: string;
}
const data: DataItem[] = [
{ arg: 'Asia', val: 3007613498, parentID: '' },
{ arg: 'North America', val: 493603615, parentID: '' },
{ arg: 'Europe', val: 438575293, parentID: '' },
{ arg: 'Africa', val: 381331438, parentID: '' },
{ arg: 'South America', val: 331126555, parentID: '' },
{ arg: 'Nigeria', val: 181562056, parentID: 'Africa' },
{ arg: 'Egypt', val: 88487396, parentID: 'Africa' },
{ arg: 'Congo', val: 77433744, parentID: 'Africa' },
{ arg: 'Morocco', val: 33848242, parentID: 'Africa' },
{ arg: 'China', val: 1380083000, parentID: 'Asia' },
{ arg: 'India', val: 1306687000, parentID: 'Asia' },
{ arg: 'Pakistan', val: 193885498, parentID: 'Asia' },
{ arg: 'Japan', val: 126958000, parentID: 'Asia' },
{ arg: 'Russia', val: 146804372, parentID: 'Europe' },
{ arg: 'Germany', val: 82175684, parentID: 'Europe' },
{ arg: 'Turkey', val: 79463663, parentID: 'Europe' },
{ arg: 'France', val: 66736000, parentID: 'Europe' },
{ arg: 'United Kingdom', val: 63395574, parentID: 'Europe' },
{ arg: 'United States', val: 325310275, parentID: 'North America' },
{ arg: 'Mexico', val: 121005815, parentID: 'North America' },
{ arg: 'Canada', val: 36048521, parentID: 'North America' },
{ arg: 'Cuba', val: 11239004, parentID: 'North America' },
{ arg: 'Brazil', val: 205737996, parentID: 'South America' },
{ arg: 'Colombia', val: 48400388, parentID: 'South America' },
{ arg: 'Venezuela', val: 30761000, parentID: 'South America' },
{ arg: 'Peru', val: 28220764, parentID: 'South America' },
{ arg: 'Chile', val: 18006407, parentID: 'South America' },
];
export default {
filterData(name: string): DataItem[] {
return data.filter((item) => item.parentID === name);
},
};
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
<!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/25.1.7/css/dx.light.css" />
<script src="https://cdn.jsdelivr.net/npm/typescript@5.4.5/lib/typescript.js"></script>
<script type="module">
import * as vueCompilerSFC from "https://cdn.jsdelivr.net/npm/@vue/compiler-sfc@3.4.27/dist/compiler-sfc.esm-browser.js";
window.vueCompilerSFC = vueCompilerSFC;
</script>
<script src="https://cdn.jsdelivr.net/npm/core-js@2.6.12/client/shim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/systemjs@0.21.3/dist/system.js"></script>
<script type="text/javascript" src="config.js"></script>
<script type="text/javascript">
System.import("./index.ts");
</script>
</head>
<body class="dx-viewport">
<div class="demo-container">
<div id="app"> </div>
</div>
</body>
</html>
Bind to Data
This demo binds the drill-down chart to an array of objects. To visualize hierarchical data in the drill-down chart, filter the data source by the parentID for different drill-down views in the filterData function.
Implement View Navigation
To navigate from the main view to a detailed view, filter the data source by a different parentID in the onPointClick event handler. To navigate back, click the Back button. This action resets the data source filter. Use the isFirstLevel flag to distinguish views.
Customize the Appearance
Use the customizePoint function to change the individual point properties. This function returns an object with properties that should be changed for a certain point. In this demo, this function changes the color and hoverStyle properties.