Skip to content

Releases: valor-software/ng2-charts

v3.0.0-rc.2 - Chart.js v3 RC.2

21 May 13:57
Compare
Choose a tag to compare
Pre-release
  • Various bugfixes
  • Angular 12 update
  • Eslint migration

v2.4.0 - Angular 10 upgrade

25 Aug 16:48
Compare
Choose a tag to compare
Angular v10 update

Introduce strong typings for everything

20 Mar 18:05
Compare
Choose a tag to compare
Pre-release

3.0.0-beta - Introduce strong typings

Table of Content

Goal
Application Chart Meta Configuration Class
Application Chart Configuration File
Integrating It All
Schematics Usage

Goal

The goal of this version is to provide strong typings for every type in the chart.js domain. Right now, many properties are not typed (or typed any) and this puts a lot of unnecessary work in writing code for configuration options.

Additionally, plugins and extensions are allowed to extend the configuration options structure in many ways (add properties to options add properties to data.datasets[] add new chart types, or scale types, etc...). The typing problem becomes worse when plugins and extensions are also brought into the game.

For the chart.js package itself I've reworked all the typings, specifically:

  1. The datasets for the different chart type (previously ChartDataSets) are now in separate classes (ChartDataSetsLine, ChartDataSetsBar, etc.)
  2. The classes describing the scales - CommonAxe and its derived classes - have been changed and rearranged to provide better protection against incompatible properties for the scale types (also, class names have changed).
  3. Many callback signatures have been updated with specific types.

With regards to extensions and plugins, I've decided to approach the issue using generics. The basic idea is to impose a requirement on application developers to provide a "meta configuration" for their chart environment. This meta configuration will include all the ways in which configuration options are extended in a central place following the DRY principle. Angular CLI schematics have been created to assist in generating this boiler plate.

Application Chart Meta Configuration Class

This meta configuration comes in the form of a class (defined in the application, not in the library) which has specially named fields with types describing the extensions for the chart.js various option types. Example:

import * as ng2Charts from 'ng2-charts';
import { ChartDataSetsFoo, FooScale } from 'foo-plugin';
import { DataLabelsOptions } from 'chartjs-plugin-datalabels';
import { AnnotationOptions} from 'chartjs-plugin-annotation';

export interface AppChartMetaConfig extends ng2Charts.BaseChartMetaConfig {
  datasetTypes: ng2Charts.ChartMetaConfig['datasetTypes'] | ChartDataSetsFoo;
  scaleTypes: ng2Charts.ChartMetaConfig['scaleTypes'] | FooScale;
  pluginOptions: {
    datalabels?: DataLabelsOptions;
  };
  additionalOptions: {
    annotation?: AnnotationOptions;
  };
}

Breaking down the above example:

The imports section describes a theoretical set of imports from various extensions:

  1. The foo plugin which defines a new chart type and a new scale type.
  2. The datalabels plugin which defines a set of options (the plugin does exist, but the options type does not, this is why this is all still theoretical)
  3. The annotation plugin which similarly defines a set of options, however this plugin plugs its options not to options.plugins but directly to options itself.

Application Chart Configuration File

Once this meta configuration type is defined, other types are defined while using this meta config as a generic type argument. This is, again, boilerplate which is generated by the schematics:

import * as ng2Charts from 'ng2-charts';
import { AppChartMetaConfig } from './app-chart-meta-config';
export { AppChartMetaConfig } from './app-chart-meta-config';
export {
  ChartsModule,
  Color,
  Colors,
  defaultColors,
  ChartType,
  ChartDataSetsBase,
  ChartDataSetsUnion,
  BaseChartMetaConfig,
  ChartMetaConfig,
  LegacyMetaConfig,
  PromiscuousMetaConfig,
  LinearScale,
  LogarithmicScale,
  CategoryScale,
  CartesianScale,
  RadialScale,
  RadialLinearScale,
  ScaleUnion,
  ThemeService,
  BaseChartDirective,
  Label,
} from 'ng2-charts';

export type AngularChart = ng2Charts.AngularChart<AppChartMetaConfig>;
export type ChartOptions = ng2Charts.ChartOptions<AppChartMetaConfig> & AppChartMetaConfig['additionalOptions'];
export type ChartDataSetsBar = ng2Charts.ChartDataSetsBar<AppChartMetaConfig>;
export type ChartDataSetsLine = ng2Charts.ChartDataSetsLine<AppChartMetaConfig>;
export type ChartDataSetsDoughnut = ng2Charts.ChartDataSetsDoughnut<AppChartMetaConfig>;
export type ChartDataSetsRadar = ng2Charts.ChartDataSetsRadar<AppChartMetaConfig>;
export type ChartDataSetsBubble = ng2Charts.ChartDataSetsBubble<AppChartMetaConfig>;
export type ChartDataSetsScatter = ng2Charts.ChartDataSetsScatter<AppChartMetaConfig>;
export type MultiDataSet = ng2Charts.MultiDataSet<AppChartMetaConfig>;
export type SingleDataSet = ng2Charts.SingleDataSet<AppChartMetaConfig>;

Integrating It All

As a final step, the application developer now imports all types from this config file, and not from ng2-charts or from chart.js. Example:

import { Component, OnInit, ViewChild } from '@angular/core';
import * as pluginAnnotations from 'chartjs-plugin-annotation';
import {
  AppChartMetaConfig,
  ChartDataSetsLine,
  ChartOptions,
  Color,
  Label,
  BaseChartDirective
} from '../app-chart-config';

@Component({
  selector: 'app-line-chart',
  templateUrl: './line-chart.component.html',
  styleUrls: ['./line-chart.component.scss']
})
export class LineChartComponent implements OnInit {
  public lineChartData: ChartDataSetsLine[] = [
    { data: [65, 59, 80, 81, 56, 55, 40], label: 'Series A' },
    { data: [28, 48, 40, 19, 86, 27, 90], label: 'Series B' },
    { data: [180, 480, 770, 90, 1000, 270, 400], label: 'Series C', yAxisID: 'y-axis-1' }
  ];
  public lineChartLabels: Label[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
  public lineChartOptions: ChartOptions = {
...

Schematics Usage

Example usage

  1. Create a minimal angular app
ng new --minimal myApp
  1. Install packages
npm install --save ng2-charts chart.js ng2-charts-schematics
  1. Generate a line chart
ng generate ng2-charts-schematics:line my-line-chart

The output of the generate command is:

CREATE src/app/my-line-chart/my-line-chart.component.html (317 bytes)
CREATE src/app/my-line-chart/my-line-chart.component.spec.ts (665 bytes)
CREATE src/app/my-line-chart/my-line-chart.component.ts (923 bytes)
CREATE src/app/my-line-chart/my-line-chart.component.css (0 bytes)
CREATE src/app/app-chart-config.ts (1604 bytes)
CREATE src/app/app-chart-meta-config.ts (402 bytes)
UPDATE src/app/app.module.ts (513 bytes)

The command calls Angular's schematics to generate a component as normal, then replaces the code of the component class with the code for a line chart. It also adds the ng2-charts ChartsModule to the module's imports section, and generates the meta config class and config file (if they did not exist already).

v1.0.2

13 Apr 14:59
Compare
Choose a tag to compare

Bug Fixes

  • charts: fixed implicit any issues (14acd8a)
  • typings: included all required typings (ecdedf5)

Features