@@ -41,9 +41,11 @@ export class PlotlyComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
4141
4242 public plotlyInstance ?: Plotly . PlotlyHTMLElement ;
4343 public resizeHandler ?: ( instance : Plotly . PlotlyHTMLElement ) => void ;
44+ public resizeObserver ?: ResizeObserver ;
4445 public layoutDiffer ?: KeyValueDiffer < string , any > ;
4546 public dataDiffer ?: IterableDiffer < Plotly . Data > ;
4647 private destroyed = false ;
48+ private resizeAnimationFrame ?: number ;
4749
4850 @ViewChild ( 'plot' , { static : true } ) plotEl ! : ElementRef ;
4951
@@ -72,49 +74,49 @@ export class PlotlyComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
7274 purge = output < Plotly . Figure > ( ) ;
7375 error = output < Error > ( ) ;
7476
75- afterExport = output ( ) ;
76- afterPlot = output ( ) ;
77- animated = output ( ) ;
78- animatingFrame = output ( ) ;
79- animationInterrupted = output ( ) ;
80- autoSize = output ( ) ;
81- beforeExport = output ( ) ;
82- beforeHover = output ( ) ;
83- buttonClicked = output ( ) ;
77+ afterExport = output < Plotly . Event > ( ) ;
78+ afterPlot = output < Plotly . Event > ( ) ;
79+ animated = output < Plotly . Event > ( ) ;
80+ animatingFrame = output < Plotly . Event > ( ) ;
81+ animationInterrupted = output < Plotly . Event > ( ) ;
82+ autoSize = output < Plotly . Event > ( ) ;
83+ beforeExport = output < Plotly . Event > ( ) ;
84+ beforeHover = output < Plotly . Event > ( ) ;
85+ buttonClicked = output < Plotly . Event > ( ) ;
8486 /**
8587 * @deprecated DEPRECATED: Reconsider using `(plotlyClick)` instead of `(click)` to avoid event conflict. Please check https://github.com/plotly/angular-plotly.js#FAQ
8688 */
87- click = output ( ) ;
88- plotlyClick = output ( ) ;
89- clickAnnotation = output ( ) ;
90- deselect = output ( ) ;
91- doubleClick = output ( ) ;
92- framework = output ( ) ;
93- hover = output ( ) ;
94- legendClick = output ( ) ;
95- legendDoubleClick = output ( ) ;
89+ click = output < Plotly . PlotMouseEvent > ( ) ;
90+ plotlyClick = output < Plotly . PlotMouseEvent > ( ) ;
91+ clickAnnotation = output < Plotly . Event > ( ) ;
92+ deselect = output < Plotly . Event > ( ) ;
93+ doubleClick = output < Plotly . Event > ( ) ;
94+ framework = output < Plotly . Event > ( ) ;
95+ hover = output < Plotly . PlotMouseEvent > ( ) ;
96+ legendClick = output < Plotly . Event > ( ) ;
97+ legendDoubleClick = output < Plotly . Event > ( ) ;
9698 /**
9799 * @deprecated DEPRECATED: Event react is not list as an plotly.js event
98100 */
99- react = output ( ) ;
100- relayout = output ( ) ;
101- relayouting = output ( ) ;
102- restyle = output ( ) ;
103- redraw = output ( ) ;
104- selected = output ( ) ;
105- selecting = output ( ) ;
106- sliderChange = output ( ) ;
107- sliderEnd = output ( ) ;
108- sliderStart = output ( ) ;
109- sunburstclick = output ( ) ;
110- transitioning = output ( ) ;
111- transitionInterrupted = output ( ) ;
112- unhover = output ( ) ;
101+ react = output < Plotly . Event > ( ) ;
102+ relayout = output < Plotly . PlotRelayoutEvent > ( ) ;
103+ relayouting = output < Plotly . PlotRelayoutEvent > ( ) ;
104+ restyle = output < Plotly . PlotRestyleEvent > ( ) ;
105+ redraw = output < Plotly . Event > ( ) ;
106+ selected = output < Plotly . PlotSelectionEvent > ( ) ;
107+ selecting = output < Plotly . PlotSelectionEvent > ( ) ;
108+ sliderChange = output < Plotly . Event > ( ) ;
109+ sliderEnd = output < Plotly . Event > ( ) ;
110+ sliderStart = output < Plotly . Event > ( ) ;
111+ sunburstclick = output < Plotly . PlotMouseEvent > ( ) ;
112+ transitioning = output < Plotly . Event > ( ) ;
113+ transitionInterrupted = output < Plotly . Event > ( ) ;
114+ unhover = output < Plotly . PlotMouseEvent > ( ) ;
113115 /**
114116 * @deprecated DEPRECATED: Event treemapclick is not list as an plotly.js event
115117 */
116- treemapclick = output ( ) ;
117- webglcontextlost = output ( ) ;
118+ treemapclick = output < Plotly . PlotMouseEvent > ( ) ;
119+ webglcontextlost = output < Plotly . Event > ( ) ;
118120
119121
120122 public eventNames = [ 'afterExport' , 'afterPlot' , 'animated' , 'animatingFrame' , 'animationInterrupted' , 'autoSize' ,
@@ -149,6 +151,12 @@ export class PlotlyComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
149151 this . getWindow ( ) . removeEventListener ( 'resize' , this . resizeHandler as any ) ;
150152 this . resizeHandler = undefined ;
151153 }
154+ this . resizeObserver ?. disconnect ( ) ;
155+ this . resizeObserver = undefined ;
156+ if ( this . resizeAnimationFrame !== undefined ) {
157+ this . getWindow ( ) . cancelAnimationFrame ?.( this . resizeAnimationFrame ) ;
158+ this . resizeAnimationFrame = undefined ;
159+ }
152160
153161 if ( this . plotlyInstance ) {
154162 const figure = this . createFigure ( ) ;
@@ -254,14 +262,14 @@ export class PlotlyComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
254262
255263 this . eventNames . forEach ( name => {
256264 const eventName = `plotly_${ name . toLowerCase ( ) } ` ;
257- const event = ( this as any ) [ name ] as OutputEmitterRef < any > ;
265+ const event = ( this as any ) [ name ] as OutputEmitterRef < Plotly . Event > ;
258266
259- plotlyInstance . on ( eventName , ( data : any ) => event . emit ( data ) ) ;
267+ plotlyInstance . on ( eventName , ( data : unknown ) => event . emit ( data as Plotly . Event ) ) ;
260268 } ) ;
261269
262- plotlyInstance . on ( 'plotly_click' , ( data : any ) => {
263- this . plotlyClick . emit ( data ) ;
264- this . click . emit ( data ) ;
270+ plotlyInstance . on ( 'plotly_click' , ( data : unknown ) => {
271+ this . plotlyClick . emit ( data as Plotly . PlotMouseEvent ) ;
272+ this . click . emit ( data as Plotly . PlotMouseEvent ) ;
265273 } ) ;
266274
267275 this . updateWindowResizeHandler ( ) ;
@@ -299,6 +307,7 @@ export class PlotlyComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
299307 this . config ( ) ,
300308 this . frames ( )
301309 ) . then ( ( ) => {
310+ this . scheduleResizeAfterLayoutUpdate ( ) ;
302311 const figure = this . createFigure ( ) ;
303312 this . update . emit ( figure ) ;
304313 } , err => {
@@ -319,6 +328,51 @@ export class PlotlyComponent implements OnInit, OnChanges, OnDestroy, DoCheck {
319328 this . resizeHandler = undefined ;
320329 }
321330 }
331+
332+ this . updateResizeObserver ( ) ;
333+ }
334+
335+ private updateResizeObserver ( ) : void {
336+ const shouldObserve = this . useResizeHandler ( )
337+ && this . plotlyInstance
338+ && isPlatformBrowser ( this . platformId )
339+ && typeof ResizeObserver !== 'undefined' ;
340+
341+ if ( shouldObserve ) {
342+ if ( this . resizeObserver === undefined ) {
343+ this . resizeObserver = new ResizeObserver ( ( ) => this . scheduleResize ( ) ) ;
344+ this . resizeObserver . observe ( this . plotEl . nativeElement ) ;
345+ }
346+ } else {
347+ this . resizeObserver ?. disconnect ( ) ;
348+ this . resizeObserver = undefined ;
349+ }
350+ }
351+
352+ private scheduleResizeAfterLayoutUpdate ( ) : void {
353+ const layout = this . layout ( ) ;
354+ if ( layout ?. [ 'autosize' ] === true && layout [ 'height' ] === undefined && layout [ 'width' ] === undefined ) {
355+ this . scheduleResize ( ) ;
356+ }
357+ }
358+
359+ private scheduleResize ( ) : void {
360+ if ( this . destroyed || ! this . plotlyInstance || ! isPlatformBrowser ( this . platformId ) || this . resizeAnimationFrame !== undefined ) {
361+ return ;
362+ }
363+
364+ const requestAnimationFrame = this . getWindow ( ) . requestAnimationFrame ;
365+ if ( typeof requestAnimationFrame !== 'function' ) {
366+ this . plotly . resize ( this . plotlyInstance ) ;
367+ return ;
368+ }
369+
370+ this . resizeAnimationFrame = requestAnimationFrame . call ( this . getWindow ( ) , ( ) => {
371+ this . resizeAnimationFrame = undefined ;
372+ if ( ! this . destroyed && this . plotlyInstance ) {
373+ this . plotly . resize ( this . plotlyInstance ) ;
374+ }
375+ } ) ;
322376 }
323377
324378 dataDifferTrackBy ( _ : number , item : any ) : unknown {
0 commit comments