Skip to content
Snippets Groups Projects
Commit a6bb02db authored by tag2y19's avatar tag2y19 Committed by Tom Greig
Browse files

Add ticks using the pretty function copied from R

It's fine, I'll EUPL it
parent 6e3d26b8
No related branches found
No related tags found
No related merge requests found
...@@ -91,6 +91,7 @@ static void parse_headers( struct context* context ); ...@@ -91,6 +91,7 @@ static void parse_headers( struct context* context );
static void parse_data( struct context* context ); static void parse_data( struct context* context );
static void plot_draw( GtkDrawingArea* plot, static void plot_draw( GtkDrawingArea* plot,
cairo_t* cr, int width, int height, void* data ); cairo_t* cr, int width, int height, void* data );
static int pretty( double* lo, double* up, int ndiv );
/* PUBLIC FUNK!!! */ /* PUBLIC FUNK!!! */
...@@ -917,6 +918,10 @@ static void plot_draw( GtkDrawingArea* plot, ...@@ -917,6 +918,10 @@ static void plot_draw( GtkDrawingArea* plot,
context->xdist = xrange[1] - xrange[0]; context->xdist = xrange[1] - xrange[0];
} }
int xdivs = pretty( &( xrange[0] ), &( xrange[1] ), 10 );
int yldivs = pretty( &( ylrange[0] ), &( ylrange[1] ), 10 );
int yrdivs = pretty( &( yrrange[0] ), &( yrrange[1] ), 10 );
/* Data */ /* Data */
struct data* first_data = context->data; struct data* first_data = context->data;
...@@ -1018,4 +1023,138 @@ static void plot_draw( GtkDrawingArea* plot, ...@@ -1018,4 +1023,138 @@ static void plot_draw( GtkDrawingArea* plot,
cairo_restore( cr ); cairo_restore( cr );
cairo_save( cr );
for ( int i = 0; i < xdivs; i++ ) {
cairo_move_to( cr,
5 + i * ( width - 10 ) / ( xdivs - 1 ),
height - 5 );
cairo_line_to( cr,
5 + i * ( width - 10 ) / ( xdivs - 1 ),
height - 2 );
cairo_stroke( cr );
}
for ( int i = 0; i < yldivs && lset; i++ ) {
cairo_move_to( cr,
2,
5 + i * ( height - 10 ) / ( yldivs - 1 ) );
cairo_line_to( cr,
5,
5 + i * ( height - 10 ) / ( yldivs - 1 ) );
cairo_stroke( cr );
}
for ( int i = 0; i < yrdivs && rset; i++ ) {
cairo_move_to( cr,
width - 5,
5 + i * ( height - 10 ) / ( yrdivs - 1 ) );
cairo_line_to( cr,
width - 2,
5 + i * ( height - 10 ) / ( yrdivs - 1 ) );
cairo_stroke( cr );
}
}
static int pretty( double* lo, double* up, int ndiv ) {
/* Shamelessly filched from the R language's source code.
* (src/appl/pretty.c) */
#define rounding_eps 1E-10
#define h 1.5
#define h5 ( .5 + 1.5 * h )
#define shrink_sml 0.75
#define f_min 2E-20
#define MAX_F 1.25
double lo_ = *lo;
double up_ = *up;
double dx = up_ - lo_;
double cell = fabs( lo_ ) > fabs( up_ ) ? fabs( lo_ ) : fabs( up_ );
double U = 1 + ( ( h5 >= 1.5 * h + 0.5 ) ?
1 / ( 1 + h ) : 1.5 / ( 1 + h5 ) );
U *= ndiv * DBL_EPSILON;
bool i_small = dx < cell * U * 3;
if ( i_small ) {
if ( cell > 10 ) {
cell = 9 + cell / 10;
}
cell *= shrink_sml;
} else {
cell = dx;
if ( 1 < ndiv ) {
cell /= ndiv;
}
}
double subsmall = f_min * DBL_MIN;
if ( subsmall == 0. ) {
subsmall = DBL_MIN;
}
if ( cell < subsmall ) {
cell = subsmall;
} else if ( cell > DBL_MAX / MAX_F ) {
cell = DBL_MAX / MAX_F;
}
double base = pow( 10.0, floor( log10( cell ) ) );
double unit = base;
if ( ( U = 2 * base ) - cell < h * ( cell - unit ) ) {
unit = U;
if ( ( U = 5 * base ) - cell < h5 * ( cell - unit ) ) {
unit = U;
if ( ( U = 10 * base ) - cell < h * ( cell - unit ) ) {
unit = U;
}
}
}
double ns = floor( lo_ / unit + rounding_eps );
double nu = ceil( up_ / unit - rounding_eps );
while ( ns * unit > *lo + rounding_eps * unit ) {
ns--;
}
while ( nu * unit < *up - rounding_eps * unit ) {
nu++;
}
int k = (int) ( .5 + nu - ns );
if ( k < 1 ) {
k = 1 - k;
if ( lo_ == 0. && ns == 0. && up_ != 0. ) {
nu += k;
} else if ( up_ == 0. && nu == 0. && lo_ != 0. ) {
ns -= k;
} else if ( ns >= 0. ) {
nu += k / 2;
ns -= k / 2 + k % 2;
} else {
ns -= k / 2;
nu += k / 2 + k % 2;
}
ndiv = 1;
} else {
ndiv = k;
}
if ( ns * unit < *lo ) {
*lo = ns * unit;
}
if ( nu * unit > *up ) {
*up = nu * unit;
}
return ndiv;
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment