xieziyu / ngx-echarts

An angular (ver >= 2.x) directive for ECharts (ver >= 3.x)
https://xieziyu.github.io/ngx-echarts/
MIT License
1.11k stars 197 forks source link

Ngx-Echarts Animation not working Initially #413

Closed KrisnaPrashatt closed 6 months ago

KrisnaPrashatt commented 11 months ago

I am using ngx echarts for my angular app and I am not able to get the animation to work during the initial load of the chart. I have attached a sample Stackblitz where you can observe that on initial load, the bars render faster whereas when toggling using the legend, the actual animation happens.

Can anyone help me out in the right direction saying what have I done wrong?

Html:

<div echarts [options]="options"></div>

Ts options object

{ xAxis: { data: xAxisData, }, legend: {}, yAxis: {}, series: [ { name: 'bar', type: 'bar', barCategoryGap: '0%', data: data1, animationDuration: 5000, }, { name: 'bar1', type: 'bar', barCategoryGap: '0%', data: data2, animationDuration: 3000, }, ], }

xieziyu commented 11 months ago

@KrisnaPrashatt ECharts applies the transition animation only when data changes after chart initialized. So you can assign an empty value to option firstly in order to initialize the chart; then, in ngAfterViewInit, you can assign data to your chart option using setTimeout. For example:

option: EChartsOption = {}

ngAfterViewInit()
{
  setTimeout(() => {
    this.option = {
       // options and series...
    };
  );
}
KrisnaPrashatt commented 11 months ago

@xieziyu , Thank you for your response but that did not work. But what did work, is the addition of [autoResize]="false". This made the animation to be similar to that of the given documentation of echarts. Can you explain what role does this have in determining the animation behaviour? If you want to see the behaviour difference for yourself, here is the Stackblitz link. There you can modify the autoResize property and see the difference in animation.

s9ke commented 11 months ago

This is a bug with [autoResize]. ResizeObserver is immediately called on init (as per spec) which then calls resize(). resize() defaults animation to none.

The following fixes need to be made to source (or something like it):

private resizeObFired: boolean = false;

ngOnInit() {
   ...
   if (this.autoResize) {
      this.resizeOb = this.ngZone.runOutsideAngular(() => new window.ResizeObserver((entries) => {
        for (const entry of entries) {
            if (entry.target === this.el.nativeElement) {
                // Ignore first fire on insertion, no resize actually happened
              if (!this.resizeObFired) {
                this.resizeObFired = true
              } else {
                this.animationFrameID = window.requestAnimationFrame(() => {
                  this.resize$.next();
                });
              }
            }
          }
      }));
      this.resizeOb.observe(this.el.nativeElement);
    }
}

ngAfterViewInit() {
   this.initChart();
}
ArielCW commented 5 months ago

@xieziyu Could the current fix on version 17 be applied to 16.2.0 ? or some kind of workaround to keep the auto resize and the initial animation on version 16?

s9ke commented 5 months ago

As a workaround, you could probably just add the property animationDurationUpdate to the options with a defined time like the following stackblitz.

Here is the documentation on ECharts.