12 #include <mrpt/config.h>
28 #if MRPT_HAS_WXWIDGETS
41 wxWindowID
id, const std::
string& caption, wxSize initialSize)
42 : m_winPlots(winPlots), m_mainFrame(parent), m_firstSubmenu(true)
45 parent,
id, caption.c_str(), wxDefaultPosition, initialSize,
46 wxDEFAULT_FRAME_STYLE, _T(
"id"));
48 SetClientSize(initialSize);
55 m_plot =
new mpWindow(
this, ID_PLOT);
56 m_plot->AddLayer(
new mpScaleX());
57 m_plot->AddLayer(
new mpScaleY());
58 m_plot->LockAspect(
false);
59 m_plot->EnableDoubleBuffer(
true);
61 m_plot->Fit(-10, 10, -10, 10);
64 auto* MenuBar1 =
new wxMenuBar();
66 auto* Menu1 =
new wxMenu();
67 wxMenuItem* MenuItem1 =
68 new wxMenuItem(Menu1,
ID_MENUITEM1, _(
"Close"), _(
""), wxITEM_NORMAL);
69 Menu1->Append(MenuItem1);
71 wxMenuItem* MenuItemPrint =
new wxMenuItem(
72 Menu1, ID_MENU_PRINT, _(
"Print..."), _(
""), wxITEM_NORMAL);
73 Menu1->Append(MenuItemPrint);
75 MenuBar1->Append(Menu1, _(
"&File"));
77 auto* Menu2 =
new wxMenu();
78 wxMenuItem* MenuItem2 =
new wxMenuItem(
79 Menu2,
ID_MENUITEM2, _(
"About..."), _(
""), wxITEM_NORMAL);
80 Menu2->Append(MenuItem2);
81 MenuBar1->Append(Menu2, _(
"&Help"));
115 XYPlot *plot =
new XYPlot();
117 XYSimpleDataset *dataset =
new XYSimpleDataset();
119 dataset->AddSerie((
double *)
data, WXSIZEOF(
data));
121 dataset->SetRenderer(
new XYLineRenderer());
123 plot->AddDataset(dataset);
125 NumberAxis *leftAxis =
new NumberAxis(AXIS_LEFT);
126 NumberAxis *bottomAxis =
new NumberAxis(AXIS_BOTTOM);
128 leftAxis->SetTitle(wxT(
"X"));
129 bottomAxis->SetTitle(wxT(
"Y"));
131 plot->AddAxis(leftAxis);
132 plot->AddAxis(bottomAxis);
134 plot->LinkDataVerticalAxis(0, 0);
135 plot->LinkDataHorizontalAxis(0, 0);
137 Chart* chart =
new Chart(plot, wxT(
"my title"));
138 wxChartPanel *m_chartPanel =
new wxChartPanel(
this );
139 m_chartPanel->SetChart( chart );
149 bool allow_close =
true;
153 m_winPlots->publishEvent(ev);
159 if (!allow_close)
return;
162 m_winPlots->notifyChildWindowDestruction();
168 m_winPlots->m_windowDestroyed.set_value();
177 const int code =
event.GetKeyCode();
180 m_winPlots->m_keyPushedCode = code;
181 m_winPlots->m_keyPushedModifier = mod;
182 m_winPlots->m_keyPushed =
true;
186 m_winPlots->publishEvent(
204 m_winPlots, event.GetSize().GetWidth(),
205 event.GetSize().GetHeight()));
222 m_winPlots,
TPixelCoord(event.GetX(), event.GetY()),
223 event.LeftDown(), event.RightDown()));
237 m_plot->ShowPrintDialog();
243 _(
"Plot viewer\n Class gui::CDisplayWindowPlots\n MRPT C++ & "
244 "wxMathPlot library"),
250 auto it = m_ID2ID.find(ev.GetId());
251 if (it != m_ID2ID.end())
253 if (m_winPlots && m_winPlots->m_callback)
254 m_winPlots->m_callback(
255 it->second,
d2f(m_curCursorPos.x),
d2f(m_curCursorPos.y),
256 m_winPlots->m_callback_param);
263 event.GetPosition(&X, &Y);
264 m_curCursorPos.x = m_plot->p2x(X);
265 m_curCursorPos.y = m_plot->p2y(Y);
266 m_last_mouse_point.x = X;
267 m_last_mouse_point.y = Y;
270 if (m_winPlots && m_winPlots->hasSubscribers())
276 event.LeftDown(), event.RightDown()));
288 const std::string& plotName)
290 mpFXYVector* theLayer;
292 wxString lyName = plotName.c_str();
293 bool updateAtTheEnd =
false;
297 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
302 auto* lyPlot2D =
dynamic_cast<mpFXYVector*
>(existingLy);
306 cerr <<
"[CWindowDialogPlots::plot] Plot name '" << plotName
307 <<
"' is not of expected class mpFXYVector!." << endl;
313 updateAtTheEnd =
true;
318 theLayer =
new mpFXYVector(lyName);
319 m_plot->AddLayer(theLayer);
324 std::vector<float> x_(x.
size()), y_(x.
size());
326 std::memcpy(&y_[0], &y[0],
sizeof(y[0]) * y_.size());
327 theLayer->SetData(x_, y_);
332 bool isContinuous =
true;
333 int lineColor[] = {0, 0, 255};
335 wxPenStyle lineStyle = wxPENSTYLE_SOLID;
338 if (string::npos != lineFormat.find(
"."))
340 isContinuous =
false;
342 if (string::npos != lineFormat.find(
"-"))
345 lineStyle = wxPENSTYLE_SOLID;
347 if (string::npos != lineFormat.find(
":"))
350 lineStyle = wxPENSTYLE_LONG_DASH;
353 if (string::npos != lineFormat.find(
"r"))
359 if (string::npos != lineFormat.find(
"g"))
365 if (string::npos != lineFormat.find(
"b"))
371 if (string::npos != lineFormat.find(
"k"))
377 if (string::npos != lineFormat.find(
"m"))
383 if (string::npos != lineFormat.find(
"c"))
390 if (string::npos != lineFormat.find(
"1"))
394 if (string::npos != lineFormat.find(
"2"))
398 if (string::npos != lineFormat.find(
"3"))
402 if (string::npos != lineFormat.find(
"4"))
406 if (string::npos != lineFormat.find(
"5"))
410 if (string::npos != lineFormat.find(
"6"))
414 if (string::npos != lineFormat.find(
"7"))
418 if (string::npos != lineFormat.find(
"8"))
422 if (string::npos != lineFormat.find(
"9"))
427 theLayer->SetContinuity(isContinuous);
430 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
432 theLayer->SetPen(pen);
434 theLayer->ShowName(
false);
436 if (updateAtTheEnd) m_plot->Refresh(
false);
444 const std::string& plotName,
bool showName)
446 mpCovarianceEllipse* theLayer;
450 cerr <<
"[CWindowDialogPlots::plotEllipse] vectors do not have "
456 wxString lyName = plotName.c_str();
457 bool updateAtTheEnd =
false;
461 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
466 auto* lyPlotEllipse =
dynamic_cast<mpCovarianceEllipse*
>(existingLy);
470 cerr <<
"[CWindowDialogPlots::plotEllipse] Plot name '" << plotName
471 <<
"' is not of expected class mpCovarianceEllipse!." << endl;
476 theLayer = lyPlotEllipse;
477 updateAtTheEnd =
true;
482 theLayer =
new mpCovarianceEllipse(1, 1, 0, 2, 32, lyName);
483 m_plot->AddLayer(theLayer);
487 theLayer->SetCovarianceMatrix(y[0], y[2], y[1]);
488 theLayer->SetCoordinateBase(x[0], x[1]);
489 theLayer->SetQuantiles(x[2]);
490 theLayer->ShowName(showName);
494 bool isContinuous =
true;
495 int lineColor[] = {0, 0, 255};
497 wxPenStyle lineStyle = wxPENSTYLE_SOLID;
500 if (string::npos != lineFormat.find(
"."))
502 isContinuous =
false;
504 if (string::npos != lineFormat.find(
"-"))
507 lineStyle = wxPENSTYLE_SOLID;
509 if (string::npos != lineFormat.find(
":"))
512 lineStyle = wxPENSTYLE_LONG_DASH;
515 if (string::npos != lineFormat.find(
"r"))
521 if (string::npos != lineFormat.find(
"g"))
527 if (string::npos != lineFormat.find(
"b"))
533 if (string::npos != lineFormat.find(
"k"))
539 if (string::npos != lineFormat.find(
"m"))
545 if (string::npos != lineFormat.find(
"c"))
552 if (string::npos != lineFormat.find(
"1"))
556 if (string::npos != lineFormat.find(
"2"))
560 if (string::npos != lineFormat.find(
"3"))
564 if (string::npos != lineFormat.find(
"4"))
568 if (string::npos != lineFormat.find(
"5"))
572 if (string::npos != lineFormat.find(
"6"))
576 if (string::npos != lineFormat.find(
"7"))
580 if (string::npos != lineFormat.find(
"8"))
584 if (string::npos != lineFormat.find(
"9"))
589 theLayer->SetContinuity(isContinuous);
592 wxColour(lineColor[0], lineColor[1], lineColor[2]), lineWidth,
594 theLayer->SetPen(pen);
596 if (updateAtTheEnd) m_plot->Refresh(
false);
600 void* theWxImage,
float x0,
float y0,
float w,
float h,
601 const std::string& plotName)
603 mpBitmapLayer* theLayer;
605 wxString lyName = plotName.c_str();
606 bool updateAtTheEnd =
false;
610 mpLayer* existingLy = m_plot->GetLayerByName(lyName);
615 auto* ly =
dynamic_cast<mpBitmapLayer*
>(existingLy);
619 cerr <<
"[CWindowDialogPlots::image] Plot name '" << plotName
620 <<
"' is not of expected class mpBitmapLayer!." << endl;
626 updateAtTheEnd =
true;
631 theLayer =
new mpBitmapLayer();
632 m_plot->AddLayer(theLayer);
636 auto* ii =
static_cast<wxImage*
>(theWxImage);
637 theLayer->SetBitmap(*ii, x0, y0, w, h);
640 theWxImage =
nullptr;
642 if (updateAtTheEnd) m_plot->Refresh();
648 const std::string& windowCaption,
unsigned int initialWindowWidth,
649 unsigned int initialWindowHeight)
651 return std::make_shared<CDisplayWindowPlots>(
652 windowCaption, initialWindowWidth, initialWindowHeight);
658 const std::string& windowCaption,
unsigned int initialWidth,
659 unsigned int initialHeight)
660 :
CBaseGUIWindow(static_cast<void*>(this), 400, 499, windowCaption)
678 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
681 win->m_plot->SetCursor(
682 *(cursorIsCross ? wxCROSS_CURSOR : wxSTANDARD_CURSOR));
690 [[maybe_unused]]
int& x, [[maybe_unused]]
int& y)
const
692 #if MRPT_HAS_WXWIDGETS && MRPT_HAS_OPENGL_GLUT
694 if (!
win)
return false;
695 x =
win->m_last_mouse_point.x;
696 y =
win->m_last_mouse_point.y;
707 [[maybe_unused]]
unsigned int width, [[maybe_unused]]
unsigned int height)
709 #if MRPT_HAS_WXWIDGETS
712 cerr <<
"[CDisplayWindowPlots::resize] Window closed!: " <<
m_caption
732 #if MRPT_HAS_WXWIDGETS
735 cerr <<
"[CDisplayWindowPlots::setPos] Window closed!: " <<
m_caption
754 [maybe_unused]]
const std::string& str)
756 #if MRPT_HAS_WXWIDGETS
759 cerr <<
"[CDisplayWindowPlots::setWindowTitle] Window closed!: "
778 #if MRPT_HAS_WXWIDGETS
785 REQ->boolVal = enabled;
795 #if MRPT_HAS_WXWIDGETS
802 REQ->boolVal = enabled;
811 [[maybe_unused]]
float x_min, [[maybe_unused]]
float x_max,
812 [[maybe_unused]]
float y_min, [[maybe_unused]]
float y_max,
813 [[maybe_unused]]
bool aspectRatioFix)
815 #if MRPT_HAS_WXWIDGETS
823 REQ->vector_x[0] = x_min;
824 REQ->vector_x[1] = x_max;
825 REQ->vector_y.resize(2);
826 REQ->vector_y[0] = y_min;
827 REQ->vector_y[1] = y_max;
828 REQ->boolVal = aspectRatioFix;
838 #if MRPT_HAS_WXWIDGETS
845 REQ->boolVal = aspectRatioFix;
853 template <
typename T>
855 [[maybe_unused]]
const T mean_x, [[maybe_unused]]
const T mean_y,
857 [[maybe_unused]]
const float quantiles,
858 [[maybe_unused]]
const std::string& lineFormat,
859 [[maybe_unused]]
const std::string& plotName,
860 [[maybe_unused]]
bool showName)
862 #if MRPT_HAS_WXWIDGETS
866 ASSERT_(cov22.cols() == 2 && cov22.rows() == 2);
869 ASSERT_(cov22(0, 1) == cov22(1, 0));
876 std::string holdon_post;
888 REQ->str = lineFormat;
889 REQ->plotName = plotName + holdon_post;
892 REQ->vector_x[0] =
d2f(mean_x);
893 REQ->vector_x[1] =
d2f(mean_y);
894 REQ->vector_x[2] = quantiles;
896 REQ->vector_y.resize(3);
897 REQ->vector_y[0] =
d2f(cov22(0, 0));
898 REQ->vector_y[1] =
d2f(cov22(1, 1));
899 REQ->vector_y[2] =
d2f(cov22(0, 1));
901 REQ->boolVal = showName;
911 const float quantiles,
const std::string& lineFormat,
912 const std::string& plotName,
bool showName);
914 const double mean_x,
const double mean_y,
916 const std::string& lineFormat,
const std::string& plotName,
bool showName);
921 template <
typename T>
923 [[maybe_unused]]
const T mean_x, [[maybe_unused]]
const T mean_y,
925 [[maybe_unused]]
const float quantiles,
926 [[maybe_unused]]
const std::string& lineFormat,
927 [[maybe_unused]]
const std::string& plotName,
928 [[maybe_unused]]
bool showName)
930 #if MRPT_HAS_WXWIDGETS
936 ASSERT_(cov22(0, 1) == cov22(1, 0));
943 std::string holdon_post;
955 REQ->str = lineFormat;
956 REQ->plotName = plotName + holdon_post;
959 REQ->vector_x[0] =
d2f(mean_x);
960 REQ->vector_x[1] =
d2f(mean_y);
961 REQ->vector_x[2] = quantiles;
963 REQ->vector_y.resize(3);
964 REQ->vector_y[0] =
d2f(cov22(0, 0));
965 REQ->vector_y[1] =
d2f(cov22(1, 1));
966 REQ->vector_y[2] =
d2f(cov22(0, 1));
968 REQ->boolVal = showName;
977 const float mean_x,
const float mean_y,
979 const std::string& lineFormat,
const std::string& plotName,
bool showName);
981 const double mean_x,
const double mean_y,
983 const std::string& lineFormat,
const std::string& plotName,
bool showName);
990 [[maybe_unused]]
float x_left, [[maybe_unused]]
float y_bottom,
991 [[maybe_unused]]
float x_width, [[maybe_unused]]
float y_height,
992 [[maybe_unused]]
const std::string& plotName)
994 #if MRPT_HAS_WXWIDGETS
1003 std::string holdon_post;
1016 REQ->plotName = plotName + holdon_post;
1019 REQ->vector_x[0] = x_left;
1020 REQ->vector_x[1] = y_bottom;
1021 REQ->vector_x[2] = x_width;
1022 REQ->vector_x[3] = y_height;
1036 [[maybe_unused]]
const std::string& lineFormat,
1037 [[maybe_unused]]
const std::string& plotName)
1039 #if MRPT_HAS_WXWIDGETS
1051 if (x.empty())
return;
1053 std::string holdon_post;
1062 REQ->str = lineFormat;
1063 REQ->plotName = plotName + holdon_post;
1064 REQ->vector_x.swap(x);
1065 REQ->vector_y.swap(y);
1078 #if MRPT_HAS_WXWIDGETS
1113 [[maybe_unused]]
const std::string& label, [[maybe_unused]]
int menuID)
1115 #if MRPT_HAS_WXWIDGETS
1122 REQ->plotName = label;
1137 ASSERT_(userFunction !=
nullptr);