module fortplot_ascii_secondary_axes !! ASCII backend secondary axis rendering !! !! Handles twin-axes tick labels for the ASCII backend. !! Separated from the rendering pipeline to keep module size compliant. use fortplot_axes, only: compute_scale_ticks, format_tick_label, MAX_TICKS use fortplot_tick_calculation, only: determine_decimals_from_ticks, & format_tick_value_consistent use fortplot_ascii, only: ascii_context use, intrinsic :: iso_fortran_env, only: wp => real64 implicit none private public :: ascii_draw_secondary_y_axis, ascii_draw_secondary_x_axis_top contains subroutine ascii_draw_secondary_x_axis_top(backend, xscale, symlog_threshold, & x_min, x_max, xlabel, date_format) !! Draw top x-axis tick labels for ASCII backend type(ascii_context), intent(inout) :: backend character(len=*), intent(in) :: xscale real(wp), intent(in) :: symlog_threshold real(wp), intent(in) :: x_min, x_max character(len=:), allocatable, intent(in), optional :: xlabel character(len=*), intent(in), optional :: date_format real(wp) :: x_tick_positions(MAX_TICKS) character(len=50) :: tick_label integer :: num_x_ticks, decimals, i integer :: text_x, text_y, label_len real(wp) :: frac call compute_scale_ticks(xscale, x_min, x_max, symlog_threshold, & x_tick_positions, num_x_ticks) if (num_x_ticks <= 0) return decimals = 0 if (trim(xscale) == 'linear' .and. num_x_ticks >= 2) then decimals = determine_decimals_from_ticks(x_tick_positions, num_x_ticks) end if text_y = 1 do i = 1, num_x_ticks if (trim(xscale) == 'linear') then tick_label = format_tick_value_consistent(x_tick_positions(i), decimals) else tick_label = format_tick_label(x_tick_positions(i), xscale, & date_format=date_format, data_min=x_min, data_max=x_max) end if frac = (x_tick_positions(i) - x_min) / (x_max - x_min) text_x = nint(frac * real(backend%plot_width - 2, wp)) + 1 text_x = max(1, min(text_x, backend%plot_width - 1)) label_len = len_trim(tick_label) text_x = max(1, min(text_x, backend%plot_width - label_len)) call backend%text(real(text_x, wp), real(text_y, wp), trim(tick_label)) end do if (present(xlabel) .and. allocated(xlabel) .and. len_trim(xlabel) > 0) then call backend%text(real(backend%plot_width / 2, wp), real(text_y, wp), & trim(xlabel)) end if end subroutine ascii_draw_secondary_x_axis_top subroutine ascii_draw_secondary_y_axis(backend, yscale, symlog_threshold, & y_min, y_max, ylabel, date_format) !! Draw right y-axis tick labels for ASCII backend type(ascii_context), intent(inout) :: backend character(len=*), intent(in) :: yscale real(wp), intent(in) :: symlog_threshold real(wp), intent(in) :: y_min, y_max character(len=:), allocatable, intent(in), optional :: ylabel character(len=*), intent(in), optional :: date_format real(wp) :: y_tick_positions(MAX_TICKS) character(len=50) :: tick_label integer :: num_y_ticks, decimals, i integer :: text_x, text_y, label_len real(wp) :: frac call compute_scale_ticks(yscale, y_min, y_max, symlog_threshold, & y_tick_positions, num_y_ticks) if (num_y_ticks <= 0) return decimals = 0 if (trim(yscale) == 'linear' .and. num_y_ticks >= 2) then decimals = determine_decimals_from_ticks(y_tick_positions, num_y_ticks) end if do i = 1, num_y_ticks if (trim(yscale) == 'linear') then tick_label = format_tick_value_consistent(y_tick_positions(i), decimals) else tick_label = format_tick_label(y_tick_positions(i), yscale, & date_format=date_format, data_min=y_min, data_max=y_max) end if frac = (y_tick_positions(i) - y_min) / (y_max - y_min) text_y = nint((1.0_wp - frac) * real(backend%plot_height - 2, wp)) + 1 text_y = max(1, min(text_y, backend%plot_height - 1)) label_len = len_trim(tick_label) text_x = backend%plot_width - label_len - 1 text_x = max(1, text_x) call backend%text(real(text_x, wp), real(text_y, wp), trim(tick_label)) end do end subroutine ascii_draw_secondary_y_axis end module fortplot_ascii_secondary_axes