@@ -60,108 +60,130 @@ pub(crate) fn pdf_export_js_script(timeout_ms: u32) -> String {
6060
6161 const graph_div = document.getElementById('plotly-html-element');
6262
63- // Check if html2pdf is available
64- if (typeof html2pdf === 'undefined') {{
65- console.error('html2pdf library not available');
66- callback('ERROR:html2pdf library not loaded');
67- return;
68- }}
63+ // Check if html2pdf is available and wait for it to load
64+ const waitForHtml2Pdf = (maxWaitMs = 5000) => {{
65+ return new Promise((resolve, reject) => {{
66+ const startTime = Date.now();
67+
68+ const checkLibrary = () => {{
69+ if (typeof html2pdf !== 'undefined' && html2pdf) {{
70+ console.log('html2pdf library loaded successfully');
71+ resolve();
72+ }} else if (Date.now() - startTime > maxWaitMs) {{
73+ console.error('html2pdf library failed to load within timeout');
74+ reject(new Error('html2pdf library not loaded within timeout'));
75+ }} else {{
76+ setTimeout(checkLibrary, 100);
77+ }}
78+ }};
79+
80+ checkLibrary();
81+ }});
82+ }};
6983
70- let tempDiv = null;
84+ // Wait for html2pdf to be available before proceeding
85+ waitForHtml2Pdf().then(() => {{
86+ console.log('html2pdf library is ready, starting PDF export...');
87+
88+ let tempDiv = null;
7189
72- const cleanup = () => {{
73- if (tempDiv) {{
74- document.body.removeChild(tempDiv);
75- }}
76- }};
90+ const cleanup = () => {{
91+ if (tempDiv) {{
92+ document.body.removeChild(tempDiv);
93+ }}
94+ }};
7795
78- Plotly.newPlot(graph_div, plot).then(function() {{
79- return Plotly.toImage(graph_div, {{
80- format: format,
81- width: width,
82- height: height,
83- }});
84- }}).then(function(dataUrl) {{
85- console.log('Plotly image generated successfully');
86- console.log('SVG data URL length:', dataUrl.length);
87- console.log('SVG data URL preview:', dataUrl.substring(0, 200) + '...');
88- console.log('PDF dimensions (px):', width, 'x', height);
96+ Plotly.newPlot(graph_div, plot).then(function() {{
97+ return Plotly.toImage(graph_div, {{
98+ format: format,
99+ width: width,
100+ height: height,
101+ }});
102+ }}).then(function(dataUrl) {{
103+ console.log('Plotly image generated successfully');
104+ console.log('SVG data URL length:', dataUrl.length);
105+ console.log('SVG data URL preview:', dataUrl.substring(0, 200) + '...');
106+ console.log('PDF dimensions (px):', width, 'x', height);
89107
90- // Create a temporary div for the image
91- tempDiv = document.createElement('div');
92- tempDiv.style.width = width + 'px';
93- tempDiv.style.height = height + 'px';
94- tempDiv.style.background = 'white';
95- tempDiv.style.position = 'fixed';
96- tempDiv.style.top = '0px';
97- tempDiv.style.left = '0px';
98- tempDiv.style.margin = '0px';
99- tempDiv.style.padding = '0px';
100- tempDiv.style.overflow = 'hidden';
101- tempDiv.style.boxSizing = 'border-box';
102- tempDiv.style.zIndex = '9999';
103- tempDiv.style.display = 'block';
104- document.body.appendChild(tempDiv);
108+ // Create a temporary div for the image
109+ tempDiv = document.createElement('div');
110+ tempDiv.style.width = width + 'px';
111+ tempDiv.style.height = height + 'px';
112+ tempDiv.style.background = 'white';
113+ tempDiv.style.position = 'fixed';
114+ tempDiv.style.top = '0px';
115+ tempDiv.style.left = '0px';
116+ tempDiv.style.margin = '0px';
117+ tempDiv.style.padding = '0px';
118+ tempDiv.style.overflow = 'hidden';
119+ tempDiv.style.boxSizing = 'border-box';
120+ tempDiv.style.zIndex = '9999';
121+ tempDiv.style.display = 'block';
122+ document.body.appendChild(tempDiv);
105123
106- // Use simple img approach with SVG data URL
107- console.log('Using SVG data URL directly with img element');
108- const img = document.createElement('img');
109- img.src = dataUrl;
110- img.style.width = '100%';
111- img.style.height = '100%';
112- img.style.display = 'block';
113- img.style.objectFit = 'contain';
114- img.style.maxWidth = '100%';
115- img.style.maxHeight = '100%';
116- img.style.verticalAlign = 'top';
117- img.style.boxSizing = 'border-box';
118- tempDiv.appendChild(img);
124+ // Use simple img approach with SVG data URL
125+ console.log('Using SVG data URL directly with img element');
126+ const img = document.createElement('img');
127+ img.src = dataUrl;
128+ img.style.width = '100%';
129+ img.style.height = '100%';
130+ img.style.display = 'block';
131+ img.style.objectFit = 'contain';
132+ img.style.maxWidth = '100%';
133+ img.style.maxHeight = '100%';
134+ img.style.verticalAlign = 'top';
135+ img.style.boxSizing = 'border-box';
136+ tempDiv.appendChild(img);
119137
120- // Wait for the image to load
121- return new Promise(function(resolve) {{
122- img.onload = function() {{
123- console.log('SVG image loaded successfully');
124- // Additional delay to ensure image is fully rendered
125- // Brief delay to ensure image is fully rendered
126- setTimeout(resolve, {timeout_ms});
127- }};
128- img.onerror = function() {{
129- cleanup();
130- callback('ERROR:Failed to load SVG image');
131- }};
138+ // Wait for the image to load
139+ return new Promise(function(resolve) {{
140+ img.onload = function() {{
141+ console.log('SVG image loaded successfully');
142+ // Additional delay to ensure image is fully rendered
143+ // Brief delay to ensure image is fully rendered
144+ setTimeout(resolve, {timeout_ms});
145+ }};
146+ img.onerror = function() {{
147+ cleanup();
148+ callback('ERROR:Failed to load SVG image');
149+ }};
150+ }});
151+ }}).then(function() {{
152+ console.log('Starting PDF generation...');
153+ return html2pdf().from(tempDiv).set({{
154+ margin: 0,
155+ filename: 'plotly-plot.pdf',
156+ image: {{ type: 'jpeg', quality: 1}},
157+ html2canvas: {{
158+ scale: scale,
159+ backgroundColor: '#fff',
160+ useCORS: true,
161+ allowTaint: true,
162+ logging: true,
163+ width: width,
164+ height: height,
165+ imageTimeout: 15000,
166+ removeContainer: true,
167+ foreignObjectRendering: {foreign_object_rendering},
168+ scrollY: 0,
169+ scrollX: 0
170+ }},
171+ jsPDF: {{
172+ unit: 'px',
173+ format: [width, height],
174+ orientation: width > height ? 'landscape' : 'portrait',
175+ compress: true
176+ }}
177+ }}).toPdf().output('datauristring');
178+ }}).then(function(dataUri) {{
179+ cleanup();
180+ callback(dataUri);
181+ }}).catch(function(err) {{
182+ cleanup();
183+ callback('ERROR:' + err.toString());
132184 }});
133- }}).then(function() {{
134- console.log('Starting PDF generation...');
135- return html2pdf().from(tempDiv).set({{
136- margin: 0,
137- filename: 'plotly-plot.pdf',
138- image: {{ type: 'jpeg', quality: 1}},
139- html2canvas: {{
140- scale: scale,
141- backgroundColor: '#fff',
142- useCORS: true,
143- allowTaint: true,
144- logging: true,
145- width: width,
146- height: height,
147- imageTimeout: 15000,
148- removeContainer: true,
149- foreignObjectRendering: {foreign_object_rendering},
150- scrollY: 0,
151- scrollX: 0
152- }},
153- jsPDF: {{
154- unit: 'px',
155- format: [width, height],
156- orientation: width > height ? 'landscape' : 'portrait',
157- compress: true
158- }}
159- }}).toPdf().output('datauristring');
160- }}).then(function(dataUri) {{
161- cleanup();
162- callback(dataUri);
163- }}).catch(function(err) {{
164- cleanup();
185+ }}).catch((err) => {{
186+ console.error('Failed to load html2pdf library:', err);
165187 callback('ERROR:' + err.toString());
166188 }});
167189"##
0 commit comments