0

I'm trying to add a custom plugin in addition to chartjs-plugin-zoom, but I failed to understand how to put the zoom plugin configs outside of the plugins object nor could I use the custom plugin on its own.

My custom plugin (taken from here):

hoverLine = {
    id: 'hoverLine',
    afterDatasetsDraw() {
      const { 
        ctx, 
        chartArea: { top, right, bottom, left, width, height },
        tooltip,
        scales: { x, y },
      } = this.chart;
      console.info(`:`, tooltip);
      
      if(tooltip._active && tooltip._active.length > 0) {
        const xCord = x.getPixelForValue(tooltip.dataPoints[0].dataIndex);
        const yCord = y.getPixelForValue(tooltip.dataPoints[0].parsed.y);
        ctx.save();
        ctx.beginPath();
        ctx.lineWidth = 1;
        ctx.strokeStyle = "rgba(33, 33, 33, 1)";
        ctx.moveTo(xCord, yCord);
        ctx.lineTo(top, bottom);
        ctx.stroke();
        ctx.closePath();
      }
    }
  }

Rest of my code:

export class ChartComponent implements OnInit, OnChanges {
  public chart: any;
  @Input() chartTitle: string = "Traffic in bit/s";
  @Input() displayTotal: { title: String; value: { value: number; unit: string } } = { title: "Total Traffic", value: { value: 1230, unit: "bit/s" } }
  @Input() chartType: ChartConfiguration["type"] = "line";
  // @Input() chartDataSets?: ChartConfiguration["data"]["datasets"];
  // @Input() chartDataLabels?: ChartConfiguration["data"]["labels"];
  @Input() chartDataSets?: any;
  @Input() chartDataLabels?: any;
  @Input() chartOptions?;
  @Output() zoomComplete = new EventEmitter<{ min: number; max: number; }>();


  public defaultOptions = {
    elements: {
      line: {
        tension: 0.5,
        fill: "-1",
      },
      point: {
        radius: 1,
      }
    },
    scales: {
      y: {
        position: "left",
        stacked: true,
        min: 0,
        border: {
          dash: [8, 4],
        }
      },
      x: {
        stacked: true,
        type: "time",
        time: {
          parser: 'dd - HH:mm',
            displayFormats: {
              hour: 'HH:mm',
              day: 'MMM-dd'
            },
        },
        grid: {
          display: false,
        },
        offset: true,
        ticks: {
          major: {
            enabled: true,
          },
          font: (context) => {
            return context.tick && context.tick.major ? { weight: 'bold', size: 14 } : '';
          },
          autoSkip: true,
          stepSize: 1,
          maxTicksLimit: 12,
        },
      },
    },
    plugins: {
      zoom: {
        pan: {
          enabled: false,
        },
        zoom: {
          drag: {
            enabled: true,
          },
          mode: 'x',
          onZoomComplete: () => {
            const { min, max } = this.chart.scales.x;
            this.zoomComplete.emit({ min, max });
          },
        },
        limits: {
          x: { min: 'original', max: 'original', minRange: 1000 * 60 * 10, },
        },
      },
    },
  };
constructor() {}

  ngOnInit(): void {    
    Chart.register(...registerables, zoomPlugin);
    this.createChart();
  }

  ngOnChanges(changes: SimpleChanges): void {
    // const chartExist = Chart.getChart("serverChart");
    // if (chartExist !== undefined) chartExist.destroy();
    
    if (this.chart) {
      this.chart.data.datasets = this.chartDataSets;
      this.chart.options = this.defaultOptions;
      this.chart.update();
    }
  }

  createChart() {
    this.chart = new Chart("serverChart", {
      type: this.chartType,
      data: {
        datasets: this.chartDataSets,
        labels: this.chartDataLabels || [],
      },
    });
  }

  // events
  
  fetchData = () => {
    const { min, max } = this.chart.scales.x;
    this.zoomComplete.emit({ min, max });
  }

I didn't found an example for what I need and couldn't follow the documentation enough to make it work. The zoom plugin works when the code is written like that, but how do I configure it to make it work in addition to the custom one (and others to be added).

Thanks.

Angular v.14; chart.js v.4; chartjs-plugin-zoom v.2

Liran_T
  • 69
  • 7
  • 1
    Your plugin doesn't seem to have any options; if it had, you would have to declare them in `defaultOptions.plugins.hoverLine`, the same way the options for `zoom` plugin are under `defaultOptions.plugins.zoom` - the options are under the corresponding plugin id. – kikon Mar 26 '23 at 09:58
  • 1
    Also, you don't seem to have added the plugin to your chart - for that, you have to add `plugins: [hoverLine]` in the `Chart` constructor second argument in your `createChart` function, i.e., after `type:...` and `data: ...`; here you are using the js identifier `hoverLine` that is assigned the plugin object, not the id as is the case with options. – kikon Mar 26 '23 at 09:58
  • @kikon, Thanks! I'm still can't make it work, but probably because I didn't copy something correctly (tooltip._active is always false). BUT! I did managed to make another plugin work, Which is great! So thanks again. – Liran_T Mar 26 '23 at 12:37
  • You're welcome! I recommend you to make a codepen or codesandbox with the code that still doesn't work so we can fork it and debug it - it will make it much more probable to get a precise answer. – kikon Mar 26 '23 at 13:07
  • @kikon, got it! x.getPixelForValue( tooltip.dataPoints[0].dataIndex ); gave me negative number (not sure why as the data is originally of type long), so I changed it to x.getPixelForValue( tooltip.dataPoints[0].parsed.x ); – Liran_T Mar 27 '23 at 07:31

0 Answers0