+/*
+ * Compute the optimum format string and the scaling
+ * for the tick drawing on a chart axis
+ * Input: lower: the lowest tick
+ * interval:the interval between the ticks
+ * nticks: the number of tick intervals (bins) on the axis
+ * Return: fs: format string for printf to print the tick value
+ * scale: scaling factor for the tick value
+ * The format string has to be freed after usage.
+ * An example format string and scalefactor:
+ * Non Scientific: "%.3lf", scale=1.00
+ * Scientific: "%.2lfe3", scale = 0.001
+ * Usage example:
+ * fs = chart_get_ticks_format(-0.7,0.1,8,&scale);
+ * printf(fs,value*scale);
+ * free(fs);
+ */
+char *
+chart_get_ticks_format (const double lower, const double interval,
+ const unsigned int nticks, double *scale)
+{
+ double logmax = log10(fmax(fabs(lower + (nticks+1)*interval),fabs(lower)));
+ double logintv = log10(interval);
+ int logshift = 0;
+ char *format_string = NULL;
+ int nrdecs = 0;
+
+ if (logmax > 0.0 && logintv < 0.0)
+ {
+ nrdecs = MIN(6,(int)(ceil(fabs(logintv))));
+ logshift = 0;
+ if (logmax < 12.0)
+ format_string = xasprintf("%%.%dlf",nrdecs);
+ else
+ format_string = xasprintf("%%lg");
+ }
+ else if (logmax > 0.0) /*logintv is > 0*/
+ {
+ if (logintv < 5.0 && logmax < 10.0)
+ {
+ logshift = 0; /* No scientific format */
+ nrdecs = 0;
+ format_string = xstrdup("%.0lf");
+ }
+ else
+ {
+ logshift = (int)logmax;
+ /* Possible intervals are 0.2Ex, 0.5Ex, 1.0Ex */
+ /* log10(0.2E9) = 8.30, log10(0.5E9) = 8.69, log10(1.0E9) = 9 */
+ /* 0.2 and 0.5 need one decimal more. For stability subtract 0.1 */
+ nrdecs = MIN(8,(int)(ceil(logshift-logintv-0.1)));
+ format_string = gen_pango_markup_scientific_format_string (nrdecs, logshift);
+ }
+ }
+ else /* logmax and logintv are < 0 */
+ {
+ if (logmax > -3.0)
+ {
+ logshift = 0; /* No scientific format */
+ nrdecs = MIN(8,(int)(ceil(-logintv)));
+ format_string = xasprintf("%%.%dlf",nrdecs);
+ }
+ else
+ {
+ logshift = (int)logmax-1;
+ nrdecs = MIN(8,(int)(ceil(logshift-logintv-0.1)));
+ format_string = gen_pango_markup_scientific_format_string (nrdecs, logshift);
+ }
+ }
+ *scale = pow(10.0,-(double)logshift);
+ return format_string;
+}