The following is based on my answer here, which itself was based on code from marmot. The idea is to determine the desired scale using an automated, iterative process.
The code given below defines a style named autoscale autoid (in /tikz). When a tikzpicture uses autoscale autoid={width}{height}, its bounding box is measured when finished, and a scale factor is computed from the size of the bounding box and the target dimensions. This scale factor is written to the .aux file, associated with an automatically generated identifier. The next time you compile the picture, thanks to the saved scale factor, the /tikz/scale key is automatically applied to the tikzpicture in order to make it as large as possible without exceeding any of the prescribed width and height, while keeping its aspect ratio.
In your case, since your only constraint is on the width, you can use \maxdimen for the height argument of the autoscale autoid style; this effectively removes the constraint on the height.
When the picture is recompiled using the computed scale, it will in general be close to the “ideal” size, but won't exactly have this size after the first run. This is because of things such as labels that are not affected by the /tikz/scale key. However, the process normally converges rather quickly and the result is already excellent after only two or three compilation runs. In extreme cases, you might want to remove the .aux file in order to start over with a scale of 1 for each picture using the autoscale autoid style.
The following example uses autoscale autoid={15cm}{\maxdimen} in the options of your tikzpicture environment and draws a 15 cm long orange rule above the picture in order to allow one to easily evaluate the result.
\documentclass{article}
\usepackage[hmargin=2cm]{geometry} % for your 15 centimeters wide figure
\usepackage{sansmath} % only needed for your particular figure
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{calc}
\makeatletter
\ExplSyntaxOn
\msg_new:nnn { nilcouv } { duplicate-figure-id }
{ duplicate~figure~identifier:~'#1'. }
% Sequence recording all figure identifiers (for the 'scale to max size' TikZ
% style) found so far
\seq_new:N \g__nilcouv_scale_to_max_style_figure_ids_seq
% Counter used when generating automatic figure identifiers for 'autoscale'
\int_new:N \g_nilcouv_last_autogenerated_figure_nb_int
\cs_new_protected:Npn \__nilcouv_check_unique_id:n #1
{
\seq_if_in:NnTF \g__nilcouv_scale_to_max_style_figure_ids_seq {#1}
{ \msg_error:nnn { nilcouv } { duplicate-figure-id } {#1} }
{ \seq_gput_right:Nn \g__nilcouv_scale_to_max_style_figure_ids_seq {#1} }
}
% Automatic generation of figure ids (the pattern is defined here)
\cs_new:Npn \__nilcouv_autogenerated_id:n #1 { nilcouv~autogenerated~id~#1 }
\cs_generate_variant:Nn \__nilcouv_autogenerated_id:n { V }
\cs_new_protected:Npn \__nilcouv_autoscale:nnn #1#2#3
{ \tikzset { scale~to~max~size={#1}{#2}{#3} } }
\cs_generate_variant:Nn \__nilcouv_autoscale:nnn { x }
\cs_new_protected:Npn \__nilcouv_autoscale_autoid:nn #1#2
{
% Increment the counter
\int_gincr:N \g_nilcouv_last_autogenerated_figure_nb_int
% Call the 'autoscale' style with the new id
\__nilcouv_autoscale:xnn
{ \__nilcouv_autogenerated_id:V
\g_nilcouv_last_autogenerated_figure_nb_int
}
{#1}
{#2}
}
% Set up aliases using LaTeX2e naming style
\cs_new_eq:NN \nilcouv@check@unique@id \__nilcouv_check_unique_id:n
\cs_new_eq:NN \nilcouv@autoscale@autoid \__nilcouv_autoscale_autoid:nn
\ExplSyntaxOff
% Autoscaling technique that doesn't affect font sizes in TikZ pictures.
% (based on code from marmot: <https://tex.stackexchange.com/a/497749/73317>)
%
% #1: unique per-picture id allowing several pictures to use this mechanism
% in a given document (it should contain no control sequence token nor
% active character)
% #2: target width
% #3: target height
\newcommand*{\nilcouv@ExportBB}[3]{%
\path let
\p1=($(current bounding box.north east)-(current bounding box.south west)$),
\n1={#2/\x1},\n2={#3/\y1}
in \pgfextra{\pgfmathsetmacro{\nilcouv@figscale}{min(\n1,\n2)}%
\expandafter\xdef\csname nilcouv@auto@figscale@#1\endcsname{%
\nilcouv@figscale}};
\immediate\write\@mainaux{%
\string\expandafter
\gdef\string\csname\space nilcouv@auto@figscale@#1\string\endcsname{%
\csname nilcouv@auto@figscale@#1\endcsname}}%
}
\tikzset{
% Arguments: figure identifier, target width, target height
scale to max size/.style n args={3}{
execute at end picture={\nilcouv@ExportBB{#1}{#2}{#3}},
/utils/exec={\nilcouv@check@unique@id{#1}%
\ifcsname nilcouv@auto@figscale@#1\endcsname
\wlog{Found autoscale value for picture '#1'}%
\else
\typeout{Automatically-scaled pictures: please recompile
for picture '#1'.}%
\expandafter\gdef
\csname nilcouv@auto@figscale@#1\endcsname{1}%
\fi},
scale=\csname nilcouv@auto@figscale@#1\endcsname,
},
% Same style except the id is automatically generated using a counter
autoscale autoid/.style 2 args={%
/utils/exec={\nilcouv@autoscale@autoid{#1}{#2}}},
}
% End of the code based on <https://tex.stackexchange.com/a/497749/73317>
\makeatother
\begin{document}
\noindent
\textcolor{orange}{\rule{15cm}{0.4pt}}\\ % print a 15cm long rule for comparison
\begin{tikzpicture}[
font={\sansmath\sffamily\Large}, line width=0.4mm, line cap=round,
line join=round, >=latex, x=1.92cm, y=1.92cm,
autoscale autoid={15cm}{\maxdimen} % <---------- this
]
\draw[->] (-5-.4,0) -- (2+.4,0);
\foreach \x in {-5,...,2} {
\draw[shift={(\x,0)},color=black] (0pt,2pt) -- (0pt,-2pt);
}
\foreach \x in {-1,1} {
\draw[shift={(\x,0)},color=black] (0,0) node[inner sep=5pt, above] {$\x$};
}
\draw[fill=orange]
(-2.9,0) coordinate (O) node[circle, draw=black, fill=orange, scale=0.4] {} node[inner sep=7pt, anchor=north, scale= 1] {$E$}
(-5,0) coordinate (A) node[circle, draw=black, fill=orange, scale=0.4] {} node[inner sep=7pt, anchor=north, scale= 1] {$F$}
(1.4,0) coordinate (B) node[circle, draw=black, fill=orange, scale=0.4] {} node[inner sep=7pt, anchor=north, scale= 1] {$G$}
(-2,0) coordinate (C) node[circle, draw=black, fill=orange, scale=0.4] {} node[inner sep=7pt, anchor=north, scale= 1] {$H$};
\end{tikzpicture}
\end{document}
