Correct config location of chartjs-plugin-annotation with ng2-charts?

1.9k views Asked by At

I'm using ng2-charts to draw a bar chart in my Angular application. At some point I had to add static lines to my charts, and I decided to use chartjs-plugin-annotation. Connecting these two libraries together is not well documented, but after some googling I was eventually able to get it working.

Here is a minimalistic demo. Yet while it works well on stackblitz, the IDE on my local machine complains that annotation is not expected by ChartOptions interface:

  public barChartOptions: ChartOptions = {
    responsive: true,
    scales: {
        yAxes: [{
            display: true,
            ticks: {
                suggestedMin: 0
            }
        }]
    },
    // This whole section is underlined in red by IDE
    annotation: {
      drawTime: 'afterDatasetsDraw',
      annotations: [
        {
          type: 'line',
          ...

So does the compiler:

    ERROR in src/app/calendar/calendar.component.ts(31,5): error TS2322: Type '{ responsive: true; scales: { yAxes: { display: true; ticks: { suggestedMin: number; }; }[]; }; annotation: { drawTime: string; annotations: { type: string; mode: string; scaleID: string; value: number; borderColor: string; borderDash: number[]; borderWidth: number; }[]; }; }' is not assignable to type 'ChartOptions'.
      Object literal may only specify known properties, but 'annotation' does not exist in type 'ChartOptions'. Did you mean to write 'rotation'?

Although this warning doesn't prevent the project from compiling, it still doesn't look right.

I checked ChartOptions, defined in node_modules/@types/chart.js/index.d.ts, and indeed, it doesn't have annotation in it (and shouldn't, because this interface is defined in chart.js library, who doesn't and shouldn't know anything about plugin specifics):

interface ChartOptions {
    responsive?: boolean;
    responsiveAnimationDuration?: number;
    aspectRatio?: number;
    maintainAspectRatio?: boolean;
    events?: string[];
    legendCallback?(chart: Chart): string;
    onHover?(this: Chart, event: MouseEvent, activeElements: Array<{}>): any;
    onClick?(event?: MouseEvent, activeElements?: Array<{}>): any;
    onResize?(this: Chart, newSize: ChartSize): void;
    title?: ChartTitleOptions;
    legend?: ChartLegendOptions;
    tooltips?: ChartTooltipOptions;
    hover?: ChartHoverOptions;
    animation?: ChartAnimationOptions;
    elements?: ChartElementsOptions;
    layout?: ChartLayoutOptions;
    scale?: RadialLinearScale;
    scales?: ChartScales | LinearScale | LogarithmicScale | TimeScale;
    showLines?: boolean;
    spanGaps?: boolean;
    cutoutPercentage?: number;
    circumference?: number;
    rotation?: number;
    devicePixelRatio?: number;
    plugins?: ChartPluginsOptions;
}

I tried to re-locate the annotation part elsewhere (chartjs-plugin-annotation documentation says it should be under plugins, which would make total sense), but in all other locations it was just ignored. So eventually, in order to get rid of the warning, I just removed the : ChartOptions part - that is, instead of this:

  public barChartOptions: ChartOptions = {

I wrote just this:

  public barChartOptions = {

That removed the warnings, but it still does not look neat enough. Does anyone have any idea how to use this plugin properly?

1

There are 1 answers

1
dcfg On BEST ANSWER

I had more or less the same issue. I figured out that in chartjs-plugin-annotations's index.d.tx file there was a deprecated definition of ChartOptions interface, which collided against the one defined in ng2-charts.

So, in ~/project-folder/node_modules/@types/chartjs-plugin-annotation/index.d.ts, change

// Extend the types from chart.js
declare module 'chart.js' {
  interface ChartOptions {
    // This is deprecated on master (not released yet)
    annotation?: ChartJsAnnotation.AnnotationConfig;
  }

  // This is the correct version on master (not released yet)
  // interface ChartPluginsOptions {
  //   annotation?: ChartJsAnnotation.AnnotationConfig;
  // }

  const Annotation: ChartJsAnnotation.AnnotationStatic;
}

to this

// Extend the types from chart.js
declare module 'chart.js' {
  // interface ChartOptions {
  //   // This is deprecated on master (not released yet)
  //   annotation?: ChartJsAnnotation.AnnotationConfig;
  // }

  // This is the correct version on master (not released yet)
  interface ChartPluginsOptions {
    annotation?: ChartJsAnnotation.AnnotationConfig;
  }

  const Annotation: ChartJsAnnotation.AnnotationStatic;
}

Doing so removed the compiler error for me.