Tabs.C 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415
  1. #include "Tabs.h"
  2. #include "Wt/WDoubleValidator"
  3. #include "Wt/WIntValidator"
  4. #include "Wt/Chart/WAbstractChartImplementation"
  5. #include "Wt/WPushButton"
  6. #include "Wt/WSelectionBox"
  7. #include <limits>
  8. #include <functional>
  9. ChartSettings::ChartSettings(WCartesian3DChart *chart,
  10. WContainerWidget * parent)
  11. : WContainerWidget(parent)
  12. {
  13. WTemplate* template_ = new WTemplate(Wt::WString::tr("chartconfig-template"), this);
  14. WCheckBox *autoRangeX_ = new WCheckBox(this);
  15. template_->bindWidget("xAuto", autoRangeX_);
  16. autoRangeX_->setCheckState(Wt::Checked);
  17. chart->initLayout();
  18. WLineEdit *xMin_ = new WLineEdit
  19. (Wt::asString(chart->axis(XAxis_3D).minimum()), this);
  20. template_->bindWidget("xAxisMin", xMin_);
  21. xMin_->setValidator(new Wt::WDoubleValidator(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
  22. xMin_->setEnabled(false);
  23. WLineEdit *xMax_ = new WLineEdit
  24. (Wt::asString(chart->axis(XAxis_3D).maximum()), this);
  25. template_->bindWidget("xAxisMax", xMax_);
  26. xMax_->setValidator(new Wt::WDoubleValidator(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
  27. xMax_->setEnabled(false);
  28. WCheckBox *autoRangeY_ = new WCheckBox(this);
  29. template_->bindWidget("yAuto", autoRangeY_);
  30. autoRangeY_->setCheckState(Wt::Checked);
  31. WLineEdit *yMin_ = new WLineEdit
  32. (Wt::asString(chart->axis(YAxis_3D).minimum()), this);
  33. template_->bindWidget("yAxisMin", yMin_);
  34. yMin_->setValidator(new Wt::WDoubleValidator(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
  35. yMin_->setEnabled(false);
  36. WLineEdit *yMax_ = new WLineEdit
  37. (Wt::asString(chart->axis(YAxis_3D).maximum()), this);
  38. template_->bindWidget("yAxisMax", yMax_);
  39. yMax_->setValidator(new Wt::WDoubleValidator(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
  40. yMax_->setEnabled(false);
  41. WCheckBox *autoRangeZ_ = new WCheckBox(this);
  42. template_->bindWidget("zAuto", autoRangeZ_);
  43. autoRangeZ_->setCheckState(Wt::Checked);
  44. WLineEdit *zMin_ = new WLineEdit
  45. (Wt::asString(chart->axis(ZAxis_3D).minimum()), this);
  46. template_->bindWidget("zAxisMin", zMin_);
  47. zMin_->setValidator(new Wt::WDoubleValidator(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
  48. zMin_->setEnabled(false);
  49. WLineEdit *zMax_ = new WLineEdit
  50. (Wt::asString(chart->axis(ZAxis_3D).maximum()), this);
  51. template_->bindWidget("zAxisMax", zMax_);
  52. zMax_->setValidator(new Wt::WDoubleValidator(-std::numeric_limits<double>::max(), std::numeric_limits<double>::max()));
  53. zMax_->setEnabled(false);
  54. WLineEdit *title = new WLineEdit(this);
  55. template_->bindWidget("chartTitle", title);
  56. WCheckBox *enableLegend = new WCheckBox(this);
  57. template_->bindWidget("chartLegend", enableLegend);
  58. WComboBox *legendSide = new WComboBox(this);
  59. legendSide->addItem("Left");
  60. legendSide->addItem("Right");
  61. legendSide->addItem("Top");
  62. legendSide->addItem("Bottom");
  63. template_->bindWidget("legendside", legendSide);
  64. switch (chart->legendSide()) {
  65. case Left:
  66. legendSide->setCurrentIndex(0); break;
  67. case Right:
  68. legendSide->setCurrentIndex(1); break;
  69. case Top:
  70. legendSide->setCurrentIndex(2); break;
  71. case Bottom:
  72. legendSide->setCurrentIndex(3); break;
  73. default:
  74. break;
  75. }
  76. WComboBox *legendAlignment = new WComboBox(this);
  77. legendAlignment->addItem("Left");
  78. legendAlignment->addItem("Center");
  79. legendAlignment->addItem("Right");
  80. legendAlignment->addItem("Top");
  81. legendAlignment->addItem("Middle");
  82. legendAlignment->addItem("Bottom");
  83. template_->bindWidget("legendalignment", legendAlignment);
  84. switch (chart->legendAlignment()) {
  85. case AlignLeft:
  86. legendAlignment->setCurrentIndex(0); break;
  87. case AlignCenter:
  88. legendAlignment->setCurrentIndex(1); break;
  89. case AlignRight:
  90. legendAlignment->setCurrentIndex(2); break;
  91. case AlignTop:
  92. legendAlignment->setCurrentIndex(3); break;
  93. case AlignMiddle:
  94. legendAlignment->setCurrentIndex(4); break;
  95. case AlignBottom:
  96. legendAlignment->setCurrentIndex(5); break;
  97. default:
  98. break;
  99. }
  100. WCheckBox *enableGridLines = new WCheckBox(this);
  101. template_->bindWidget("gridlines", enableGridLines);
  102. WCheckBox *enableIntersectionLines = new WCheckBox(this);
  103. template_->bindWidget("intersectionlines", enableIntersectionLines);
  104. WComboBox *intersectionLineColor = new WComboBox(this);
  105. intersectionLineColor->addItem("red");
  106. intersectionLineColor->addItem("green");
  107. intersectionLineColor->addItem("blue");
  108. intersectionLineColor->addItem("black");
  109. intersectionLineColor->addItem("cyan");
  110. intersectionLineColor->addItem("magenta");
  111. intersectionLineColor->addItem("yellow");
  112. intersectionLineColor->setCurrentIndex(intersectionLineColor->count() - 1);
  113. template_->bindWidget("intersectionlinecolor", intersectionLineColor);
  114. WLineEdit *widgetWidth = new WLineEdit(Wt::asString(chart->width().value()), this);
  115. widgetWidth->setValidator(new Wt::WIntValidator(1, 2000));
  116. WLineEdit *widgetHeight = new WLineEdit(Wt::asString(chart->height().value()), this);
  117. widgetHeight->setValidator(new Wt::WIntValidator(1, 2000));
  118. template_->bindWidget("width", widgetWidth);
  119. template_->bindWidget("height", widgetHeight);
  120. WLineEdit *xAxisTitle = new WLineEdit(chart->axis(XAxis_3D).title(), this);
  121. WLineEdit *yAxisTitle = new WLineEdit(chart->axis(YAxis_3D).title(), this);
  122. WLineEdit *zAxisTitle = new WLineEdit(chart->axis(ZAxis_3D).title(), this);
  123. template_->bindWidget("xTitle", xAxisTitle);
  124. template_->bindWidget("yTitle", yAxisTitle);
  125. template_->bindWidget("zTitle", zAxisTitle);
  126. // hook it up
  127. autoRangeX_->checked().connect(std::bind([=] () {
  128. chart->axis(XAxis_3D).setAutoLimits(Chart::MinimumValue
  129. | Chart::MaximumValue);
  130. xMin_->setEnabled(false); xMax_->setEnabled(false);
  131. }));
  132. autoRangeX_->unChecked().connect(std::bind([=] () {
  133. xMin_->setEnabled(true); xMax_->setEnabled(true);
  134. chart->axis(XAxis_3D).setRange(Wt::asNumber(xMin_->text()),
  135. Wt::asNumber(xMax_->text()));
  136. }));
  137. autoRangeY_->checked().connect(std::bind([=] () {
  138. chart->axis(YAxis_3D).setAutoLimits(Chart::MinimumValue
  139. | Chart::MaximumValue);
  140. yMin_->setEnabled(false); yMax_->setEnabled(false);
  141. }));
  142. autoRangeY_->unChecked().connect(std::bind([=] () {
  143. yMin_->setEnabled(true); yMax_->setEnabled(true);
  144. chart->axis(YAxis_3D).setRange(Wt::asNumber(yMin_->text()),
  145. Wt::asNumber(yMax_->text()));
  146. }));
  147. autoRangeZ_->checked().connect(std::bind([=] () {
  148. chart->axis(ZAxis_3D).setAutoLimits(Chart::MinimumValue
  149. | Chart::MaximumValue);
  150. zMin_->setEnabled(false); zMax_->setEnabled(false);
  151. }));
  152. autoRangeZ_->unChecked().connect(std::bind([=] () {
  153. zMin_->setEnabled(true); zMax_->setEnabled(true);
  154. chart->axis(ZAxis_3D).setRange(Wt::asNumber(zMin_->text()),
  155. Wt::asNumber(zMax_->text()));
  156. }));
  157. xMin_->changed().connect(std::bind([=] () {
  158. chart->axis(XAxis_3D).setRange(Wt::asNumber(xMin_->text()),
  159. Wt::asNumber(xMax_->text()));
  160. }));
  161. xMax_->changed().connect(std::bind([=] () {
  162. chart->axis(XAxis_3D).setRange(Wt::asNumber(xMin_->text()),
  163. Wt::asNumber(xMax_->text()));
  164. }));
  165. yMin_->changed().connect(std::bind([=] () {
  166. chart->axis(YAxis_3D).setRange(Wt::asNumber(yMin_->text()),
  167. Wt::asNumber(yMax_->text()));
  168. }));
  169. yMax_->changed().connect(std::bind([=] () {
  170. chart->axis(YAxis_3D).setRange(Wt::asNumber(yMin_->text()),
  171. Wt::asNumber(yMax_->text()));
  172. }));
  173. zMin_->changed().connect(std::bind([=] () {
  174. chart->axis(ZAxis_3D).setRange(Wt::asNumber(zMin_->text()),
  175. Wt::asNumber(zMax_->text()));
  176. }));
  177. zMax_->changed().connect(std::bind([=] () {
  178. chart->axis(ZAxis_3D).setRange(Wt::asNumber(zMin_->text()),
  179. Wt::asNumber(zMax_->text()));
  180. }));
  181. enableGridLines->checked().connect(std::bind([=]() {
  182. chart->setGridEnabled(Wt::Chart::XY_Plane, Wt::Chart::XAxis_3D, true);
  183. chart->setGridEnabled(Wt::Chart::XY_Plane, Wt::Chart::YAxis_3D, true);
  184. chart->setGridEnabled(Wt::Chart::XZ_Plane, Wt::Chart::XAxis_3D, true);
  185. chart->setGridEnabled(Wt::Chart::XZ_Plane, Wt::Chart::ZAxis_3D, true);
  186. chart->setGridEnabled(Wt::Chart::YZ_Plane, Wt::Chart::YAxis_3D, true);
  187. chart->setGridEnabled(Wt::Chart::YZ_Plane, Wt::Chart::ZAxis_3D, true);
  188. }));
  189. enableGridLines->unChecked().connect(std::bind([=]() {
  190. chart->setGridEnabled(Wt::Chart::XY_Plane, Wt::Chart::XAxis_3D, false);
  191. chart->setGridEnabled(Wt::Chart::XY_Plane, Wt::Chart::YAxis_3D, false);
  192. chart->setGridEnabled(Wt::Chart::XZ_Plane, Wt::Chart::XAxis_3D, false);
  193. chart->setGridEnabled(Wt::Chart::XZ_Plane, Wt::Chart::ZAxis_3D, false);
  194. chart->setGridEnabled(Wt::Chart::YZ_Plane, Wt::Chart::YAxis_3D, false);
  195. chart->setGridEnabled(Wt::Chart::YZ_Plane, Wt::Chart::ZAxis_3D, false);
  196. }));
  197. auto changeIntersectionLinesColor = [=]() {
  198. switch (intersectionLineColor->currentIndex()) {
  199. case 0:
  200. chart->setIntersectionLinesColor(WColor(255,0,0)); break;
  201. case 1:
  202. chart->setIntersectionLinesColor(WColor(0,255,0)); break;
  203. case 2:
  204. chart->setIntersectionLinesColor(WColor(0,0,255)); break;
  205. case 3:
  206. chart->setIntersectionLinesColor(WColor(0,0,0)); break;
  207. case 4:
  208. chart->setIntersectionLinesColor(WColor(0,255,255)); break;
  209. case 5:
  210. chart->setIntersectionLinesColor(WColor(255,0,255)); break;
  211. case 6:
  212. chart->setIntersectionLinesColor(WColor(255,255,0)); break;
  213. }
  214. };
  215. enableIntersectionLines->checked().connect(std::bind([=]() {
  216. chart->setIntersectionLinesEnabled(true);
  217. changeIntersectionLinesColor();
  218. }));
  219. enableIntersectionLines->unChecked().connect(std::bind([=]() {
  220. chart->setIntersectionLinesEnabled(false);
  221. }));
  222. intersectionLineColor->changed().connect(std::bind(changeIntersectionLinesColor));
  223. enableLegend->checked().connect(std::bind([=]() {
  224. chart->setLegendEnabled(true);
  225. }));
  226. enableLegend->unChecked().connect(std::bind([=]() {
  227. chart->setLegendEnabled(false);
  228. }));
  229. legendSide->changed().connect(std::bind([=]() {
  230. switch (legendSide->currentIndex()) {
  231. case 0:
  232. chart->setLegendLocation(Left, chart->legendAlignment()); break;
  233. case 1:
  234. chart->setLegendLocation(Right, chart->legendAlignment()); break;
  235. case 2:
  236. chart->setLegendLocation(Top, chart->legendAlignment()); break;
  237. case 3:
  238. chart->setLegendLocation(Bottom, chart->legendAlignment()); break;
  239. }
  240. }));
  241. legendAlignment->changed().connect(std::bind([=]() {
  242. switch (legendAlignment->currentIndex()) {
  243. case 0:
  244. chart->setLegendLocation(chart->legendSide(), AlignLeft); break;
  245. case 1:
  246. chart->setLegendLocation(chart->legendSide(), AlignCenter); break;
  247. case 2:
  248. chart->setLegendLocation(chart->legendSide(), AlignRight); break;
  249. case 3:
  250. chart->setLegendLocation(chart->legendSide(), AlignTop); break;
  251. case 4:
  252. chart->setLegendLocation(chart->legendSide(), AlignMiddle); break;
  253. case 5:
  254. chart->setLegendLocation(chart->legendSide(), AlignBottom); break;
  255. }
  256. }));
  257. title->changed().connect(std::bind([=] () {
  258. chart->setTitle(Wt::asString(title->text()));
  259. }));
  260. widgetWidth->changed().connect(std::bind([=] () {
  261. chart->resize(Wt::asNumber(widgetWidth->text()),
  262. Wt::asNumber(widgetHeight->text()));
  263. }));
  264. widgetHeight->changed().connect(std::bind([=] () {
  265. chart->resize(Wt::asNumber(widgetWidth->text()),
  266. Wt::asNumber(widgetHeight->text()));
  267. }));
  268. xAxisTitle->changed().connect(std::bind([=]() {
  269. chart->axis(XAxis_3D).setTitle(xAxisTitle->text());
  270. }));
  271. yAxisTitle->changed().connect(std::bind([=]() {
  272. chart->axis(YAxis_3D).setTitle(yAxisTitle->text());
  273. }));
  274. zAxisTitle->changed().connect(std::bind([=]() {
  275. chart->axis(ZAxis_3D).setTitle(zAxisTitle->text());
  276. }));
  277. }
  278. /*
  279. * Data selection Widget definition
  280. */
  281. DataSelection::DataSelection(WCartesian3DChart *chart)
  282. {
  283. WTemplate* template_ = new WTemplate(Wt::WString::tr("dataselection-template"), this);
  284. notShown = new WSelectionBox(this);
  285. template_->bindWidget("notshownselection", notShown);
  286. shown = new WSelectionBox(this);
  287. template_->bindWidget("shownselection", shown);
  288. WPushButton *addSelected = new WPushButton("add dataset", this);
  289. template_->bindWidget("addbutton", addSelected);
  290. WPushButton *removeSelected = new WPushButton("remove dataset", this);
  291. template_->bindWidget("removebutton", removeSelected);
  292. // define functionality
  293. notShown->sactivated().connect(std::bind([=] (WString selection) {
  294. //WString selection;
  295. shown->clearSelection();
  296. for (unsigned i = 0; i < dataCollection_.size(); i++) {
  297. if (dataCollection_[i].first == selection)
  298. selectionChange_.emit(dataCollection_[i].second);
  299. }
  300. }, std::placeholders::_1));
  301. shown->sactivated().connect(std::bind([=] (WString selection) {
  302. notShown->clearSelection();
  303. for (unsigned i = 0; i < dataCollection_.size(); i++) {
  304. if (dataCollection_[i].first == selection)
  305. selectionChange_.emit(dataCollection_[i].second);
  306. }
  307. }, std::placeholders::_1));
  308. addSelected->clicked().connect(std::bind([=] () {
  309. int index = notShown->currentIndex();
  310. if (index == -1)
  311. return;
  312. const WString currentText = notShown->currentText();
  313. for (unsigned i = 0; i < dataCollection_.size(); i++) {
  314. if (dataCollection_[i].first == currentText){
  315. chart->addDataSeries(dataCollection_[i].second);
  316. selectionChange_.emit(dataCollection_[i].second);
  317. }
  318. }
  319. shown->addItem(currentText);
  320. shown->setCurrentIndex(shown->count()-1);
  321. notShown->removeItem(index);
  322. notShown->clearSelection();
  323. }));
  324. removeSelected->clicked().connect(std::bind([=] () {
  325. int index = shown->currentIndex();
  326. if (index == -1)
  327. return;
  328. const WString currentText = shown->currentText();
  329. for (unsigned i = 0; i < dataCollection_.size(); i++) {
  330. if (dataCollection_[i].first == currentText)
  331. chart->removeDataSeries(dataCollection_[i].second);
  332. }
  333. notShown->addItem(currentText);
  334. notShown->setCurrentIndex(shown->count()-1);
  335. shown->removeItem(index);
  336. shown->clearSelection();
  337. }));
  338. }
  339. void DataSelection::addDataToCollection(WString name,
  340. WAbstractDataSeries3D* data)
  341. {
  342. DataSelectionItem item(name, data);
  343. dataCollection_.push_back(item);
  344. notShown->addItem(name);
  345. }
  346. DataConfig::DataConfig(WCartesian3DChart* chart)
  347. {
  348. WTemplate *template_ = new WTemplate(Wt::WString::tr("totaldataconfig-template"), this);
  349. dataselection_ = new DataSelection(chart);
  350. template_->bindWidget("dataselection", dataselection_);
  351. WStackedWidget *sw = new WStackedWidget(this);
  352. sw->addWidget(new WText("Select data to configure it"));
  353. numgriddatasettings_ = new NumGridDataSettings();
  354. catgriddatasettings_ = new CatGridDataSettings();
  355. scatterdatasettings_ = new ScatterDataSettings();
  356. sw->addWidget(numgriddatasettings_);
  357. sw->addWidget(catgriddatasettings_);
  358. sw->addWidget(scatterdatasettings_);
  359. template_->bindWidget("dataconfig", sw);
  360. dataselection_->selectionChanged().connect(std::bind([=] (WAbstractDataSeries3D* data) {
  361. if (dynamic_cast<WAbstractGridData*>(data)) {
  362. WAbstractGridData *gridData = dynamic_cast<WAbstractGridData*>(data);
  363. if (gridData->type() == BarSeries3D) {
  364. catgriddatasettings_->bindDataSet(gridData);
  365. sw->setCurrentIndex(2);
  366. } else {
  367. numgriddatasettings_->bindDataSet(gridData);
  368. sw->setCurrentIndex(1);
  369. }
  370. } else if (dynamic_cast<WScatterData*>(data)) {
  371. scatterdatasettings_->bindDataSet(dynamic_cast<WScatterData*>(data));
  372. sw->setCurrentIndex(3);
  373. }
  374. }, std::placeholders::_1));
  375. }
  376. void DataConfig::addDataToCollection(WString name, WAbstractDataSeries3D *data)
  377. {
  378. dataselection_->addDataToCollection(name, data);
  379. }