/* NOTE : every path through this must push something onto obj_stack. */ static void gogo_start (GsfXMLIn *xin, xmlChar const **attrs) { GogXMLReadState *state = (GogXMLReadState *)xin->user_state; xmlChar const *type = NULL, *role = NULL; GogObject *res; unsigned i; for (i = 0; attrs != NULL && attrs[i] && attrs[i+1] ; i += 2) if (0 == strcmp (attrs[i], "type")) type = attrs[i+1]; else if (0 == strcmp (attrs[i], "role")) role = attrs[i+1]; if (NULL != type) { GType t = g_type_from_name (type); if (t == 0) { res = (GogObject *)gog_plot_new_by_name (type); if (NULL == res) res = (GogObject *)gog_trend_line_new_by_name (type); } else if (g_type_is_a (t, GOG_TYPE_OBJECT) && !G_TYPE_IS_ABSTRACT (t)) res = g_object_new (t, NULL); else res = NULL; if (res == NULL) { g_warning ("unknown type '%s'", type); } if (GOG_IS_GRAPH (res)) ((GogGraph *) res)->doc = (GODoc *) g_object_get_data (G_OBJECT (gsf_xml_in_get_input (xin)), "document"); } else res = NULL; if (role != NULL) { if (strcmp (role, GOG_BACKPLANE_OLD_ROLE_NAME) == 0) res = gog_object_add_by_name (state->obj, GOG_BACKPLANE_NEW_ROLE_NAME, res); else res = gog_object_add_by_name (state->obj, role, res); } if (res != NULL) { res->explicitly_typed_role = (type != NULL); if (GO_IS_PERSIST (res)) go_persist_prep_sax (GO_PERSIST (res), xin, attrs); } state->obj_stack = g_slist_prepend (state->obj_stack, state->obj); state->obj = res; }
static void graph_setup_chart (GogGraph *graph, CutRunContext *run_context) { GogChart *chart; GogPlot *pie; GOData *data; GogSeries *series; gchar **legends; double *values; gint n = 0; chart = GOG_CHART(gog_object_get_child_by_name(GOG_OBJECT(graph), "Chart")); pie = gog_plot_new_by_name("GogPiePlot"); gog_object_add_by_name(GOG_OBJECT(chart), "Plot", GOG_OBJECT(pie)); legends = g_new0(gchar *, CUT_TEST_RESULT_LAST); values = g_new0(double, CUT_TEST_RESULT_LAST); #define STATUS(status) (CUT_TEST_RESULT_ ## status) #define SET_DATA(status, n_statuses) G_STMT_START \ { \ const gchar *name; \ name = cut_test_result_status_to_signal_name(STATUS(status)); \ legends[STATUS(status)] = g_strdup(name); \ values[STATUS(status)] = \ cut_run_context_get_n_ ## n_statuses(run_context); \ n++; \ } G_STMT_END \ SET_DATA(SUCCESS, successes); SET_DATA(NOTIFICATION, notifications); SET_DATA(OMISSION, omissions); SET_DATA(PENDING, pendings); SET_DATA(FAILURE, failures); SET_DATA(ERROR, errors); #undef STATUS #undef SET_DATA series = gog_plot_new_series(pie); data = go_data_vector_str_new((const gchar * const *)legends, n, (GDestroyNotify)g_strfreev); gog_series_set_dim(series, 0, data, NULL); data = go_data_vector_val_new(values, n, g_free); gog_series_set_dim(series, 1, data, NULL); gog_object_add_by_name(GOG_OBJECT(chart), "Legend", NULL); }
static void role_plot_post_add (GogObject *parent, GogObject *plot) { GogChart *chart = GOG_CHART (parent); gboolean ok = TRUE; GogPlotClass *plot_klass = GOG_PLOT_CLASS (G_OBJECT_GET_CLASS (plot)); GogAxisSet axis_set = plot_klass->axis_set & ~GOG_AXIS_SET_FUNDAMENTAL; if (axis_set) { int i = GOG_AXIS_VIRTUAL, j = 1 << GOG_AXIS_VIRTUAL; for (; i < GOG_AXIS_TYPES; i++, j <<= 1) if ((axis_set & j) != 0 && (chart->axis_set & j) == 0) { GogObject *axis = GOG_OBJECT (g_object_new (GOG_TYPE_AXIS, "type", i, NULL)); chart->axis_set |= j; switch (i) { case GOG_AXIS_PSEUDO_3D: gog_object_add_by_name (GOG_OBJECT (chart), "Pseudo-3D-Axis", axis); break; case GOG_AXIS_COLOR: gog_object_add_by_name (GOG_OBJECT (chart), "Color-Axis", axis); break; case GOG_AXIS_BUBBLE: gog_object_add_by_name (GOG_OBJECT (chart), "Bubble-Axis", axis); break; default: g_warning ("Unknown axis type: %x\n", i); } } } /* APPEND to keep order, there won't be that many */ chart->plots = g_slist_append (chart->plots, plot); gog_chart_request_cardinality_update (chart); if (chart->plots->next == NULL) ok = gog_chart_axis_set_assign (chart, gog_plot_axis_set_pref (GOG_PLOT (plot))); ok |= gog_plot_axis_set_assign (GOG_PLOT (plot), chart->axis_set); /* a quick post condition to keep us on our toes */ g_return_if_fail (ok); }
static GogGraph * graph_new (const gchar *title, CutRunContext *run_context) { GogGraph *graph; graph = g_object_new(GOG_TYPE_GRAPH, NULL); gog_object_add_by_name(GOG_OBJECT(graph), "Chart", NULL); graph_setup_title(graph, title); graph_setup_chart(graph, run_context); return graph; }
static GogPlot * setup_page (GtkNotebook *notebook, const gchar *service_id) { GtkWidget *child, *w; GogChart *chart; GogGraph *graph; GogLabel *label; GogPlot *plot; GOData *data; GOStyle *style; PangoFontDescription *desc; child = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); gtk_notebook_append_page (notebook, child, gtk_label_new (service_id)); /* Create a graph widget and add it to the GtkVBox */ w = go_graph_widget_new (NULL); gtk_box_pack_end (GTK_BOX (child), w, TRUE, TRUE, 0); /* Get the embedded graph */ graph = go_graph_widget_get_graph (GO_GRAPH_WIDGET (w)); /* Add a title */ label = (GogLabel *) g_object_new (GOG_TYPE_LABEL, NULL); data = go_data_scalar_str_new (service_id, FALSE); gog_dataset_set_dim (GOG_DATASET (label), 0, data, NULL); gog_object_add_by_name (GOG_OBJECT (graph), "Title", GOG_OBJECT (label)); /* Change the title font */ style = go_styled_object_get_style (GO_STYLED_OBJECT (label)); desc = pango_font_description_from_string ("Sans bold 16"); go_style_set_font_desc (style, desc); /* Get the chart created by the widget initialization */ chart = go_graph_widget_get_chart (GO_GRAPH_WIDGET (w)); /* Create a plot and add it to the chart */ plot = (GogPlot *) gog_plot_new_by_name (service_id); gog_object_add_by_name (GOG_OBJECT (chart), "Plot", GOG_OBJECT (plot)); /* Add a legend to the chart */ gog_object_add_by_name (GOG_OBJECT (chart), "Legend", NULL); return plot; }
static void graph_setup_title (GogGraph *graph, const gchar *title) { GogLabel *label; GOData *data; GOStyle *style; PangoFontDescription *desc; label = g_object_new(GOG_TYPE_LABEL, NULL); data = go_data_scalar_str_new(title, FALSE); gog_dataset_set_dim(GOG_DATASET(label), 0, data, NULL); gog_object_add_by_name(GOG_OBJECT(graph), "Title", GOG_OBJECT(label)); style = go_styled_object_get_style(GO_STYLED_OBJECT(label)); desc = pango_font_description_from_string("Sans bold 16"); go_style_set_font_desc(style, desc); }
static void gog_tool_move_pie_double_click (GogToolAction *action) { MovePieData *data = action->data; GogPieSeries *series; GogObject *obj; unsigned int index; if (!find_element (action->view, data->x, data->y, action->start_x, action->start_y, &index, &series)) return; obj = GOG_OBJECT (gog_series_get_element (GOG_SERIES (series), index)); if (obj == NULL) { obj = g_object_new (gog_pie_series_element_get_type (), "index", index, NULL); gog_object_add_by_name (GOG_OBJECT (series), "Point", obj); } }
static gboolean analysis_tool_normality_engine_run (data_analysis_output_t *dao, analysis_tools_data_normality_t *info) { guint col; GSList *data = info->base.input; GnmFunc *fd; GnmFunc *fd_if; char const *fdname; char const *testname; char const *n_comment; GogGraph *graph = NULL; GogPlot *plot = NULL; SheetObject *so; switch (info->type) { case normality_test_type_andersondarling: fdname = "ADTEST"; testname = N_("Anderson-Darling Test"); n_comment = N_("For the Anderson-Darling Test\n" "the sample size must be at\n" "least 8."); break; case normality_test_type_cramervonmises: fdname = "CVMTEST"; testname = N_("Cram\xc3\xa9r-von Mises Test"); n_comment = N_("For the Cram\xc3\xa9r-von Mises Test\n" "the sample size must be at\n" "least 8."); break; case normality_test_type_lilliefors: fdname = "LKSTEST"; testname = N_("Lilliefors (Kolmogorov-Smirnov) Test"); n_comment = N_("For the Lilliefors (Kolmogorov-Smirnov) Test\n" "the sample size must be at least 5."); break; case normality_test_type_shapirofrancia: fdname = "SFTEST"; testname = N_("Shapiro-Francia Test"); n_comment = N_("For the Shapiro-Francia Test\n" "the sample size must be at\n" "least 5 and at most 5000."); break; default: g_assert_not_reached(); } fd = gnm_func_lookup_or_add_placeholder (fdname); gnm_func_ref (fd); fd_if = gnm_func_lookup_or_add_placeholder ("IF"); gnm_func_ref (fd_if); dao_set_italic (dao, 0, 0, 0, 5); dao_set_cell (dao, 0, 0, _(testname)); if (info->graph) { GogChart *chart; graph = g_object_new (GOG_TYPE_GRAPH, NULL); chart = GOG_CHART (gog_object_add_by_name ( GOG_OBJECT (graph), "Chart", NULL)); plot = gog_plot_new_by_name ("GogProbabilityPlot"); go_object_set_property (G_OBJECT (plot), "distribution", "Distribution", "GODistNormal", NULL, NULL); gog_object_add_by_name (GOG_OBJECT (chart), "Plot", GOG_OBJECT (plot)); } /* xgettext: * Note to translators: in the following string and others like it, * the "/" is a separator character that can be changed to anything * if the translation needs the slash; just use, say, "|" instead. * * The items are bundled like this to increase translation context. */ set_cell_text_col (dao, 0, 1, _("/Alpha" "/p-Value" "/Statistic" "/N" "/Conclusion")); dao_set_cell_comment (dao, 0, 4, _(n_comment)); for (col = 1; data != NULL; data = data->next, col++) { GnmValue *val_org = value_dup (data->data); /* Note that analysis_tools_write_label may modify val_org */ dao_set_italic (dao, col, 0, col, 0); analysis_tools_write_label (val_org, dao, &info->base, col, 0, col); if (info->graph) { GogSeries *series; series = gog_plot_new_series (plot); gog_series_set_dim (series, 0, gnm_go_data_vector_new_expr (val_org->v_range.cell.a.sheet, gnm_expr_top_new (gnm_expr_new_constant (value_dup (val_org)))), NULL); } if (col == 1) dao_set_cell_float (dao, col, 1, info->alpha); else dao_set_cell_expr (dao, col, 1, make_cellref (1 - col, 0)); dao_set_array_expr (dao, col, 2, 1, 3, gnm_expr_new_funcall1 (fd, gnm_expr_new_constant (val_org))); dao_set_cell_expr (dao, col, 5, gnm_expr_new_funcall3 (fd_if, gnm_expr_new_binary (make_cellref (0, -4), GNM_EXPR_OP_GTE, make_cellref (0, -3)), gnm_expr_new_constant (value_new_string (_("Not normal"))), gnm_expr_new_constant (value_new_string (_("Possibly normal"))))); } if (info->graph) { so = sheet_object_graph_new (graph); g_object_unref (graph); dao_set_sheet_object (dao, 0, 1, so); } gnm_func_unref (fd); gnm_func_unref (fd_if); dao_redraw_respan (dao); return 0; }
int main (int argc, char *argv[]) { GtkWidget *window, *box, *w; GogChart *chart; GogGraph *graph; GogLabel *label; GogPlot *pie; GogSeries *series; GOStyle *style; GOData *data; GError *error; PangoFontDescription *desc; char const *title = "Some statistics"; char const * const legends[] = {"first", "second", "third", "fourth"}; double values[] = {10., 20., 30., 40.}; gtk_init (&argc, &argv); /* Initialize libgoffice */ libgoffice_init (); /* Initialize plugins manager */ go_plugins_init (NULL, NULL, NULL, NULL, TRUE, GO_TYPE_PLUGIN_LOADER_MODULE); window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_resize (GTK_WINDOW (window), 300, 340); gtk_window_set_title (GTK_WINDOW (window), "pie demo"); g_signal_connect (window, "destroy", gtk_main_quit, NULL); box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); w = gtk_button_new_from_stock (GTK_STOCK_QUIT); g_signal_connect_swapped (w, "clicked", G_CALLBACK (on_quit), window); gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 0); w = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_end (GTK_BOX (box), w, FALSE, FALSE, 2); /* Create a graph widget and add it to the GtkVBox */ w = go_graph_widget_new (NULL); gtk_box_pack_end (GTK_BOX (box), w, TRUE, TRUE, 0); /* Get the embedded graph */ graph = go_graph_widget_get_graph (GO_GRAPH_WIDGET (w)); /* Add a title */ label = (GogLabel *) g_object_new (GOG_TYPE_LABEL, NULL); data = go_data_scalar_str_new (title, FALSE); gog_dataset_set_dim (GOG_DATASET (label), 0, data, NULL); gog_object_add_by_name (GOG_OBJECT (graph), "Title", GOG_OBJECT (label)); /* Change the title font */ style = go_styled_object_get_style (GO_STYLED_OBJECT (label)); desc = pango_font_description_from_string ("Sans bold 16"); go_style_set_font_desc (style, desc); /* Get the chart created by the widget initialization */ chart = go_graph_widget_get_chart (GO_GRAPH_WIDGET (w)); /* Create a pie plot and add it to the chart */ pie = (GogPlot *) gog_plot_new_by_name ("GogPiePlot"); gog_object_add_by_name (GOG_OBJECT (chart), "Plot", GOG_OBJECT (pie)); /* Create a series for the plot and populate it with some simple data */ series = gog_plot_new_series (pie); data = go_data_vector_str_new (legends, 4, NULL); gog_series_set_dim (series, 0, data, &error); data = go_data_vector_val_new (values, 4, NULL); gog_series_set_dim (series, 1, data, &error); /* Add a legend to the chart */ gog_object_add_by_name (GOG_OBJECT (chart), "Legend", NULL); gtk_container_add (GTK_CONTAINER (window), box); gtk_widget_show_all (GTK_WIDGET (window)); w = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL); gtk_box_pack_start (GTK_BOX (box), w, FALSE, FALSE, 0); gtk_main (); /* Clean libgoffice stuff */ libgoffice_shutdown (); return 0; }
static gboolean analysis_tool_frequency_engine_run (data_analysis_output_t *dao, analysis_tools_data_frequency_t *info) { gint i_limit, col; GSList *l; GnmFunc *fd_sum; GnmFunc *fd_if; GnmFunc *fd_index; GnmFunc *fd_isblank; GnmFunc *fd_rows = NULL; GnmFunc *fd_columns = NULL; GnmFunc *fd_exact = NULL; fd_sum = gnm_func_lookup_or_add_placeholder ("SUM"); gnm_func_ref (fd_sum); fd_if = gnm_func_lookup_or_add_placeholder ("IF"); gnm_func_ref (fd_if); fd_index = gnm_func_lookup_or_add_placeholder ("INDEX"); gnm_func_ref (fd_index); fd_isblank = gnm_func_lookup_or_add_placeholder ("ISBLANK"); gnm_func_ref (fd_isblank); if (info->exact) { fd_exact = gnm_func_lookup_or_add_placeholder ("EXACT"); gnm_func_ref (fd_exact); } if (info->percentage) { fd_rows = gnm_func_lookup_or_add_placeholder ("ROWS"); gnm_func_ref (fd_rows); fd_columns = gnm_func_lookup_or_add_placeholder ("COLUMNS"); gnm_func_ref (fd_columns); } /* General Info */ dao_set_italic (dao, 0, 0, 0, 1); set_cell_text_col (dao, 0, 0, _("/Frequency Table" "/Category")); /* Setting up the categories */ if (info->predetermined) { int row = 2, i, j, i_h_limit, i_w_limit; GnmExpr const *expr_bin; GnmRange range; range_init_value (&range, info->bin); i_h_limit = range_height (&range); i_w_limit = range_width (&range); i_limit = i_h_limit * i_w_limit; expr_bin = gnm_expr_new_constant (info->bin); for (i = 1; i <= i_h_limit; i++) for (j = 1; j <= i_w_limit; j++) { GnmExpr const *expr_index; expr_index = gnm_expr_new_funcall3 (fd_index, gnm_expr_copy (expr_bin), gnm_expr_new_constant (value_new_int (i)), gnm_expr_new_constant (value_new_int (j))); dao_set_cell_expr (dao, 0, row++, gnm_expr_new_funcall3 (fd_if, gnm_expr_new_funcall1 (fd_isblank, gnm_expr_copy (expr_index)), gnm_expr_new_constant (value_new_string ("")), expr_index)); } gnm_expr_free (expr_bin); } else { i_limit = info->n; } for (l = info->base.input, col = 1; l; col++, l = l->next) { GnmValue *val = value_dup ((GnmValue *)l->data); GnmValue *val_c = NULL; GnmExpr const *expr_count; GnmExpr const *expr_data; GnmExpr const *expr_if; int i, row = 2; dao_set_italic (dao, col, 1, col, 1); if (info->base.labels) { val_c = value_dup (val); switch (info->base.group_by) { case GROUPED_BY_ROW: val->v_range.cell.a.col++; break; default: val->v_range.cell.a.row++; break; } dao_set_cell_expr (dao, col, 1, gnm_expr_new_funcall1 (fd_index, gnm_expr_new_constant (val_c))); } else { char const *format; switch (info->base.group_by) { case GROUPED_BY_ROW: format = _("Row %d"); break; case GROUPED_BY_COL: format = _("Column %d"); break; default: format = _("Area %d"); break; } dao_set_cell_printf (dao, col, 1, format, col); } expr_data = gnm_expr_new_constant (val); if (info->exact) expr_if = gnm_expr_new_funcall2 (fd_exact, gnm_expr_copy (expr_data), make_cellref (- col, 0)); else expr_if = gnm_expr_new_binary (gnm_expr_copy (expr_data), GNM_EXPR_OP_EQUAL, make_cellref (- col, 0)); expr_count = gnm_expr_new_funcall1 (fd_sum, gnm_expr_new_funcall3 (fd_if, expr_if, gnm_expr_new_constant (value_new_int (1)), gnm_expr_new_constant (value_new_int (0)))); if (info->percentage) { dao_set_format (dao, col, 2, col, i_limit + 2, "0.0%"); expr_count = gnm_expr_new_binary (expr_count, GNM_EXPR_OP_DIV, gnm_expr_new_binary (gnm_expr_new_funcall1 (fd_rows, gnm_expr_copy (expr_data)), GNM_EXPR_OP_MULT, gnm_expr_new_funcall1 (fd_columns, expr_data))); } else gnm_expr_free (expr_data); for (i = 0; i < i_limit; i++, row++) dao_set_cell_array_expr (dao, col, row, gnm_expr_copy (expr_count)); gnm_expr_free (expr_count); } gnm_func_unref (fd_if); gnm_func_unref (fd_sum); gnm_func_unref (fd_index); gnm_func_unref (fd_isblank); if (fd_rows != NULL) gnm_func_unref (fd_rows); if (fd_columns != NULL) gnm_func_unref (fd_columns); if (fd_exact != NULL) gnm_func_unref (fd_exact); /* Create Chart if requested */ if (info->chart != NO_CHART) { SheetObject *so; GogGraph *graph; GogChart *chart; GogPlot *plot; GogSeries *series; GOData *cats; GOData *values; int ct; graph = g_object_new (GOG_TYPE_GRAPH, NULL); chart = GOG_CHART (gog_object_add_by_name ( GOG_OBJECT (graph), "Chart", NULL)); plot = gog_plot_new_by_name ("GogBarColPlot"); if (info->chart == BAR_CHART) go_object_toggle (plot, "horizontal"); gog_object_add_by_name (GOG_OBJECT (chart), "Plot", GOG_OBJECT (plot)); cats = dao_go_data_vector (dao, 0, 2, 0, 2 + i_limit); for (ct = 1; ct < col; ct ++) { g_object_ref (cats); values = dao_go_data_vector (dao, ct, 2, ct, 2 + i_limit); series = gog_plot_new_series (plot); gog_series_set_dim (series, 0, cats, NULL); gog_series_set_dim (series, 1, values, NULL); } g_object_unref (cats); so = sheet_object_graph_new (graph); g_object_unref (graph); dao_set_sheet_object (dao, 0, 1, so); } dao_redraw_respan (dao); return FALSE; }
static void gog_chart_view_3d_process (GogView *view, GogViewAllocation *bbox) { /* A XYZ axis set in supposed. If new sets (cylindrical, spherical or other are added, we'll need to change this code */ GogViewAllocation tmp = *bbox; GogAxis *axisX, *axisY, *axisZ, *ref = NULL; GSList *axes; double xmin, xmax, ymin, ymax, zmin, zmax; double o[3], x[3], y[3], z[3], tg, d; Gog3DBox *box; Gog3DBoxView *box_view; GogChart *chart = GOG_CHART (gog_view_get_model (view)); GogObject *obj = gog_object_get_child_by_name (GOG_OBJECT (chart), "3D-Box"); GSList *ptr; GogView *child; GogViewPadding padding; GogAxisMetrics xm, ym, zm; if (!obj) { obj = g_object_new (GOG_3D_BOX_TYPE, NULL); gog_object_add_by_name (GOG_OBJECT (chart), "3D-Box", obj); } box = GOG_3D_BOX (obj); box_view = GOG_3D_BOX_VIEW (gog_view_find_child_view (view, obj)); /* Only use the first of the axes. */ axes = gog_chart_get_axes (chart, GOG_AXIS_X); axisX = GOG_AXIS (axes->data); xm = gog_axis_get_metrics (axisX); if (xm != GOG_AXIS_METRICS_DEFAULT) ref = gog_axis_get_ref_axis (axisX); g_slist_free (axes); gog_axis_get_bounds (axisX, &xmin, &xmax); axes = gog_chart_get_axes (chart, GOG_AXIS_Y); axisY = GOG_AXIS (axes->data); ym = gog_axis_get_metrics (axisY); if (ym != GOG_AXIS_METRICS_DEFAULT && ref == NULL) ref = gog_axis_get_ref_axis (axisY); g_slist_free (axes); gog_axis_get_bounds (axisY, &ymin, &ymax); axes = gog_chart_get_axes (chart, GOG_AXIS_Z); axisZ = GOG_AXIS (axes->data); zm = gog_axis_get_metrics (axisZ); if (zm != GOG_AXIS_METRICS_DEFAULT && ref == NULL) ref = gog_axis_get_ref_axis (axisZ); g_slist_free (axes); gog_axis_get_bounds (axisZ, &zmin, &zmax); /* define the 3d box */ if (ref == NULL) { box_view->dz = tmp.h; if (ymax - ymin > xmax - xmin) { box_view->dy = tmp.w; box_view->dx = (xmax - xmin) / (ymax - ymin) * tmp.w; } else { box_view->dx = tmp.w; box_view->dy = (ymax - ymin) / (xmax - xmin) * tmp.w; } } else { double ref_length, ref_tick_dist, xspan, yspan, zspan; gog_axis_get_bounds (ref, &ref_length, &xspan); ref_length -= xspan; ref_tick_dist = gog_axis_get_major_ticks_distance (ref); xspan = xmax - xmin; if (xm == GOG_AXIS_METRICS_RELATIVE_TICKS) { double ratio, tick_dist = gog_axis_get_major_ticks_distance (axisX); g_object_get (axisX, "metrics-ratio", &ratio, NULL); xspan = (xmax - xmin) / tick_dist * ref_tick_dist * ratio; } yspan = ymax - ymin; if (ym == GOG_AXIS_METRICS_RELATIVE_TICKS) { double ratio, tick_dist = gog_axis_get_major_ticks_distance (axisY); g_object_get (axisY, "metrics-ratio", &ratio, NULL); yspan = (ymax - ymin) / tick_dist * ref_tick_dist * ratio; } zspan = zmax - zmin; if (zm == GOG_AXIS_METRICS_RELATIVE_TICKS) { double ratio, tick_dist = gog_axis_get_major_ticks_distance (axisZ); g_object_get (axisZ, "metrics-ratio", &ratio, NULL); zspan = (zmax - zmin) / tick_dist * ref_tick_dist * ratio; } if (ref == axisZ) { gboolean xrel = FALSE; box_view->dz = tmp.h; switch (xm) { case GOG_AXIS_METRICS_RELATIVE: case GOG_AXIS_METRICS_RELATIVE_TICKS: box_view->dx = xspan / zspan * tmp.h; if (box_view->dx > tmp.w) { box_view->dz *= tmp.w / box_view->dx; box_view->dx = tmp.w; } xrel = TRUE; break; default: box_view->dx = tmp.w; break; } switch (ym) { case GOG_AXIS_METRICS_RELATIVE: case GOG_AXIS_METRICS_RELATIVE_TICKS: box_view->dy = yspan / zspan * box_view->dz; if (box_view->dy > tmp.w) { box_view->dz *= tmp.w / box_view->dy; if (xrel) box_view->dx *= tmp.w / box_view->dy; box_view->dy = tmp.w; } break; default: box_view->dy = tmp.w; break; } } else { if (yspan > xspan) { box_view->dy = tmp.w; box_view->dx = xspan / yspan * tmp.w; } else { box_view->dx = tmp.w; box_view->dy = yspan / xspan * tmp.w; } if (zm == GOG_AXIS_METRICS_DEFAULT) box_view->dz = tmp.h; else box_view->dz = (ref == axisX)? zspan / xspan * box_view->dx: zspan / yspan * box_view->dy; } } /* now compute the position of each vertex, ignoring the fov */ go_matrix3x3_transform (&box->mat, -box_view->dx, -box_view->dy, -box_view->dz, o, o + 1, o + 2); go_matrix3x3_transform (&box->mat, box_view->dx, -box_view->dy, -box_view->dz, x, x + 1, x + 2); go_matrix3x3_transform (&box->mat, -box_view->dx, box_view->dy, -box_view->dz, y, y + 1, y + 2); go_matrix3x3_transform (&box->mat, -box_view->dx, -box_view->dy, box_view->dz, z, z + 1, z + 2); /* for each diagonal, we need to take the vertex closer to the view point */ if (o[1] > 0) { o[0] = -o[0]; o[1] = -o[1]; o[2] = -o[2]; } if (x[1] > 0) { x[0] = -x[0]; x[1] = -x[1]; x[2] = -x[2]; } if (y[1] > 0) { y[0] = -y[0]; y[1] = -y[1]; y[2] = -y[2]; } if (z[1] > 0) { z[0] = -z[0]; z[1] = -z[1]; z[2] = -z[2]; } /* if the fov is positive, calculate the position of the viewpoint */ if (box->fov > 0.) { tg = tan (box->fov / 2.); box_view->r = -sqrt (o[0] * o[0] + o[2] * o[2]) / tg + o[1]; d = -sqrt (x[0] * x[0] + x[2] * x[2]) / tg + x[1]; if (d < box_view->r) box_view->r = d; d = -sqrt (y[0] * y[0] + y[2] * y[2]) / tg + y[1]; if (d < box_view->r) box_view->r = d; d = -sqrt (z[0] *z[0] + z[2] * z[2]) / tg + z[1]; if (d < box_view->r) box_view->r = d; /* also calculate the reduction factor we need to make things fit in the bbox */ xmax = fabs (o[0]) / (1. - o[1] / box_view->r); zmax = fabs (o[2]) / (1. - o[1] / box_view->r); d = fabs (x[0]) / (1. - x[1] / box_view->r); if (d > xmax) xmax = d; d = fabs (x[2]) / (1. - x[1] / box_view->r); if (d > zmax) zmax = d; d = fabs (y[0]) / (1. - y[1] / box_view->r); if (d > xmax) xmax = d; d = fabs (y[2]) / (1. - y[1] / box_view->r); if (d > zmax) zmax = d; d = fabs (z[0]) / (1. - z[1] / box_view->r); if (d > xmax) xmax = d; d = fabs (z[2]) / (1. - z[1] / box_view->r); if (d > zmax) zmax = d; } else { /* calculate the reduction factor we need to make things fit in the bbox */ xmax = fabs (o[0]); zmax = fabs (o[2]); d = fabs (x[0]); if (d > xmax) xmax = d; d = fabs (x[2]); if (d > zmax) zmax = d; d = fabs (y[0]); if (d > xmax) xmax = d; d = fabs (y[2]); if (d > zmax) zmax = d; d = fabs (z[0]); if (d > xmax) xmax = d; d = fabs (z[2]); if (d > zmax) zmax = d; } /* use d and tg as x and z ratios, respectively */ d = xmax / tmp.w; tg = zmax / tmp.h; box_view->ratio = (d > tg)? d: tg; gog_view_padding_request (view, bbox, &padding); if (!chart->is_plot_area_manual) { bbox->x += padding.wl; bbox->w -= padding.wl + padding.wr; bbox->y += padding.ht; bbox->h -= padding.ht + padding.hb; } else { tmp.x -= padding.wl; tmp.w += padding.wl + padding.wr; tmp.y -= padding.ht; tmp.h += padding.ht + padding.hb; } /* Recalculating ratio */ d = xmax / bbox->w; tg = zmax / bbox->h; box_view->ratio = (d > tg)? d: tg; for (ptr = view->children; ptr != NULL ; ptr = ptr->next) { child = ptr->data; if (GOG_POSITION_IS_PADDING (child->model->position)) { gog_view_size_allocate (child, &tmp); } } /* by default, overlay all GOG_POSITION_SPECIAL children in residual */ for (ptr = view->children; ptr != NULL ; ptr = ptr->next) { child = ptr->data; if (GOG_POSITION_IS_SPECIAL (child->model->position)) gog_view_size_allocate (child, bbox); } }