static void role_grid_pre_remove (GogObject *parent, GogObject *grid) { GogChart *chart = GOG_CHART (parent); g_return_if_fail (chart->grid == grid); chart->grid = NULL; }
static void role_grid_post_add (GogObject *parent, GogObject *child) { GogChart *chart = GOG_CHART (parent); g_return_if_fail (chart->grid == NULL); chart->grid = child; }
static gboolean axis_can_add (GogObject const *parent, GogAxisType t) { GogChart *chart = GOG_CHART (parent); if (chart->axis_set == GOG_AXIS_SET_UNKNOWN || chart->axis_set == GOG_AXIS_SET_XYZ) return FALSE; return (chart->axis_set & (1 << t)) != 0; }
static void axis_post_add (GogObject *axis, GogAxisType t) { GogChart *chart = GOG_CHART (axis->parent); g_object_set (G_OBJECT (axis), "type", (int)t, NULL); chart->axes = g_slist_prepend (chart->axes, axis); gog_axis_base_set_position (GOG_AXIS_BASE (axis), GOG_AXIS_AUTO); }
static void color_scale_pre_remove (GogObject *parent, GogObject *scale) { /* Unlink the color scale */ GSList const *l = gog_axis_contributors (gog_color_scale_get_axis (GOG_COLOR_SCALE (scale))); gog_color_scale_set_axis (GOG_COLOR_SCALE (scale), NULL); for (; l; l = l->next) gog_object_request_update (GOG_OBJECT (l->data)); gog_chart_request_cardinality_update (GOG_CHART (parent)); }
static void gog_chart_view_size_allocate (GogView *view, GogViewAllocation const *bbox) { GSList *ptr; GogView *child; GogChartView *chart_view = GOG_CHART_VIEW (view); GogViewAllocation tmp, *plot_area = &chart_view->plot_area; GogViewPadding padding; GogChart *chart = GOG_CHART (gog_view_get_model (view)); (cview_parent_klass->size_allocate) (view, bbox); if (chart->is_plot_area_manual) { plot_area->x = bbox->x + chart->plot_area.x * bbox->w; plot_area->y = bbox->y + chart->plot_area.y * bbox->h; plot_area->w = chart->plot_area.w * bbox->w; plot_area->h = chart->plot_area.h * bbox->h; } else *plot_area = view->residual; /* special treatment for 3d charts */ if (gog_chart_is_3d (chart)) { gog_chart_view_3d_process (view, plot_area); return; } tmp = *plot_area; gog_view_padding_request (view, plot_area, &padding); if (!chart->is_plot_area_manual) { plot_area->x += padding.wl; plot_area->w -= padding.wl + padding.wr; plot_area->y += padding.ht; plot_area->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; } 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, plot_area); } }
static void axis_pre_remove (GogObject *parent, GogObject *child) { GogChart *chart = GOG_CHART (parent); GogAxis *axis = GOG_AXIS (child); GogColorScale *scale = gog_axis_get_color_scale (axis); if (scale) gog_color_scale_set_axis (scale, NULL); gog_axis_clear_contributors (GOG_AXIS (axis)); chart->axes = g_slist_remove (chart->axes, axis); }
static void gog_chart_view_render (GogView *view, GogViewAllocation const *bbox) { GSList *ptr; GogView *child_view; gboolean grid_line_rendered = FALSE; GogChart *chart = GOG_CHART (gog_view_get_model (view)); cview_parent_klass->render (view, bbox); if (gog_chart_is_3d (chart)) { for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) { child_view = ptr->data; if (!GOG_IS_AXIS (child_view->model) && !GOG_IS_PLOT (child_view->model) && !GOG_IS_LABEL (child_view->model)) gog_view_render (ptr->data, bbox); } /* now render plot and axes */ for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) { child_view = ptr->data; if (!GOG_IS_AXIS (child_view->model)) continue; gog_view_render (ptr->data, bbox); grid_line_render (ptr, bbox); } for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) { child_view = ptr->data; if (!GOG_IS_PLOT (child_view->model)) continue; gog_view_render (ptr->data, bbox); } } else { /* KLUDGE: render grid lines before axis */ for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) { child_view = ptr->data; if (!grid_line_rendered && GOG_IS_AXIS (child_view->model)) { plot_render (view, bbox, GOG_PLOT_RENDERING_BEFORE_GRID); grid_line_render (ptr, bbox); plot_render (view, bbox, GOG_PLOT_RENDERING_BEFORE_AXIS); grid_line_rendered = TRUE; } if (GOG_IS_PLOT (child_view->model)) { if (!GOG_PLOT (child_view->model)->rendering_order) gog_view_render (ptr->data, bbox); } else if (!GOG_IS_LABEL (child_view->model)) gog_view_render (ptr->data, bbox); } } for (ptr = view->children ; ptr != NULL ; ptr = ptr->next) { child_view = ptr->data; if (!GOG_IS_LABEL (child_view->model)) continue; gog_view_render (ptr->data, bbox); } }
static void gog_chart_finalize (GObject *obj) { GogChart *chart = GOG_CHART (obj); /* on exit the role remove routines are not called */ g_slist_free (chart->plots); g_slist_free (chart->axes); (chart_parent_klass->finalize) (obj); }
static gboolean role_grid_can_add (GogObject const *parent) { GogChart const *chart = GOG_CHART (parent); return chart->grid == NULL && (chart->axis_set == GOG_AXIS_SET_XY || chart->axis_set == GOG_AXIS_SET_X || chart->axis_set == GOG_AXIS_SET_XY_pseudo_3d || chart->axis_set == GOG_AXIS_SET_XY_COLOR || chart->axis_set == GOG_AXIS_SET_RADAR); }
static void gog_chart_update (GogObject *obj) { GogChart *chart = GOG_CHART (obj); unsigned full = chart->full_cardinality; unsigned visible = chart->visible_cardinality; gog_chart_get_cardinality (chart, NULL, NULL); if (full != chart->full_cardinality || visible != chart->visible_cardinality) g_object_notify (G_OBJECT (chart), "cardinality-valid"); }
static void gog_chart_set_property (GObject *obj, guint param_id, GValue const *value, GParamSpec *pspec) { GogChart *chart = GOG_CHART (obj); char **str_doubles; char const *str; gboolean changed = FALSE; switch (param_id) { case CHART_PROP_PLOT_AREA: str = g_value_get_string (value); str_doubles = g_strsplit (str, " ", 4); if (g_strv_length (str_doubles) != 4) { g_strfreev (str_doubles); break; } chart->plot_area.x = g_ascii_strtod (str_doubles[0], NULL); chart->plot_area.y = g_ascii_strtod (str_doubles[1], NULL); chart->plot_area.w = g_ascii_strtod (str_doubles[2], NULL); chart->plot_area.h = g_ascii_strtod (str_doubles[3], NULL); g_strfreev (str_doubles); break; case CHART_PROP_PLOT_AREA_IS_MANUAL: chart->is_plot_area_manual = g_value_get_boolean (value); break; case CHART_PROP_X_POS: chart->x_pos = g_value_get_int (value); changed = TRUE; break; case CHART_PROP_Y_POS: chart->y_pos = g_value_get_int (value); changed = TRUE; break; case CHART_PROP_COLUMNS: chart->cols = g_value_get_int (value); changed = TRUE; break; case CHART_PROP_ROWS: chart->rows = g_value_get_int (value); changed = TRUE; break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec); return; /* NOTE : RETURN */ } if (changed) { gog_graph_validate_chart_layout (GOG_GRAPH (GOG_OBJECT (chart)->parent)); gog_object_emit_changed (GOG_OBJECT (obj), TRUE); } }
static void gog_chart_children_reordered (GogObject *obj) { GSList *ptr, *accum = NULL; GogChart *chart = GOG_CHART (obj); for (ptr = obj->children; ptr != NULL ; ptr = ptr->next) if (GOG_IS_PLOT (ptr->data)) accum = g_slist_prepend (accum, ptr->data); g_slist_free (chart->plots); chart->plots = g_slist_reverse (accum); gog_chart_request_cardinality_update (chart); }
/** * gog_chart_get_position: * @chart: const #GogChart * @x: * @y: * @cols: * @rows: * * Returns: TRUE if the chart has been positioned. **/ gboolean gog_chart_get_position (GogChart const *chart, unsigned *x, unsigned *y, unsigned *cols, unsigned *rows) { g_return_val_if_fail (GOG_CHART (chart), FALSE); if (chart->cols <= 0 || chart->rows <= 0) return FALSE; if (x != NULL) *x = chart->x_pos; if (y != NULL) *y = chart->y_pos; if (cols != NULL) *cols = chart->cols; if (rows != NULL) *rows = chart->rows; return TRUE; }
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 gog_chart_get_property (GObject *obj, guint param_id, GValue *value, GParamSpec *pspec) { GogChart *chart = GOG_CHART (obj); GString *string; char buffer[G_ASCII_DTOSTR_BUF_SIZE]; switch (param_id) { case CHART_PROP_CARDINALITY_VALID: g_value_set_boolean (value, chart->cardinality_valid); break; case CHART_PROP_PLOT_AREA: string = g_string_new (""); g_string_append (string, g_ascii_dtostr (buffer, sizeof (buffer), chart->plot_area.x)); g_string_append_c (string, ' '); g_string_append (string, g_ascii_dtostr (buffer, sizeof (buffer), chart->plot_area.y)); g_string_append_c (string, ' '); g_string_append (string, g_ascii_dtostr (buffer, sizeof (buffer), chart->plot_area.w)); g_string_append_c (string, ' '); g_string_append (string, g_ascii_dtostr (buffer, sizeof (buffer), chart->plot_area.h)); g_value_set_string (value, string->str); g_string_free (string, TRUE); break; case CHART_PROP_PLOT_AREA_IS_MANUAL: g_value_set_boolean (value, chart->is_plot_area_manual); break; case CHART_PROP_X_POS: g_value_set_int (value, chart->x_pos); break; case CHART_PROP_Y_POS: g_value_set_int (value, chart->y_pos); break; case CHART_PROP_COLUMNS: g_value_set_int (value, chart->cols); break; case CHART_PROP_ROWS: g_value_set_int (value, chart->rows); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (obj, param_id, pspec); break; } }
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); }
/* Color scale related code */ static gboolean color_scale_can_add (GogObject const *parent) { /* TRUE if there are more color or pseudo-3d axes than there are color scales */ GogChart *chart = GOG_CHART (parent); GSList *ptr; GogAxis *axis; GogAxisType type; if ((chart->axis_set & ((1 << GOG_AXIS_COLOR) | (1 << GOG_AXIS_PSEUDO_3D ))) == 0) return FALSE; for (ptr = chart->axes; ptr && ptr->data; ptr = ptr->next) { axis = GOG_AXIS (ptr->data); type = gog_axis_get_atype (axis); if ((type == GOG_AXIS_COLOR || type == GOG_AXIS_PSEUDO_3D) && gog_axis_get_color_scale (axis) == NULL) return TRUE; } return FALSE; }
static void role_plot_pre_remove (GogObject *parent, GogObject *plot) { GogChart *chart = GOG_CHART (parent); gog_plot_axis_clear (GOG_PLOT (plot), GOG_AXIS_SET_ALL); chart->plots = g_slist_remove (chart->plots, plot); gog_chart_request_cardinality_update (chart); if (chart->plots == NULL) gog_chart_axis_set_assign (chart, GOG_AXIS_SET_UNKNOWN); if (chart->grid != NULL && chart->axis_set != GOG_AXIS_SET_XY && chart->axis_set != GOG_AXIS_SET_X && chart->axis_set != GOG_AXIS_SET_XY_pseudo_3d && chart->axis_set != GOG_AXIS_SET_XY_COLOR && chart->axis_set != GOG_AXIS_SET_RADAR) { GogObject *grid = chart->grid; /* clear_parent clears ::grid */ gog_object_clear_parent (GOG_OBJECT (grid)); g_object_unref (grid); } }
static void color_scale_post_add (GogObject *parent, GogObject *child) { /* Link the color scale to an axis without a preexisting color scale */ GogChart *chart = GOG_CHART (parent); GSList *ptr; GogAxis *axis; GogAxisType type; GSList const *l; for (ptr = chart->axes; ptr && ptr->data; ptr = ptr->next) { axis = GOG_AXIS (ptr->data); type = gog_axis_get_atype (axis); if ((type == GOG_AXIS_COLOR || type == GOG_AXIS_PSEUDO_3D) && gog_axis_get_color_scale (axis) == NULL) { gog_color_scale_set_axis (GOG_COLOR_SCALE (child), axis); for (l = gog_axis_contributors (axis); l; l = l->next) gog_object_request_update (GOG_OBJECT (l->data)); break; } } gog_chart_request_cardinality_update (chart); }
static void gog_smoothed_curve_view_render (GogView *view, GogViewAllocation const *bbox) { GogSmoothedCurve *curve = GOG_SMOOTHED_CURVE (view->model); GogSeries *series = GOG_SERIES ((GOG_OBJECT (curve))->parent); GogPlot *plot = series->plot; GogChart *chart = GOG_CHART (GOG_OBJECT (plot)->parent); GogChartMap *chart_map; GOStyle *style; GOPath *path; if (curve->nb == 0 || curve->x == NULL || curve->y == NULL) return; chart_map = gog_chart_map_new (chart, &view->residual, plot->axis[GOG_AXIS_X], plot->axis[GOG_AXIS_Y], NULL, FALSE); if (!gog_chart_map_is_valid (chart_map)) { gog_chart_map_free (chart_map); return; } gog_renderer_push_clip_rectangle (view->renderer, view->residual.x, view->residual.y, view->residual.w, view->residual.h); path = gog_chart_map_make_path (chart_map, curve->x, curve->y, curve->nb, GO_LINE_INTERPOLATION_LINEAR, FALSE, NULL); style = GOG_STYLED_OBJECT (curve)->style; gog_renderer_push_style (view->renderer, style); gog_renderer_stroke_serie (view->renderer, path); gog_renderer_pop_style (view->renderer); go_path_free (path); gog_renderer_pop_clip (view->renderer); gog_chart_map_free (chart_map); }
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; }
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_populate_editor (GogObject *gobj, GOEditor *editor, G_GNUC_UNUSED GogDataAllocator *dalloc, GOCmdContext *cc) { static guint chart_pref_page = 0; GtkBuilder *gui; PlotAreaPrefState *state; gboolean is_plot_area_manual; GogViewAllocation plot_area; GtkWidget *w; GogChart *chart = GOG_CHART (gobj); g_return_if_fail (chart != NULL); gui = go_gtk_builder_load_internal ("res:go:graph/gog-plot-prefs.ui", GETTEXT_PACKAGE, cc); g_return_if_fail (gui != NULL); (GOG_OBJECT_CLASS(chart_parent_klass)->populate_editor) (gobj, editor, dalloc, cc); state = g_new (PlotAreaPrefState, 1); state->chart = chart; state->gui = gui; g_object_ref (chart); is_plot_area_manual = gog_chart_get_plot_area (chart, &plot_area); state->x_spin = go_gtk_builder_get_widget (gui, "x_spin"); gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->x_spin), plot_area.x * 100.0); g_signal_connect (G_OBJECT (state->x_spin), "value-changed", G_CALLBACK (cb_plot_area_changed), state); state->y_spin = go_gtk_builder_get_widget (gui, "y_spin"); gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->y_spin), plot_area.y * 100.0); g_signal_connect (G_OBJECT (state->y_spin), "value-changed", G_CALLBACK (cb_plot_area_changed), state); state->w_spin = go_gtk_builder_get_widget (gui, "w_spin"); gtk_spin_button_set_range (GTK_SPIN_BUTTON (state->w_spin), 0.0, (1.0 - plot_area.x) * 100.0); gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->w_spin), 100.0 * plot_area.w); state->w_spin_signal = g_signal_connect (G_OBJECT (state->w_spin), "value-changed", G_CALLBACK (cb_plot_area_changed), state); state->h_spin = go_gtk_builder_get_widget (gui, "h_spin"); gtk_spin_button_set_range (GTK_SPIN_BUTTON (state->h_spin), 0.0, (1.0 - plot_area.y) * 100.0); gtk_spin_button_set_value (GTK_SPIN_BUTTON (state->h_spin), 100.0 * plot_area.h); state->h_spin_signal = g_signal_connect (G_OBJECT (state->h_spin), "value-changed", G_CALLBACK (cb_plot_area_changed), state); state->position_select_combo = go_gtk_builder_get_widget (gui, "position_select_combo"); gtk_combo_box_set_active (GTK_COMBO_BOX (state->position_select_combo), is_plot_area_manual ? 1 : 0); state->manual_setting_grid = go_gtk_builder_get_widget (gui, "manual-setting-grid"); if (!is_plot_area_manual) gtk_widget_hide (state->manual_setting_grid); g_signal_connect (G_OBJECT (state->position_select_combo), "changed", G_CALLBACK (cb_manual_position_changed), state); w = go_gtk_builder_get_widget (gui, "gog-plot-prefs"); g_signal_connect_swapped (G_OBJECT (w), "destroy", G_CALLBACK (plot_area_pref_state_free), state); go_editor_add_page (editor, w, _("Plot area")); go_editor_set_store_page (editor, &chart_pref_page); }
static gboolean zx_grid_3d_can_add (GogObject const *parent) { return (GOG_CHART (parent)->axis_set == GOG_AXIS_SET_XYZ && NULL == gog_object_get_child_by_name (parent, "ZX-Backplane")); }
static gboolean role_plot_can_add (GogObject const *parent) { GogChart *chart = GOG_CHART (parent); return (chart->axis_set & (1 << GOG_AXIS_Z)) == 0 || g_slist_length (chart->plots) == 0; }
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); } }