AG Charts leverages TypeScript Generics for chart data and context. This significantly enhances the developer experience through improved code completion and compile-time validation.
Type <TDatum> Copy Link
The TDatum (default: any) generic parameter is used to specify the interface of datums in the data.
import { Component } from "@angular/core";
import { AgCharts } from "ag-charts-angular";
import {
AgChartOptions,
BarSeriesModule,
CategoryAxisModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
} from "ag-charts-community";
type MyDatumType = {
country: string;
gdp: number;
region: "AMER" | "APAC" | "EMEA";
};
function unreachable(_arg: never): never {
throw new Error();
}
ModuleRegistry.registerModules([
BarSeriesModule,
CategoryAxisModule,
LegendModule,
NumberAxisModule,
]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgCharts],
template: `<ag-charts
[options]="options"
></ag-charts>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
title: {
text: "Country GDP by region (in USD)",
},
data: [
{ region: "AMER", country: "Brazil", gdp: 2200 },
{ region: "AMER", country: "Canada", gdp: 2000 },
{ region: "AMER", country: "United States", gdp: 25000 },
{ region: "APAC", country: "China", gdp: 17000 },
{ region: "APAC", country: "India", gdp: 3400 },
{ region: "APAC", country: "Japan", gdp: 5000 },
{ region: "EMEA", country: "France", gdp: 3000 },
{ region: "EMEA", country: "Germany", gdp: 4000 },
{ region: "EMEA", country: "South Africa", gdp: 900 },
{ region: "EMEA", country: "United Kingdom", gdp: 3200 },
],
series: [
{
type: "bar",
yKey: "gdp",
xKey: "country",
itemStyler: (params) => {
switch (params.datum.region) {
case "AMER":
return { fill: "red" };
case "APAC":
return { fill: "blue" };
case "EMEA":
return { fill: "green" };
default:
unreachable(params.datum.region);
}
},
},
],
};
}
}
type MyDatumType = {
country: string;
gdp: number;
region: 'AMER' | 'APAC' | 'EMEA';
};
const options: AgChartOptions<MyDatumType> = {
data: [
{ region: 'AMER', country: 'Brazil', gdp: 2200 },
{ region: 'AMER', country: 'Canada', gdp: 2000 },
{ region: 'AMER', country: 'United States', gdp: 25000 },
{ region: 'APAC', country: 'China', gdp: 17000 },
{ region: 'APAC', country: 'India', gdp: 3400 },
{ region: 'APAC', country: 'Japan', gdp: 5000 },
{ region: 'EMEA', country: 'France', gdp: 3000 },
{ region: 'EMEA', country: 'Germany', gdp: 4000 },
{ region: 'EMEA', country: 'South Africa', gdp: 900 },
{ region: 'EMEA', country: 'United Kingdom', gdp: 3200 },
],
series: [
{
type: 'bar',
yKey: 'gdp',
xKey: 'country',
itemStyler: (params) => {
switch (params.datum.region) {
case 'AMER':
return { fill: 'red' };
case 'APAC':
return { fill: 'blue' };
case 'EMEA':
return { fill: 'green' };
default:
// (unreachable code)
throw new Error();
}
},
},
],
/* ... */
};In this example, specifying the TDatum = MyDatumType generic parameter does the following:
Enables compile-time checks & auto-complete for the elements of the
data[]property.Enforces type-safety for the
series[].xKeyandseries[].yKey. These properties must be keys of theMyDatumTypetype.Automatically infers the type of
params.datum.regionin theitemStylercallback.
Type <TContext> Copy Link
The TContext type (default: unknown) generic parameter is used to specify the interface of the context properties.
The Context Object is arbitrary user-defined data that will be passed to all callbacks. This is useful for attaching custom state to your chart.
import { Component } from "@angular/core";
import { AgCharts } from "ag-charts-angular";
import {
AgCartesianChartOptions,
AnimationModule,
CandlestickSeriesModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
ModuleRegistry,
NumberAxisModule,
TimeAxisModule,
} from "ag-charts-enterprise";
import {
Currency,
CurrencyConverter,
makeCurrencyConverter,
} from "./currencyConverter";
import { TradeDatum, getData } from "./data";
import clone from "clone";
ModuleRegistry.registerModules([
AnimationModule,
CandlestickSeriesModule,
ContextMenuModule,
CrosshairModule,
LegendModule,
NumberAxisModule,
TimeAxisModule,
]);
@Component({
selector: "my-app",
standalone: true,
imports: [AgCharts],
template: `<div class="example-controls">
<div class="controls-row">
<label for="mySelect">User Currency: </label>
<select id="mySelect" (change)="onMySelectChange($event.target.value)">
<option value="EUR">🇪🇺 Euros (€)</option>
<option value="USD">🇺🇸 US Dollars ($)</option>
<option value="GBP">🇬🇧 Sterling Pound (£)</option>
<option value="JPY">🇯🇵 Japanese Yen (¥)</option>
<option value="INR">🇮🇳 Indian Rupee (₹)</option>
</select>
</div>
</div>
<ag-charts
[options]="options"
></ag-charts>
`,
})
export class AppComponent {
public options;
constructor() {
this.options = {
context: makeCurrencyConverter("EUR"),
title: {
text: "Stock Prices",
},
data: getData(),
series: [
{
type: "candlestick",
xKey: "date",
openKey: "open",
highKey: "high",
lowKey: "low",
closeKey: "close",
tooltip: {
renderer: ({ datum, context }) => {
if (context == null) return {};
return {
title: datum.date.toDateString(),
data: [
{
label: "Open",
value: context.formatBothCurrencies(datum.open),
},
{
label: "High",
value: context.formatBothCurrencies(datum.high),
},
{
label: "Low",
value: context.formatBothCurrencies(datum.low),
},
{
label: "Close",
value: context.formatBothCurrencies(datum.close),
},
],
};
},
},
},
],
axes: {
x: {
type: "time",
},
y: {
type: "number",
label: {
formatter: ({ value, context }) => {
return context?.formatUserCurrency(value);
},
},
},
},
contextMenu: {
items: [
{
showOn: "series-node",
label: "Log as USD",
action: ({ datum, context }) =>
console.log(context?.formatLog(datum, "USD")),
},
{
showOn: "series-node",
label: "Log as EUR",
action: ({ datum, context }) =>
console.log(context?.formatLog(datum, "EUR")),
},
{
showOn: "series-node",
label: "Log as GBP",
action: ({ datum, context }) =>
console.log(context?.formatLog(datum, "GBP")),
},
{
showOn: "series-node",
label: "Log as JPY",
action: ({ datum, context }) =>
console.log(context?.formatLog(datum, "JPY")),
},
{
showOn: "series-node",
label: "Log as INR",
action: ({ datum, context }) =>
console.log(context?.formatLog(datum, "INR")),
},
],
},
};
}
onMySelectChange = (value: Currency) => {
const options = clone(this.options);
options.context = makeCurrencyConverter(value);
this.options = options;
};
}
In this example the TContext generic parameter is set to a CurrencyConverter object to convert stock prices from USD to a user-defined target currency.
This is used by:
- The Y-axis Label Formatter, to convert USD values to the preferred User Currency.
- The Tooltip Renderer, to render both the stock prices in USD and the User Currency (if applicable).
- The Context Menu Actions, to log converted stock prices to the console.