DevExtreme v24.1 is now available.

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

Your search did not match any results.

Angular Charts - Stock

A stock series type displays variations in stock prices over the course of a day. You can specify the stock series type for each object in the series or specify the type in the commonSeriesSettings object for all series in the Chart. Use the commonSeriesSettings.stock object to configure properties of the Chart stock series.

In stock series, the bottom and top values of a vertical line correspond to high and low prices. Use the highValueField and lowValueField properties to specify data source fields for high and low prices.

Backend API
<dx-chart id="chart" title="Stock Price" [dataSource]="stockPrices"> <dxi-series name="E-Mart" openValueField="o" highValueField="h" lowValueField="l" closeValueField="c" > <dxo-reduction color="red"></dxo-reduction> </dxi-series> <dxo-common-series-settings argumentField="date" type="stock"> </dxo-common-series-settings> <dxi-value-axis [tickInterval]="1"> <dxo-title text="US dollars"></dxo-title> <dxo-label> <dxo-format type="currency" [precision]="0"> </dxo-format> </dxo-label> </dxi-value-axis> <dxo-argument-axis [workdaysOnly]="true"> <dxo-label format="shortDate"></dxo-label> </dxo-argument-axis> <dxo-export [enabled]="true"></dxo-export> <dxo-tooltip [enabled]="true" location="edge" [customizeTooltip]="customizeTooltip" > </dxo-tooltip> </dx-chart>
import { NgModule, Component, enableProdMode } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; import { DxChartModule } from 'devextreme-angular'; import { StockPrice, Service } from './app.service'; if (!/localhost/.test(document.location.host)) { enableProdMode(); } @Component({ selector: 'demo-app', templateUrl: `app/app.component.html`, styleUrls: [`app/app.component.css`], providers: [Service], }) export class AppComponent { stockPrices: StockPrice[]; constructor(service: Service) { this.stockPrices = service.getStockPrices(); } customizeTooltip(arg) { return { text: `Open: $${arg.openValue}<br/>` + `Close: $${arg.closeValue}<br/>` + `High: $${arg.highValue}<br/>` + `Low: $${arg.lowValue}<br/>`, }; } } @NgModule({ imports: [ BrowserModule, DxChartModule, ], declarations: [AppComponent], bootstrap: [AppComponent], }) export class AppModule { } platformBrowserDynamic().bootstrapModule(AppModule);
::ng-deep #chart { height: 440px; }
import { Injectable } from '@angular/core'; export class StockPrice { date: Date; l: number; h: number; o: number; c: number; } const stockPrices: StockPrice[] = [{ date: new Date(1994, 2, 1), l: 24.00, h: 25.00, o: 25.00, c: 24.875, }, { date: new Date(1994, 2, 2), l: 23.625, h: 25.125, o: 24.00, c: 24.875, }, { date: new Date(1994, 2, 3), l: 26.25, h: 28.25, o: 26.75, c: 27.00, }, { date: new Date(1994, 2, 4), l: 26.50, h: 27.875, o: 26.875, c: 27.25, }, { date: new Date(1994, 2, 7), l: 26.375, h: 27.50, o: 27.375, c: 26.75, }, { date: new Date(1994, 2, 8), l: 25.75, h: 26.875, o: 26.75, c: 26.00, }, { date: new Date(1994, 2, 9), l: 25.75, h: 26.75, o: 26.125, c: 26.25, }, { date: new Date(1994, 2, 10), l: 25.75, h: 26.375, o: 26.375, c: 25.875, }, { date: new Date(1994, 2, 11), l: 24.875, h: 26.125, o: 26.00, c: 25.375, }, { date: new Date(1994, 2, 14), l: 25.125, h: 26.00, o: 25.625, c: 25.75, }, { date: new Date(1994, 2, 15), l: 25.875, h: 26.625, o: 26.125, c: 26.375, }, { date: new Date(1994, 2, 16), l: 26.25, h: 27.375, o: 26.25, c: 27.25, }, { date: new Date(1994, 2, 17), l: 26.875, h: 27.25, o: 27.125, c: 26.875, }, { date: new Date(1994, 2, 18), l: 26.375, h: 27.125, o: 27.00, c: 27.125, }, { date: new Date(1994, 2, 21), l: 26.75, h: 27.875, o: 26.875, c: 27.75, }, { date: new Date(1994, 2, 22), l: 26.75, h: 28.375, o: 27.50, c: 27.00, }, { date: new Date(1994, 2, 23), l: 26.875, h: 28.125, o: 27.00, c: 28.00, }, { date: new Date(1994, 2, 24), l: 26.25, h: 27.875, o: 27.75, c: 27.625, }, { date: new Date(1994, 2, 25), l: 27.50, h: 28.75, o: 27.75, c: 28.00, }, { date: new Date(1994, 2, 28), l: 25.75, h: 28.25, o: 28.00, c: 27.25, }, { date: new Date(1994, 2, 29), l: 26.375, h: 27.50, o: 27.50, c: 26.875, }, { date: new Date(1994, 2, 30), l: 25.75, h: 27.50, o: 26.375, c: 26.25, }, { date: new Date(1994, 2, 31), l: 24.75, h: 27.00, o: 26.50, c: 25.25, }]; @Injectable() export class Service { getStockPrices(): StockPrice[] { return stockPrices; } }
// In real applications, you should not transpile code in the browser. // You can see how to create your own application with Angular and DevExtreme here: // https://js.devexpress.com/Documentation/Guide/Angular_Components/Getting_Started/Create_a_DevExtreme_Application/ const componentNames = [ 'accordion', 'action-sheet', 'autocomplete', 'bar-gauge', 'box', 'bullet', 'button-group', 'button', 'calendar', 'chart', 'check-box', 'circular-gauge', 'color-box', 'context-menu', 'data-grid', 'date-box', 'date-range-box', 'defer-rendering', 'diagram', 'draggable', 'drawer', 'drop-down-box', 'drop-down-button', 'file-manager', 'file-uploader', 'filter-builder', 'form', 'funnel', 'gallery', 'gantt', 'html-editor', 'linear-gauge', 'list', 'load-indicator', 'load-panel', 'lookup', 'map', 'menu', 'multi-view', 'nested', 'number-box', 'pie-chart', 'pivot-grid-field-chooser', 'pivot-grid', 'polar-chart', 'popover', 'popup', 'progress-bar', 'radio-group', 'range-selector', 'range-slider', 'recurrence-editor', 'resizable', 'responsive-box', 'sankey', 'scheduler', 'scroll-view', 'select-box', 'slider', 'sortable', 'sparkline', 'speed-dial-action', 'splitter', 'switch', 'tab-panel', 'tabs', 'tag-box', 'text-area', 'text-box', 'tile-view', 'toast', 'toolbar', 'tooltip', 'tree-list', 'tree-map', 'tree-view', 'validation-group', 'validation-summary', 'validator', 'vector-map', ]; window.exports = window.exports || {}; window.config = { transpiler: 'ts', typescriptOptions: { module: 'system', emitDecoratorMetadata: true, experimentalDecorators: true, }, meta: { 'typescript': { 'exports': 'ts', }, 'devextreme/time_zone_utils.js': { 'esModule': true, }, 'devextreme/localization.js': { 'esModule': true, }, 'devextreme/viz/palette.js': { 'esModule': true, }, '@angular/platform-browser-dynamic': { 'esModule': true, }, '@angular/platform-browser': { 'esModule': true, }, '@angular/core': { 'esModule': true, }, '@angular/common': { 'esModule': true, }, '@angular/common/http': { 'esModule': true, }, '@angular/compiler': { 'esModule': true, }, '@angular/animations': { 'esModule': true, }, '@angular/forms': { 'esModule': true, }, }, paths: { 'npm:': 'https://unpkg.com/', 'bundles:': '../../../../bundles/', }, map: { 'ts': 'npm:plugin-typescript@4.2.4/lib/plugin.js', 'typescript': 'npm:typescript@4.2.4/lib/typescript.js', /* @angular */ '@angular/compiler': 'bundles:@angular/compiler.umd.js', '@angular/platform-browser-dynamic': 'bundles:@angular/platform-browser-dynamic.umd.js', '@angular/core': 'bundles:@angular/core.umd.js', '@angular/core/primitives/signals': 'bundles:@angular/core.primitives.signals.umd.js', '@angular/common': 'bundles:@angular/common.umd.js', '@angular/common/http': 'bundles:@angular/common-http.umd.js', '@angular/platform-browser': 'bundles:@angular/platform-browser.umd.js', '@angular/platform-browser/animations': 'bundles:@angular/platform-browser.umd.js', '@angular/forms': 'bundles:@angular/forms.umd.js', /* devextreme */ 'devextreme': 'npm:devextreme@24.1.7/cjs', '@devextreme/runtime': 'npm:@devextreme/runtime@3.0.13', 'devextreme/bundles/dx.all': 'npm:devextreme@24.1.7/bundles/dx.all.js', 'devextreme-quill': 'npm:devextreme-quill@1.7.1/dist/dx-quill.min.js', 'devexpress-diagram': 'npm:devexpress-diagram@2.2.12', 'devexpress-gantt': 'npm:devexpress-gantt@4.1.56', /* devextreme-angular umd maps */ 'devextreme-angular': 'bundles:devextreme-angular/devextreme-angular.umd.js', 'devextreme-angular/core': 'bundles:devextreme-angular/devextreme-angular-core.umd.js', 'devextreme-angular/http': 'bundles:devextreme-angular/devextreme-angular-http.umd.js', ...componentNames.reduce((acc, name) => { acc[`devextreme-angular/ui/${name}`] = `bundles:devextreme-angular/devextreme-angular-ui-${name}.umd.js`; return acc; }, {}), 'jszip': 'npm:jszip@3.10.1/dist/jszip.min.js', 'tslib': 'npm:tslib@2.6.1/tslib.js', 'rxjs': 'npm:rxjs@7.5.3/dist/bundles/rxjs.umd.js', 'rxjs/operators': 'npm:rxjs@7.5.3/dist/cjs/operators/index.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', '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', // Prettier 'prettier/standalone': 'npm:prettier@2.8.8/standalone.js', 'prettier/parser-html': 'npm:prettier@2.8.8/parser-html.js', }, packages: { 'app': { main: './app.component.ts', defaultExtension: 'ts', }, 'devextreme': { defaultExtension: 'js', }, 'devextreme/events/utils': { main: 'index', }, 'devextreme/events': { main: 'index', }, 'es6-object-assign': { main: './index.js', defaultExtension: 'js', }, 'rxjs': { defaultExtension: 'js', }, 'rxjs/operators': { defaultExtension: 'js', }, }, packageConfigPaths: [ 'npm:@devextreme/*/package.json', 'npm:@devextreme/runtime@3.0.13/inferno/package.json', 'npm:rxjs@7.5.3/package.json', 'npm:rxjs@7.5.3/operators/package.json', 'npm:devexpress-diagram@2.2.12/package.json', 'npm:devexpress-gantt@4.1.56/package.json', ], }; System.config(window.config); // System.import('@angular/compiler').catch(console.error.bind(console));
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" 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/24.1.7/css/dx.light.css" /> <script src="https://unpkg.com/core-js@2.6.12/client/shim.min.js"></script> <script src="https://unpkg.com/zone.js@0.13.3/bundles/zone.umd.min.js"></script> <script src="https://unpkg.com/reflect-metadata@0.1.13/Reflect.js"></script> <script src="https://unpkg.com/systemjs@0.21.3/dist/system.js"></script> <script src="config.js"></script> <script> System.import("app").catch(console.error.bind(console)); </script> </head> <body class="dx-viewport"> <div class="demo-container"> <demo-app>Loading...</demo-app> </div> </body> </html>

Open and close prices are displayed as left and right tick marks. To specify these prices, use the openValueField and closeValueField properties.

To reflect changes on the market, the Chart component compares the price of every point with the price of the previous point. The Chart paints the points whose price has decreased in a specific reduction color. To switch between high, low, open or close prices of points as sources for data comparison, use the series.reduction.level property.

Additionally, use the tooltip.contentTemplate property to declare a custom tooltip that shows prices. You can also enable the argumentAxis.workdaysOnly property to display only the work days on the argument axis.