@@ -3557,17 +3557,6 @@ fn render(args: &Args, graph: &Graph) -> Vec<u8> {
35573557 }
35583558 }
35593559
3560- // Draw horizontal axis line (PNG)
3561- for x in path_names_width..total_width {
3562- let idx = ( ( axis_y * total_width + x) * 4 ) as usize ;
3563- if idx + 3 < buffer. len ( ) {
3564- buffer[ idx] = 0 ;
3565- buffer[ idx + 1 ] = 0 ;
3566- buffer[ idx + 2 ] = 0 ;
3567- buffer[ idx + 3 ] = 255 ;
3568- }
3569- }
3570-
35713560 // Calculate tick positions and labels
35723561 let num_ticks = args. x_ticks . max ( 2 ) as usize ;
35733562 let is_pangenomic = coord_system. to_lowercase ( ) == "pangenomic" ;
@@ -3579,40 +3568,73 @@ fn render(args: &Args, graph: &Graph) -> Vec<u8> {
35793568
35803569 // For pangenomic coordinates, use total graph length
35813570 // For path-based coordinates, find the path and use its length
3582- let ( coord_start, coord_end) = if is_pangenomic {
3583- ( 0u64 , len_to_visualize)
3571+ // Also calculate pixel range where the path actually appears
3572+ let ( coord_start, coord_end, pixel_start, pixel_end) = if is_pangenomic {
3573+ ( 0u64 , len_to_visualize, 0u32 , viz_width)
35843574 } else if let Some ( path) = graph. paths . iter ( ) . find ( |p| p. name == * coord_system) {
3585- let path_len: u64 = path
3586- . steps
3587- . iter ( )
3588- . map ( |step| {
3589- let seg_id = step. segment_id as usize ;
3590- if seg_id < graph. segments . len ( ) {
3591- graph. segments [ seg_id] . sequence_len
3592- } else {
3593- 0
3575+ // Calculate path length and pangenomic positions from its steps
3576+ let mut path_len: u64 = 0 ;
3577+ let mut pangenomic_start: Option < u64 > = None ;
3578+ let mut pangenomic_end: u64 = 0 ;
3579+
3580+ for step in & path. steps {
3581+ let seg_id = step. segment_id as usize ;
3582+ if seg_id < graph. segments . len ( ) {
3583+ let seg_len = graph. segments [ seg_id] . sequence_len ;
3584+ let seg_offset = graph. segment_offsets [ seg_id] ;
3585+
3586+ // Track first segment's pangenomic position
3587+ if pangenomic_start. is_none ( ) {
3588+ pangenomic_start = Some ( seg_offset) ;
35943589 }
3595- } )
3596- . sum ( ) ;
3590+ // Track last segment's end position
3591+ pangenomic_end = seg_offset + seg_len;
3592+ path_len += seg_len;
3593+ }
3594+ }
3595+
3596+ let pangenomic_start = pangenomic_start. unwrap_or ( 0 ) ;
3597+
3598+ // Convert pangenomic positions to pixel positions
3599+ let pix_start = ( ( pangenomic_start as f64 / bin_width) as u32 ) . min ( viz_width) ;
3600+ let pix_end = ( ( pangenomic_end as f64 / bin_width) as u32 ) . min ( viz_width) ;
3601+
35973602 // Add subpath start offset if --x-axis-absolute is enabled
35983603 let offset = if args. x_axis_absolute {
35993604 parse_subpath_start ( coord_system)
36003605 } else {
36013606 0
36023607 } ;
3603- ( offset, offset + path_len)
3608+ ( offset, offset + path_len, pix_start , pix_end )
36043609 } else {
36053610 debug ! (
36063611 "Path '{}' not found, using pangenomic coordinates" ,
36073612 coord_system
36083613 ) ;
3609- ( 0u64 , len_to_visualize)
3614+ ( 0u64 , len_to_visualize, 0u32 , viz_width )
36103615 } ;
36113616
3612- // Draw ticks and labels
3617+ // Calculate the pixel width of the path's range
3618+ let path_pixel_width = pixel_end. saturating_sub ( pixel_start) ;
3619+
3620+ // Draw horizontal axis line only where the path exists (PNG)
3621+ let axis_line_start = path_names_width + pixel_start;
3622+ let axis_line_end = path_names_width + pixel_end;
3623+ for x in axis_line_start..axis_line_end {
3624+ let idx = ( ( axis_y * total_width + x) * 4 ) as usize ;
3625+ if idx + 3 < buffer. len ( ) {
3626+ buffer[ idx] = 0 ;
3627+ buffer[ idx + 1 ] = 0 ;
3628+ buffer[ idx + 2 ] = 0 ;
3629+ buffer[ idx + 3 ] = 255 ;
3630+ }
3631+ }
3632+
3633+ // Draw ticks and labels only where the path exists
36133634 for i in 0 ..num_ticks {
36143635 let t = i as f64 / ( num_ticks - 1 ) as f64 ;
3615- let x_pos = path_names_width + ( t * ( viz_width as f64 - 1.0 ) ) as u32 ;
3636+ // Map tick position to the path's pixel range
3637+ let x_pos = path_names_width + pixel_start + ( t * ( path_pixel_width as f64 - 1.0 ) . max ( 0.0 ) ) as u32 ;
36163638 let coord_value = coord_start as f64 + t * ( coord_end - coord_start) as f64 ;
36173639
36183640 // Draw tick mark
@@ -4956,9 +4978,8 @@ fn render_svg(args: &Args, graph: &Graph) -> String {
49564978 // Y position for the axis line (at the bottom of paths)
49574979 let axis_y = path_space_with_gap + axis_padding;
49584980
4959- // X start and end of the axis line
4981+ // X start of the axis line (end will be calculated based on path's pangenomic extent)
49604982 let axis_x_start = dendrogram_width + cluster_bar_width + text_width;
4961- let axis_x_end = total_width;
49624983
49634984 // Draw axis label on the left
49644985 // Strip the :start-end range from the label when showing absolute coordinates
@@ -4988,13 +5009,6 @@ fn render_svg(args: &Args, graph: &Graph) -> String {
49885009 ) ) ;
49895010 svg. push ( '\n' ) ;
49905011
4991- // Draw horizontal axis line
4992- svg. push_str ( & format ! (
4993- r#"<line x1="{}" y1="{}" x2="{}" y2="{}" stroke="black" stroke-width="1"/>"# ,
4994- axis_x_start, axis_y, axis_x_end, axis_y
4995- ) ) ;
4996- svg. push ( '\n' ) ;
4997-
49985012 // Calculate tick positions and labels
49995013 let num_ticks = args. x_ticks . max ( 2 ) as usize ;
50005014 let is_pangenomic = coord_system. to_lowercase ( ) == "pangenomic" ;
@@ -5006,45 +5020,73 @@ fn render_svg(args: &Args, graph: &Graph) -> String {
50065020
50075021 // For pangenomic coordinates, use total graph length
50085022 // For path-based coordinates, find the path and use its length
5009- let ( coord_start, coord_end) = if is_pangenomic {
5010- ( 0u64 , len_to_visualize)
5023+ // Also calculate pixel range where the path actually appears
5024+ let ( coord_start, coord_end, pixel_start, pixel_end) = if is_pangenomic {
5025+ ( 0u64 , len_to_visualize, 0.0f64 , viz_width as f64 )
50115026 } else {
50125027 // Find the path with the specified name
50135028 if let Some ( path) = graph. paths . iter ( ) . find ( |p| p. name == * coord_system) {
5014- // Calculate path length from its steps
5015- let path_len: u64 = path
5016- . steps
5017- . iter ( )
5018- . map ( |step| {
5019- let seg_id = step. segment_id as usize ;
5020- if seg_id < graph. segments . len ( ) {
5021- graph. segments [ seg_id] . sequence_len
5022- } else {
5023- 0
5029+ // Calculate path length and pangenomic positions from its steps
5030+ let mut path_len: u64 = 0 ;
5031+ let mut pangenomic_start: Option < u64 > = None ;
5032+ let mut pangenomic_end: u64 = 0 ;
5033+
5034+ for step in & path. steps {
5035+ let seg_id = step. segment_id as usize ;
5036+ if seg_id < graph. segments . len ( ) {
5037+ let seg_len = graph. segments [ seg_id] . sequence_len ;
5038+ let seg_offset = graph. segment_offsets [ seg_id] ;
5039+
5040+ // Track first segment's pangenomic position
5041+ if pangenomic_start. is_none ( ) {
5042+ pangenomic_start = Some ( seg_offset) ;
50245043 }
5025- } )
5026- . sum ( ) ;
5044+ // Track last segment's end position
5045+ pangenomic_end = seg_offset + seg_len;
5046+ path_len += seg_len;
5047+ }
5048+ }
5049+
5050+ let pangenomic_start = pangenomic_start. unwrap_or ( 0 ) ;
5051+
5052+ // Convert pangenomic positions to pixel positions
5053+ let pix_start = ( pangenomic_start as f64 / bin_width) . min ( viz_width as f64 ) ;
5054+ let pix_end = ( pangenomic_end as f64 / bin_width) . min ( viz_width as f64 ) ;
5055+
50275056 // Add subpath start offset if --x-axis-absolute is enabled
50285057 let offset = if args. x_axis_absolute {
50295058 parse_subpath_start ( coord_system)
50305059 } else {
50315060 0
50325061 } ;
5033- ( offset, offset + path_len)
5062+ ( offset, offset + path_len, pix_start , pix_end )
50345063 } else {
50355064 // Path not found, fall back to pangenomic
50365065 debug ! (
50375066 "Path '{}' not found, using pangenomic coordinates" ,
50385067 coord_system
50395068 ) ;
5040- ( 0u64 , len_to_visualize)
5069+ ( 0u64 , len_to_visualize, 0.0f64 , viz_width as f64 )
50415070 }
50425071 } ;
50435072
5044- // Draw ticks
5073+ // Calculate the pixel width of the path's range
5074+ let path_pixel_width = pixel_end - pixel_start;
5075+
5076+ // Draw horizontal axis line only where the path exists
5077+ let axis_line_x_start = axis_x_start as f64 + pixel_start;
5078+ let axis_line_x_end = axis_x_start as f64 + pixel_end;
5079+ svg. push_str ( & format ! (
5080+ r#"<line x1="{:.1}" y1="{}" x2="{:.1}" y2="{}" stroke="black" stroke-width="1"/>"# ,
5081+ axis_line_x_start, axis_y, axis_line_x_end, axis_y
5082+ ) ) ;
5083+ svg. push ( '\n' ) ;
5084+
5085+ // Draw ticks only where the path exists
50455086 for i in 0 ..num_ticks {
50465087 let t = i as f64 / ( num_ticks - 1 ) as f64 ;
5047- let x_pos = axis_x_start as f64 + t * ( viz_width as f64 - 1.0 ) ;
5088+ // Map tick position to the path's pixel range
5089+ let x_pos = axis_x_start as f64 + pixel_start + t * ( path_pixel_width - 1.0 ) . max ( 0.0 ) ;
50485090 let coord_value = coord_start as f64 + t * ( coord_end - coord_start) as f64 ;
50495091
50505092 // Draw tick mark
0 commit comments