/* SciGraphica - Scientific graphics and data manipulation
* Copyright (C) 2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <stdlib.h>
#include <math.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include <gtkextra/gtkextra.h>
#include "sg_layer.h"
#include "sg.h"
#include "sg_dataset.h"
static void sg_layer_init (SGlayer *layer);
static void sg_layer_class_init (SGlayerClass *klass);
static void sg_layer_destroy (GtkObject *object);
static gboolean custom_tick_labels (GtkPlotAxis *axis,
gdouble *tick_value,
gchar *label,
gpointer data);
static void plot_changed (GtkPlot *plot, gpointer data);
static void clone_axis (GtkPlotAxis *old_axis,
GtkPlotAxis *new_axis);
static GtkObjectClass *parent_class = NULL;
GtkType
sg_layer_get_type (void)
{
static GtkType layer_type = 0;
if (!layer_type)
{
GtkTypeInfo layer_info =
{
"SGlayer",
sizeof (SGlayer),
sizeof (SGlayerClass),
(GtkClassInitFunc) sg_layer_class_init,
(GtkObjectInitFunc) sg_layer_init,
/* reserved 1*/ NULL,
/* reserved 2 */ NULL,
(GtkClassInitFunc) NULL,
};
layer_type = gtk_type_unique (GTK_TYPE_OBJECT, &layer_info);
}
return layer_type;
}
static void
sg_layer_class_init (SGlayerClass *klass)
{
GtkObjectClass *object_class;
parent_class = (GtkObjectClass *)gtk_type_class (gtk_object_get_type ());
object_class = (GtkObjectClass *) klass;
object_class->destroy = sg_layer_destroy;
}
SGlayer *
sg_layer_new (SGlayerType layer_type, gdouble width, gdouble height)
{
SGlayer *layer;
GtkPlot *plot;
layer = SG_LAYER(gtk_type_new(sg_layer_get_type()));
layer->type = layer_type;
switch (layer_type){
case SG_LAYER_2D:
layer->real_plot = gtk_plot_new_with_size(NULL, width, height);
break;
case SG_LAYER_3D:
layer->real_plot = gtk_plot3d_new_with_size(NULL, width, height);
break;
case SG_LAYER_POLAR:
layer->real_plot = gtk_plot_polar_new_with_size(NULL, width, height);
break;
}
layer->button = gtk_toggle_button_new_with_label(" ");
gtk_widget_set_usize(layer->button, 24, 24);
plot = GTK_PLOT(layer->real_plot);
gtk_plot_set_transparent(plot, TRUE);
plot->clip_data = TRUE;
gtk_signal_connect(GTK_OBJECT(plot), "changed",
GTK_SIGNAL_FUNC(plot_changed), NULL);
gtk_signal_connect(GTK_OBJECT(plot->left), "tick_label",
GTK_SIGNAL_FUNC(custom_tick_labels), layer);
gtk_signal_connect(GTK_OBJECT(plot->right), "tick_label",
GTK_SIGNAL_FUNC(custom_tick_labels), layer);
gtk_signal_connect(GTK_OBJECT(plot->top), "tick_label",
GTK_SIGNAL_FUNC(custom_tick_labels), layer);
gtk_signal_connect(GTK_OBJECT(plot->bottom), "tick_label",
GTK_SIGNAL_FUNC(custom_tick_labels), layer);
return layer;
}
SGlayer *
sg_layer_clone (SGlayer *old_layer)
{
SGlayer *new_layer;
GtkPlot *new_plot, *old_plot;
new_layer = sg_layer_new(old_layer->type,
GTK_PLOT(old_layer->real_plot)->width,
GTK_PLOT(old_layer->real_plot)->height);
new_plot = GTK_PLOT(new_layer->real_plot);
old_plot = GTK_PLOT(old_layer->real_plot);
new_layer->left_labels_worksheet = old_layer->left_labels_worksheet;
new_layer->left_labels_column = old_layer->left_labels_column;
new_layer->left_values_column = old_layer->left_values_column;
new_layer->right_labels_worksheet = old_layer->right_labels_worksheet;
new_layer->right_labels_column = old_layer->right_labels_column;
new_layer->right_values_column = old_layer->right_values_column;
new_layer->top_labels_worksheet = old_layer->top_labels_worksheet;
new_layer->top_labels_column = old_layer->top_labels_column;
new_layer->top_values_column = old_layer->top_values_column;
new_layer->bottom_labels_worksheet = old_layer->bottom_labels_worksheet;
new_layer->bottom_labels_column = old_layer->bottom_labels_column;
new_layer->bottom_values_column = old_layer->bottom_values_column;
new_layer->rescale = old_layer->rescale;
clone_axis(old_plot->left, new_plot->left);
clone_axis(old_plot->right, new_plot->right);
clone_axis(old_plot->bottom, new_plot->bottom);
clone_axis(old_plot->top, new_plot->top);
new_plot->xmin = old_plot->xmin;
new_plot->xmax = old_plot->xmax;
new_plot->ymin = old_plot->ymin;
new_plot->ymax = old_plot->ymax;
new_plot->transparent = old_plot->transparent;
new_plot->background = old_plot->background;
new_plot->grids_on_top = old_plot->grids_on_top;
new_plot->show_x0 = old_plot->show_x0;
new_plot->x = old_plot->x;
new_plot->y = old_plot->y;
new_plot->width = old_plot->width;
new_plot->height = old_plot->height;
new_plot->xscale = old_plot->xscale;
new_plot->yscale = old_plot->yscale;
new_plot->bottom_align = old_plot->bottom_align;
new_plot->top_align = old_plot->top_align;
new_plot->right_align = old_plot->right_align;
new_plot->left_align = old_plot->left_align;
new_plot->x0_line = old_plot->x0_line;
new_plot->y0_line = old_plot->y0_line;
new_plot->legends_x = old_plot->legends_x;
new_plot->legends_y = old_plot->legends_y;
new_plot->legends_border = old_plot->legends_border;
new_plot->legends_border_width = old_plot->legends_border_width;
new_plot->legends_shadow_width = old_plot->legends_shadow_width;
new_plot->show_legends = old_plot->show_legends;
new_plot->legends_attr = old_plot->legends_attr;
if(GTK_IS_PLOT3D(old_layer->real_plot)){
GtkPlot3D *old_plot3d, *new_plot3d;
new_plot3d = GTK_PLOT3D(new_layer->real_plot);
old_plot3d = GTK_PLOT3D(old_layer->real_plot);
new_plot3d->zmin = old_plot3d->zmin;
new_plot3d->zmax = old_plot3d->zmax;
new_plot3d->zscale = old_plot3d->zscale;
new_plot3d->e1 = old_plot3d->e1;
new_plot3d->e2 = old_plot3d->e2;
new_plot3d->e3 = old_plot3d->e3;
new_plot3d->origin = old_plot3d->origin;
new_plot3d->center = old_plot3d->center;
new_plot3d->a1 = old_plot3d->a1;
new_plot3d->a2 = old_plot3d->a2;
new_plot3d->a3 = old_plot3d->a3;
new_plot3d->xy_visible = old_plot3d->xy_visible;
new_plot3d->yz_visible = old_plot3d->yz_visible;
new_plot3d->zx_visible = old_plot3d->zx_visible;
new_plot3d->color_xy = old_plot3d->color_xy;
new_plot3d->color_yz = old_plot3d->color_yz;
new_plot3d->color_zx = old_plot3d->color_zx;
new_plot3d->frame = old_plot3d->frame;
new_plot3d->corner = old_plot3d->corner;
new_plot3d->corner_visible = old_plot3d->corner_visible;
new_plot3d->titles_offset = old_plot3d->titles_offset;
new_plot3d->xfactor = old_plot3d->xfactor;
new_plot3d->yfactor = old_plot3d->yfactor;
new_plot3d->zfactor = old_plot3d->zfactor;
new_plot3d->zfactor = old_plot3d->zfactor;
clone_axis(&old_plot3d->xy, &new_plot3d->xy);
clone_axis(&old_plot3d->xz, &new_plot3d->xz);
clone_axis(&old_plot3d->yx, &new_plot3d->yx);
clone_axis(&old_plot3d->yz, &new_plot3d->yz);
clone_axis(&old_plot3d->zx, &new_plot3d->zx);
clone_axis(&old_plot3d->zy, &new_plot3d->zy);
}
if(GTK_IS_PLOT_POLAR(old_layer->real_plot)){
GtkPlotPolar *old_plot, *new_plot;
new_plot = GTK_PLOT_POLAR(new_layer->real_plot);
old_plot = GTK_PLOT_POLAR(old_layer->real_plot);
new_plot->rotation = old_plot->rotation;
}
return new_layer;
}
static void
clone_axis(GtkPlotAxis *old_axis, GtkPlotAxis *new_axis)
{
GtkPlotTicks new_ticks;
GtkPlotText new_title;
new_ticks = new_axis->ticks;
new_title = new_axis->title;
*new_axis = *old_axis;
new_axis->ticks = new_ticks;
new_axis->title = new_title;
if(old_axis->title.text && strlen(old_axis->title.text) > 0)
new_axis->title.text = g_strdup(old_axis->title.text);
new_axis->title.x = old_axis->title.x;
new_axis->title.y = old_axis->title.y;
if(old_axis->labels_prefix && strlen(old_axis->labels_prefix) > 0)
new_axis->labels_prefix = g_strdup(old_axis->labels_prefix);
if(old_axis->labels_suffix && strlen(old_axis->labels_suffix) > 0)
new_axis->labels_suffix = g_strdup(old_axis->labels_suffix);
}
static void
sg_layer_init(SGlayer *layer)
{
layer->parent = NULL;
layer->datasets = NULL;
layer->active_data = NULL;
layer->left_labels_worksheet = NULL;
layer->left_values_column = layer->left_labels_column = -1;
layer->right_labels_worksheet = NULL;
layer->right_values_column = layer->right_labels_column = -1;
layer->top_labels_worksheet = NULL;
layer->top_values_column = layer->top_labels_column = -1;
layer->bottom_labels_worksheet = NULL;
layer->bottom_values_column = layer->bottom_labels_column = -1;
layer->symbol = 1;
layer->symbol_style = 0;
layer->line_style = 1;
layer->connector = 1;
layer->rescale = 1;
gdk_color_black(gdk_colormap_get_system(), &layer->symbol_color);
gdk_color_black(gdk_colormap_get_system(), &layer->line_color);
}
static void
sg_layer_destroy(GtkObject *object)
{
SGlayer *layer;
layer = SG_LAYER(object);
sg_layer_clear(layer);
if(layer->real_plot && GTK_IS_WIDGET(layer->real_plot))
gtk_widget_destroy(layer->real_plot);
GTK_OBJECT_CLASS(parent_class)->destroy(object);
}
static gboolean
custom_tick_labels(GtkPlotAxis *axis, gdouble *tick_value, gchar *label, gpointer data)
{
SGworksheet *worksheet;
SGlayer *layer;
GtkPlot *plot;
gint labels_column, values_column;
gchar labels[100];
gint i;
layer = (SGlayer *)data;
plot = GTK_PLOT(layer->real_plot);
if(axis == plot->left){
worksheet = layer->left_labels_worksheet;
values_column = layer->left_values_column;
labels_column = layer->left_labels_column;
}
if(axis == plot->right){
worksheet = layer->right_labels_worksheet;
values_column = layer->right_values_column;
labels_column = layer->right_labels_column;
}
if(axis == plot->top){
worksheet = layer->top_labels_worksheet;
values_column = layer->top_values_column;
labels_column = layer->top_labels_column;
}
if(axis == plot->bottom){
worksheet = layer->bottom_labels_worksheet;
values_column = layer->bottom_values_column;
labels_column = layer->bottom_labels_column;
}
g_snprintf(label, 100, "%s", " ");
if(!worksheet) return FALSE;
if(labels_column < 0) return FALSE;
for(i = 0; i <= GTK_SHEET(worksheet->sheet)->maxallocrow; i++){
gchar *vtext, *ltext;
gdouble value;
vtext = sg_worksheet_cell_get_text(worksheet, i, values_column);
if (values_column>=0)
{
if(vtext)
value = atof(vtext);
else
value = 0.0;
}
else
value=(gdouble)i;
if(fabs(value - *tick_value) < 1.e-10){
ltext = sg_worksheet_cell_get_text(worksheet, i, labels_column);
if(ltext){
g_snprintf(label, 100, "%s", ltext);
}else{
g_snprintf(label, 100, "%s", " ");
}
return TRUE;
}
}
return FALSE;
}
void
sg_layer_set_tick_labels(SGlayer *layer,
gint axis_pos,
SGworksheet *worksheet,
gint values_col,
gint labels_col)
{
switch(axis_pos){
case GTK_PLOT_AXIS_LEFT:
layer->left_labels_worksheet = worksheet;
layer->left_labels_column = labels_col;
layer->left_values_column = values_col;
GTK_PLOT(layer->real_plot)->left->custom_labels = TRUE;
break;
case GTK_PLOT_AXIS_RIGHT:
layer->right_labels_worksheet = worksheet;
layer->right_labels_column = labels_col;
layer->right_values_column = values_col;
GTK_PLOT(layer->real_plot)->right->custom_labels = TRUE;
break;
case GTK_PLOT_AXIS_TOP:
layer->top_labels_worksheet = worksheet;
layer->top_labels_column = labels_col;
layer->top_values_column = values_col;
GTK_PLOT(layer->real_plot)->top->custom_labels = TRUE;
break;
case GTK_PLOT_AXIS_BOTTOM:
layer->bottom_labels_worksheet = worksheet;
layer->bottom_labels_column = labels_col;
layer->bottom_values_column = values_col;
GTK_PLOT(layer->real_plot)->bottom->custom_labels = TRUE;
break;
}
}
void
sg_layer_add_dataset(SGlayer *layer, SGdataset *dataset)
{
gtk_plot_add_data(GTK_PLOT(layer->real_plot), dataset->real_data);
gtk_widget_show(GTK_WIDGET(dataset->real_data));
layer->datasets = g_list_append(layer->datasets, dataset);
}
void
sg_layer_add_dataset_default(SGlayer *layer, SGdataset *dataset)
{
dataset->real_data->symbol.symbol_type = (GtkPlotSymbolType)layer->symbol;
dataset->real_data->symbol.symbol_style = (GtkPlotSymbolStyle)layer->symbol_style;
dataset->real_data->symbol.color = layer->symbol_color;
dataset->real_data->symbol.border.color = layer->symbol_color;
dataset->real_data->line.line_style = (GtkPlotLineStyle)layer->line_style;
dataset->real_data->line_connector = (GtkPlotConnector)layer->connector;
dataset->real_data->line.color = layer->line_color;
gtk_plot_add_data(GTK_PLOT(layer->real_plot), dataset->real_data);
gtk_widget_show(GTK_WIDGET(dataset->real_data));
layer->datasets = g_list_append(layer->datasets, dataset);
}
void
sg_layer_remove_dataset(SGlayer *layer, SGdataset *dataset)
{
GList *list;
SGdataset *link;
list = layer->datasets;
while(list) {
if(list->data == dataset){
link = (SGdataset *)gtk_plot_data_get_link(GTK_PLOT_DATA(dataset->real_data));
link->ref_count--;
if(layer->real_plot && GTK_IS_WIDGET(layer->real_plot)){
gtk_plot_remove_data(GTK_PLOT(layer->real_plot),
dataset->real_data);
}
if(GTK_IS_OBJECT(dataset->real_data)){
gtk_widget_destroy(GTK_WIDGET(dataset->real_data));
}
gtk_object_destroy(GTK_OBJECT(dataset));
layer->datasets = g_list_remove_link(layer->datasets, list);
g_list_free_1(list);
break;
}
list = list->next;
}
}
void
sg_layer_clear(SGlayer *layer)
{
GList *list;
list = layer->datasets;
while(list){
sg_layer_remove_dataset(layer, SG_DATASET(list->data));
list = layer->datasets;
}
layer->datasets = NULL;
}
void
sg_layer_button_set_label(SGlayer *layer, gint num)
{
gchar title[10];
sprintf(title,"%i\n",num);
gtk_misc_set_alignment(GTK_MISC(GTK_BIN(layer->button)->child), .5, .0);
gtk_label_set_text(GTK_LABEL(GTK_BIN(layer->button)->child), title);
}
static void
plot_changed (GtkPlot *plot, gpointer data)
{
sg_project_changed(TRUE);
}
void
sg_layer_remove_markers(SGlayer *layer)
{
SGplot *plot;
GtkPlotCanvas *canvas;
if(!layer || !layer->active_data) return;
plot = (SGplot *)layer->parent;
canvas = GTK_PLOT_CANVAS(plot->real_canvas);
gtk_plot_data_remove_markers(layer->active_data);
layer->active_data = NULL;
gtk_plot_canvas_paint(canvas);
gtk_plot_canvas_refresh(canvas);
}
void
sg_layer_show_markers(SGlayer *layer, gboolean show)
{
SGplot *plot;
GtkPlotCanvas *canvas;
if(!layer || !layer->active_data) return;
if(gtk_plot_data_markers_visible(layer->active_data) == show) return;
plot = (SGplot *)layer->parent;
canvas = GTK_PLOT_CANVAS(plot->real_canvas);
gtk_plot_data_show_markers(layer->active_data, show);
gtk_plot_canvas_paint(canvas);
gtk_plot_canvas_refresh(canvas);
}
void
sg_layer_refresh_datasets(SGlayer *layer)
{
GList *aux_datasets;
aux_datasets = layer->datasets;
while(aux_datasets){
SGdataset *data;
data = (SGdataset *)aux_datasets->data;
sg_dataset_refresh(data);
aux_datasets = aux_datasets->next;
}
}
gint
sg_layer_min_max(SGlayer *layer, gdouble *xmin, gdouble *xmax, gdouble *ymin, gdouble *ymax)
{
GtkPlotData *dataset;
GList *list;
gint n;
GtkPlot *plot;
gboolean change;
plot = GTK_PLOT(layer->real_plot);
if(!layer) return FALSE;
*xmin = plot->xmin;
*ymin = plot->ymin;
*xmax = plot->xmax;
*ymax = plot->ymax;
list = plot->data_sets;
while(list){
gdouble fx, fy, fz, fa;
gdouble fdx, fdy, fdz, fda;
gchar *label;
gboolean error;
dataset = GTK_PLOT_DATA(list->data);
if(!dataset->is_function){
for(n = 0; n < dataset->num_points; n++){
gtk_plot_data_get_point(dataset, n,
&fx, &fy, &fz, &fa,
&fdx, &fdy, &fdz, &fda,
&label, &error);
if (n==0 && list==plot->data_sets){
*xmin = fx;
*ymin = fy;
*xmax = fx;
*ymax = fy;
change = TRUE;
}
else
{ if(fx < *xmin){
change = TRUE;
*xmin = fx;
}
if(fy < *ymin){
change = TRUE;
*ymin = fy;
}
if(fx > *xmax){
change = TRUE;
*xmax = fx;
}
if(fy > *ymax){
change = TRUE;
*ymax = fy;
}
}
}
}
list = list->next;
}
return change;
}
void
sg_layer_autoscale(SGlayer *layer,
gint left_offset, gint right_offset,
gint top_offset, gint bottom_offset)
{
GtkPlotData *dataset;
GList *list;
gdouble xmin, xmax;
gdouble ymin, ymax;
gdouble pmin, pmax;
gdouble min, max;
gdouble pstep;
gdouble dx, dy;
gint n;
gboolean change = FALSE,contour=FALSE;
GtkPlot *plot;
plot = GTK_PLOT(layer->real_plot);
if(!layer) return;
if(!layer->datasets) return;
list = layer->datasets;
while(list){
GtkPlotData *real_data;
real_data = GTK_PLOT_DATA(SG_DATASET(list->data)->real_data);
if (GTK_IS_PLOT_SURFACE(real_data)){
contour=TRUE;
gtk_plot_data_gradient_autoscale_z(real_data);
}else if(real_data->iterator_mask & GTK_PLOT_DATA_DA){
gtk_plot_data_gradient_autoscale_da(real_data);
}else{
gtk_plot_data_gradient_autoscale_a(real_data);
}
list=list->next;
}
if(GTK_IS_PLOT3D(layer->real_plot)){
gtk_plot3d_autoscale(GTK_PLOT3D(layer->real_plot));
return;
}
change=sg_layer_min_max(layer,&xmin,&xmax,&ymin,&ymax);
if(!change) return;
if(plot->bottom->scale == GTK_PLOT_SCALE_LOG10) {
plot->bottom->ticks.step = 1;
plot->bottom->ticks.nminor = 8;
xmin = floor(log10(fabs(xmin))) - 1.;
xmin = pow(10., xmin);
xmax = ceil(log10(fabs(xmax)));
xmax = pow(10., xmax);
} else {
if (!contour && layer->rescale==1){
min = xmin;
max = xmax;
if(xmin == xmax){
if(xmin == 0.0){
max = xmax = 0.1;
}else{
pstep = floor(log10(fabs(xmin)));
dx = xmin/pow(10., pstep) * pow(10., pstep);
max = xmax = xmin + dx;
min = xmin = xmin - dx;
}
}
xmin -= (max - min)*left_offset/100.;
xmax += (max - min)*right_offset/100.;
if (xmin==xmax) xmax=xmax+1.;
dx = (xmax - xmin) / 8.;
min = xmin;
max = xmax;
if (xmin==0.0) xmin -= dx;
if (xmax==0.0) xmax += dx;
pmin = floor(log10(fabs(xmin))) - 1.;
pmax = floor(log10(fabs(xmax))) - 1.;
xmin = floor(xmin/pow(10., pmin)) * pow(10., pmin);
xmax = floor(xmax/pow(10., pmax)) * pow(10., pmax);
pstep = floor(log10(fabs(dx)));
dx = plot->bottom->ticks.step = dx/pow(10., pstep) * pow(10., pstep);
if (dx!=0){
while(xmin > min) xmin -= dx;
while(xmax < max) xmax += dx;
}
dx = (xmax - xmin)/plot->bottom->ticks.step;
while(dx > 5.){
plot->bottom->ticks.step *= 2;
dx = floor((xmax - xmin)/plot->bottom->ticks.step);
}
while (dx < 5){
plot->bottom->ticks.step /= 2;
dx = (xmax - xmin)/plot->bottom->ticks.step;
}
xmin = floor(xmin/plot->bottom->ticks.step) * plot->bottom->ticks.step;
xmax = ceil(xmax/plot->bottom->ticks.step) * plot->bottom->ticks.step;
plot->top->ticks.step = plot->bottom->ticks.step;
}
else
{ if (!contour){
xmin -= (xmax - xmin)*left_offset/100.;
xmax += (xmax - xmin)*right_offset/100.;
}
if (xmin==xmax) xmax=xmin+1.;
dx = (plot->bottom->ticks.step!=0?(xmax - xmin)/plot->bottom->ticks.step:(xmax-xmin)/10);
while(dx > 5.){
plot->bottom->ticks.step *= 2;
dx = floor((xmax - xmin)/plot->bottom->ticks.step);
}
while(dx < 5.){
plot->bottom->ticks.step /= 2;
dx = floor((xmax - xmin)/plot->bottom->ticks.step);
}
plot->top->ticks.step = plot->bottom->ticks.step;
}
pstep = floor(log10(fabs(dx)));
if (plot->top->label_style==0)
plot->top->label_precision = floor(fabs(pstep));
if (plot->bottom->label_style==0)
plot->bottom->label_precision = floor(fabs(pstep));
if (plot->bottom->label_style>0)
{ pstep = (dy!=0?fabs(log10(fabs(dy))):1);
plot->bottom->label_precision = ceil(fabs(pstep));
}
else
{ pstep = (plot->bottom->ticks.step!=0?log10(fabs(plot->bottom->ticks.step)):1);
if (pstep>=2) pstep=0;
if (pstep>0.) pstep=1.;
plot->bottom->label_precision = ceil(fabs(pstep));
}
if (plot->top->label_style>0)
{ pstep = (dy!=0?fabs(log10(fabs(dy))):1);
if (pstep>=2) pstep=0;
if (pstep>0.) pstep=1.;
plot->top->label_precision = ceil(fabs(pstep));
}
else
{ pstep = (plot->top->ticks.step!=0?log10(fabs(plot->top->ticks.step)):1);
if (pstep>=2) pstep=0;
if (pstep>0) pstep=1;
plot->top->label_precision = ceil(fabs(pstep));
}
}
if(plot->left->scale == GTK_PLOT_SCALE_LOG10) {
plot->left->ticks.step = 1;
plot->left->ticks.nminor = 8;
ymin = floor(log10(fabs(ymin))) - 1.;
ymin = pow(10., ymin);
ymax = ceil(log10(fabs(ymax)));
ymax = pow(10., ymax);
} else {
if (!contour && layer->rescale==1){
min = ymin;
max = ymax;
if(ymin == ymax){
if(ymin == 0.0){
max = ymax = 0.1;
}else{
pstep = floor(log10(fabs(ymin)));
dy = ymin/pow(10., pstep) * pow(10., pstep);
max = ymax = ymin + dy;
min = ymin = ymin - dy;
}
}
ymin -= (max - min)*bottom_offset/100.;
ymax += (max - min)*top_offset/100.;
if (ymin==ymax) ymax=ymax+1.;
dy = (ymax - ymin) / 8.;
min = ymin;
max = ymax;
if (ymin==0.0) ymin -= dy;
if (ymax==0.0) ymax += dy;
pmin = floor(log10(fabs(ymin))) - 1.;
pmax = floor(log10(fabs(ymax))) - 1.;
ymin = floor(ymin/pow(10., pmin)) * pow(10., pmin);
ymax = floor(ymax/pow(10., pmax)) * pow(10., pmax);
pstep = floor(log10(fabs(dy)));
dy = plot->left->ticks.step = dy/pow(10., pstep) * pow(10., pstep);
if (dy!=0){
while(ymin > min) ymin -= dy;
while(ymax < max) ymax += dy;
}
dy = (ymax - ymin)/plot->left->ticks.step;
while(dy > 5.){
plot->left->ticks.step *= 2;
dy = floor((ymax - ymin)/plot->left->ticks.step);
}
while (dy < 5){
plot->left->ticks.step /= 2;
dy = (ymax - ymin)/plot->left->ticks.step;
}
ymin = floor(ymin/plot->left->ticks.step) * plot->left->ticks.step;
ymax = ceil(ymax/plot->left->ticks.step) * plot->left->ticks.step;
plot->right->ticks.step = plot->left->ticks.step;
}
else
{ if (!contour){
ymin -= (ymax - ymin)*bottom_offset/100.;
ymax += (ymax - ymin)*top_offset/100.;
}
if (ymin==ymax) ymax=ymin+1.;
dy = (plot->left->ticks.step!=0?(ymax - ymin)/plot->left->ticks.step:(ymax-ymin)/10);
while (dy > 5.){
plot->left->ticks.step *= 2;
dy = floor((ymax - ymin)/plot->left->ticks.step);
}
plot->right->ticks.step = plot->left->ticks.step;
while (dy < 5){
plot->left->ticks.step /= 2;
dy = (ymax - ymin)/plot->left->ticks.step;
}
plot->right->ticks.step = plot->left->ticks.step;
}
if (plot->left->label_style>0)
{ pstep = (dy!=0?fabs(log10(fabs(dy))):1);
plot->left->label_precision = ceil(fabs(pstep));
}
else
{ pstep = (plot->left->ticks.step!=0?log10(fabs(plot->left->ticks.step)):1);
if (pstep>=2) pstep=0;
if (pstep>0.) pstep=1.;
plot->left->label_precision = ceil(fabs(pstep));
}
if (plot->right->label_style>0)
{ pstep = (dy!=0?fabs(log10(fabs(dy))):1);
if (pstep>=2) pstep=0;
if (pstep>0.) pstep=1.;
plot->right->label_precision = ceil(fabs(pstep));
}
else
{ pstep = (plot->right->ticks.step!=0?log10(fabs(plot->right->ticks.step)):1);
if (pstep>=2) pstep=0;
if (pstep>0) pstep=1;
plot->right->label_precision = ceil(fabs(pstep));
}
}
gtk_plot_set_range(plot, xmin, xmax, ymin, ymax);
}
syntax highlighted by Code2HTML, v. 0.9.1