Update app.py
Browse files
app.py
CHANGED
|
@@ -146,6 +146,7 @@ ui.card(
|
|
| 146 |
{"style": "width: 870px;"},
|
| 147 |
ui.head_content(
|
| 148 |
ui.tags.script(src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"),
|
|
|
|
| 149 |
ui.tags.script("""
|
| 150 |
async function downloadSVG() {
|
| 151 |
const content = document.getElementById('capture-section');
|
|
@@ -207,17 +208,65 @@ ui.card(
|
|
| 207 |
document.body.removeChild(link);
|
| 208 |
URL.revokeObjectURL(url);
|
| 209 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 210 |
|
| 211 |
-
$(document).on('click', '#
|
| 212 |
downloadSVG();
|
| 213 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
| 214 |
""")
|
| 215 |
),
|
| 216 |
ui.output_text("status"),
|
| 217 |
ui.div(
|
| 218 |
{
|
| 219 |
"id": "capture-section",
|
| 220 |
-
"style": "background-color: white; padding: 0; margin-left: 20px; margin-right: 20px; margin-top: 20px; margin-bottom: 20px;"
|
| 221 |
},
|
| 222 |
# Plot section with relative positioning for brush
|
| 223 |
ui.div(
|
|
@@ -228,12 +277,14 @@ ui.card(
|
|
| 228 |
ui.div(
|
| 229 |
{"style": "margin-top: 20px;"},
|
| 230 |
ui.row(ui.tags.b("Pitches in Selection"), ui.output_table("in_brush")),
|
| 231 |
-
|
| 232 |
-
|
| 233 |
),
|
| 234 |
ui.div({"style": "height: 20px;"})
|
| 235 |
),
|
| 236 |
-
ui.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 237 |
)
|
| 238 |
# ),
|
| 239 |
# )
|
|
|
|
| 146 |
{"style": "width: 870px;"},
|
| 147 |
ui.head_content(
|
| 148 |
ui.tags.script(src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"),
|
| 149 |
+
ui.tags.script(src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"),
|
| 150 |
ui.tags.script("""
|
| 151 |
async function downloadSVG() {
|
| 152 |
const content = document.getElementById('capture-section');
|
|
|
|
| 208 |
document.body.removeChild(link);
|
| 209 |
URL.revokeObjectURL(url);
|
| 210 |
}
|
| 211 |
+
|
| 212 |
+
async function downloadPNG() {
|
| 213 |
+
const content = document.getElementById('capture-section');
|
| 214 |
+
|
| 215 |
+
try {
|
| 216 |
+
// Create a wrapper div with margins
|
| 217 |
+
const wrapper = document.createElement('div');
|
| 218 |
+
wrapper.style.padding = '20px';
|
| 219 |
+
wrapper.style.backgroundColor = 'white';
|
| 220 |
+
|
| 221 |
+
// Clone the content
|
| 222 |
+
const clonedContent = content.cloneNode(true);
|
| 223 |
+
wrapper.appendChild(clonedContent);
|
| 224 |
+
|
| 225 |
+
// Add wrapper to document temporarily
|
| 226 |
+
document.body.appendChild(wrapper);
|
| 227 |
+
|
| 228 |
+
const canvas = await html2canvas(wrapper, {
|
| 229 |
+
backgroundColor: 'white',
|
| 230 |
+
scale: 2,
|
| 231 |
+
useCORS: true,
|
| 232 |
+
logging: false,
|
| 233 |
+
width: content.offsetWidth + 40, // Add padding width
|
| 234 |
+
height: content.offsetHeight + 40 // Add padding height
|
| 235 |
+
});
|
| 236 |
+
|
| 237 |
+
// Remove temporary wrapper
|
| 238 |
+
document.body.removeChild(wrapper);
|
| 239 |
+
|
| 240 |
+
// Convert canvas to blob
|
| 241 |
+
canvas.toBlob(function(blob) {
|
| 242 |
+
const url = URL.createObjectURL(blob);
|
| 243 |
+
const link = document.createElement('a');
|
| 244 |
+
link.href = url;
|
| 245 |
+
link.download = 'plot_and_table.png';
|
| 246 |
+
document.body.appendChild(link);
|
| 247 |
+
link.click();
|
| 248 |
+
document.body.removeChild(link);
|
| 249 |
+
URL.revokeObjectURL(url);
|
| 250 |
+
}, 'image/png');
|
| 251 |
+
} catch (error) {
|
| 252 |
+
console.error('Error generating PNG:', error);
|
| 253 |
+
}
|
| 254 |
+
}
|
| 255 |
|
| 256 |
+
$(document).on('click', '#capture_svg_btn', function() {
|
| 257 |
downloadSVG();
|
| 258 |
});
|
| 259 |
+
|
| 260 |
+
$(document).on('click', '#capture_png_btn', function() {
|
| 261 |
+
downloadPNG();
|
| 262 |
+
});
|
| 263 |
""")
|
| 264 |
),
|
| 265 |
ui.output_text("status"),
|
| 266 |
ui.div(
|
| 267 |
{
|
| 268 |
"id": "capture-section",
|
| 269 |
+
"style": "background-color: white; padding: 0; margin-left: 20px; margin-right: 20px; margin-top: 20px; margin-bottom: 20px;"
|
| 270 |
},
|
| 271 |
# Plot section with relative positioning for brush
|
| 272 |
ui.div(
|
|
|
|
| 277 |
ui.div(
|
| 278 |
{"style": "margin-top: 20px;"},
|
| 279 |
ui.row(ui.tags.b("Pitches in Selection"), ui.output_table("in_brush")),
|
|
|
|
|
|
|
| 280 |
),
|
| 281 |
ui.div({"style": "height: 20px;"})
|
| 282 |
),
|
| 283 |
+
ui.div(
|
| 284 |
+
{"style": "display: flex; gap: 10px;"},
|
| 285 |
+
ui.input_action_button("capture_svg_btn", "Save as SVG", class_="btn-primary"),
|
| 286 |
+
ui.input_action_button("capture_png_btn", "Save as PNG", class_="btn-success"),
|
| 287 |
+
),
|
| 288 |
)
|
| 289 |
# ),
|
| 290 |
# )
|