/* For a given axis range, compute a step size (in data space) to
* generate a suitable number of ticks (5 or so). */
static double
-_step_for_range (double range)
+_step_for_range (double range, int *minor_divisions)
{
double step, scale_factor;
* 10). The threshold values between these are computed
* logarithmically. */
if (step < 3.535533905932738) {
- if (step < 1.58113883008419)
+ if (step < 1.58113883008419) {
step = 1.0;
- else
+ *minor_divisions = 4;
+ } else {
step = 2.5;
+ *minor_divisions = 5;
+ }
} else {
- if (step < 7.071067811865475)
+ if (step < 7.071067811865475) {
step = 5.0;
- else
+ *minor_divisions = 5;
+ } else {
step = 10.0;
+ *minor_divisions = 4;
+ }
}
/* Un-normalize and we now have the data value that we want to
* nice-looking pixel-snapped ticks we want to expand the range
* slightly. */
static void
-_expand_range_for_width (double *axis_min, double *axis_max, int pixel_size)
+_expand_range_for_width (double *axis_min, double *axis_max, int pixel_range)
{
- double range, new_range, step, pixel_step;
+ double range, new_range, step, step_minor, pixel_step;
+ int minor_divisions;
range = *axis_max - *axis_min;
- step = _step_for_range (range);
- pixel_step = step * pixel_size / range;
+ step = _step_for_range (range, &minor_divisions);
+ step_minor = step / minor_divisions;
+
+ pixel_step = step_minor * (pixel_range / range);
/* We expand the range by the ratio of the pixel step to the floor
* of the pixel_step.
}
}
- /* Next, increase the axis ranges just enough so that the step
+ /* Next, we want to ensure that the data never collides with the
+ * ticks. So we expand each axis on its minimum side as needed. */
+ cairo_save (cr);
+ {
+ double x, y;
+
+ _set_transform_to_data_space (acre);
+
+ x = ACRE_TICK_MAJOR_SIZE + 2.0;
+ y = ACRE_TICK_MAJOR_SIZE + 2.0;
+ cairo_device_to_user_distance (cr, &x, &y);
+
+ acre->x_axis.min -= x;
+ acre->y_axis.min += y;
+ }
+ cairo_restore (cr);
+
+ /* Then, increase the axis ranges just enough so that the step
* sizes for the ticks will be integers.
*/
_expand_range_for_width (&acre->x_axis.min,
{
cairo_t *cr = acre->cr;
double t, step, sub_step;
- int minor_divisions = 5;
+ int minor_divisions;
cairo_save (cr);
_set_transform_to_data_space (acre);
- step = _step_for_range (axis_max - axis_min);
+ step = _step_for_range (axis_max - axis_min, &minor_divisions);
sub_step = step / minor_divisions;
for (t = (floor (axis_min / sub_step) + 1) * sub_step;