module fplot_plot_data_function use iso_fortran_env use fplot_plot_data use fplot_colors use fplot_constants use strings implicit none private public :: plot_data_function type, extends(line_plot_data) :: plot_data_function !! Defines a function to plot. character(len = :), private, allocatable :: m_function !! The function to plot (e.g. sin(x)) character(len = :), private, allocatable :: m_functionName !! The name of the function (e.g. f(x), g(x), etc.). real(real64), private :: m_minX = -1.0d0 !! The minimum X value of the plot range. real(real64), private :: m_maxX = 1.0d0 integer(int32), private :: m_sampleCount = 100 !! The number of times to sample the function contains procedure, public :: get_function => pdf_get_function procedure, public :: get_function_name => pdf_get_function_name procedure, public :: define_data => pdf_define_data procedure, public :: get_command_string => pdf_get_cmd procedure, public :: get_data_string => pdf_get_data_cmd procedure, public :: clear_data => pdf_clear_data procedure, public :: get_minimum_x => pdf_get_min_x procedure, public :: set_minimum_x => pdf_set_min_x procedure, public :: get_maximum_x => pdf_get_max_x procedure, public :: set_maximum_x => pdf_set_max_x ! procedure, public :: get_line_width => pdf_get_line_width ! procedure, public :: set_line_width => pdf_set_line_width ! procedure, public :: get_line_style => pdf_get_line_style ! procedure, public :: set_line_style => pdf_set_line_style procedure, public :: get_sample_count => pfd_get_sample_count procedure, public :: set_sample_count => pfd_set_sample_count end type contains ! ------------------------------------------------------------------------------ pure function pdf_get_function(this) result(rst) !! Gets the function to plot. class(plot_data_function), intent(in) :: this !! The plot_data_function object. character(len = :), allocatable :: rst !! The function. if (allocated(this%m_function)) then rst = this%m_function else rst = "" end if end function ! ------------------------------------------------------------------------------ pure function pdf_get_function_name(this) result(rst) !! Gets the name of the function to plot (e.g. f(x), g(x), etc.). class(plot_data_function), intent(in) :: this !! The plot_data_function object. character(len = :), allocatable :: rst !! The function name. if (allocated(this%m_functionName)) then rst = this%m_functionName else rst = "" end if end function ! ------------------------------------------------------------------------------ subroutine pdf_define_data(this, f, fname, minX, maxX, name) !! Defines the function to plot. class(plot_data_function), intent(inout) :: this !! The plot_data_function object. character(len = *), intent(in) :: f !! The function to plot (e.g. sin(x)). character(len = *), intent(in) :: fname !! The name of the function to plot (e.g. f(x)). real(real64), intent(in), optional :: minX !! The minimum value to plot. If not supplied, this will default !! to a value of -1. real(real64), intent(in), optional :: maxX !! The maximum x value to plot. If not supplied, this will default !! to a value of 1. character(len = *), intent(in), optional :: name !! An optional input that specifies the name that will be displayed !! in the legend. If nothing is supplied, the input string for !! parameter f will be utilized. this%m_function = f this%m_functionName = fname if (present(minX)) then this%m_minX = minX else this%m_minX = -1.0d0 end if if (present(maxX)) then this%m_maxX = maxX else this%m_maxX = 1.0d0 end if if (present(name)) then call this%set_name(name) else call this%set_name(f) end if end subroutine ! ------------------------------------------------------------------------------ function pdf_get_cmd(this) result(rst) !! Gets the GNUPLOT command string for this object. class(plot_data_function), intent(in) :: this !! The plot_data_function object. character(len = :), allocatable :: rst !! The command string. ! Local Variables integer(int32) :: n type(string_builder) :: str type(color) :: clr ! Build the command string call str%initialize() call str%append("[") call str%append(to_string(this%get_minimum_x())) call str%append(":") call str%append(to_string(this%get_maximum_x())) call str%append("] ") call str%append(this%get_function_name()) ! Use the base object to define the line properties call str%append(lpd_get_cmd(this)) ! Return the complete command string rst = char(str%to_string()) end function ! ------------------------------------------------------------------------------ function pdf_get_data_cmd(this) result(rst) !! Gets the GNUPLOT command string defining the data for this object. class(plot_data_function), intent(in) :: this !! The plot_data_function object. character(len = :), allocatable :: rst !! The command string. ! Local Variables type(string_builder) :: str ! Build the command string call str%initialize() call str%append(new_line('a')) call str%append(this%get_function_name()) call str%append(" = ") call str%append(this%get_function()) ! Samples call str%append(new_line('a')) call str%append("set samples ") call str%append(to_string(this%get_sample_count())) ! End rst = char(str%to_string()) end function ! ------------------------------------------------------------------------------ subroutine pdf_clear_data(this) !! Clears the function from this data set. class(plot_data_function), intent(inout) :: this !! The plot_data_function object. this%m_function = "" this%m_functionName = "" end subroutine ! ------------------------------------------------------------------------------ pure function pdf_get_min_x(this) result(rst) !! Gets the minimum X plot range value. class(plot_data_function), intent(in) :: this !! The plot_data_function object. real(real64) :: rst !! The value. rst = this%m_minX end function ! -------------------- subroutine pdf_set_min_x(this, x) !! Sets the minimum X plot range value. class(plot_data_function), intent(inout) :: this !! The plot_data_function object. real(real64), intent(in) :: x !! The value. this%m_minX = x end subroutine ! ------------------------------------------------------------------------------ pure function pdf_get_max_x(this) result(rst) !! Gets the maximum X plot range value. class(plot_data_function), intent(in) :: this !! The plot_data_function object. real(real64) :: rst !! The value. rst = this%m_maxX end function ! -------------------- subroutine pdf_set_max_x(this, x) !! Sets the maximum X plot range value. class(plot_data_function), intent(inout) :: this !! The plot_data_function object. real(real64), intent(in) :: x !! The value. this%m_maxX = x end subroutine ! ------------------------------------------------------------------------------ pure function pfd_get_sample_count(this) result(rst) !! Gets the number of times to sample the function. class(plot_data_function), intent(in) :: this !! The plot_data_function object. integer(int32) :: rst !! The sample count. rst = this%m_sampleCount end function ! -------------------- subroutine pfd_set_sample_count(this, x) !! Sets the number of times to sample the function. This variable is !! global for all function plots as GNUPLOT does not allow inline !! sample modification currently. Hopefully this will change somewhere !! down the road. class(plot_data_function), intent(inout) :: this !! The plot_data_function object. integer(int32), intent(in) :: x !! The sample count. Must be greater than 1. if (x <= 1) then this%m_sampleCount = 2 else this%m_sampleCount = x end if end subroutine ! ------------------------------------------------------------------------------ ! -------------------- ! ------------------------------------------------------------------------------ ! -------------------- ! ------------------------------------------------------------------------------ end module