// The following function assumes that the set of selectable objects // all rectangles. void ConnectivityHistCanvas::UpdateSelection(bool shiftdown, bool pointsel) { bool rect_sel = (!pointsel && (brushtype == rectangle)); std::vector<bool>& hs = highlight_state->GetHighlight(); std::vector<int>& nh = highlight_state->GetNewlyHighlighted(); std::vector<int>& nuh = highlight_state->GetNewlyUnhighlighted(); int total_newly_selected = 0; int total_newly_unselected = 0; int total_sel_shps = selectable_shps.size(); wxPoint lower_left; wxPoint upper_right; if (rect_sel) { GenUtils::StandardizeRect(sel1, sel2, lower_left, upper_right); } if (!shiftdown) { bool any_selected = false; for (int i=0; i<total_sel_shps; i++) { GdaRectangle* rec = (GdaRectangle*) selectable_shps[i]; if ((pointsel && rec->pointWithin(sel1)) || (rect_sel && GenUtils::RectsIntersect(rec->lower_left, rec->upper_right, lower_left, upper_right))) { //LOG_MSG(wxString::Format("ival %d selected", i)); any_selected = true; break; } else { //LOG_MSG(wxString::Format("ival %d not selected", i)); //LOG_MSG(wxString::Format("")); } } if (!any_selected) { highlight_state->SetEventType(HighlightState::unhighlight_all); highlight_state->notifyObservers(); return; } } for (int i=0; i<total_sel_shps; i++) { GdaRectangle* rec = (GdaRectangle*) selectable_shps[i]; bool selected = ((pointsel && rec->pointWithin(sel1)) || (rect_sel && GenUtils::RectsIntersect(rec->lower_left, rec->upper_right, lower_left, upper_right))); bool all_sel = (ival_obs_cnt[i] == ival_obs_sel_cnt[i]); if (pointsel && all_sel && selected) { // unselect all in ival for (std::list<int>::iterator it=ival_to_obs_ids[i].begin(); it != ival_to_obs_ids[i].end(); it++) { nuh[total_newly_unselected++] = (*it); } } else if (!all_sel && selected) { // select currently unselected in ival for (std::list<int>::iterator it=ival_to_obs_ids[i].begin(); it != ival_to_obs_ids[i].end(); it++) { if (hs[*it]) continue; nh[total_newly_selected++] = (*it); } } else if (!selected && !shiftdown) { // unselect all selected in ival for (std::list<int>::iterator it=ival_to_obs_ids[i].begin(); it != ival_to_obs_ids[i].end(); it++) { if (!hs[*it]) continue; nuh[total_newly_unselected++] = (*it); } } } if (total_newly_selected > 0 || total_newly_unselected > 0) { highlight_state->SetTotalNewlyHighlighted(total_newly_selected); highlight_state->SetTotalNewlyUnhighlighted(total_newly_unselected); NotifyObservables(); } UpdateStatusBar(); }
void LineChartCanvas::PopulateCanvas() { LOG_MSG("Entering LineChartCanvas::PopulateCanvas"); BOOST_FOREACH( GdaShape* shp, background_shps ) { delete shp; } background_shps.clear(); BOOST_FOREACH( GdaShape* shp, selectable_shps ) { delete shp; } selectable_shps.clear(); BOOST_FOREACH( GdaShape* shp, foreground_shps ) { delete shp; } foreground_shps.clear(); tm_rects.clear(); // NOTE: tm_rects are owned by background_shps summ_avg_circs[0] = 0; // NOTE: summ_avg_circs contents are owned summ_avg_circs[1] = 0; // by background_shps. summ_avg_circs[2] = 0; summ_avg_circs[3] = 0; comb_circs.clear(); sel_circs.clear(); excl_circs.clear(); wxSize size(GetVirtualSize()); int win_width = size.GetWidth(); int win_height = size.GetHeight(); double scale_x, scale_y, trans_x, trans_y; GdaScaleTrans::calcAffineParams(shps_orig_xmin, shps_orig_ymin, shps_orig_xmax, shps_orig_ymax, virtual_screen_marg_top, virtual_screen_marg_bottom, virtual_screen_marg_left, virtual_screen_marg_right, win_width, win_height, fixed_aspect_ratio_mode, fit_to_window_mode, &scale_x, &scale_y, &trans_x, &trans_y, 0, 0, ¤t_shps_width, ¤t_shps_height); fixed_aspect_ratio_val = current_shps_width / current_shps_height; double y_min = 0; double y_max = 100; if (lcs.Y_avg_valid) { y_min = lcs.Y_avg_min; y_max = lcs.Y_avg_max; } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_sel_avg_valid) { if (lcs.Y_sel_avg_min < y_min) y_min = lcs.Y_sel_avg_min; if (lcs.Y_sel_avg_max > y_max) y_max = lcs.Y_sel_avg_max; } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_excl_avg_valid) { if (lcs.Y_excl_avg_min < y_min) y_min = lcs.Y_excl_avg_min; if (lcs.Y_excl_avg_max > y_max) y_max = lcs.Y_excl_avg_max; } double y_pad = 0.1 * (y_max - y_min); double axis_min = y_min - y_pad; double axis_max = y_max + y_pad; if (y_min >= 0 && axis_min < 0) axis_min = 0; if (!def_y_min.IsEmpty()) def_y_min.ToDouble(&axis_min); if (!def_y_max.IsEmpty()) def_y_max.ToDouble(&axis_max); axis_scale_y = AxisScale(axis_min, axis_max, 4, y_axis_precision); //LOG_MSG(wxString(axis_scale_y.ToString().c_str(), wxConvUTF8)); scaleY = 100.0 / (axis_scale_y.scale_range); TableInterface* table_int = project->GetTableInt(); // create axes std::vector<wxString> tm_strs; table_int->GetTimeStrings(tm_strs); bool time_variant = lcs.Y.size() > 1; wxRealPoint* y_pts = 0; size_t num_points = lcs.Y_avg.size(); if (time_variant && num_points > 0) { // draw summary average circs // Will define avg point 1 and avg point 2 depending on // state of lcs. Will ultimately need these points to // be detectable objects so that we can report summaries. // NULL indicates avg is not currently defined. if (lcs.compare_regimes) { if (lcs.Y_sel_tm0_avg_valid) { summ_avg_circs[0] = MakeSummAvgHelper(lcs.Y_sel_tm0_avg,GdaConst::ln_cht_clr_sel_dark); } if (lcs.Y_excl_tm0_avg_valid) { summ_avg_circs[1] = MakeSummAvgHelper(lcs.Y_excl_tm0_avg,GdaConst::ln_cht_clr_exl_dark); } } else if (lcs.compare_time_periods) { if (lcs.Y_avg_tm0_valid) { summ_avg_circs[0] = MakeSummAvgHelper(lcs.Y_avg_tm0,GdaConst::ln_cht_clr_tm1_dark); } if (lcs.Y_avg_tm1_valid) { summ_avg_circs[1] = MakeSummAvgHelper(lcs.Y_avg_tm1,GdaConst::ln_cht_clr_tm2_dark); } } else if (lcs.compare_r_and_t) { if (lcs.Y_sel_tm0_avg_valid) { summ_avg_circs[0] = MakeSummAvgHelper(lcs.Y_sel_tm0_avg,GdaConst::ln_cht_clr_sel_dark,GdaConst::ln_cht_clr_tm1_light); } if (lcs.Y_excl_tm0_avg_valid) { summ_avg_circs[1] = MakeSummAvgHelper(lcs.Y_excl_tm0_avg,GdaConst::ln_cht_clr_exl_dark,GdaConst::ln_cht_clr_tm1_light); } if (lcs.Y_sel_tm1_avg_valid) { summ_avg_circs[2] = MakeSummAvgHelper(lcs.Y_sel_tm1_avg,GdaConst::ln_cht_clr_sel_dark,GdaConst::ln_cht_clr_tm2_light); } if (lcs.Y_excl_tm1_avg_valid) { summ_avg_circs[3] = MakeSummAvgHelper(lcs.Y_excl_tm1_avg,GdaConst::ln_cht_clr_exl_dark,GdaConst::ln_cht_clr_tm2_light); } } } if (time_variant && num_points > 0) { size_t tms = lcs.Y_avg.size(); y_pts = new wxRealPoint[num_points]; // Draw subset highlight line and invisible selection // rectangles first if (lcs.Y_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_avg[t] - axis_scale_y.scale_min) * scaleY; // draw a rectangle behind x-axis line to indicate // time period 0 or 1. double x0 = 0.0; double x1 = 100.0; double x_p1 = ((double) (t+1))/((double) (tms-1)) * 100.0; double x_m1 = ((double) (t-1))/((double) (tms-1)) * 100.0; if (t == 0) { x1 = (x+x_p1)/2.0; } else if (t+1 == tms) { x0 = (x_m1+x)/2.0; } else { // not an end-point x0 = (x_m1+x)/2.0; x1 = (x+x_p1)/2.0; } if (lcs.tms_subset0[t]) { GdaPolyLine* p = new GdaPolyLine(x0, 0, x1, 0); if (lcs.compare_time_periods || lcs.compare_r_and_t) { p->setPen(wxPen(GdaConst::ln_cht_clr_tm1_light, 9)); } else { p->setPen(wxPen(GdaConst::ln_cht_clr_regimes_hl, 9)); } p->setNudge(0, 5); background_shps.push_back(p); } if ((lcs.compare_time_periods || lcs.compare_r_and_t) && lcs.tms_subset1[t]) { GdaPolyLine* p = new GdaPolyLine(x0, 0, x1, 0); p->setPen(wxPen(GdaConst::ln_cht_clr_tm2_light, 9)); p->setNudge(0, 5); background_shps.push_back(p); } // Create invisible selection rectangles { double x0_nudge = 0; double x1_nudge = 0; if (t == 0) { x0_nudge = -5; } else if (t+1 == tms) { x1_nudge = 5; } GdaRectangle* r = new GdaRectangle(wxRealPoint(x0, 0), wxRealPoint(x1, 100)); tm_rects.push_back(r); r->setPen(*wxTRANSPARENT_PEN); r->setBrush(*wxTRANSPARENT_BRUSH); background_shps.push_back(r); } } } // Push subset circle highlights to the background first if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_excl_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_excl_avg[t] - axis_scale_y.scale_min) * scaleY; if (lcs.tms_subset0[t]) { GdaCircle* c = new GdaCircle(wxRealPoint(x, y), ss_circ_rad); if (lcs.compare_r_and_t) { c->setPen(GdaConst::ln_cht_clr_tm1_light); c->setBrush(GdaConst::ln_cht_clr_tm1_light); } else { c->setPen(GdaConst::ln_cht_clr_regimes_hl); c->setBrush(GdaConst::ln_cht_clr_regimes_hl); } background_shps.push_back(c); } if (lcs.compare_r_and_t && lcs.tms_subset1[t]) { GdaCircle* c = new GdaCircle(wxRealPoint(x, y), ss_circ_rad); c->setPen(GdaConst::ln_cht_clr_tm2_light); c->setBrush(GdaConst::ln_cht_clr_tm2_light); background_shps.push_back(c); } } } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_sel_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_sel_avg[t] - axis_scale_y.scale_min) * scaleY; if (lcs.tms_subset0[t]) { GdaCircle* c = new GdaCircle(wxRealPoint(x, y), ss_circ_rad); if (lcs.compare_r_and_t) { c->setPen(GdaConst::ln_cht_clr_tm1_light); c->setBrush(GdaConst::ln_cht_clr_tm1_light); } else { c->setPen(GdaConst::ln_cht_clr_regimes_hl); c->setBrush(GdaConst::ln_cht_clr_regimes_hl); } background_shps.push_back(c); } if (lcs.compare_r_and_t && lcs.tms_subset1[t]) { GdaCircle* c = new GdaCircle(wxRealPoint(x, y), ss_circ_rad); c->setPen(GdaConst::ln_cht_clr_tm2_light); c->setBrush(GdaConst::ln_cht_clr_tm2_light); background_shps.push_back(c); } } } if (lcs.Y_avg_valid && lcs.Y_excl_avg_valid == lcs.Y_sel_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_avg[t] - axis_scale_y.scale_min) * scaleY; if (lcs.tms_subset0[t]) { GdaCircle* c = new GdaCircle(wxRealPoint(x, y), ss_circ_rad); if (lcs.compare_time_periods || lcs.compare_r_and_t) { c->setPen(GdaConst::ln_cht_clr_tm1_light); c->setBrush(GdaConst::ln_cht_clr_tm1_light); } else { c->setPen(GdaConst::ln_cht_clr_regimes_hl); c->setBrush(GdaConst::ln_cht_clr_regimes_hl); } background_shps.push_back(c); } if ((lcs.compare_time_periods || lcs.compare_r_and_t) && lcs.tms_subset1[t]) { GdaCircle* c = new GdaCircle(wxRealPoint(x, y), ss_circ_rad); c->setPen(GdaConst::ln_cht_clr_tm2_light); c->setBrush(GdaConst::ln_cht_clr_tm2_light); background_shps.push_back(c); } } } // Draw everything else if (lcs.Y_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_avg[t] - axis_scale_y.scale_min) * scaleY; y_pts[t].x = x; y_pts[t].y = y; } GdaPolyLine* p = new GdaPolyLine(num_points, y_pts); p->setPen(wxPen(*wxBLACK, 1, wxSHORT_DASH)); background_shps.push_back(p); for (size_t t=0; t<tms; ++t) { GdaCircle* c = new GdaCircle(wxRealPoint(y_pts[t].x, y_pts[t].y), circ_rad); wxColour lc = *wxBLACK; wxColour dc = GdaColorUtils::ChangeBrightness(lc); c->setPen(lc); c->setBrush(dc); background_shps.push_back(c); comb_circs.push_back(c); } } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_excl_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_excl_avg[t] - axis_scale_y.scale_min) * scaleY; y_pts[t].x = x; y_pts[t].y = y; } GdaPolyLine* p = new GdaPolyLine(num_points, y_pts); p->setPen(GdaConst::ln_cht_clr_exl_dark); background_shps.push_back(p); for (size_t t=0; t<tms; ++t) { GdaCircle* c = new GdaCircle(wxRealPoint(y_pts[t].x, y_pts[t].y), circ_rad); wxColour lc = GdaConst::ln_cht_clr_exl_dark; wxColour dc = GdaColorUtils::ChangeBrightness(lc); c->setPen(lc); c->setBrush(dc); background_shps.push_back(c); excl_circs.push_back(c); } } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_sel_avg_valid) { for (size_t t=0; t<tms; ++t) { double fracX = ((double) t)/((double) (tms-1)); double x = fracX * 100.0; double y = (lcs.Y_sel_avg[t] - axis_scale_y.scale_min) * scaleY; y_pts[t].x = x; y_pts[t].y = y; } GdaPolyLine* p = new GdaPolyLine(num_points, y_pts); p->setPen(GdaConst::ln_cht_clr_sel_dark); background_shps.push_back(p); for (size_t t=0; t<tms; ++t) { GdaCircle* c = new GdaCircle(wxRealPoint(y_pts[t].x, y_pts[t].y), circ_rad); wxColour lc = GdaConst::ln_cht_clr_sel_dark; wxColour dc = GdaColorUtils::ChangeBrightness(lc); c->setPen(lc); c->setBrush(dc); background_shps.push_back(c); sel_circs.push_back(c); } } } if (!time_variant) { size_t t = 0; const double d=5.0; const double x = 50.0; if (lcs.Y_avg_valid && lcs.Y_excl_avg_valid == lcs.Y_sel_avg_valid) { double y = (lcs.Y_avg[t] - axis_scale_y.scale_min) * scaleY; GdaPolyLine* p = new GdaPolyLine(x-d, y, x+d, y); p->setPen(*wxBLACK_PEN); background_shps.push_back(p); GdaCircle* c = new GdaCircle(wxRealPoint(x,y), circ_rad); wxColour lc = *wxBLACK; wxColour dc = GdaColorUtils::ChangeBrightness(lc); c->setPen(lc); c->setBrush(dc); background_shps.push_back(c); comb_circs.push_back(c); } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_excl_avg_valid) { double y = (lcs.Y_excl_avg[t] - axis_scale_y.scale_min) * scaleY; GdaPolyLine* p = new GdaPolyLine(x-d, y, x+d, y); p->setPen(GdaConst::ln_cht_clr_exl_dark); background_shps.push_back(p); GdaCircle* c = new GdaCircle(wxRealPoint(x,y), circ_rad); wxColour lc = GdaConst::ln_cht_clr_exl_dark; wxColour dc = GdaColorUtils::ChangeBrightness(lc); c->setPen(lc); c->setBrush(dc); background_shps.push_back(c); excl_circs.push_back(c); } if ((lcs.compare_regimes || lcs.compare_r_and_t) && lcs.Y_sel_avg_valid) { double y = (lcs.Y_sel_avg[t] - axis_scale_y.scale_min) * scaleY; GdaPolyLine* p = new GdaPolyLine(x-d, y, x+d, y); p->setPen(GdaConst::ln_cht_clr_sel_dark); background_shps.push_back(p); GdaCircle* c = new GdaCircle(wxRealPoint(x,y), circ_rad); wxColour lc = GdaConst::ln_cht_clr_sel_dark; wxColour dc = GdaColorUtils::ChangeBrightness(lc); c->setPen(lc); c->setBrush(dc); background_shps.push_back(c); sel_circs.push_back(c); } } GdaAxis* x_baseline = 0; if (time_variant) { x_baseline = new GdaAxis("", tm_strs, wxRealPoint(0,0), wxRealPoint(100, 0), 0, 5); x_baseline->hideCaption(true); x_baseline->setPen(*GdaConst::scatterplot_scale_pen); x_baseline->autoDropScaleValues(true); x_baseline->moveOuterValTextInwards(false); background_shps.push_back(x_baseline); } GdaAxis* y_baseline = new GdaAxis(lcs.Yname, axis_scale_y, wxRealPoint(0,0), wxRealPoint(0, 100), -5, 0); y_baseline->autoDropScaleValues(true); y_baseline->moveOuterValTextInwards(true); y_baseline->setPen(*GdaConst::scatterplot_scale_pen); background_shps.push_back(y_baseline); if (y_pts) delete [] y_pts; ResizeSelectableShps(); Refresh(false); LOG_MSG("Exiting LineChartCanvas::PopulateCanvas"); }
// The following function assumes that the set of selectable objects // are all rectangles. void ConditionalHistogramCanvas::UpdateSelection(bool shiftdown, bool pointsel) { bool rect_sel = (!pointsel && (brushtype == rectangle)); int t = var_info[HIST_VAR].time; std::vector<bool>& hs = highlight_state->GetHighlight(); bool selection_changed = false; int total_sel_shps = selectable_shps.size(); wxPoint lower_left; wxPoint upper_right; if (rect_sel) { GenGeomAlgs::StandardizeRect(sel1, sel2, lower_left, upper_right); } if (!shiftdown) { bool any_selected = false; for (int i=0; i<total_sel_shps; i++) { GdaRectangle* rec = (GdaRectangle*) selectable_shps[i]; if ((pointsel && rec->pointWithin(sel1)) || (rect_sel && GenGeomAlgs::RectsIntersect(rec->lower_left, rec->upper_right, lower_left, upper_right))) { any_selected = true; break; } } if (!any_selected) { highlight_state->SetEventType(HLStateInt::unhighlight_all); highlight_state->notifyObservers(); return; } } for (int i=0; i<total_sel_shps; i++) { int r, c, ival; 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[t][r][c].ival_obs_cnt[ival] == cell_data[t][r][c].ival_obs_sel_cnt[ival]); if (pointsel && all_sel && selected) { // unselect all in ival for (std::list<int>::iterator 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++) { hs[(*it)]= false; selection_changed = true; } } else if (!all_sel && selected) { // select currently unselected in ival for (std::list<int>::iterator 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++) { if (hs[*it]) continue; hs[(*it)]= true; selection_changed = true; } } else if (!selected && !shiftdown) { // unselect all selected in ival for (std::list<int>::iterator 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++) { if (!hs[*it]) continue; hs[(*it)]= false; selection_changed = true; } } } if ( selection_changed ) { highlight_state->SetEventType(HLStateInt::delta); highlight_state->notifyObservers(); } UpdateStatusBar(); }