diff --git a/DialogTools/MultiQuantileLisaDlg.cpp b/DialogTools/MultiQuantileLisaDlg.cpp index fc04f13ad..8941dc4af 100644 --- a/DialogTools/MultiQuantileLisaDlg.cpp +++ b/DialogTools/MultiQuantileLisaDlg.cpp @@ -58,7 +58,7 @@ MultiQuantileLisaDlg::~MultiQuantileLisaDlg() void MultiQuantileLisaDlg::CreateControls() { wxScrolledWindow* scrl = new wxScrolledWindow(this, wxID_ANY, wxDefaultPosition, - wxSize(800,560), wxHSCROLL|wxVSCROLL ); + wxSize(800,520), wxHSCROLL|wxVSCROLL ); scrl->SetScrollRate(5, 5); wxPanel *panel = new wxPanel(scrl); @@ -108,7 +108,7 @@ void MultiQuantileLisaDlg::CreateControls() var_box->Add(gbox, 0, wxEXPAND); // list contrl - lst_quantile = new wxListCtrl(panel, wxID_ANY, wxDefaultPosition, wxSize(400, 180), wxLC_REPORT); + lst_quantile = new wxListCtrl(panel, wxID_ANY, wxDefaultPosition, wxSize(400, 160), wxLC_REPORT); lst_quantile->AppendColumn(_("Variable")); lst_quantile->SetColumnWidth(0, 80); lst_quantile->AppendColumn(_("Number of Quantiles"), wxLIST_FORMAT_RIGHT); @@ -118,7 +118,6 @@ void MultiQuantileLisaDlg::CreateControls() lst_quantile->AppendColumn(_("New Field")); lst_quantile->SetColumnWidth(3, 80); - // move buttons move_left = new wxButton(panel, wxID_ANY, "<", wxDefaultPosition, wxSize(25,25)); move_right = new wxButton(panel, wxID_ANY, ">", wxDefaultPosition, wxSize(25,25)); @@ -127,7 +126,10 @@ void MultiQuantileLisaDlg::CreateControls() left_box->Add(var_box); right_box->Add(lst_quantile, 1, wxALL|wxEXPAND, 5); - + + chk_nocolocation = new wxCheckBox(panel, wxID_ANY, "No co-location"); + right_box->Add(chk_nocolocation, 0, wxALL, 5); + hbox_quantile->Add(left_box); hbox_quantile->Add(middle_box); hbox_quantile->Add(right_box, 1, wxALL|wxEXPAND); @@ -217,6 +219,13 @@ void MultiQuantileLisaDlg::OnAddRow(wxCommandEvent& event) // check if inputs are valid if (project == NULL) return; + if (chk_nocolocation->GetValue() && lst_quantile->GetItemCount() >= 2) { + wxString err_msg = _("No-colocation only works with two variables for Quantile LISA."); + wxMessageDialog dlg(NULL, err_msg, _("Error"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return; + } + // get selected variable int sel_var = combo_var->GetSelection(); if (sel_var < 0) { @@ -343,6 +352,13 @@ void MultiQuantileLisaDlg::OnOK(wxCommandEvent& event ) return; } + if (chk_nocolocation->GetValue() && lst_quantile->GetItemCount() != 2) { + wxString err_msg = _("No-colocation only works with two variables for Quantile LISA."); + wxMessageDialog dlg(NULL, err_msg, _("Error"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return; + } + std::vector col_ids(num_vars); std::vector var_info(num_vars); wxString var_details; @@ -441,6 +457,63 @@ void MultiQuantileLisaDlg::OnOK(wxCommandEvent& event ) } boost::uuids::uuid w_id = weights_ids[sel]; + // check if satisfy colocation and no-colocation cases + if (num_vars >= 2) { + std::vector data(num_vars); // data[variable][time][obs] + std::vector undef_data(num_vars); + for (int i=0; iGetColData(col_ids[i], data[i]); + table_int->GetColUndefined(col_ids[i], undef_data[i]); + } + GalElement* W = gw->gal; + int t = 0; + vector local_t; + for (int v=0; v undefs; + for (int i=0; iGetValue()) { + wxMessageDialog dlg (this, _("The selected variables have no co-location. Please change your selection, or select \"No colocation\" option for bivariate case."), _("Error"), wxOK | wxICON_WARNING); + dlg.ShowModal(); + return; + } else if (chk_nocolocation->GetValue() && nocolocation == false) { + wxMessageDialog dlg (this, _("The selected variables have co-location. Please change your selection, or unselect \"No colocation\" option for bivariate case."), _("Error"), wxOK | wxICON_WARNING); + dlg.ShowModal(); + return; + } + } + JCCoordinator* lc = new JCCoordinator(w_id, project, var_info, col_ids); MLJCMapFrame *sf = new MLJCMapFrame(parent, project, lc, false); diff --git a/DialogTools/MultiQuantileLisaDlg.h b/DialogTools/MultiQuantileLisaDlg.h index 8020dae1d..c378a469d 100644 --- a/DialogTools/MultiQuantileLisaDlg.h +++ b/DialogTools/MultiQuantileLisaDlg.h @@ -58,6 +58,7 @@ class MultiQuantileLisaDlg : public AbstractClusterDlg wxListCtrl* lst_quantile; wxButton* move_left; wxButton* move_right; + wxCheckBox* chk_nocolocation; std::set new_fields; diff --git a/Explore/ConditionalHistogramView.cpp b/Explore/ConditionalHistogramView.cpp index ec20c99b8..005360969 100644 --- a/Explore/ConditionalHistogramView.cpp +++ b/Explore/ConditionalHistogramView.cpp @@ -65,13 +65,15 @@ ConditionalHistogramCanvas(wxWindow *parent, const wxPoint& pos, const wxSize& size) : ConditionalNewCanvas(parent, t_frame, project_s, v_info, col_ids, false, true, pos, size), -show_axes(true), scale_x_over_time(true), scale_y_over_time(true) +show_axes(true), scale_x_over_time(true), scale_y_over_time(true), set_uniquevalue(false) { full_map_redraw_needed = true; - int hist_var_tms = data[HIST_VAR].shape()[0]; + int hist_var_tms = (int)data[HIST_VAR].shape()[0]; data_stats.resize(hist_var_tms); data_sorted.resize(hist_var_tms); + s_data_sorted.resize(hist_var_tms); + VAR_STRING.resize(hist_var_tms); // create bins for histogram for (int t=0; t undefs(num_obs, false); for (int j=0; jUpdateOptionMenuItems(); } +void ConditionalHistogramCanvas::OnSetUniqueValue(wxCommandEvent& event) +{ + set_uniquevalue = !set_uniquevalue; + + if (set_uniquevalue) { + for (int t=0; t sel_data(num_obs); + + for (int i=0; i unique_dict; + // data_sorted is a pair value {string value: index} + VAR_STRING[t].resize(num_obs); + for (int i=0; i 0) { + cur_intervals = std::max(cur_intervals, (int)unique_dict.size()); + } else { + cur_intervals = (int)unique_dict.size(); + } + } + } else { + // restore bins for histogram + for (int t=0; t undefs(num_obs, false); + + for (int i=0; i orig_x_pos(cur_intervals); + for (int i=0; iapplyScaleTrans(st[r][c]); foreground_shps.push_front(s); + s = new GdaAxis(*y_axis); s->applyScaleTrans(st[r][c]); foreground_shps.push_front(s); + + if (set_uniquevalue) { + for (int ival=0; ivalapplyScaleTrans(st[r][c]); + foreground_shps.push_back(brk); + } + } } } } @@ -479,22 +557,23 @@ void ConditionalHistogramCanvas::PopulateCanvas() axis_scale_x.tics_str.resize(axis_scale_x.ticks); axis_scale_x.tics_str_show.resize(axis_scale_x.tics_str.size()); for (int i=0; i - setPen(GdaConst::qualitative_colors[ival%sz]); - selectable_shps[i]-> - setBrush(GdaConst::qualitative_colors[ival%sz]); + double y1 = cell_data[t][r][c].ival_obs_cnt[ival]; + selectable_shps[i] = new GdaRectangle(wxRealPoint(x0, 0), wxRealPoint(x1, y1)); + int sz = (int)GdaConst::qualitative_colors.size(); + selectable_shps[i]->setPen(GdaConst::qualitative_colors[ival%sz]); + selectable_shps[i]->setBrush(GdaConst::qualitative_colors[ival%sz]); i++; } } @@ -552,7 +627,7 @@ void ConditionalHistogramCanvas::ShowAxes(bool show_axes_s) void ConditionalHistogramCanvas::DetermineMouseHoverObjects(wxPoint pt) { total_hover_obs = 0; - for (int i=0, iend=selectable_shps.size(); ipointWithin(pt)) { hover_obs[total_hover_obs++] = i; if (total_hover_obs == max_hover_obs) break; @@ -564,13 +639,13 @@ void ConditionalHistogramCanvas::DetermineMouseHoverObjects(wxPoint pt) // are all rectangles. void ConditionalHistogramCanvas::UpdateSelection(bool shiftdown, bool pointsel) { + int t = var_info[HIST_VAR].time; bool rect_sel = (!pointsel && (brushtype == rectangle)); - int t = var_info[HIST_VAR].time; std::vector& hs = highlight_state->GetHighlight(); bool selection_changed = false; - int total_sel_shps = selectable_shps.size(); + int total_sel_shps = (int)selectable_shps.size(); wxPoint lower_left; wxPoint upper_right; @@ -608,17 +683,12 @@ void ConditionalHistogramCanvas::UpdateSelection(bool shiftdown, bool pointsel) sel_shp_to_cell(i, r, c, ival); GdaRectangle* rec = (GdaRectangle*) selectable_shps[i]; bool selected = ((pointsel && rec->pointWithin(sel1)) || - (rect_sel && - GenGeomAlgs::RectsIntersect(rec->lower_left, - rec->upper_right, - lower_left, upper_right))); - bool all_sel = (cell_data[0][r][c].ival_obs_cnt[ival] == - cell_data[0][r][c].ival_obs_sel_cnt[ival]); + (rect_sel && GenGeomAlgs::RectsIntersect(rec->lower_left, rec->upper_right, lower_left, upper_right))); if (selected) { // select currently unselected in ival for (std::list::iterator it = - cell_data[0][r][c].ival_to_obs_ids[ival].begin(); - it != cell_data[0][r][c].ival_to_obs_ids[ival].end(); it++) { + cell_data[t][r][c].ival_to_obs_ids[ival].begin(); + it != cell_data[t][r][c].ival_to_obs_ids[ival].end(); it++) { new_hs[(*it)]= true; selection_changed = true; } @@ -644,12 +714,12 @@ void ConditionalHistogramCanvas::UpdateSelection(bool shiftdown, bool pointsel) void ConditionalHistogramCanvas::DrawSelectableShapes(wxMemoryDC &dc) { - int t = var_info[HIST_VAR].time; int i=0; + int t = var_info[HIST_VAR].time; for (int r=0; rpaintSelf(dc); } i++; @@ -660,14 +730,14 @@ void ConditionalHistogramCanvas::DrawSelectableShapes(wxMemoryDC &dc) void ConditionalHistogramCanvas::DrawHighlightedShapes(wxMemoryDC &dc) { - int t = var_info[HIST_VAR].time; int i=0; + int t = var_info[HIST_VAR].time; double s; for (int r=0; rSet as Unique Values\" is selected."); + wxMessageDialog dlg (this, msg, _("Warning"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return; + } cur_intervals = dlg.num_intervals; InitIntervals(); invalidateBms(); @@ -713,7 +789,7 @@ void ConditionalHistogramCanvas::HistogramIntervals() obs_id_to_sel_shp, ival_obs_cnt and ival_obs_sel_cnt */ void ConditionalHistogramCanvas::InitIntervals() { - std::vector& hs = highlight_state->GetHighlight(); + std::vector& hs = highlight_state->GetHighlight(); // determine correct ivals for each obs in current time period min_ival_val.resize(num_time_vals); @@ -721,32 +797,59 @@ void ConditionalHistogramCanvas::InitIntervals() max_num_obs_in_ival.resize(num_time_vals); overall_max_num_obs_in_ival = 0; - for (int t=0; t unique_ival_dict; ival_breaks.resize(boost::extents[num_time_vals][cur_intervals-1]); + s_ival_breaks.resize(boost::extents[num_time_vals][cur_intervals]); + for (int t=0; t undefs = undef_tms[t]; - if (scale_x_over_time) { - min_ival_val[t] = data_min_over_time; - max_ival_val[t] = data_max_over_time; - } else { - min_ival_val[t] = data_sorted[t][0].first; - max_ival_val[t] = data_sorted[t][num_obs-1].first; - } - if (min_ival_val[t] == max_ival_val[t]) { - if (min_ival_val[t] == 0) { - max_ival_val[t] = 1; - } else { - max_ival_val[t] += fabs(max_ival_val[t])/2.0; - } - } - double range = max_ival_val[t] - min_ival_val[t]; - double ival_size = range/((double) cur_intervals); - - for (int i=0; i unique_dict; + // data_sorted is a pair value {string value: index} + for (int i=0; i::iterator it; + for (it=unique_dict.begin(); it!=unique_dict.end();it++){ + wxString lbl = it->first; + s_ival_breaks[t][cur_ival] = lbl; + unique_ival_dict[lbl] = cur_ival; + cur_ival += 1; + } + + } else { + std::vector undefs = undef_tms[t]; + if (scale_x_over_time) { + min_ival_val[t] = data_min_over_time; + max_ival_val[t] = data_max_over_time; + } else { + min_ival_val[t] = data_sorted[t][0].first; + max_ival_val[t] = data_sorted[t][num_obs-1].first; + } + if (min_ival_val[t] == max_ival_val[t]) { + if (min_ival_val[t] == 0) { + max_ival_val[t] = 1; + } else { + max_ival_val[t] += fabs(max_ival_val[t])/2.0; + } + } + double range = max_ival_val[t] - min_ival_val[t]; + double ival_size = range/((double) cur_intervals); + + for (int i=0; i= ival_breaks[0][cur_ival]) - { - cur_ival++; - } - int r = 0, c = 0; - if (!vert_cat_data.categories.empty()) { - r = vert_cat_data.categories[vt].id_to_cat[id]; + + // record each obs in the correct cell and ival. + if (set_uniquevalue) { + for (int i=0; i max_num_obs_in_ival[t]) + { + max_num_obs_in_ival[t] = cell_data[t][r][c].ival_obs_cnt[cur_ival]; + if (max_num_obs_in_ival[t] > overall_max_num_obs_in_ival) { + overall_max_num_obs_in_ival = max_num_obs_in_ival[t]; + } + } + if (hs[s_data_sorted[dt][i].second]) { + cell_data[t][r][c].ival_obs_sel_cnt[cur_ival]++; + } } - if (!horiz_cat_data.categories.empty()) { - c = horiz_cat_data.categories[ht].id_to_cat[id]; + + } else { + + for (int i=0; i= ival_breaks[0][cur_ival]) + { + cur_ival++; + } + int r = 0, c = 0; + if (!vert_cat_data.categories.empty()) { + r = vert_cat_data.categories[vt].id_to_cat[id]; + } + if (!horiz_cat_data.categories.empty()) { + c = horiz_cat_data.categories[ht].id_to_cat[id]; + } + obs_id_to_sel_shp[t][id] = cell_to_sel_shp_gen(r, c, cur_ival, + cols, cur_intervals); + cell_data[t][r][c].ival_to_obs_ids[cur_ival].push_front(id); + cell_data[t][r][c].ival_obs_cnt[cur_ival]++; + if (cell_data[t][r][c].ival_obs_cnt[cur_ival] > max_num_obs_in_ival[t]) + { + max_num_obs_in_ival[t] = cell_data[t][r][c].ival_obs_cnt[cur_ival]; + if (max_num_obs_in_ival[t] > overall_max_num_obs_in_ival) { + overall_max_num_obs_in_ival = max_num_obs_in_ival[t]; + } + } + if (hs[data_sorted[dt][i].second]) { + cell_data[t][r][c].ival_obs_sel_cnt[cur_ival]++; + } } - obs_id_to_sel_shp[t][id] = cell_to_sel_shp_gen(r, c, cur_ival, - cols, cur_intervals); - cell_data[0][r][c].ival_to_obs_ids[cur_ival].push_front(id); - cell_data[0][r][c].ival_obs_cnt[cur_ival]++; - if (cell_data[0][r][c].ival_obs_cnt[cur_ival] > max_num_obs_in_ival[t]) - { - max_num_obs_in_ival[t] = - cell_data[0][r][c].ival_obs_cnt[cur_ival]; - if (max_num_obs_in_ival[t] > overall_max_num_obs_in_ival) { - overall_max_num_obs_in_ival = max_num_obs_in_ival[t]; - } - } - if (hs[data_sorted[dt][i].second]) { - cell_data[0][r][c].ival_obs_sel_cnt[cur_ival]++; - } - } + } } } @@ -835,15 +976,15 @@ void ConditionalHistogramCanvas::UpdateIvalSelCnts() if (var_info[HOR_VAR].sync_with_global_time) ht += t; int rows = 1, cols = 1; if (!vert_cat_data.categories.empty()) { - rows = vert_cat_data.categories[vt].cat_vec.size(); + rows = (int)vert_cat_data.categories[vt].cat_vec.size(); } if (!horiz_cat_data.categories.empty()) { - cols = horiz_cat_data.categories[ht].cat_vec.size(); + cols = (int)horiz_cat_data.categories[ht].cat_vec.size(); } for (int r=0; rSetStatusText(s); } -void ConditionalHistogramCanvas::sel_shp_to_cell_gen(int i, - int& r, int& c, int& ival, - int cols, int ivals) +void ConditionalHistogramCanvas::sel_shp_to_cell_gen(int i, int& r, int& c, int& ival, int cols, int ivals) { int t = cols*ivals; r = t > 0 ? i/t : 0; @@ -967,8 +1113,7 @@ void ConditionalHistogramCanvas::sel_shp_to_cell_gen(int i, ival = t%ivals; } -void ConditionalHistogramCanvas::sel_shp_to_cell(int i, int& r, - int& c, int& ival) +void ConditionalHistogramCanvas::sel_shp_to_cell(int i, int& r, int& c, int& ival) { // rows == vert_num_cats // cols == horiz_num_cats @@ -1005,10 +1150,7 @@ ConditionalHistogramFrame::ConditionalHistogramFrame(wxFrame *parent, int width, height; GetClientSize(&width, &height); - template_canvas = new ConditionalHistogramCanvas(this, this, project, - var_info, col_ids, - wxDefaultPosition, - wxSize(width,height)); + template_canvas = new ConditionalHistogramCanvas(this, this, project, var_info, col_ids, wxDefaultPosition, wxSize(width,height)); SetTitle(template_canvas->GetCanvasTitle()); template_canvas->SetScrollRate(1,1); DisplayStatusBar(true); @@ -1027,23 +1169,30 @@ void ConditionalHistogramFrame::OnActivate(wxActivateEvent& event) wxLogMessage("In ConditionalMapFrame::OnActivate()"); RegisterAsActive("ConditionalHistogramFrame", GetTitle()); } - if ( event.GetActive() && template_canvas ) + if ( event.GetActive() && template_canvas ) { template_canvas->SetFocus(); + } } void ConditionalHistogramFrame::MapMenus() { wxMenuBar* mb = GdaFrame::GetGdaFrame()->GetMenuBar(); // Map Options Menus - wxMenu* optMenu = wxXmlResource::Get()-> - LoadMenu("ID_COND_HISTOGRAM_VIEW_MENU_OPTIONS"); - ((ConditionalHistogramCanvas*) template_canvas)-> - AddTimeVariantOptionsToMenu(optMenu); - TemplateCanvas::AppendCustomCategories(optMenu, - project->GetCatClassifManager()); + wxMenu* optMenu = wxXmlResource::Get()->LoadMenu("ID_COND_HISTOGRAM_VIEW_MENU_OPTIONS"); + ((ConditionalHistogramCanvas*) template_canvas)->AddTimeVariantOptionsToMenu(optMenu); + TemplateCanvas::AppendCustomCategories(optMenu, project->GetCatClassifManager()); ((ConditionalHistogramCanvas*) template_canvas)->SetCheckMarks(optMenu); GeneralWxUtils::ReplaceMenu(mb, _("Options"), optMenu); UpdateOptionMenuItems(); + + // connect menu item ID_VIEW_HISTOGRAM_SET_UNIQUE + wxMenuItem* uniquevalue_menu = optMenu->FindItem(XRCID("ID_VIEW_HISTOGRAM_SET_UNIQUE")); + Connect(uniquevalue_menu->GetId(), wxEVT_MENU, wxCommandEventHandler(ConditionalHistogramFrame::OnSetUniqueValue)); +} + +void ConditionalHistogramFrame::OnSetUniqueValue(wxCommandEvent& event) +{ + ((ConditionalHistogramCanvas*) template_canvas)->OnSetUniqueValue(event); } void ConditionalHistogramFrame::UpdateOptionMenuItems() @@ -1051,8 +1200,7 @@ void ConditionalHistogramFrame::UpdateOptionMenuItems() TemplateFrame::UpdateOptionMenuItems(); // set common items first wxMenuBar* mb = GdaFrame::GetGdaFrame()->GetMenuBar(); int menu = mb->FindMenu(_("Options")); - if (menu == wxNOT_FOUND) { - } else { + if (menu != wxNOT_FOUND) { ((ConditionalHistogramCanvas*) template_canvas)->SetCheckMarks(mb->GetMenu(menu)); } @@ -1064,7 +1212,6 @@ void ConditionalHistogramFrame::UpdateContextMenuItems(wxMenu* menu) // following menu items if they were specified for this particular // view in the xrc file. Items that cannot be enable/disabled, // or are not checkable do not appear. - TemplateFrame::UpdateContextMenuItems(menu); // set common items } @@ -1078,8 +1225,7 @@ void ConditionalHistogramFrame::update(TimeState* o) void ConditionalHistogramFrame::OnShowAxes(wxCommandEvent& ev) { wxLogMessage("In ConditionalHistogramFrame::OnShowAxes()"); - ConditionalHistogramCanvas* t = - (ConditionalHistogramCanvas*) template_canvas; + ConditionalHistogramCanvas* t = (ConditionalHistogramCanvas*) template_canvas; t->ShowAxes(!t->IsShowAxes()); UpdateOptionMenuItems(); } @@ -1087,14 +1233,15 @@ void ConditionalHistogramFrame::OnShowAxes(wxCommandEvent& ev) void ConditionalHistogramFrame::OnHistogramIntervals(wxCommandEvent& ev) { wxLogMessage("In ConditionalHistogramFrame::OnHistogramIntervals()"); - ConditionalHistogramCanvas* t = - (ConditionalHistogramCanvas*) template_canvas; + ConditionalHistogramCanvas* t = (ConditionalHistogramCanvas*) template_canvas; t->HistogramIntervals(); } void ConditionalHistogramFrame::OnSaveCanvasImageAs(wxCommandEvent& event) { - if (!template_canvas) return; + if (!template_canvas) { + return; + } wxString title = project->GetProjectTitle(); GeneralWxUtils::SaveWindowAsImage(template_canvas, title); } diff --git a/Explore/ConditionalHistogramView.h b/Explore/ConditionalHistogramView.h index 2d8737e10..249fae7bf 100644 --- a/Explore/ConditionalHistogramView.h +++ b/Explore/ConditionalHistogramView.h @@ -68,14 +68,17 @@ class ConditionalHistogramCanvas : public ConditionalNewCanvas { virtual void UpdateStatusBar(); virtual void TimeSyncVariableToggle(int var_index); - + virtual void UserChangedCellCategories(); + void ShowAxes(bool show_axes); bool IsShowAxes() { return show_axes; } void HistogramIntervals(); void InitIntervals(); void UpdateIvalSelCnts(); - virtual void UserChangedCellCategories(); + + void OnSetUniqueValue(wxCommandEvent& event); + protected: void sel_shp_to_cell_gen(int i, int& r, int& c, int& ival, int cols, int ivals); @@ -85,7 +88,10 @@ class ConditionalHistogramCanvas : public ConditionalNewCanvas { static const int HIST_VAR; // histogram variable - // size = time_steps if HIST_VAR is time variant + bool set_uniquevalue; + std::vector > VAR_STRING; + std::vector s_data_sorted; + std::vector data_sorted; std::vector data_stats; std::vector > undef_tms; @@ -101,6 +107,7 @@ class ConditionalHistogramCanvas : public ConditionalNewCanvas { bool show_axes; + s_array_type s_ival_breaks; double data_min_over_time; double data_max_over_time; d_array_type ival_breaks; // size = num_time_vals * cur_num_intervals-1 @@ -147,7 +154,8 @@ class ConditionalHistogramFrame : public ConditionalNewFrame { void OnShowAxes(wxCommandEvent& event); void OnHistogramIntervals(wxCommandEvent& event); - + void OnSetUniqueValue(wxCommandEvent& event); + DECLARE_EVENT_TABLE() }; diff --git a/Explore/HistogramView.cpp b/Explore/HistogramView.cpp index 220f4ffc9..2bd30d55b 100644 --- a/Explore/HistogramView.cpp +++ b/Explore/HistogramView.cpp @@ -244,8 +244,12 @@ void HistogramCanvas::OnSetUniqueValue(wxCommandEvent& event) unique_dict[sel_data[i]] += 1; } // add current [id] to ival_to_obs_ids - max_intervals = (int)unique_dict.size(); - cur_intervals = (int)unique_dict.size(); + max_intervals = std::min(MAX_INTERVALS, (int)unique_dict.size()); + if (t > 0) { + cur_intervals = std::max(cur_intervals, (int)unique_dict.size()); + } else { + cur_intervals = (int)unique_dict.size(); + } } } else { // restore diff --git a/GeoDa.cpp b/GeoDa.cpp index adbc93429..aa0657c92 100644 --- a/GeoDa.cpp +++ b/GeoDa.cpp @@ -228,9 +228,9 @@ bool GdaApp::OnInit(void) // initialize OGR connection OGRDataAdapter::GetInstance(); - - checker = new wxSingleInstanceChecker("GdaApp"); - +#ifdef __WIN32__ + checker = new wxSingleInstanceChecker(); +#endif // load preferences PreferenceDlg::ReadFromCache(); @@ -285,7 +285,7 @@ bool GdaApp::OnInit(void) GdaInitXmlResource(); // call the init function in GdaAppResources.cpp // check crash - if (GdaConst::disable_crash_detect == false && !checker->IsAnotherRunning()) { + if (GdaConst::disable_crash_detect == false && (checker && !checker->IsAnotherRunning())) { std::vector items = OGRDataAdapter::GetInstance().GetHistory("NoCrash"); if (items.size() > 0) { wxString no_crash = items[0]; @@ -778,9 +778,9 @@ GdaFrame::GdaFrame(const wxString& title, const wxPoint& pos, //CallAfter(&GdaFrame::ShowOpenDatasourceDlg,wxPoint(80, 220),true); // check update in a new thread - if (GdaConst::disable_auto_upgrade == false) { - CallAfter(&GdaFrame::CheckUpdate); - } + //if (GdaConst::disable_auto_upgrade == false) { + // CallAfter(&GdaFrame::CheckUpdate); + //} } GdaFrame::~GdaFrame() @@ -4256,20 +4256,23 @@ void GdaFrame::OnOpenBivariateLJC(wxCommandEvent& event) } // check if binary data - std::vector data; + std::vector data1, data2; + std::vector undef_data1, undef_data2; TableInterface* table_int = p->GetTableInt(); - table_int->GetColData(VS.col_ids[0], VS.var_info[0].time, data); - for (int i=0; iGetColData(VS.col_ids[0], VS.var_info[0].time, data1); + table_int->GetColUndefined(VS.col_ids[0], VS.var_info[0].time, undef_data1); + for (int i=0; iGetColData(VS.col_ids[1], VS.var_info[1].time, data); - for (int i=0; iGetColData(VS.col_ids[1], VS.var_info[1].time, data2); + table_int->GetColUndefined(VS.col_ids[1], VS.var_info[1].time, undef_data2); + for (int i=0; iGetNumRecords(); + + vector undefs; + for (int i=0; i 2) { + if (num_vars >= 2) { std::vector data(num_vars); // data[variable][time][obs] std::vector undef_data(num_vars); for (int i=0; i + + + 1 + 0 + diff --git a/version.h b/version.h index d9ca2481f..7d93e33fd 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 16; const int version_build = 0; - const int version_subbuild = 12; + const int version_subbuild = 16; const int version_year = 2020; const int version_month = 10; - const int version_day = 15; + const int version_day = 20; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release }