A Volume Profile shows the volume traded at each price level as horizontal bars against the price axis. It can be shown within a Financial Chart, or on its own as a Volume Profile Chart.
import { Component } from "@angular/core";
import { AgFinancialCharts } from "ag-charts-angular";
import {
AgFinancialChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import { getData, getVolumeProfile } from "./data";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgFinancialCharts],
template: `<ag-financial-charts
[options]="options"
></ag-financial-charts>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getData(),
title: { text: "Acme Inc." },
volumeProfile: {
data: getVolumeProfile(),
upKey: "upVolume",
downKey: "downVolume",
},
};
}
}
Data Copy Link
Volume Profile data has one row per price level, holding the price and the volume bought and sold at that price:
{
data: [
{ price: 135, upVolume: 3873690, downVolume: 3499965 },
{ price: 137.5, upVolume: 15861342, downVolume: 13138794 },
{ price: 140, upVolume: 19126307, downVolume: 25942209 },
],
priceKey: 'price', // default
upKey: 'upVolume',
downKey: 'downVolume',
} Financial Chart Copy Link
Set volumeProfile on a Financial Chart to show a Volume Profile alongside the price data, as in the example at the top of this page. It takes its own data, separate from the chart's data.
{
data: prices,
volumeProfile: {
data: profile,
upKey: 'upVolume',
downKey: 'downVolume',
},
}Hovering the chart shows the price level under the pointer in the status bar, after the price data values: its price range, up volume, down volume and total volume.
Volume Profile Chart Copy Link
Use a Volume Profile Chart to show a Volume Profile on its own, against a price axis.
import { Component } from "@angular/core";
import { AgVolumeProfileChart } from "ag-charts-angular";
import {
AgVolumeProfileChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import { getVolumeProfile } from "./data";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgVolumeProfileChart],
template: `<ag-volume-profile-chart
[options]="options"
></ag-volume-profile-chart>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getVolumeProfile(),
title: { text: "Acme Inc." },
upKey: "upVolume",
downKey: "downVolume",
};
}
}
@Component({
selector: 'app-root',
standalone: true,
imports: [AgVolumeProfileChart],
template: `<ag-volume-profile-chart [options]="options"></ag-volume-profile-chart>`,
})
export class AppComponent {
public options: AgVolumeProfileChartOptions;
constructor() {
this.options = {
data: getVolumeProfile(),
upKey: 'upVolume',
downKey: 'downVolume',
};
}
}Hovering a price level shows a tooltip.
Selecting Price Levels Copy Link
Set selection.enabled to let users select price levels. Selection is only available in a Volume Profile Chart.
import { Component } from "@angular/core";
import { AgVolumeProfileChart } from "ag-charts-angular";
import {
AgVolumeProfileChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import { getRegularVolumeProfile } from "./data";
import clone from "clone";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgVolumeProfileChart],
template: `<div class="example-controls">
<div class="controls-row">
<span>Click Mode:</span>
<div class="button-group" role="group" aria-label="Click Mode">
<input type="radio" id="mode-single" name="click-mode" value="single" checked="" (change)="changeClickMode($event)">
<label for="mode-single">Single</label>
<input type="radio" id="mode-multiple" name="click-mode" value="multiple" (change)="changeClickMode($event)">
<label for="mode-multiple">Multiple</label>
</div>
</div>
</div>
<ag-volume-profile-chart
[options]="options"
></ag-volume-profile-chart>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getRegularVolumeProfile(),
title: { text: "Acme Inc." },
upKey: "upVolume",
downKey: "downVolume",
tickSize: 5,
selection: { enabled: true, enableDrag: true },
};
}
changeClickMode = (event: Event) => {
const options = clone(this.options);
options.selection = {
...options.selection,
clickMode: (event.target as HTMLInputElement).value as
"single" | "multiple",
};
this.options = options;
};
}
{
selection: {
enabled: true,
enableDrag: true,
},
}In this example:
- Click a price level to select it, or drag across the chart to select every level the rectangle touches.
- Use the Click Mode buttons to switch
selection.clickModebetween'single'and'multiple'. - See Selection for styling and the Selection API, and Events to respond to selection changes.
Tick Size Copy Link
Set tickSize to the price increment of the instrument to fix the height of each price level. Without it, each level is as high as the smallest gap between prices in the data.
import { Component } from "@angular/core";
import { AgFinancialCharts } from "ag-charts-angular";
import {
AgFinancialChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import {
getData,
getIrregularVolumeProfile,
getRegularVolumeProfile,
} from "./data";
import clone from "clone";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgFinancialCharts],
template: `<div class="example-controls">
<div class="controls-row">
<span>Data:</span>
<div class="button-group" role="group" aria-label="Data">
<input type="radio" id="data-regular" name="data" value="regular" checked="" (change)="changeData($event)">
<label for="data-regular">Regular</label>
<input type="radio" id="data-irregular" name="data" value="irregular" (change)="changeData($event)">
<label for="data-irregular">Irregular</label>
</div>
<span class="gap-left">Tick Size:</span>
<div class="button-group" role="group" aria-label="Tick Size">
<input type="radio" id="tick-auto" name="tick-size" value="auto" checked="" (change)="changeTickSize($event)">
<label for="tick-auto">Auto</label>
<input type="radio" id="tick-1" name="tick-size" value="1" (change)="changeTickSize($event)">
<label for="tick-1">1</label>
<input type="radio" id="tick-2-5" name="tick-size" value="2.5" (change)="changeTickSize($event)">
<label for="tick-2-5">2.5</label>
<input type="radio" id="tick-5" name="tick-size" value="5" (change)="changeTickSize($event)">
<label for="tick-5">5</label>
</div>
</div>
</div>
<ag-financial-charts
[options]="options"
></ag-financial-charts>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getData(),
title: { text: "Acme Inc." },
volumeProfile: {
data: getRegularVolumeProfile(),
upKey: "upVolume",
downKey: "downVolume",
},
};
}
changeData = (event: Event) => {
const options = clone(this.options);
const value = (event.target as HTMLInputElement).value;
options.volumeProfile!.data =
value === "irregular"
? getIrregularVolumeProfile()
: getRegularVolumeProfile();
this.options = options;
};
changeTickSize = (event: Event) => {
const options = clone(this.options);
const value = (event.target as HTMLInputElement).value;
options.tickSize = value === "auto" ? undefined : Number(value);
this.options = options;
};
}
{
tickSize: 2.5,
}In this example:
- Each price is rounded to the nearest multiple of
tickSize, and the volumes of prices that round to the same level are added together. - Every level between the lowest and highest price is shown, so the levels stay evenly spaced. Levels with no data are left empty.
- With the Irregular data and Tick Size Auto, the smallest gap between prices sets the level height, giving thin, uneven bars. Choose a Tick Size to group them into regular levels.
- A larger
tickSizemerges more prices into each level, giving fewer, taller bars.
Total Segment Copy Link
Set totalSegment.enabled to show each price level's total volume in a column between the price axis and the bars.
import { Component } from "@angular/core";
import { AgVolumeProfileChart } from "ag-charts-angular";
import {
AgVolumeProfileChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import { getRegularVolumeProfile } from "./data";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgVolumeProfileChart],
template: `<ag-volume-profile-chart
[options]="options"
></ag-volume-profile-chart>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getRegularVolumeProfile(),
title: { text: "Acme Inc." },
upKey: "upVolume",
downKey: "downVolume",
tickSize: 5,
totalSegment: { enabled: true },
};
}
}
In a Volume Profile Chart, totalSegment is a top-level option. In a Financial Chart, set it on volumeProfile:
{
volumeProfile: {
data: profile,
upKey: 'upVolume',
downKey: 'downVolume',
totalSegment: {
enabled: true,
},
},
}- Totals are abbreviated, such as
1.2Kor3.0M. Uselabel.formatterto change them. - The column is as wide as its widest label, but no narrower than
minWidth. Setwidthto fix it instead.
Customisation Copy Link
Width and Placement Copy Link
In a Financial Chart, set widthRatio and placement on volumeProfile to change the size and side of the bars.
import { Component } from "@angular/core";
import { AgFinancialCharts } from "ag-charts-angular";
import {
AgFinancialChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import { getData, getVolumeProfile } from "./data";
import clone from "clone";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgFinancialCharts],
template: `<div class="example-controls">
<div class="controls-row">
<span>Placement:</span>
<div class="button-group" role="group" aria-label="Placement">
<input type="radio" id="placement-left" name="placement" value="left" (change)="changePlacement($event)">
<label for="placement-left">Left</label>
<input type="radio" id="placement-right" name="placement" value="right" checked="" (change)="changePlacement($event)">
<label for="placement-right">Right</label>
</div>
<span class="gap-left">Width Ratio:</span>
<div class="button-group" role="group" aria-label="Width Ratio">
<input type="radio" id="ratio-0-25" name="width-ratio" value="0.25" (change)="changeWidthRatio($event)">
<label for="ratio-0-25">0.25</label>
<input type="radio" id="ratio-0-5" name="width-ratio" value="0.5" checked="" (change)="changeWidthRatio($event)">
<label for="ratio-0-5">0.5</label>
<input type="radio" id="ratio-0-75" name="width-ratio" value="0.75" (change)="changeWidthRatio($event)">
<label for="ratio-0-75">0.75</label>
</div>
</div>
</div>
<ag-financial-charts
[options]="options"
></ag-financial-charts>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getData(),
title: { text: "Acme Inc." },
volumeProfile: {
data: getVolumeProfile(),
upKey: "upVolume",
downKey: "downVolume",
placement: "right",
widthRatio: 0.5,
},
};
}
changePlacement = (event: Event) => {
const options = clone(this.options);
options.volumeProfile!.placement = (event.target as HTMLInputElement)
.value as "left" | "right";
this.options = options;
};
changeWidthRatio = (event: Event) => {
const options = clone(this.options);
options.volumeProfile!.widthRatio = Number(
(event.target as HTMLInputElement).value,
);
this.options = options;
};
}
{
volumeProfile: {
data: profile,
upKey: 'upVolume',
downKey: 'downVolume',
placement: 'left',
widthRatio: 0.75,
},
}In this example:
widthRatiosets the length of the longest bar as a ratio of the series area width. It defaults to0.5.placementsets the edge the bars extend from,'left'or'right'. It defaults to'right'.
Colours Copy Link
By default, the bars use the up and down fills of the theme palette.
Set up and down to style the bars of each direction with options such as fill, fillOpacity, stroke and strokeWidth. These take precedence over the theme palette.
import { Component } from "@angular/core";
import { AgFinancialCharts } from "ag-charts-angular";
import {
AgFinancialChartOptions,
FinancialChartModule,
ModuleRegistry,
} from "ag-charts-enterprise";
import { getData, getVolumeProfile } from "./data";
ModuleRegistry.registerModules([FinancialChartModule]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgFinancialCharts],
template: `<ag-financial-charts
[options]="options"
></ag-financial-charts>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
data: getData(),
title: { text: "Acme Inc." },
volumeProfile: {
data: getVolumeProfile(),
upKey: "upVolume",
downKey: "downVolume",
up: { fill: "#F2C12E", stroke: "#B8901A" },
down: { fill: "#2E6BF2", stroke: "#1A45A8" },
},
};
}
}
{
//...other volume profile options
up: { fill: '#F2C12E', stroke: '#B8901A' },
down: { fill: '#2E6BF2', stroke: '#1A45A8' },
}In this example:
upanddowncolour the bars of the up and down volume.- A
strokeis 1 pixel wide unlessstrokeWidthis set.
The status bar uses the up.fill and down.fill colours to display these values.
API Reference Copy Link
Properties available on the AgVolumeProfileChartOptions interface.
- upKey required
string - The key used to retrieve the up volume of each level from the data.
- downKey required
string - The key used to retrieve the down volume of each level from the data.
- theme
AgChartTheme | AgChartThemeName - A predefined theme name or an object containing theme overrides. See: [Themes Reference](/themes-api/)
- listeners
AgAxesChartListeners - A map of event names to event listeners.
- data
DatumDefault[] - The data to render the chart from. If this is not specified, it must be set on individual series instead.
- dataIdKey
DatumKey - The key of the property on each datum that contains its unique identifier. When specified, transactions will match items by this field instead of by object reference. The values of this field must be unique across the dataset.
- container
HTMLElement | null - The element to place the rendered chart into.
- initialState
AgInitialStateOptions - The initial state of the chart. This must be a serialisable value.
- width
PixelSize - The width of the chart in pixels.
- height
PixelSize - The height of the chart in pixels.
- minHeight
PixelSizedefault: 300 - Sets the minimum height of the chart. Ignored if `height` is specified.
- minWidth
PixelSizedefault: 300 - Sets the minimum width of the chart. Ignored if `width` is specified.
- title
AgChartCaptionOptions - Configuration for the title shown at the top of the chart.
- dataSource
AgDataSourceOptions - Configuration for asynchronously loaded data.
- formatter
FormatterConfiguration - Global formatter configuration.
- enableRtl
boolean - Set to `true` to render the chart in right-to-left mode. If not specified, the chart will detect the `dir` attribute on the container or its ancestors.
- priceKey
stringdefault: 'price' - The key holding the price of each level in the data.
- up
AgBarSeriesStyle - Styling for the bars showing the up volume of each level.
- down
AgBarSeriesStyle - Styling for the bars showing the down volume of each level.
- tickSize
number - The height of each price level, in price units. If not set, the smallest gap between the prices in the data is used.
- totalSegment
AgVolumeProfileTotalSegmentOptions - A fixed-width column showing each level's total volume, set between the price axis and the up and down bars.
- selection
AgVolumeProfileSelectionOptions - Selection of price levels.
Properties available on the AgVolumeProfileChartOptions interface.
- upKey required
string - The key used to retrieve the up volume of each level from the data.
- downKey required
string - The key used to retrieve the down volume of each level from the data.
- theme
AgChartTheme | AgChartThemeName - A predefined theme name or an object containing theme overrides. See: [Themes Reference](/themes-api/)
- listeners
AgAxesChartListeners - A map of event names to event listeners.
- data
DatumDefault[] - The data to render the chart from. If this is not specified, it must be set on individual series instead.
- dataIdKey
DatumKey - The key of the property on each datum that contains its unique identifier. When specified, transactions will match items by this field instead of by object reference. The values of this field must be unique across the dataset.
- container
HTMLElement | null - The element to place the rendered chart into.
- initialState
AgInitialStateOptions - The initial state of the chart. This must be a serialisable value.
- width
PixelSize - The width of the chart in pixels.
- height
PixelSize - The height of the chart in pixels.
- minHeight
PixelSizedefault: 300 - Sets the minimum height of the chart. Ignored if `height` is specified.
- minWidth
PixelSizedefault: 300 - Sets the minimum width of the chart. Ignored if `width` is specified.
- title
AgChartCaptionOptions - Configuration for the title shown at the top of the chart.
- dataSource
AgDataSourceOptions - Configuration for asynchronously loaded data.
- formatter
FormatterConfiguration - Global formatter configuration.
- enableRtl
boolean - Set to `true` to render the chart in right-to-left mode. If not specified, the chart will detect the `dir` attribute on the container or its ancestors.
- priceKey
stringdefault: 'price' - The key holding the price of each level in the data.
- up
AgBarSeriesStyle - Styling for the bars showing the up volume of each level.
- down
AgBarSeriesStyle - Styling for the bars showing the down volume of each level.
- tickSize
number - The height of each price level, in price units. If not set, the smallest gap between the prices in the data is used.
- totalSegment
AgVolumeProfileTotalSegmentOptions - A fixed-width column showing each level's total volume, set between the price axis and the up and down bars.
- selection
AgVolumeProfileSelectionOptions - Selection of price levels.
Properties available on the AgFinancialChartOptions interface.
- volumeProfile
AgVolumeProfileOptions - Configuration for a Volume Profile, showing the traded volume at each price level as horizontal bars against the price axis.
- tickSize
number - The height of each Volume Profile price level, in price units. If not set, the smallest gap between the prices in `volumeProfile.data` is used.
Properties available on the AgFinancialChartOptions interface.
- volumeProfile
AgVolumeProfileOptions - Configuration for a Volume Profile, showing the traded volume at each price level as horizontal bars against the price axis.
- tickSize
number - The height of each Volume Profile price level, in price units. If not set, the smallest gap between the prices in `volumeProfile.data` is used.