chartjs / chartjs-plugin-annotation

Annotation plugin for Chart.js
MIT License
603 stars 325 forks source link

Updating line annotation value #924

Closed godind closed 6 months ago

godind commented 7 months ago

Hi,

Probably a stupid question but I can't seem to be able to dynamically change the line value. I am dynamically pushing data as it coming on and want to have the annotation line adjust with the mean value of the growing dataset.data:

Using Angular and charts.js v4.4.2

plugins: {
      annotation: {
        annotations: {
          meanLine: {
            type: 'line',
            scaleID: 'y',
            value: 0,
            borderColor: 'red',
            drawTime: 'beforeDatasetsDraw',
            label: {
              display: true,
              content: "Dataset Mean value"
            }
          }
        }
      }
    }

tried a few things...

this.lineChartOptions.plugins.annotation.annotations['meanLine'].value = 50;
this.chart?.update('none');
this.lineChartOptions.plugins.annotation.annotations[0].value = 50;
this.chart?.update('none');
this.lineChartOptions.plugins.annotation.annotations.meanLine.value = 50;
this.chart?.update('none');
stockiNail commented 7 months ago

@godind there are never stupid questions..

The approach is correct but I have the feeling that lineChartOptions are the options you use to configure the chart. That options are used only to initialize the chart.

If you need to change a live chart, you should use chart.options.

In your code, you should use the following:

this.chart?.options.plugins.annotation.annotations.meanLine.value = 50;
this.chart?.update('none');

Codepen: https://codepen.io/stockinail/pen/LYvVPPK

Another options could be to set the value as scriptable options (in chart init):

plugins: {
      annotation: {
        annotations: {
          meanLine: {
            type: 'line',
            scaleID: 'y',
            value: (context) => {...... you code.... }, // <- this scriptable options is invoked at each chart update
            borderColor: 'red',
            drawTime: 'beforeDatasetsDraw',
            label: {
              display: true,
              content: "Dataset Mean value"
            }
          }
        }
      }
    }

Let me know if it is working for you as well

godind commented 6 months ago

Wonderful. Thank you so much!!! I get this error. Probably related to Typescript types but not sure how to fit it!

image

image

godind commented 6 months ago

I've also tried as a Record approach: this.chart?.options.plugins.annotation.annotations["meanLine"].value = 10;

no luck

stockiNail commented 6 months ago

afaik you could NOT use ?. left of the equal during an assignment even if I'm not an Angular expert

godind commented 6 months ago

I also made sure to include the following:

import { Chart, ChartConfiguration, ChartData, ChartType } from 'chart.js';
import annotationPlugin from 'chartjs-plugin-annotation';
import 'chartjs-adapter-date-fns';
 constructor() {
    Chart.register(annotationPlugin);
   }

I also tried this with no luck:

let x: LineAnnotationOptions = this.chart?.options.plugins.annotation.annotations[1];
        x.value = 100;

Sorry to shoot at you like this ;)

godind commented 6 months ago

afaik you could NOT use ?. left of the equal during an assignment even if I'm not an Angular expert

I tried removing it but still no luck. With ts-ignore it compiles and runs but the value is not updated.

//@ts-ignore
this.chart.options.plugins.annotation.annotations.meanLine.value = 100;
this.chart?.update('none'); 
godind commented 6 months ago

Found the problem. It's with ng2-chart's type definition. It works fine in plain js.

Sorry for the trouble. Thank you!

stockiNail commented 6 months ago

Found the problem. It's with ng2-chart's type definition. It works fine in plain js.

Sorry for the trouble. Thank you!

@godind No problem, no need to be sorry!! I had planned to do a test, installing an Angular app and I'll do anyway later. Glad to hear that's working!