jpc_helper_cross_tab.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. let JV = require("../jpc_value_define");
  2. let JE = require("../jpc_rte");
  3. let JpcCommonHelper = require("./jpc_helper_common");
  4. let JpcCrossTabHelper = {
  5. getColIDX: function (cl, val) {
  6. let rst = -1;
  7. for (let i = 0; i < cl.length; i++) {
  8. let ca = cl[i];
  9. for (let j = 0; j < ca.length; j++) {
  10. if (ca[j] == val) {
  11. rst = i;
  12. break;
  13. }
  14. }
  15. if (rst != -1) {
  16. break;
  17. }
  18. }
  19. return rst;
  20. },
  21. pushToSeg: function (segArr, dataSeq, segIdx, sIdx, eIdx) {
  22. let arrIdx = [];
  23. for (let k = sIdx; k < eIdx; k++) {
  24. arrIdx.push(dataSeq[segIdx][k]);
  25. }
  26. segArr.push(arrIdx);
  27. },
  28. sortFieldValue: function (sIDX, eIDX, sortOrder, dataField, dataValSeq) {
  29. let tmpSeq = [];
  30. if (sortOrder && sortOrder !== JV.TAB_FIELD_PROP_SORT_VAL_NOSORT) {
  31. if (sIDX >= 0 && eIDX >= sIDX && dataValSeq.length > eIDX) {
  32. let reversed = 1;
  33. if (sortOrder === JV.TAB_FIELD_PROP_SORT_VAL_DESC) {
  34. reversed = -1;
  35. }
  36. for (let i = sIDX; i <= eIDX; i++) {
  37. tmpSeq.push(dataValSeq[i]);
  38. }
  39. tmpSeq.sort(function (idx1, idx2) {
  40. let rst = 0;
  41. // if (isNaN(parseFloat(dataField[idx1])) || isNaN(parseFloat(dataField[idx1]))) {
  42. if (
  43. typeof dataField[idx1] === "string" ||
  44. typeof dataField[idx1] === "string"
  45. ) {
  46. if (dataField[idx1] > dataField[idx2]) {
  47. rst = reversed;
  48. } else if (dataField[idx1] < dataField[idx2]) {
  49. rst = -reversed;
  50. }
  51. } else {
  52. if (1.0 * dataField[idx1] > 1.0 * dataField[idx2]) {
  53. rst = reversed;
  54. } else if (1.0 * dataField[idx1] < 1.0 * dataField[idx2]) {
  55. rst = -reversed;
  56. }
  57. }
  58. return rst;
  59. });
  60. }
  61. }
  62. if (tmpSeq.length > 0) {
  63. for (let i = sIDX; i <= eIDX; i++) {
  64. dataValSeq[i] = tmpSeq[i - sIDX];
  65. }
  66. }
  67. return tmpSeq;
  68. },
  69. checkIfEqual: function (dataFields, seq1, seq2) {
  70. let rst = true;
  71. for (let i = 0; i < dataFields.length; i++) {
  72. if (dataFields[i][seq1] !== dataFields[i][seq2]) {
  73. rst = false;
  74. break;
  75. }
  76. }
  77. return rst;
  78. },
  79. sortTabFields: function (
  80. tabFields,
  81. fieldSeqs,
  82. data_details,
  83. dataSeq,
  84. $CURRENT_RPT
  85. ) {
  86. let me = this;
  87. let sIDX = 0,
  88. eIDX = -1,
  89. isFirstSort = true;
  90. for (let i = 0; i < tabFields.length; i++) {
  91. let tabField = tabFields[i];
  92. if (
  93. tabField[JV.TAB_FIELD_PROP_SORT] !== JV.TAB_FIELD_PROP_SORT_VAL_NOSORT
  94. ) {
  95. if (isFirstSort) {
  96. isFirstSort = false;
  97. //first field, should sort all data items
  98. for (let j = 0; j < dataSeq.length; j++) {
  99. sIDX = 0;
  100. eIDX = dataSeq[j].length - 1;
  101. //sort the field value here
  102. if (typeof fieldSeqs[i] === "object") {
  103. let exFirstField = JE.F(fieldSeqs[i][JV.PROP_ID], $CURRENT_RPT);
  104. if (exFirstField) {
  105. me.sortFieldValue(
  106. sIDX,
  107. eIDX,
  108. tabField[JV.TAB_FIELD_PROP_SORT],
  109. exFirstField[JV.PROP_AD_HOC_DATA],
  110. dataSeq[j]
  111. );
  112. } else {
  113. //不排序(健壮性)
  114. }
  115. } else {
  116. me.sortFieldValue(
  117. sIDX,
  118. eIDX,
  119. tabField[JV.TAB_FIELD_PROP_SORT],
  120. data_details[fieldSeqs[i]],
  121. dataSeq[j]
  122. );
  123. }
  124. // me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT],data_details[fieldSeqs[i]], dataSeq[j]);
  125. }
  126. } else {
  127. //then sort the rest fields one by one
  128. for (let j = 0; j < dataSeq.length; j++) {
  129. let chkFields = [];
  130. for (let k = 0; k < i; k++) {
  131. if (typeof fieldSeqs[k] === "object") {
  132. let exField = JE.F(fieldSeqs[k][JV.PROP_ID], $CURRENT_RPT);
  133. if (exField) {
  134. chkFields.push(exField[JV.PROP_AD_HOC_DATA]);
  135. } else {
  136. chkFields.push(null);
  137. }
  138. } else {
  139. chkFields.push(data_details[fieldSeqs[k]]);
  140. }
  141. // chkFields.push(data_details[fieldSeqs[k]]);
  142. }
  143. (sIDX = 0), (eIDX = -1);
  144. for (let m = 1; m < dataSeq[j].length; m++) {
  145. if (
  146. !me.checkIfEqual(chkFields, dataSeq[j][m - 1], dataSeq[j][m])
  147. ) {
  148. eIDX = m - 1;
  149. } else if (m == dataSeq[j].length - 1) {
  150. eIDX = m;
  151. }
  152. if (eIDX >= sIDX) {
  153. if (eIDX != sIDX) {
  154. if (typeof fieldSeqs[i] === "object") {
  155. let exOtherField = JE.F(
  156. fieldSeqs[i][JV.PROP_ID],
  157. $CURRENT_RPT
  158. );
  159. if (exOtherField) {
  160. me.sortFieldValue(
  161. sIDX,
  162. eIDX,
  163. tabField[JV.TAB_FIELD_PROP_SORT],
  164. exOtherField[JV.PROP_AD_HOC_DATA],
  165. dataSeq[j]
  166. );
  167. } else {
  168. //不排序(健壮性)
  169. }
  170. } else {
  171. me.sortFieldValue(
  172. sIDX,
  173. eIDX,
  174. tabField[JV.TAB_FIELD_PROP_SORT],
  175. data_details[fieldSeqs[i]],
  176. dataSeq[j]
  177. );
  178. }
  179. // me.sortFieldValue(sIDX, eIDX, tabField[JV.TAB_FIELD_PROP_SORT],data_details[fieldSeqs[i]], dataSeq[j]);
  180. }
  181. sIDX = m;
  182. eIDX = m - 1; //for protection purpose
  183. }
  184. }
  185. }
  186. }
  187. }
  188. }
  189. },
  190. getMaxRowsPerPage: function (bands, rptTpl) {
  191. let rst = 1;
  192. let band =
  193. bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_BAND_NAME]];
  194. if (band) {
  195. rst = getMaxTabCntPerPage(
  196. rptTpl,
  197. JV.NODE_CROSS_ROW,
  198. JV.PROP_CMN_HEIGHT,
  199. band.Bottom - band.Top
  200. );
  201. }
  202. return rst;
  203. },
  204. getMaxColsPerPage: function (bands, rptTpl) {
  205. let rst = 1;
  206. let band =
  207. bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_BAND_NAME]];
  208. if (band) {
  209. rst = getMaxTabCntPerPage(
  210. rptTpl,
  211. JV.NODE_CROSS_COL,
  212. JV.PROP_CMN_WIDTH,
  213. band.Right - band.Left
  214. );
  215. }
  216. return rst;
  217. },
  218. getActualRowsHeight: function (bands, rptTpl, segments, page) {
  219. let rst = 1;
  220. let band =
  221. bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_BAND_NAME]];
  222. if (band) {
  223. rst = getActualContentAreaMeasurement(
  224. rptTpl,
  225. JV.NODE_CROSS_ROW,
  226. JV.PROP_CMN_HEIGHT,
  227. band.Bottom - band.Top,
  228. segments,
  229. page
  230. );
  231. }
  232. return rst;
  233. },
  234. getActualColsWidth: function (bands, rptTpl, segments, page) {
  235. let rst = 1;
  236. let band =
  237. bands[rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_BAND_NAME]];
  238. if (band) {
  239. rst = getActualContentAreaMeasurement(
  240. rptTpl,
  241. JV.NODE_CROSS_COL,
  242. JV.PROP_CMN_WIDTH,
  243. band.Right - band.Left,
  244. segments,
  245. page
  246. );
  247. }
  248. return rst;
  249. },
  250. chkTabEnd: function (
  251. tabType,
  252. rptTpl,
  253. bands,
  254. sortedSequence,
  255. segIdx,
  256. preRec,
  257. nextRec
  258. ) {
  259. let me = this,
  260. rst = true;
  261. let remainAmt = preRec + nextRec - sortedSequence[segIdx].length;
  262. rst = me.hasEnoughSpace(tabType, rptTpl, bands, remainAmt);
  263. return rst;
  264. },
  265. hasEnoughSpace: function (tabType, rptTpl, bands, remainAmt) {
  266. if (remainAmt < 0) return false;
  267. let rst = true,
  268. measurement = 1.0,
  269. douDiffForCompare = 0.00001;
  270. let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
  271. let band = null;
  272. if (rptTpl[JV.NODE_CROSS_INFO][tabType]) {
  273. band = bands[rptTpl[JV.NODE_CROSS_INFO][tabType][JV.PROP_BAND_NAME]];
  274. }
  275. if (band != null && band != undefined) {
  276. if (
  277. tabType === JV.NODE_CROSS_ROW_SUM ||
  278. tabType === JV.NODE_CROSS_ROW_EXT
  279. ) {
  280. measurement =
  281. 1.0 *
  282. rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_ROW][JV.PROP_CMN_HEIGHT] *
  283. unitFactor;
  284. let spareHeight = measurement * remainAmt;
  285. let douH = 1.0 * (band.Bottom - band.Top);
  286. rst = spareHeight >= douH || spareHeight - douH <= douDiffForCompare;
  287. } else if (tabType === JV.NODE_CROSS_COL_SUM) {
  288. measurement =
  289. 1.0 *
  290. rptTpl[JV.NODE_CROSS_INFO][JV.NODE_CROSS_COL][JV.PROP_CMN_WIDTH] *
  291. unitFactor;
  292. let spareWidth = measurement * remainAmt;
  293. let douW = 1.0 * (band.Right - band.Left);
  294. rst = spareWidth >= douW || spareWidth - douW <= douDiffForCompare;
  295. }
  296. }
  297. return rst;
  298. },
  299. initialPageStatus: function (pageStatus) {
  300. pageStatus[JV.STATUS_NORMAL] = true;
  301. pageStatus[JV.STATUS_REPORT_START] = false;
  302. pageStatus[JV.STATUS_REPORT_END] = false;
  303. pageStatus[JV.STATUS_SEGMENT_START] = false;
  304. pageStatus[JV.STATUS_SEGMENT_END] = false;
  305. pageStatus[JV.STATUS_GROUP] = false;
  306. pageStatus[JV.STATUS_CROSS_ROW_END] = false;
  307. pageStatus[JV.STATUS_CROSS_COL_END] = false;
  308. },
  309. };
  310. function getMaxTabCntPerPage(
  311. rptTpl,
  312. tabNodeName,
  313. tabMeasurePropName,
  314. measureForCal
  315. ) {
  316. let rst = 1;
  317. if (rptTpl[JV.NODE_CROSS_INFO][tabNodeName]) {
  318. let tab = rptTpl[JV.NODE_CROSS_INFO][tabNodeName];
  319. let maxFieldMeasure = 1.0;
  320. if (
  321. JV.CAL_TYPE_ABSTRACT ===
  322. JpcCommonHelper.getPosCalculationType(tab[JV.PROP_CALCULATION])
  323. ) {
  324. let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
  325. maxFieldMeasure =
  326. 1.0 *
  327. rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName] *
  328. unitFactor;
  329. } else {
  330. maxFieldMeasure =
  331. (measureForCal *
  332. rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName]) /
  333. JV.HUNDRED_PERCENT;
  334. }
  335. rst = Math.floor(measureForCal / maxFieldMeasure);
  336. }
  337. if (rst <= 0) rst = 1;
  338. return rst;
  339. }
  340. function getActualContentAreaMeasurement(
  341. rptTpl,
  342. tabNodeName,
  343. tabMeasurePropName,
  344. measureForCal,
  345. segments,
  346. page
  347. ) {
  348. let rst = 1;
  349. if (rptTpl[JV.NODE_CROSS_INFO][tabNodeName]) {
  350. let tab = rptTpl[JV.NODE_CROSS_INFO][tabNodeName];
  351. let maxFieldMeasure = 1.0;
  352. if (
  353. JV.CAL_TYPE_ABSTRACT ===
  354. JpcCommonHelper.getPosCalculationType(tab[JV.PROP_CALCULATION])
  355. ) {
  356. let unitFactor = JpcCommonHelper.getUnitFactor(rptTpl);
  357. maxFieldMeasure =
  358. 1.0 *
  359. rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName] *
  360. unitFactor;
  361. } else {
  362. maxFieldMeasure =
  363. (measureForCal *
  364. rptTpl[JV.NODE_CROSS_INFO][tabNodeName][tabMeasurePropName]) /
  365. JV.HUNDRED_PERCENT;
  366. }
  367. if (segments.length >= page) {
  368. rst = segments[page - 1].length * maxFieldMeasure;
  369. }
  370. }
  371. return rst;
  372. }
  373. module.exports = JpcCrossTabHelper;