ZingChart Angular: Extending TDF

TypeScript supports a great feature: the ability to define properties with dynamic keys and template literal types. This allows us to define properties with a specific pattern in the  ZingChart type definition file (TDF) .

The zingchart-angular wrapper only supports up to TypeScript 3, which does not include the template literal types (available in TypeScript 4.1). This limitation prevents the addition of custom tokens (data-custom-token) and user-specified properties (link[cls-CustomLinkClass]) within the chart configuration object.

In this post, we will discuss how to extend the zingchart-angular wrapper TDF to include your own properties on the chart configuration object.

Simple Example

Let’s assume you have the following chart configuration object.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-extend-tdf',
  templateUrl: './extendTdf.component.html',
})
export class ExtendTdf {
  config: ZingchartAngular.graphset = { 
    type: 'bar',
    title: { text: 'My custom "data-description" property' },
		'data-description': 'test',
    series: [{ values: [4, 5, 3, 4, 5, 3, 5] }] 
  };
}

The data-description property is not defined in the TDF, resulting in a type error and preventing the code from compiling.

First create a TDF (index.d.ts) in your project.

Within the TDF, import the ZingchartAngular type from the original TDF. Give this import an alias, which we will reference when extending interfaces in the next steps.

import { default as _ZingchartAngular } from 'zingchart-angular/index';

Next, we will redefine both the ZingchartAngluar namespace and graphset interface to include our new data-description property. For the graphset interface, we want to extend from the original interface.

declare namespace ZingchartAngular {
  interface graphset extends _ZingchartAngular.graphset {
    'data-description'?: string;
  }
}```

Lastly, we export the new ZingchartAngular type.

Altogether, the final TDF should look like this:

import { default as _ZingchartAngular } from 'zingchart-angular/index';

declare namespace ZingchartAngular {
  interface graphset extends _ZingchartAngular.graphset {
    'data-description'?: string;
  }
}

export default ZingchartAngular; 

Going back to your component file, just import the new ZingchartAngular type from the TDF you just created. The zingchart-angular wrapper TDF is now extended with your TDF.

All type errors are gone and your project will now compile.

import { Component, OnInit } from '@angular/core';
import { ZingchartAngular } from '../path/to/index.d.ts';

@Component({
  selector: 'app-extend-tdf',
  templateUrl: './extendTdf.component.html'
})
export class ExtendTdf {
  config: ZingchartAngular.graphset = { 
    type: 'bar',
    title: { text: 'My custom "data-description" property' },
    'data-description': 'test',
    series: [{ values: [4, 5, 3, 4, 5, 3, 5] }] 
  };
}

Advance example

In the previous example, we extended the TDF to include the graphset['data-description'] property to the chart configuration object.

A more complex example is defining a property that is nested deeper in the chart configuration.

Let’s look into how to add data-description to the graphset.series object.

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-extend-tdf',
  templateUrl: './extendTdf.component.html'
})
export class ExtendTdf {
  config: ZingchartAngular.graphset = { 
    type: 'bar',
    title: { text: 'Extend TDF with custom token: data-description'},
    plot: {
      tooltip: {
        text: '%v - %data-description',
      }
    },
    series: [{
			values: [4, 5, 3, 4, 5, 3, 5],
			'data-description': ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'],
		}] 
  };
}```

For this example, redefine each property (graphset → plot → selectedMarker) within the nested object.

For each interface that is accessed:

  1. extend from the original interface
  2. redefine the next property of the nested object

Following these steps, your TDF should look like this:

import {default as _ZingchartAngular} from 'zingchart-angular/index';

declare namespace ZingchartAngular {
  interface graphset extends _ZingchartAngular.graphset {
    series?: series[];
  }
  interface series extends _ZingchartAngular.series {
    'data-description'?: string[];
  }
}

export default ZingchartAngular;

Demo

Check out the two example we went through here:

Conclusion

Following the examples above, you can now define your own properties for custom tokens or user-specific properties to the chart configuration file.

Interested in learning more about ZingChart or trying it out for yourself? Let us know at support@zingchart.com or visit us at https://www.zingchart.com and chat directly with our team via our online chat!