From 1a931b14bd0cb2b524e97b2e8eec59bf7dc5268a Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 26 Jul 2019 15:40:04 -0700 Subject: [PATCH] custom category update and fix fix issues in basic mapping: 1. make sure custom breaks works when no active map window 2. custom breaks editor: make sure all combobox works when changing values 3. make sure the fixed natural breaks #1829 in custom category applies to all other maps --- DialogTools/CatClassifDlg.cpp | 290 ++++++++++++++++++----------- DialogTools/CatClassifDlg.h | 8 +- Explore/CatClassification.cpp | 337 ++++++++++++++++++++++------------ GeoDa.cpp | 9 +- 4 files changed, 410 insertions(+), 234 deletions(-) diff --git a/DialogTools/CatClassifDlg.cpp b/DialogTools/CatClassifDlg.cpp index 61f8fbe4d..bb1963be2 100644 --- a/DialogTools/CatClassifDlg.cpp +++ b/DialogTools/CatClassifDlg.cpp @@ -326,9 +326,11 @@ void CatClassifHistCanvas::GetBarPositions(std::vector& x_center_pos, st x_right = val_range==0 ? 0 : x_max * (ticks[i+1] - left) / val_range; if (x_left == x_right && ival_obs_cnt[i] > 0 && j>0) { - for (int k=j-1; k>=0; k--) - if (x_left_pos[k] != x_left) + for (int k=j-1; k>=0; k--) { + if (x_left_pos[k] != x_left) { x_left = x_left_pos[j]; + } + } } } x_left_pos[j] = x_left; @@ -370,16 +372,13 @@ void CatClassifHistCanvas::PopulateCanvas() double y_max = max_num_obs_in_ival; last_scale_trans.SetData(x_min, 0, x_max, max_num_obs_in_ival); - - - axis_scale_y = AxisScale(0, y_max, 5, axis_display_precision, + axis_scale_y = AxisScale(0, y_max, 5, axis_display_precision, axis_display_fixed_point); y_max = axis_scale_y.scale_max; y_axis = new GdaAxis(_("Frequency"), axis_scale_y, wxRealPoint(0,0), wxRealPoint(0, y_max), -9, 0); foreground_shps.push_back(y_axis); - selectable_shps.resize(cur_intervals); wxClientDC dc(this); @@ -459,46 +458,63 @@ void CatClassifHistCanvas::InitIntervals() ival_obs_cnt[0] = num_obs; ival_obs_sel_cnt[0] = highlight_state->GetTotalHighlighted(); } else { - int num_breaks = breaks->size(); - int num_breaks_lower = (num_breaks+1)/2; - - double val; - int ind; - + double val; + int ind; + int num_breaks = breaks->size(); + // get max, min values max_val = (*data)[0].first; min_val = (*data)[num_obs-1].first; - - for (int i=0; i max_val) - max_val = val; - if (val < min_val) - min_val = val; - - bool found = false; - int cat = num_breaks; // last cat by default - for (int j=0; j max_val) max_val = val; + if (val < min_val) min_val = val; + } + if (break_type == CatClassification::natural_breaks_break_vals) { + int cat = 0; + double brk_val = (*breaks)[0]; + for (int j=0; j= brk_val) { + cat += 1; + brk_val = (*breaks)[cat]; + } + // at this point we know that index ind belongs to category cat + ind = (*data)[j].second; + obs_id_to_ival[ind] = cat; + ival_to_obs_ids[cat].push_front(ind); + ival_obs_cnt[cat]++; + if (hs[ind]) ival_obs_sel_cnt[cat]++; + } + } else { + int num_breaks_lower = (num_breaks+1)/2; + for (int i=0; i* new_breaks, std::vector* new_colors) { data = new_data; + break_type = new_break_type; breaks = new_breaks; colors = new_colors; cur_intervals = breaks->size() + 1; @@ -591,31 +609,44 @@ void CatClassifHistCanvas::UpdateStatusBar() int ival = hover_obs[0]; wxString s; s << "bin: " << ival+1 << ", range: "; - if (cur_intervals <= 1) { - s << "(-inf, inf)"; - } else if (ival == 0) { - s << "(-inf, " << (*breaks)[ival] << ")"; - } else if (ival == cur_intervals-1 && cur_intervals != 2) { - s << "(" << (*breaks)[ival-1] << ", inf)"; - } else if (ival == cur_intervals-1 && cur_intervals == 2) { - s << "[" << (*breaks)[ival-1] << ", inf)"; - } else { - int num_breaks = cur_intervals-1; - int num_breaks_lower = (num_breaks+1)/2; - wxString a; - wxString b; - if (ival < num_breaks_lower) { - a = "["; - b = ")"; - } else if (ival == num_breaks_lower) { - a = "["; - b = "]"; - } else { - a = "("; - b = "]"; - } - s << a << (*breaks)[ival-1] << ", " << (*breaks)[ival] << b; - } + + if (break_type == CatClassification::natural_breaks_break_vals) { + if (cur_intervals <= 1) { + s << "(-inf, inf)"; + } else if (ival == 0) { + s << "(-inf, " << (*breaks)[ival] << ")"; + } else if (ival == cur_intervals-1) { + s << "[" << (*breaks)[ival-1] << ", inf)"; + } else { + s << "[" << (*breaks)[ival-1] << ", " << (*breaks)[ival] << ")"; + } + } else { + if (cur_intervals <= 1) { + s << "(-inf, inf)"; + } else if (ival == 0) { + s << "(-inf, " << (*breaks)[ival] << ")"; + } else if (ival == cur_intervals-1 && cur_intervals != 2) { + s << "(" << (*breaks)[ival-1] << ", inf)"; + } else if (ival == cur_intervals-1 && cur_intervals == 2) { + s << "[" << (*breaks)[ival-1] << ", inf)"; + } else { + int num_breaks = cur_intervals-1; + int num_breaks_lower = (num_breaks+1)/2; + wxString a; + wxString b; + if (ival < num_breaks_lower) { + a = "["; + b = ")"; + } else if (ival == num_breaks_lower) { + a = "["; + b = "]"; + } else { + a = "("; + b = "]"; + } + s << a << (*breaks)[ival-1] << ", " << (*breaks)[ival] << b; + } + } s << ", "; s << _("#obs") << ": " << ival_obs_cnt[ival]; double p = 100.0*((double) ival_obs_cnt[ival])/((double) num_obs); @@ -698,7 +729,7 @@ useScientificNotation(_useScientificNotation) cc_data.uniform_dist_min, cc_data.uniform_dist_max); cc_data.cat_classif_type = CatClassification::custom; - cc_data.break_vals_type = CatClassification::custom_break_vals; + cc_data.break_vals_type = CatClassification::quantile_break_vals; cc_data.color_scheme = CatClassification::diverging_color_scheme; CatClassification::ChangeNumCats(default_intervals, cc_data); @@ -858,10 +889,10 @@ useScientificNotation(_useScientificNotation) if (cc_state) { cc_data = cc_state->GetCatClassif(); SetSyncVars(true); - + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; InitFromCCData(); EnableControls(true); @@ -929,10 +960,12 @@ CatClassifState* CatClassifPanel::PromptNew(const CatClassifDef& ccd, if (cc_data.cat_classif_type == CatClassification::no_theme) { CatClassification::CatClassifTypeToBreakValsType(cc_data.cat_classif_type); - cc_data.cat_classif_type = CatClassification::custom; + + cc_data.cat_classif_type = GetClassifyType(); cc_data.break_vals_type = CatClassification::quantile_break_vals; CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); + cc_data.cat_classif_type = CatClassification::custom; // CorrectCatClassifFromTable() will change the break_vals_type // to custom_break_vals, and will impact the "Breaks" contrl cc_data.break_vals_type = CatClassification::quantile_break_vals; @@ -961,9 +994,11 @@ CatClassifState* CatClassifPanel::PromptNew(const CatClassifDef& ccd, EnableControls(true); return cc_state; + } else { + wxCommandEvent ev; + OnBreaksChoice(ev); + return NULL; } - - return NULL; } /** A new Custom Category was selected. Copy cc_data from cc_state and @@ -983,9 +1018,10 @@ void CatClassifPanel::OnCurCatsChoice(wxCommandEvent& event) // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; InitFromCCData(); UpdateCCState(); EnableControls(true); @@ -1014,9 +1050,9 @@ void CatClassifPanel::OnBreaksChoice(wxCommandEvent& event) // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - // always mark the custom breaks CatClassification::custom cc_data.cat_classif_type = CatClassification::custom; cc_data.break_vals_type = bv_type; InitFromCCData(); @@ -1053,16 +1089,27 @@ void CatClassifPanel::OnColorSchemeChoice(wxCommandEvent& event) } } - - // Verify that cc data is self-consistent and correct if not. This - // will result in all breaks, colors and names being initialized. - CatClassification::CorrectCatClassifFromTable(cc_data, table_int, - IsAutomaticLabels()); - InitFromCCData(); UpdateCCState(); } +CatClassification::CatClassifType CatClassifPanel::GetClassifyType() +{ + // Get classifytype from the breaks dropdown control + CatClassification::BreakValsType new_cat_typ = GetBreakValsTypeChoice(); + if (new_cat_typ == CatClassification::quantile_break_vals) { + return CatClassification::quantile; + } else if (new_cat_typ == CatClassification::unique_values_break_vals) { + return CatClassification::unique_values; + } else if (new_cat_typ == CatClassification::natural_breaks_break_vals) { + return CatClassification::natural_breaks; + } else if (new_cat_typ == CatClassification::equal_intervals_break_vals) { + return CatClassification::equal_intervals; + } else { + return CatClassification::custom; + } +} + void CatClassifPanel::OnNumCatsChoice(wxCommandEvent& event) { wxLogMessage("CatClassifPanel::OnNumCatsChoice"); @@ -1112,8 +1159,10 @@ void CatClassifPanel::OnNumCatsChoice(wxCommandEvent& event) cc_data.num_cats = new_num_cats; // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); + cc_data.cat_classif_type = CatClassification::custom; // check if breaks have same values std::set brks; for (int i=0; iSetSelection(old_breaks_choice); - hist_canvas->ChangeAll(&preview_data, &cc_data.breaks, &cc_data.colors); + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, &cc_data.breaks, &cc_data.colors); } void CatClassifPanel::OnAssocVarChoice(wxCommandEvent& ev) @@ -1154,9 +1203,10 @@ void CatClassifPanel::OnAssocVarChoice(wxCommandEvent& ev) // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; InitFromCCData(); UpdateCCState(); } @@ -1171,9 +1221,10 @@ void CatClassifPanel::OnAssocVarTmChoice(wxCommandEvent& ev) // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; InitFromCCData(); UpdateCCState(); } @@ -1226,7 +1277,7 @@ void CatClassifPanel::OnPreviewVarChoice(wxCommandEvent& ev) } CatClassifHistCanvas::InitUniformData(preview_data, prev_min, prev_max); } - hist_canvas->ChangeAll(&preview_data, + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, &cc_data.breaks, &cc_data.colors); Refresh(); } @@ -1248,7 +1299,7 @@ void CatClassifPanel::OnPreviewVarTmChoice(wxCommandEvent& ev) preview_data[i].first = dd[i]; preview_data[i].second = i; } - hist_canvas->ChangeAll(&preview_data, + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, &cc_data.breaks, &cc_data.colors); Refresh(); } @@ -1294,9 +1345,10 @@ void CatClassifPanel::OnUnifDistMinEnter(wxCommandEvent& event) // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; InitFromCCData(); UpdateCCState(); } @@ -1347,9 +1399,10 @@ void CatClassifPanel::OnUnifDistMaxEnter(wxCommandEvent& event) // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; InitFromCCData(); UpdateCCState(); } @@ -1438,8 +1491,8 @@ void CatClassifPanel::OnBrkTxtEnter(wxCommandEvent& event) SetUnifDistMinMaxTxt(cc_data.uniform_dist_min, cc_data.uniform_dist_max); UpdateCCState(); - hist_canvas->ChangeAll(&preview_data, &cc_data.breaks, - &cc_data.colors); + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, + &cc_data.breaks, &cc_data.colors); SetSliderFromBreak(nbrk); } } else { @@ -1471,7 +1524,8 @@ void CatClassifPanel::OnBrkSlider(wxCommandEvent& event) cc_data.cat_classif_type = CatClassification::custom; SetBrkTxtFromVec(cc_data.breaks); SetActiveBrkRadio(nbrk); - hist_canvas->ChangeAll(&preview_data, &cc_data.breaks, &cc_data.colors); + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, + &cc_data.breaks, &cc_data.colors); for (int i=0; iSetBackgroundColour(cc_data.colors[i]); @@ -1506,8 +1560,8 @@ void CatClassifPanel::OnKillFocusEvent(wxFocusEvent& event) cc_data); SetBrkTxtFromVec(cc_data.breaks); SetActiveBrkRadio(nbrk); - hist_canvas->ChangeAll(&preview_data, &cc_data.breaks, - &cc_data.colors); + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, + &cc_data.breaks, &cc_data.colors); max_lbl->SetLabelText(GenUtils::DblToStr(GetBrkSliderMin())); SetSliderFromBreak(nbrk); UpdateCCState(); @@ -1565,7 +1619,8 @@ void CatClassifPanel::OnCategoryColorButton(wxMouseEvent& event) cc_data.colors[obj_id] = retData.GetColour(); cat_color_button[obj_id]->SetBackgroundColour(retData.GetColour()); UpdateCCState(); - hist_canvas->ChangeAll(&preview_data, &cc_data.breaks, &cc_data.colors); + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, + &cc_data.breaks, &cc_data.colors); Refresh(); } @@ -1649,18 +1704,23 @@ void CatClassifPanel::OnButtonNew(wxCommandEvent& event) cur_cats_choice->Append(new_title); cur_cats_choice->SetSelection(cur_cats_choice->GetCount()-1); SetSyncVars(true); - + // Verify that cc data is self-consistent and correct if not. This // will result in all breaks, colors and names being initialized. + cc_data.cat_classif_type = GetClassifyType(); CatClassification::CorrectCatClassifFromTable(cc_data, table_int, IsAutomaticLabels()); - + cc_data.cat_classif_type = CatClassification::custom; + cc_data.break_vals_type = CatClassification::quantile_break_vals; + InitFromCCData(); EnableControls(true); UpdateCCState(); retry = false; } } else { + wxCommandEvent ev; + OnCurCatsChoice(ev); retry = false; } } @@ -1688,7 +1748,7 @@ void CatClassifPanel::OnButtonDelete(wxCommandEvent& event) default_min, default_max); CatClassifHistCanvas::InitUniformData(preview_data, default_min, default_max); - hist_canvas->ChangeAll(&preview_data, + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, &cc_data.breaks, &cc_data.colors); EnableControls(false); } @@ -1825,7 +1885,7 @@ void CatClassifPanel::ResetValuesToDefault() cc_data.names.clear(); cc_data.cat_classif_type = CatClassification::custom; - cc_data.break_vals_type = CatClassification::custom_break_vals; + cc_data.break_vals_type = CatClassification::quantile_break_vals; CatClassification::SetBreakPoints(cc_data.breaks, cc_data.names, data, data_undef, CatClassification::quantile, @@ -1988,7 +2048,8 @@ void CatClassifPanel::InitFromCCData() auto_labels_cb->SetValue(true); } - hist_canvas->ChangeAll(&preview_data, &cc_data.breaks, &cc_data.colors); + hist_canvas->ChangeAll(&preview_data, cc_data.break_vals_type, + &cc_data.breaks, &cc_data.colors); Refresh(); } @@ -2353,17 +2414,22 @@ void CatClassifPanel::SetBrkTxtFromVec(const std::vector& brks) for (int i=0, sz=brks.size(); iChangeValue(GenUtils::DblToStr(brks[i])); } - if (IsAutomaticLabels() && - GetBreakValsTypeChoice() != CatClassification::unique_values_break_vals) { - std::vector new_labels; - CatClassification::CatLabelsFromBreaks(brks, new_labels, - cc_data.cat_classif_type, - useScientificNotation); - int sz = new_labels.size(); - cc_data.names.resize(sz); - for (int i=0; iChangeValue(new_labels[i]); + CatClassification::BreakValsType brk_type = GetBreakValsTypeChoice(); + bool auto_lbl = IsAutomaticLabels(); + if (auto_lbl && brk_type != CatClassification::unique_values_break_vals) { + if (brk_type != CatClassification::natural_breaks_break_vals) { + std::vector new_labels; + CatClassification::CatLabelsFromBreaks(brks, new_labels, + cc_data.cat_classif_type, + useScientificNotation); + int sz = new_labels.size(); + cc_data.names.resize(sz); + for (int i=0; iChangeValue(cc_data.names[i]); } } } diff --git a/DialogTools/CatClassifDlg.h b/DialogTools/CatClassifDlg.h index db60095fc..d6fdf0271 100644 --- a/DialogTools/CatClassifDlg.h +++ b/DialogTools/CatClassifDlg.h @@ -85,7 +85,8 @@ class CatClassifHistCanvas : public TemplateCanvas { static const double default_max; void ChangeAll(Gda::dbl_int_pair_vec_type* new_data, - std::vector* new_breaks, + CatClassification::BreakValsType new_break_type, + std::vector* new_breaks, std::vector* new_colors); static void InitRandNormData(Gda::dbl_int_pair_vec_type& rn_data); static void InitUniformData(Gda::dbl_int_pair_vec_type& data, @@ -94,7 +95,7 @@ class CatClassifHistCanvas : public TemplateCanvas { protected: Project* project; - + CatClassification::BreakValsType break_type; int num_obs; Gda::dbl_int_pair_vec_type* data; Gda::dbl_int_pair_vec_type default_data; @@ -226,7 +227,8 @@ class CatClassifPanel: public wxPanel, public TableStateObserver bool IsOkToDelete(const wxString& custom_cat_title); void UpdateCCState(); - + CatClassification::CatClassifType GetClassifyType(); + /** Implementation of TableStateObserver interface */ virtual void update(TableState* o); virtual bool AllowTimelineChanges() { return true; } diff --git a/Explore/CatClassification.cpp b/Explore/CatClassification.cpp index cb5efc485..87264eca2 100644 --- a/Explore/CatClassification.cpp +++ b/Explore/CatClassification.cpp @@ -301,8 +301,53 @@ void CatClassification::SetBreakPoints(std::vector& breaks, } } else if (theme == natural_breaks) { FindNaturalBreaks(num_cats, var, var_undef, breaks); - CatLabelsFromBreaks(breaks, cat_labels, theme, useScientificNotation, - cat_disp_precision); + // Get labels + cat_labels.resize(num_cats); + stringstream s; + if (useScientificNotation) + s << std::setprecision(cat_disp_precision) << std::scientific; + else + s << std::setprecision(cat_disp_precision) << std::fixed; + int cur_intervals = num_cats; + for (int ival=0; ival= "; + // if floating point number can be render as integer + if (ss_val == (int)ss_val) s << (int)ss_val; + else s << ss_val; + + } else { + int num_breaks = cur_intervals-1; + int num_breaks_lower = (num_breaks+1)/2; + wxString a = "[", b = ")"; + double ss_val = breaks[ival-1]; + double tt_val = breaks[ival]; + s << a; + if (ss_val == (int)ss_val) s << (int)ss_val; + else s << ss_val; + s << ", "; + if (tt_val == (int)tt_val) s << (int)tt_val; + else s << tt_val; + s << b; + } + cat_labels[ival] = s.str(); + } } else { double min_val = var[0].first; @@ -745,7 +790,6 @@ PopulateCatClassifData(const CatClassifDef& cat_def, cat_data.SetCategoryMinMax(t, 0, low_v, high_v); } } else { - std::vector cat_min(num_cats); std::vector cat_max(num_cats); std::vector breaks(num_cats-1); @@ -759,132 +803,189 @@ PopulateCatClassifData(const CatClassifDef& cat_def, if (undef_cnts_tms[t]>0 && useUndefinedCategory) cat_data.AppendUndefCategory(t, undef_cnts_tms[t]); - - // Set default cat_min / cat_max values for when - // category size is 0 - cat_min[0] = var[t][0].first; - cat_max[0] = cat_def.breaks[0]; - for (int i=1; i cat_max[cat]) { - cat_max[cat] = val; - } - } - cat_data.AppendIdToCategory(t, cat, ind); - } - - if (cat_def.automatic_labels) { - for (int ival=0; ival "; - if ( cat_def.breaks[ival-1] == (int) cat_def.breaks[ival-1]) - ss << (int)cat_def.breaks[ival-1]; - else - ss << cat_def.breaks[ival-1]; - cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); - - } else if (ival == num_cats-1 && num_cats == 2) { + double tt_val = cat_def.breaks[ival]; + // if floating point number can be render as integer + if (tt_val == (int)tt_val) ss << (int)tt_val; else ss << tt_val; + for (int j=0; j= "; - if ( cat_def.breaks[ival-1] == (int) cat_def.breaks[ival-1]) - ss << (int)cat_def.breaks[ival-1]; - else - ss << cat_def.breaks[ival-1]; - cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); - - } else { - int num_breaks = num_cats-1; - int num_breaks_lower = (num_breaks+1)/2; - wxString a; - wxString b; - if (ival < num_breaks_lower) { - a = "["; - b = ")"; - } else if (ival == num_breaks_lower) { - a = "["; - b = "]"; - } else { - a = "("; - b = "]"; - } + // if floating point number can be render as integer + if (ss_val == (int)ss_val) ss << (int)ss_val; else ss << ss_val; + for (int j=0; j= ss_val) cat_data.AppendIdToCategory(t, ival, ind); + } + cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); + + } else { + wxString a = "[", b = ")"; + double ss_val = cat_def.breaks[ival-1]; + double tt_val = cat_def.breaks[ival]; ss << a; - if (cat_def.breaks[ival-1] == (int)cat_def.breaks[ival-1]) - ss << wxString::Format("%d", (int) cat_def.breaks[ival-1]); - else - ss << cat_def.breaks[ival-1]; + if (ss_val == (int)ss_val) ss << (int)ss_val; else ss << ss_val; ss << ", "; - if (cat_def.breaks[ival] == (int)cat_def.breaks[ival]) - ss << wxString::Format("%d", (int) cat_def.breaks[ival]); - else - ss << cat_def.breaks[ival]; + if (tt_val == (int)tt_val) ss << (int)tt_val; else ss << tt_val; ss << b; - cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); + for (int j=0; j= ss_val && val < tt_val) cat_data.AppendIdToCategory(t, ival, ind); + } + cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); - } + } cat_data.SetCategoryLabel(t, ival, wxString(ss.str())); - cat_data.SetCategoryMinMax(t, ival, - cat_min[ival], cat_max[ival]); - } + cat_data.SetCategoryMinMax(t, ival, cat_min[ival], cat_max[ival]); + } } else { - for (int ival=0; ival cat_max[cat]) { + cat_max[cat] = val; + } + } + cat_data.AppendIdToCategory(t, cat, ind); + } + + if (cat_def.automatic_labels) { + for (int ival=0; ival "; + if ( cat_def.breaks[ival-1] == (int) cat_def.breaks[ival-1]) + ss << (int)cat_def.breaks[ival-1]; + else + ss << cat_def.breaks[ival-1]; + cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); + + } else if (ival == num_cats-1 && num_cats == 2) { + ss << ">= "; + if ( cat_def.breaks[ival-1] == (int) cat_def.breaks[ival-1]) + ss << (int)cat_def.breaks[ival-1]; + else + ss << cat_def.breaks[ival-1]; + cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); + + } else { + int num_breaks = num_cats-1; + int num_breaks_lower = (num_breaks+1)/2; + wxString a; + wxString b; + if (ival < num_breaks_lower) { + a = "["; + b = ")"; + } else if (ival == num_breaks_lower) { + a = "["; + b = "]"; + } else { + a = "("; + b = "]"; + } + ss << a; + if (cat_def.breaks[ival-1] == (int)cat_def.breaks[ival-1]) + ss << wxString::Format("%d", (int) cat_def.breaks[ival-1]); + else + ss << cat_def.breaks[ival-1]; + ss << ", "; + if (cat_def.breaks[ival] == (int)cat_def.breaks[ival]) + ss << wxString::Format("%d", (int) cat_def.breaks[ival]); + else + ss << cat_def.breaks[ival]; + ss << b; + cat_data.SetCategoryCount(t, ival, cat_data.GetNumObsInCategory(t, ival)); + } + cat_data.SetCategoryLabel(t, ival, wxString(ss.str())); + cat_data.SetCategoryMinMax(t, ival, + cat_min[ival], cat_max[ival]); + } + } else { + for (int ival=0; ival(t)) { f->OnCustomCatClassifA(cc_title); } else if (ConditionalMapFrame* f = dynamic_cast(t)) { @@ -1108,6 +1112,9 @@ void GdaFrame::OnCustomCategoryClick(wxCommandEvent& event) f->OnCustomCatClassifA(cc_title); } else if (ScatterNewPlotFrame* f = dynamic_cast(t)) { f->OnCustomCatClassifA(cc_title); + } else { + // if there is no active map window, pop to create new map window + OnEmptyCustomCategoryClick(event); } } }