@@ -99,16 +99,6 @@ function ReceptorContent() {
9999 < ChevronLeft className = "h-8 w-8" />
100100 < h1 className = "text-3xl font-bold" > { `${ receptor . geneName } - ${ receptor . name } ` } </ h1 >
101101 </ Link >
102- < div className = "mt-4" >
103- < button
104- type = "button"
105- className = "inline-flex items-center gap-2 px-3 py-1.5 rounded-md border text-sm hover:bg-accent"
106- onClick = { ( ) => downloadAllSvgs ( receptor ) }
107- data-action = "download-all-svgs"
108- >
109- < Download className = "h-4 w-4" /> Download All SVGs
110- </ button >
111- </ div >
112102 </ div >
113103
114104 { /* basic info card ----------------------------------------------- */ }
@@ -130,75 +120,6 @@ function ReceptorContent() {
130120 </ >
131121 ) ;
132122}
133- function downloadAllSvgs ( receptor : Receptor ) {
134- try {
135- // Conservation chart (has its own exporter)
136- const conservationButton = document . querySelector ( '[data-action="download-conservation"]' ) as HTMLButtonElement | null ;
137- conservationButton ?. click ( ) ;
138-
139- // Sequence logo: trigger its built-in button if present
140- const logoButton = document . querySelector ( '[data-action="download-sequence-logo"]' ) as HTMLButtonElement | null ;
141- logoButton ?. click ( ) ;
142-
143- // Snake plot: trigger its built-in button if present
144- const snakeButton = document . querySelector ( '[data-action="download-snakeplot"]' ) as HTMLButtonElement | null ;
145- snakeButton ?. click ( ) ;
146-
147- // Combined view: export outer container as SVG snapshot - rely on its own internal SVGs
148- // We will try to find the right-side alignment SVG and left tree SVG and combine side-by-side similar to conservation export.
149- const combinedContainer = document . querySelector ( '[data-plot="combined-tree-msa"]' ) as HTMLElement | null ;
150- if ( combinedContainer ) {
151- const svgs = combinedContainer . querySelectorAll ( 'svg' ) ;
152- if ( svgs . length > 0 ) {
153- // Compute total bounds by concatenating horizontally
154- let totalWidth = 0 ;
155- let maxHeight = 0 ;
156- const clones : SVGElement [ ] = [ ] ;
157- svgs . forEach ( ( svg ) => {
158- const w = parseInt ( svg . getAttribute ( 'width' ) || '0' ) ;
159- const h = parseInt ( svg . getAttribute ( 'height' ) || '0' ) ;
160- totalWidth += w ;
161- maxHeight = Math . max ( maxHeight , h ) ;
162- clones . push ( svg . cloneNode ( true ) as SVGElement ) ;
163- } ) ;
164- if ( totalWidth > 0 && maxHeight > 0 ) {
165- const combinedSvg = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'svg' ) ;
166- combinedSvg . setAttribute ( 'width' , `${ totalWidth } ` ) ;
167- combinedSvg . setAttribute ( 'height' , `${ maxHeight } ` ) ;
168- combinedSvg . setAttribute ( 'viewBox' , `0 0 ${ totalWidth } ${ maxHeight } ` ) ;
169- combinedSvg . setAttribute ( 'xmlns' , 'http://www.w3.org/2000/svg' ) ;
170-
171- let xOffset = 0 ;
172- clones . forEach ( ( clone ) => {
173- const w = parseInt ( clone . getAttribute ( 'width' ) || '0' ) ;
174- const wrapper = document . createElementNS ( 'http://www.w3.org/2000/svg' , 'g' ) ;
175- wrapper . setAttribute ( 'transform' , `translate(${ xOffset } ,0)` ) ;
176- wrapper . appendChild ( clone ) ;
177- combinedSvg . appendChild ( wrapper ) ;
178- xOffset += w ;
179- } ) ;
180-
181- const serializer = new XMLSerializer ( ) ;
182- const svgString = serializer . serializeToString ( combinedSvg ) ;
183- const svgWithDeclaration = `<?xml version="1.0" encoding="UTF-8"?>\n${ svgString } ` ;
184- const blob = new Blob ( [ svgWithDeclaration ] , { type : 'image/svg+xml' } ) ;
185- const url = URL . createObjectURL ( blob ) ;
186- const fileName = `${ receptor . geneName } _combined_tree_alignment.svg` ;
187- const link = document . createElement ( 'a' ) ;
188- link . href = url ;
189- link . download = fileName ;
190- document . body . appendChild ( link ) ;
191- link . click ( ) ;
192- document . body . removeChild ( link ) ;
193- URL . revokeObjectURL ( url ) ;
194- }
195- }
196- }
197- } catch ( err ) {
198- // best-effort: no-op on error
199- console . error ( 'Download all SVGs error:' , err ) ;
200- }
201- }
202123
203124/* helper for tidy info pairs */
204125const InfoItem = ( { label, value } : { label : string ; value : string | number } ) => (
0 commit comments