| 118 | } |
| 119 | |
| 120 | private createGraph(model: IRenderMime.IMimeModel): Promise<void> { |
| 121 | const { data, layout, frames, config } = model.data[this._mimeType] as |
| 122 | | any |
| 123 | | IPlotlySpec; |
| 124 | |
| 125 | if (!layout.height) { |
| 126 | layout.height = 360; |
| 127 | } |
| 128 | |
| 129 | // Load plotly asynchronously |
| 130 | const loadPlotly = async (): Promise<void> => { |
| 131 | if (RenderedPlotly.Plotly === null) { |
| 132 | RenderedPlotly.Plotly = await import("plotly.js"); |
| 133 | RenderedPlotly._resolveLoadingPlotly(); |
| 134 | } |
| 135 | return RenderedPlotly.loadingPlotly; |
| 136 | }; |
| 137 | |
| 138 | return loadPlotly() |
| 139 | .then(() => RenderedPlotly.Plotly!.react(this.node, data, layout, config)) |
| 140 | .then((plot) => { |
| 141 | this.showGraph(); |
| 142 | this.hideImage(); |
| 143 | this.update(); |
| 144 | if (frames) { |
| 145 | RenderedPlotly.Plotly!.addFrames(this.node, frames); |
| 146 | } |
| 147 | if (this.node.offsetWidth > 0 && this.node.offsetHeight > 0) { |
| 148 | RenderedPlotly.Plotly!.toImage(plot, { |
| 149 | format: "png", |
| 150 | width: this.node.offsetWidth, |
| 151 | height: this.node.offsetHeight, |
| 152 | }).then((url: string) => { |
| 153 | const imageData = url.split(",")[1]; |
| 154 | if (model.data["image/png"] !== imageData) { |
| 155 | model.setData({ |
| 156 | data: { |
| 157 | ...model.data, |
| 158 | "image/png": imageData, |
| 159 | }, |
| 160 | }); |
| 161 | } |
| 162 | }); |
| 163 | } |
| 164 | |
| 165 | // Handle webgl context lost events |
| 166 | (<PlotlyType.PlotlyHTMLElement>this.node).on( |
| 167 | "plotly_webglcontextlost", |
| 168 | () => { |
| 169 | const png_data = <string>model.data["image/png"]; |
| 170 | if (png_data !== undefined && png_data !== null) { |
| 171 | // We have PNG data, use it |
| 172 | this.updateImage(png_data); |
| 173 | return Promise.resolve(); |
| 174 | } |
| 175 | } |
| 176 | ); |
| 177 | }); |