GreyClusteringSampleTable.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. #include "GreyClusteringItemDelegate.h"
  2. #include "GreyClusteringSampleTable.h"
  3. #include "MultiLevelHeaderView.h"
  4. #include "CMind.h"
  5. #include "dbService/GradeInfoService.h"
  6. #include "dbService/EffectIndexInfoService.h"
  7. #include <QHeaderView>
  8. #include <QDebug>
  9. #include <QMessageBox>
  10. /**
  11. * example
  12. * QVector<GreyClusteringItem> gcItems;
  13. gcItems << GreyClusteringItem { "火力", 0, 0, 9, 1, nullptr };
  14. QSharedPointer<GreyClusteringValue> sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  15. sg->units = "m";
  16. sg->weiget = 2;
  17. sg->greyRanges << GreyRange { "较差类", true, 85, true, 100 };
  18. sg->greyRanges << GreyRange { "一般类", true, 100, true, 115 };
  19. sg->greyRanges << GreyRange { "较好类", true, 115, true, 125 };
  20. sg->leftExtension = 70;
  21. sg->rightExtension = 140;
  22. sg->oldValue = 0;
  23. sg->newValue = 0;
  24. gcItems << GreyClusteringItem { "火炮口径", 0, 1, 1, 2, sg };
  25. gcItems << GreyClusteringItem { "初速", 1, 1, 3, 1, nullptr };
  26. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  27. sg->units = "m";
  28. sg->weiget = 4;
  29. sg->greyRanges << GreyRange { "较差类", true, 1600, true, 1300 };
  30. sg->greyRanges << GreyRange { "一般类", true, 1600, true, 1900 };
  31. sg->greyRanges << GreyRange { "较好类", true, 1600, true, 1900 };
  32. sg->leftExtension = 500;
  33. sg->rightExtension = 220;
  34. sg->oldValue = 0;
  35. sg->newValue = 0;
  36. gcItems << GreyClusteringItem { "穿甲弹", 1, 2, 1, 1, sg };
  37. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  38. sg->units = "m";
  39. sg->weiget = 4;
  40. sg->greyRanges << GreyRange { "较差类", true, 1000, true, 1200 };
  41. sg->greyRanges << GreyRange { "一般类", true, 1200, true, 1400 };
  42. sg->greyRanges << GreyRange { "较好类", true, 1200, true, 1400 };
  43. sg->leftExtension = 600;
  44. sg->rightExtension = 1700;
  45. sg->oldValue = 0;
  46. sg->newValue = 0;
  47. gcItems << GreyClusteringItem { "破甲弹", 2, 2, 1, 1, sg };
  48. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  49. sg->units = "m";
  50. sg->weiget = 4;
  51. sg->greyRanges << GreyRange { "较差类", true, 500, false, 650 };
  52. sg->greyRanges << GreyRange { "一般类", true, 650, false, 800 };
  53. sg->greyRanges << GreyRange { "较好类", true, 800, false, 1000 };
  54. sg->leftExtension = 400;
  55. sg->rightExtension = 1100;
  56. sg->oldValue = 0;
  57. sg->newValue = 0;
  58. gcItems << GreyClusteringItem { "榴弹", 3, 2, 1, 1, sg };
  59. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  60. sg->units = "";
  61. sg->weiget = 5;
  62. sg->greyRanges << GreyRange { "较差类", true, 0.5, false, 0.65 };
  63. sg->greyRanges << GreyRange { "一般类", true, 0.65, false, 0.75 };
  64. sg->greyRanges << GreyRange { "较好类", true, 0.75, false, 0.9 };
  65. sg->leftExtension = 0.45;
  66. sg->rightExtension = 0.95;
  67. sg->oldValue = 0;
  68. sg->newValue = 0;
  69. gcItems << GreyClusteringItem { "首发命中", 4, 1, 1, 2, sg };
  70. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  71. sg->units = "m";
  72. sg->weiget = 5;
  73. sg->greyRanges << GreyRange { "较差类", true, 800, false, 1200 };
  74. sg->greyRanges << GreyRange { "一般类", true, 1200, false, 1600 };
  75. sg->greyRanges << GreyRange { "较好类", true, 1600, false, 2200 };
  76. sg->leftExtension = 500;
  77. sg->rightExtension = 2500;
  78. sg->oldValue = 0;
  79. sg->newValue = 0;
  80. gcItems << GreyClusteringItem { "直射距离", 5, 1, 1, 2, sg };
  81. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  82. sg->units = "发";
  83. sg->weiget = 3;
  84. sg->greyRanges << GreyRange { "较差类", true, 30, false, 40 };
  85. sg->greyRanges << GreyRange { "一般类", true, 40, false, 50 };
  86. sg->greyRanges << GreyRange { "较好类", true, 50, false, 65 };
  87. sg->leftExtension = 28;
  88. sg->rightExtension = 70;
  89. sg->oldValue = 0;
  90. sg->newValue = 0;
  91. gcItems << GreyClusteringItem { "弹药基数", 6, 1, 1, 2, sg };
  92. gcItems << GreyClusteringItem { "时间", 7, 1, 2, 1, nullptr };
  93. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  94. sg->units = "s";
  95. sg->weiget = 3;
  96. sg->greyRanges << GreyRange { "较差类", true, 11, false, 10 };
  97. sg->greyRanges << GreyRange { "一般类", true, 10, false, 7 };
  98. sg->greyRanges << GreyRange { "较好类", true, 7, false, 4 };
  99. sg->leftExtension = 12;
  100. sg->rightExtension = 3;
  101. sg->oldValue = 0;
  102. sg->newValue = 0;
  103. gcItems << GreyClusteringItem { "静对静", 7, 2, 1, 1, sg };
  104. sg = QSharedPointer<GreyClusteringValue>(new GreyClusteringValue);
  105. sg->units = "s";
  106. sg->weiget = 3;
  107. sg->greyRanges << GreyRange { "较差类", true, 14, false, 12 };
  108. sg->greyRanges << GreyRange { "一般类", true, 12, false, 10 };
  109. sg->greyRanges << GreyRange { "较好类", true, 10, false, 7 };
  110. sg->leftExtension = 15;
  111. sg->rightExtension = 5;
  112. sg->oldValue = 0;
  113. sg->newValue = 0;
  114. gcItems << GreyClusteringItem { "静对动", 8, 2, 1, 1, sg };
  115. GreyClusteringSampleTable gcst(gcItems, 3, 9);
  116. gcst.resize(1200, 800);
  117. gcst.refreshTableView();
  118. gcst.show();
  119. */
  120. GreyClusteringSampleTable::GreyClusteringSampleTable(CMind *mind, int grayNumber, QWidget *parent)
  121. : QTableView(parent), m_mind(mind), m_nodeDepth(2), m_grayNumber(grayNumber)
  122. {
  123. m_model = new QStandardItemModel();
  124. this->setModel(m_model);
  125. init();
  126. initClusteringItems();
  127. refreshTableView();
  128. }
  129. void GreyClusteringSampleTable::refreshTableView()
  130. {
  131. m_model->clear();
  132. if (m_greyClusterings.size() == 0) {
  133. return;
  134. }
  135. QStringList greyNames; // 灰数
  136. for (auto &item : m_greyClusterings) {
  137. if (!item.value.isNull()) {
  138. for (const auto &s : item.value->greyRanges) {
  139. greyNames << s.name;
  140. }
  141. break;
  142. }
  143. }
  144. int colCount = m_nodeDepth + 6 + greyNames.size();
  145. // 设置表头
  146. {
  147. auto hHeader = new MultiLevelHeaderView(Qt::Horizontal, 2, colCount, this);
  148. hHeader->setSectionResizeMode(QHeaderView::Stretch);
  149. hHeader->setCellSpan(0, 0, 2, m_nodeDepth); // 指标占位
  150. for (int n = 0; n < 2 + greyNames.size(); ++n) { // 单位+权重+灰度级占位
  151. hHeader->setCellSpan(0, m_nodeDepth + n, 2, 1);
  152. }
  153. hHeader->setCellSpan(0, m_nodeDepth + 2 + greyNames.size(), 1, 2); // 延拓值占位
  154. hHeader->setCellSpan(1, m_nodeDepth + 2 + greyNames.size(), 1, 1);
  155. hHeader->setCellSpan(1, m_nodeDepth + 2 + greyNames.size() + 1, 1, 1);
  156. hHeader->setCellSpan(0, m_nodeDepth + 4 + greyNames.size(), 1, 2); // 实现值占位
  157. hHeader->setCellSpan(1, m_nodeDepth + 4 + greyNames.size(), 1, 1);
  158. hHeader->setCellSpan(1, m_nodeDepth + 4 + greyNames.size() + 1, 1, 1);
  159. // 一级
  160. hHeader->setCellText(0, 0, QString("指标"));
  161. hHeader->setCellText(0, m_nodeDepth, QString("单位"));
  162. hHeader->setCellText(0, m_nodeDepth + 1, QString("权重"));
  163. for (int i = 0; i < greyNames.size(); ++i) {
  164. hHeader->setCellText(0, m_nodeDepth + 2 + i, greyNames.at(i));
  165. }
  166. hHeader->setCellText(0, m_nodeDepth + 2 + greyNames.size(), QString("延拓值"));
  167. hHeader->setCellText(0, m_nodeDepth + 4 + greyNames.size(), QString("实现值"));
  168. // 二级
  169. hHeader->setCellText(1, m_nodeDepth + 2 + greyNames.size(), "左");
  170. hHeader->setCellText(1, m_nodeDepth + 3 + greyNames.size(), "右");
  171. hHeader->setCellText(1, m_nodeDepth + 4 + greyNames.size(), "改前");
  172. hHeader->setCellText(1, m_nodeDepth + 5 + greyNames.size(), "改后");
  173. this->setHorizontalHeader(hHeader);
  174. }
  175. m_model->setColumnCount(colCount);
  176. m_model->setRowCount(m_rowCount);
  177. for (const auto &item : m_greyClusterings) {
  178. // 第一步,设置指标名
  179. auto s = new QStandardItem(item.indexName);
  180. s->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
  181. s->setTextAlignment(Qt::AlignCenter);
  182. s->setToolTip(item.indexName);
  183. m_model->setItem(item.row, item.col, s);
  184. if (item.rowSpan > 1 || item.colSpan > 1) {
  185. this->setSpan(item.row, item.col, item.rowSpan, item.colSpan);
  186. }
  187. // 第二步,查看当前指标下是否附带值
  188. if (!item.value.isNull()) {
  189. int offset = item.colSpan;
  190. m_model->setItem(item.row, item.col + offset, new QStandardItem(item.value->units)); // 单位
  191. ++offset;
  192. m_model->setItem(item.row, item.col + offset,
  193. new QStandardItem(QString::number(item.value->weiget))); // 权重
  194. ++offset;
  195. for (auto &range : item.value->greyRanges) { // 灰度级
  196. QString r;
  197. r += range.leftClose ? "[" : "(";
  198. r += QString("%1, %2").arg(range.leftValue).arg(range.rightValue);
  199. r += range.rightClose ? "]" : ")";
  200. m_model->setItem(item.row, item.col + offset, new QStandardItem(r));
  201. ++offset;
  202. }
  203. m_model->setItem(item.row, item.col + offset,
  204. new QStandardItem(QString::number(item.value->leftExtension))); // 延拓值左
  205. ++offset;
  206. m_model->setItem(item.row, item.col + offset,
  207. new QStandardItem(QString::number(item.value->rightExtension))); // 延拓值右
  208. ++offset;
  209. m_model->setItem(item.row, item.col + offset,
  210. new QStandardItem(QString::number(item.value->oldValue))); // 实现值前
  211. ++offset;
  212. m_model->setItem(item.row, item.col + offset,
  213. new QStandardItem(QString::number(item.value->newValue))); // 实现值后
  214. ++offset;
  215. for (int c = item.colSpan; c < offset - 2; ++c) {
  216. m_model->item(item.row, item.col + c)->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable);
  217. m_model->item(item.row, item.col + c)->setTextAlignment(Qt::AlignCenter);
  218. }
  219. for (int c = offset - 2; c < offset; ++c) {
  220. m_model->item(item.row, item.col + c)->setTextAlignment(Qt::AlignCenter);
  221. this->setItemDelegateForColumn(item.col + c, new GreyClusteringItemSpinDelegate(this));
  222. }
  223. }
  224. }
  225. }
  226. void GreyClusteringSampleTable::init()
  227. {
  228. setAlternatingRowColors(false);
  229. horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
  230. horizontalHeader()->setStyleSheet("QHeaderView::section{background:rgb(244,244,244);color: black;}");
  231. verticalHeader()->setStyleSheet("QHeaderView::section{background:rgb(244,244,244);color: black;}");
  232. verticalHeader()->setDefaultAlignment(Qt::AlignCenter);
  233. setSelectionMode(QAbstractItemView::SingleSelection);
  234. QList<GradeInfo *> gradeInfoList;
  235. QMap<QString, QString> grayLevelMaps;
  236. int projectId = m_mind->root().projectId;
  237. if (!GradeInfoService().QueryGradeByProjectIdAndType(&gradeInfoList, projectId, 1)) {
  238. QMessageBox::warning(this, "警告", "数据库访问失败");
  239. } else {
  240. if (gradeInfoList.size() == 0) {
  241. for (int lvl = 0; lvl < m_grayNumber; ++lvl) {
  242. grayLevelMaps.insert(QString("级别 %1:").arg(lvl + 1), QString("E%1").arg(lvl + 1));
  243. GradeInfo ginfo;
  244. ginfo.projectId = projectId;
  245. ginfo.gradeName = QString("级别 %1").arg(lvl + 1);
  246. ginfo.gradeValue = QString("灰类%1级").arg(lvl + 1);
  247. ginfo.type = 1;
  248. if (!GradeInfoService().AddGradeInfo(ginfo)) {
  249. QMessageBox::warning(this, "警告", "数据库访问失败");
  250. }
  251. }
  252. } else {
  253. for (const auto &gi : gradeInfoList) {
  254. grayLevelMaps.insert(gi->gradeName, gi->gradeValue);
  255. if (grayLevelMaps.size() >= m_grayNumber) {
  256. break;
  257. }
  258. }
  259. // 缺少再补
  260. for (int lvl = grayLevelMaps.size(); lvl < m_grayNumber; ++lvl) {
  261. grayLevelMaps.insert(QString("级别 %1:").arg(lvl + 1), QString("E%1").arg(lvl + 1));
  262. GradeInfo ginfo;
  263. ginfo.projectId = projectId;
  264. ginfo.gradeName = QString("级别 %1").arg(lvl + 1);
  265. ginfo.gradeValue = QString("灰类%1级").arg(lvl + 1);
  266. ginfo.type = 1;
  267. if (!GradeInfoService().AddGradeInfo(ginfo)) {
  268. QMessageBox::warning(this, "警告", "数据库访问失败");
  269. }
  270. }
  271. m_grayNames = grayLevelMaps.values();
  272. }
  273. }
  274. qDeleteAll(gradeInfoList);
  275. }
  276. void GreyClusteringSampleTable::initClusteringItems()
  277. {
  278. // 脑图层级 < 2 时无效
  279. if (m_mind->levels() < 2) {
  280. return;
  281. }
  282. m_greyClusterings.clear();
  283. // 使用倒数第二层节点及其子节点
  284. int row = 0;
  285. for (CNodeData n : m_mind->nodesInLevel(m_mind->levels() - 1)) {
  286. GreyClusteringItem parentItem = { n.name, row, 0, 1, 1, nullptr };
  287. QList<CNodeData> subNodes = m_mind->subNodes(n);
  288. parentItem.colSpan = subNodes.size() == 0 ? 2 : 1; // 没有子节点,占两列,否则占一列
  289. parentItem.rowSpan = subNodes.size() == 0 ? 1 : subNodes.size(); // 没有子节点,占一行,否则占子节点数目行
  290. if (subNodes.size() == 0) { // 没有子节点,需要录入值
  291. GreyClusteringValue *sg = new GreyClusteringValue;
  292. sg->units = "";
  293. sg->weiget = 0;
  294. for (const auto &gname : m_grayNames) {
  295. sg->greyRanges << GreyRange { gname, true, 0, true, 0 };
  296. }
  297. sg->leftExtension = 0;
  298. sg->rightExtension = 0;
  299. sg->oldValue = 0;
  300. sg->newValue = 0;
  301. parentItem.value.reset(sg);
  302. }
  303. m_greyClusterings.append(parentItem);
  304. int subRow = row;
  305. // 子节点
  306. for (const CNodeData &sub : subNodes) {
  307. // 因为已有父节点,所以在第2列
  308. GreyClusteringItem childItem = { sub.name, subRow, 1, 1, 1, nullptr };
  309. GreyClusteringValue *sg = new GreyClusteringValue;
  310. sg->units = "";
  311. sg->weiget = 0;
  312. for (const auto &gname : m_grayNames) {
  313. sg->greyRanges << GreyRange { gname, true, 0, true, 0 };
  314. }
  315. sg->leftExtension = 0;
  316. sg->rightExtension = 0;
  317. sg->oldValue = 0;
  318. sg->newValue = 0;
  319. childItem.value.reset(sg);
  320. m_greyClusterings.append(childItem);
  321. subRow++;
  322. }
  323. row += parentItem.rowSpan;
  324. }
  325. m_rowCount = row;
  326. // 更新
  327. QList<EffectIndexInfo *> effectIndexInfoList;
  328. int projectid = m_mind->root().projectId;
  329. if (!EffectIndexInfoService().QueryEffectIndexInfoByProjectId(&effectIndexInfoList, projectid)) {
  330. QMessageBox::warning(this, "警告", "数据库访问失败");
  331. return;
  332. }
  333. if (effectIndexInfoList.size() > 0) {
  334. for (auto &item : m_greyClusterings) {
  335. if (item.value.isNull()) {
  336. continue;
  337. }
  338. for (const auto &effInfo : effectIndexInfoList) {
  339. if (effInfo->effectIndexName == item.indexName) {
  340. item.value->units = effInfo->effectIndexUnit;
  341. item.value->leftExtension = effInfo->extendLeft.toDouble();
  342. item.value->rightExtension = effInfo->extendRight.toDouble();
  343. //[0:0],[0:0],[0:0]
  344. QStringList valueList = effInfo->effectIndexValue.split(",");
  345. int align = qMin(valueList.size(), item.value->greyRanges.size());
  346. for (int str = 0; str < align; str++) {
  347. //[0:0]
  348. QStringList lr = valueList.at(str).mid(1, valueList.at(str).size() - 2).split(":");
  349. item.value->greyRanges[str].leftValue = lr.at(0).toDouble();
  350. item.value->greyRanges[str].rightValue = lr.at(1).toDouble();
  351. }
  352. }
  353. }
  354. }
  355. }
  356. qDeleteAll(effectIndexInfoList);
  357. }