Bocian.php.graphShowHide.js 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843
  1. var getItemLocalStorage = global.getItemLocalStorage;
  2. var setItemLocalStorage = global.setItemLocalStorage;
  3. var p5WFS_GetFeature = global.p5WFS_GetFeature;
  4. var renderGraph = global.renderGraph; // @from sankey-init
  5. var DBG = DBG || 0;
  6. var DBG1 = 1;
  7. var globalGraphStore = null;
  8. function graphStore(state, action) {
  9. var prevState = state || {
  10. isLoading: false,
  11. sentRequestId: 0,
  12. receivedRequestId: 0,
  13. items: [],
  14. };
  15. DBG && console.log('DBG: graph store', { prevState, action });
  16. switch (action.type) {
  17. case 'SET_SENT_REQUEST_ID': return Object.assign(prevState, {
  18. sentRequestId: action.sentRequestId,
  19. isLoading: true
  20. });
  21. case 'SET_RESPONSE': return Object.assign(prevState, {
  22. receivedRequestId: action.requestId,
  23. items: action.items,
  24. isLoading: (prevState.sentRequestId > action.requestId) ? true : false,
  25. });
  26. default: return prevState;
  27. }
  28. }
  29. var createGraphActions = function () {
  30. var setSentRequestId = function (sentRequestId) {
  31. return { type: 'SET_SENT_REQUEST_ID', sentRequestId: sentRequestId };
  32. }
  33. var setResponse = function (obj) {
  34. return Object.assign(obj, { type: 'SET_RESPONSE' });
  35. }
  36. var fetchData = function (nameSection) {
  37. return function (dispatch, getState) {
  38. var state = getState();
  39. var this__requestId = state.sentRequestId + 1;
  40. dispatch(setSentRequestId(this__requestId));
  41. var reqPromise = graphFetchData(nameSection);
  42. return reqPromise.then(function (response) {
  43. var items = response;
  44. var state = getState();
  45. if (state.receivedRequestId > this__requestId) {
  46. DBG && console.log('DBG: skiped response', { 'state.receivedRequestId': state.receivedRequestId, this__requestId });
  47. return;
  48. }
  49. dispatch(
  50. setResponse({
  51. requestId: this__requestId,
  52. msg: "Pobrano dane",
  53. typeName: ('pracownicy' === nameSection) ? 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY' : 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI',
  54. items: items
  55. })
  56. );
  57. }).catch(function (e) {
  58. p5UI__notifyAjaxCallback({type: 'error', msg: 'Wystąpił błąd #GS1: ' + e});
  59. // dispatch( setErrorMsg(e) ); // TODO: show error with msg and refresh button
  60. });
  61. }
  62. }
  63. return {
  64. fetchData: fetchData,
  65. }
  66. }
  67. var globalGraphActions = ''; // createGraphActions();
  68. var createReactClass = global.p5VendorJs.createReactClass;
  69. var h = global.p5VendorJs.React.createElement;
  70. var ReactDOM = global.p5VendorJs.ReactDOM;
  71. var Redux = global.p5VendorJs.Redux;
  72. var ReduxThunk = global.p5VendorJs.ReduxThunk;
  73. var createStoreWithThunkMiddleware = Redux.applyMiddleware(ReduxThunk)(Redux.createStore); // TODO: to vendor.js
  74. global['P5UI__BocianGraphView'] = createReactClass({
  75. // props.nameSection: PropTypes.string.isRequired
  76. // props.store: Redux store with state: { isLoading: false, sentRequestId: 0, receivedRequestId: 0, items: [] }
  77. // props.actions: Redux store actions { }
  78. getStateFromStore: function () {
  79. var state = this.props.store.getState();
  80. return {
  81. isLoading: state.isLoading,
  82. items: state.items,
  83. sentRequestId: state.sentRequestId,
  84. receivedRequestId: state.receivedRequestId,
  85. };
  86. },
  87. getInitialState: function () {
  88. return this.getStateFromStore();
  89. },
  90. componentDidMount: function () {
  91. DBG && console.log('DBG::P5UI__BocianGraphView::componentDidMount');
  92. this.unsubscribe = this.props.store.subscribe(this.storeUpdated)
  93. },
  94. componentWillUnmount: function () {
  95. this.unsubscribe()
  96. },
  97. storeUpdated: function () {
  98. DBG && console.log('DBG::P5UI__BocianGraphView::storeUpdated');
  99. this.setState(this.getStateFromStore())
  100. },
  101. shouldComponentUpdate: function (nextProps, nextState) {
  102. DBG && console.log('DBG::P5UI__BocianGraphView::shouldComponentUpdate', { state: this.state, nextState});
  103. // return (
  104. // this.state.isLoading !== nextState.isLoading
  105. // || this.state.sentRequestId !== nextState.sentRequestId
  106. // || this.state.receivedRequestId !== nextState.receivedRequestId
  107. // );
  108. if (nextState.receivedRequestId > this.state.receivedRequestId) {
  109. var htmlId = 'p5_graphView_' + this.props.nameSection; // #smad-'+nameSection+'-graph-view
  110. graphRaportRender({
  111. msg: "Pobrano dane",
  112. typeName: ('pracownicy' === this.props.nameSection) ? 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY' : 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI',
  113. items: nextState.items
  114. }, document.getElementById(htmlId))
  115. }
  116. return (
  117. this.state.isLoading !== nextState.isLoading
  118. );
  119. },
  120. render: function () {
  121. DBG && console.log('DBG::P5UI__BocianGraphView::render', { props: this.props, state: this.state });
  122. var htmlId = 'p5_graphView_' + this.props.nameSection; // #smad-'+nameSection+'-graph-view
  123. var msg = (this.state.isLoading) ? "Pobieranie danych..." : null;
  124. return h('div', {}, [
  125. msg && h('div', {
  126. className: 'alert alert-info',
  127. style: {
  128. maxWidth: '600px',
  129. margin: '0 auto',
  130. padding: '3px 24px',
  131. }
  132. }, msg),
  133. h('div', { id: htmlId })
  134. ]);
  135. }
  136. });
  137. var btnRefresh = null;
  138. var btnHide = null;
  139. function graphShowHide(btnNode, nameSection) {
  140. var node = $('#smad-'+nameSection+'-graph-view')
  141. if (!node || !node.length) {
  142. console.log("Missing dom node '#smad-"+nameSection+"-graph-view'")
  143. return;
  144. }
  145. var btnJqNode = jQuery(btnNode);
  146. if ('block' == node.css('display')) {
  147. DBG && console.warn("DBG:graphShowHide: hide");
  148. node.hide()
  149. btnRefresh.remove();
  150. btnHide.remove();
  151. return;
  152. }
  153. node.show()
  154. btnRefresh = jQuery('<button class="btn btn-primary" style="padding:1px 5px">odśwież</button>').appendTo(btnJqNode.parent());
  155. btnRefresh.on('click', function () {
  156. globalGraphStore.dispatch(globalGraphActions.fetchData(nameSection));
  157. })
  158. btnHide = jQuery('<button class="btn btn-primary" style="padding:1px 5px"><i class="glyphicon glyphicon-remove"></i></button>').appendTo(btnJqNode.parent());
  159. btnHide.on('click', function () {
  160. node.hide()
  161. btnRefresh.remove();
  162. btnHide.remove();
  163. })
  164. var graphResultNode = node.get(0)
  165. if (!globalGraphStore) {
  166. globalGraphStore = createStoreWithThunkMiddleware(graphStore);
  167. globalGraphActions = createGraphActions();
  168. ReactDOM.render(
  169. h(P5UI__BocianGraphView, {
  170. nameSection: nameSection,
  171. store: globalGraphStore,
  172. actions: globalGraphActions,
  173. }),
  174. graphResultNode
  175. );
  176. }
  177. globalGraphStore.dispatch(globalGraphActions.fetchData(nameSection));
  178. }
  179. function graphFetchData(nameSection) { // @return Promise
  180. var page = page || getItemLocalStorage('Bocian.biAuditForm.'+nameSection+'.pagination.page');
  181. if ( page === 1) {
  182. setItemLocalStorage('Bocian.biAuditForm.'+nameSection+'.pagination.page', 1);
  183. }
  184. var filterIdGroup = getItemLocalStorage('Bocian.biAuditForm.'+nameSection+'.filterIdGroup');
  185. var filterIdRaport = getItemLocalStorage('Bocian.biAuditForm.'+nameSection+'.filterIdRaport');
  186. var frm = document.getElementById('filtersFieldRemoveBtn-' + nameSection.toUpperCase()).form
  187. var fieldNameList = ('pracownicy' === nameSection) ? FIELD_LIST_PRACOWNICY : FIELD_LIST_KONTRAHENCI
  188. var filterFields = fieldNameList.filter(function (fieldName) {
  189. if (!frm[fieldName] && DBG) console.log('Err missing field: "'+fieldName+'"')
  190. return (frm[fieldName]) ? true : false
  191. }).map(function (fieldName) {
  192. return [ fieldName, frm[fieldName].value ]
  193. }).filter(function (filter) {
  194. return ( filter[1].length > 0 )
  195. })
  196. // filterFields = (filterFields.length > 0) ? '&' + filterFields : ''
  197. // <ogc:Filter>
  198. // <ogc:Or>
  199. // <ogc:PropertyIsLike wildCard="*" singleChar="%23" escapeChar="!">
  200. // <ogc:PropertyName>A_STATUS</ogc:PropertyName>
  201. // <ogc:Literal>*O%23MA*</ogc:Literal>
  202. // </ogc:PropertyIsLike>
  203. // <ogc:PropertyIsLike wildCard="*" singleChar="%23" escapeChar="!">
  204. // <ogc:PropertyName>A_STATUS</ogc:PropertyName>
  205. // <ogc:Literal>*ARNING</ogc:Literal>
  206. // </ogc:PropertyIsLike>
  207. // </ogc:Or>
  208. // </ogc:Filter>
  209. var ogcFilterFields = (filterFields.length > 0)
  210. ? '<ogc:Filter><ogc:And>' + filterFields.map(function(filter) {
  211. if ('ID' === filter[0].substr(2)) return '<ogc:PropertyIsEqualTo>' +
  212. '<ogc:PropertyName>' + filter[0].substr(2) + '</ogc:PropertyName>' +
  213. '<ogc:Literal>' + filter[1] + '</ogc:Literal>' +
  214. '</ogc:PropertyIsEqualTo>';
  215. return '<ogc:PropertyIsLike wildCard="*" singleChar="%23" escapeChar="!">' +
  216. '<ogc:PropertyName>' + filter[0].substr(2) + '</ogc:PropertyName>' +
  217. '<ogc:Literal>*' + filter[1] + '*</ogc:Literal>' +
  218. '</ogc:PropertyIsLike>';
  219. }) + '</ogc:And></ogc:Filter>'
  220. : ''
  221. var paginationLimit = 20;
  222. DBG && console.log('graphFetchData...', {
  223. paginationLimit: paginationLimit,
  224. page: page,
  225. filterIdGroup: filterIdGroup,
  226. filterIdRaport: filterIdRaport,
  227. filterFields: filterFields,
  228. ogcFilterFields: ogcFilterFields,
  229. });
  230. function refFieldsOnPathToList(typeName, fields) {
  231. var fields = fields || []
  232. var flatList = []
  233. var refPathBase = [
  234. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  235. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
  236. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object'
  237. ]
  238. flatList.push(refPathBase.concat(typeName).join('/'))
  239. fields.forEach(function (fieldName) {
  240. flatList.push(refPathBase.concat(typeName, fieldName).join('/'))
  241. })
  242. return flatList;
  243. }
  244. return p5WFS_GetFeature(('pracownicy' === nameSection) ? 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY' : 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI',
  245. Object.assign({
  246. sortBy: 'ID+D',
  247. maxFeatures: paginationLimit,
  248. startIndex: (page - 1) * paginationLimit,
  249. // TODO: backRefNS, backRefPK, backRefField - TODO: from groups
  250. // resolve: 'all',
  251. // resolveDepth: 2
  252. // 'ogc:Filter': '<wfs:Query>' + '\n' + [
  253. // 'ID',
  254. // 'imiona',
  255. // 'nazwisko',
  256. // 'miejscowosc'
  257. // ]
  258. 'ogc:Filter': '<wfs:Query>' + '\n' + [].concat(
  259. ('pracownicy' === nameSection)
  260. ? [
  261. 'ID',
  262. 'imiona',
  263. 'nazwisko',
  264. 'miejscowosc'
  265. ] : [
  266. 'ID',
  267. 'Pelna_nazwa_kontrahenta'
  268. ]
  269. )
  270. .concat(refFieldsOnPathToList('default_db__x3A__BI_audit_KRS:BI_audit_KRS', [ 'ID', 'nazwa', 'krs', 'S_miejscowosc' ]))
  271. .concat(refFieldsOnPathToList('default_db__x3A__BI_audit_MSIG:BI_audit_MSIG', [ 'ID', 'nazwa' ]))
  272. .concat(refFieldsOnPathToList('default_db__x3A__BI_audit_CEIDG:BI_audit_CEIDG', [ 'ID', 'nazwisko', 'firma' ]))
  273. .concat(refFieldsOnPathToList('default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI', [ 'ID', 'Pelna_nazwa_kontrahenta' ]))
  274. .concat(
  275. ('pracownicy' === nameSection)
  276. ? []
  277. : refFieldsOnPathToList('default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY', [ 'ID', 'imiona', 'nazwisko', 'miejscowosc' ])
  278. )
  279. .concat([
  280. // '*',
  281. // 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY_adresy:BI_audit_ENERGA_PRACOWNICY_adresy/*',
  282. [
  283. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  284. 'ID'
  285. ].join('/'),
  286. [
  287. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  288. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
  289. 'ID'
  290. ].join('/'),
  291. [
  292. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  293. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
  294. 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  295. 'ID'
  296. ].join('/')
  297. ]).map(function (fieldName) {
  298. return '<wfs:PropertyName>' + fieldName + '</wfs:PropertyName>';
  299. }).join('\n') + '\n' +
  300. ( ogcFilterFields ? ogcFilterFields : '' ) +
  301. '</wfs:Query>'
  302. }, ('pracownicy' === nameSection && filterIdRaport > 0)
  303. ? {
  304. backRefNS: 'default_db/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA',
  305. backRefPK: filterIdRaport,
  306. backRefField: 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY',
  307. }
  308. : {}
  309. , ('kontrahenci' === nameSection && filterIdRaport > 0)
  310. ? {
  311. backRefNS: 'default_db/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA',
  312. backRefPK: filterIdRaport,
  313. backRefField: 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI',
  314. }
  315. : {}
  316. , ('pracownicy' === nameSection && filterIdGroup > 0)
  317. ? {
  318. backRefNS: 'default_db/BI_audit_ENERGA_PRACOWNICY_group/BI_audit_ENERGA_PRACOWNICY_group',
  319. backRefPK: filterIdGroup,
  320. backRefField: 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY',
  321. }
  322. : {}
  323. , ('kontrahenci' === nameSection && filterIdGroup > 0)
  324. ? {
  325. backRefNS: 'default_db/BI_audit_ENERGA_PRACOWNICY_group/BI_audit_ENERGA_PRACOWNICY_group',
  326. backRefPK: filterIdGroup,
  327. backRefField: 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI',
  328. }
  329. : {}
  330. )
  331. );
  332. }
  333. function graphRender(props, wrapNode) {
  334. throw "TODO: graphRender..."
  335. }
  336. function graphRaportRender(props, wrapNode) {
  337. var svgNode = jQuery(wrapNode).children('svg')
  338. svgNode = (svgNode.length) ? d3.select(svgNode.get(0)) : d3.select(wrapNode).append("svg")
  339. // svg.append("rect").attr("x",0).attr("y",0).attr("width","100%").attr("height","100%").attr("fill","white").attr('class','background').on('mouseup', () => redraw())
  340. // svgNode.attr("width", '100%')
  341. // .attr("height", '300px')
  342. // .append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  343. // var data = parseGraphRec(props.items, props.nameSection)
  344. var _todoGraphData = [];
  345. parseResponseRec(_todoGraphData, props.items, props.typeName)
  346. DBG && console.log('_todoGraphData', _todoGraphData)
  347. var _nodes = [];
  348. var _links = [];
  349. var mapNodeIdToIdx = {};
  350. _todoGraphData.forEach(function (levelData, levelIdx) {
  351. if (levelData.nodes && levelData.nodes.length) {
  352. levelData.nodes.forEach(function (node) {
  353. try {
  354. if (node.id in mapNodeIdToIdx) return;
  355. _nodes.push(node) // _nodes.add(node)
  356. mapNodeIdToIdx[node.id] = _nodes.length - 1
  357. } catch (e) {
  358. DBG && console.log('_graphData.nodes.add [level='+levelIdx+'] error:', e);
  359. }
  360. })
  361. }
  362. })
  363. var linkIdsAdded = []
  364. _todoGraphData.forEach(function (levelData, levelIdx) {
  365. if (levelData.edges && levelData.edges.length) {
  366. levelData.edges.forEach(function (edge) {
  367. DBG && console.log('_graphData.edges.add [level='+levelIdx+']:', {edge, source:mapNodeIdToIdx[edge.source], target:mapNodeIdToIdx[edge.target], mapNodeIdToIdx});
  368. // try {
  369. // var source = mapNodeIdToIdx[edge.source]
  370. // var target = mapNodeIdToIdx[edge.target]
  371. // if (!source || !target) { // && !== 0
  372. // console.warn('(!source || !target)', {source, target, edge, mapNodeIdToIdx})
  373. // }
  374. if (-1 !== linkIdsAdded.indexOf(edge.id)) return
  375. // _links.push({
  376. // id: edge.id,
  377. // source: mapNodeIdToIdx[edge.source],
  378. // target: mapNodeIdToIdx[edge.target],
  379. // value: 1
  380. // })
  381. _links.push({
  382. id: edge.id,
  383. source: edge.source,
  384. target: edge.target,
  385. value: 1
  386. }) // _edges.add(edge)
  387. linkIdsAdded.push(edge.id)
  388. // } catch (e) {
  389. // DBG && console.log('_graphData.edges.add [level='+levelIdx+'] error:', e);
  390. // }
  391. })
  392. }
  393. })
  394. var totalLinks = _links.length
  395. // console.log('DBG:0: _links', _links)
  396. DBG && console.log('DBG:1: _nodes', _nodes)
  397. _nodes = _nodes.filter(function (node, idx) {
  398. if (node.typeName !== props.typeName) return true
  399. for (var i=0; i<totalLinks; i++) {
  400. var link = _links[i]
  401. if (_links[i].source === node.id) return true
  402. if (_links[i].target === node.id) return true
  403. }
  404. return false
  405. })
  406. // console.log('DBG:2: _nodes', _nodes)
  407. jQuery(wrapNode).find('p').remove()
  408. if (!_nodes || !_nodes.length) {
  409. jQuery(wrapNode).find('svg').remove()
  410. jQuery(wrapNode).append('<p>Brak powiązań</p>')
  411. return;
  412. }
  413. var rightSideNodes = _nodes.filter(function (node, idx) {
  414. for (var i=0; i<totalLinks; i++) {
  415. var link = _links[i]
  416. // if (_links[i].source === node.id) return true
  417. if (_links[i].target === node.id) return true
  418. }
  419. return false
  420. })
  421. DBG && console.log('DBG: rightSideNodes (total:'+rightSideNodes.length+') ', rightSideNodes)
  422. if (rightSideNodes.length > 20) {
  423. // TODO: increase height
  424. }
  425. var graphData = {
  426. nodes: _nodes,
  427. links: _links.filter(function (link) {
  428. DBG && console.log('DBG loop link', { link, source: link.source, target: link.target, filtered: (link.source && link.target) });
  429. return (link.source && link.target);
  430. })
  431. };
  432. DBG && console.warn('render graphData', graphData);
  433. var graf = renderGraph(svgNode, graphData, {
  434. width: jQuery(wrapNode).width(),
  435. height: (rightSideNodes.length > 20) ? rightSideNodes.length * 22 : 500
  436. })
  437. graf.on('click', (event) => {
  438. DBG && console.log('event', event)
  439. // event = {
  440. // nativeEvent: d3.event,
  441. // node: a,
  442. // element: d3.event.srcElement
  443. // }
  444. // TODO: !a.expanded && redraw({type: a.name, criteria: 'ID'})
  445. })
  446. }
  447. function parseResponseRec(_todoGraphData, json, typeName, parentNodeId, level) {
  448. var level = level || 0
  449. var parentNodeId = parentNodeId || null
  450. DBG && console.log('DBG::parseResponseRec', {json:json, typeName:typeName, parentNodeId:parentNodeId, isString: p5Utils__isString(json), isArray: p5Utils__isArray(json), isObject: p5Utils__isObject(json)});
  451. if (p5Utils__isArray(json)) {
  452. // TODO: create named group
  453. var isXlinkList = (json.length > 0 && p5Utils__isString(json[0]))
  454. json.forEach(function (subJson) {
  455. if (isXlinkList) {
  456. parseResponseXlinkListRec(_todoGraphData, subJson, typeName, parentNodeId, level)
  457. } else {
  458. parseResponseRec(_todoGraphData, subJson, typeName, parentNodeId, level)
  459. }
  460. })
  461. } else if (p5Utils__isObject(json) && isP5LinkObject(json)) {
  462. DBG && console.log('DBG::parseResponseRec isP5LinkObject');
  463. parseResponseP5Link(_todoGraphData, json, typeName, parentNodeId, level)
  464. } else if (p5Utils__isObject(json)) {
  465. // _todoGraphData.nodes.add({ id: nodeId, label: nodeId })
  466. if (!_todoGraphData[level]) _todoGraphData[level] = { nodes: [], edges: [] }
  467. var nodeObject = dataMakeNode({
  468. typeName: typeName,
  469. primaryKey: (json['ID']) ? json['ID'] : null, // TODO: get primaryKey from object
  470. row: json,
  471. })
  472. var nodeId = nodeObject.id
  473. if ("default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row" === typeName) {
  474. parseResponseRec__row(_todoGraphData, json, typeName, parentNodeId, level)
  475. }
  476. else if ("default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object" === typeName) {
  477. // parseResponseRec__row_object(_todoGraphData, json, typeName, parentNodeId, level)
  478. Object.keys(json).filter(function (fieldName) {
  479. return (fieldName.indexOf(':') > -1)
  480. })
  481. .forEach(function (fieldName) {
  482. var value = json[fieldName]
  483. parseResponseRec(_todoGraphData, value, fieldName, parentNodeId, level + 1)
  484. })
  485. }
  486. else {
  487. DBG && console.warn('DBG::parseResponseRec: obj node.push', { id: nodeObject.id, parentNodeId, typeName, nodeObject });
  488. _todoGraphData[level].nodes.push(nodeObject)
  489. if (parentNodeId) {
  490. _todoGraphData[level].edges.push(dataMakeEdge(parentNodeId, nodeObject))
  491. }
  492. Object.keys(json).filter(function (fieldName) {
  493. return (fieldName.indexOf(':') > -1)
  494. })
  495. .forEach(function (fieldName) {
  496. var value = json[fieldName]
  497. parseResponseRec(_todoGraphData, value, fieldName, nodeId, level + 1)
  498. })
  499. }
  500. } else if (p5Utils__isString(json)) {
  501. DBG && console.log('TODO: Not implemented - parseResponseRec isString');
  502. } else {
  503. DBG && console.log('TODO: Not implemented - parseResponseRec is not string, not array and not object');
  504. }
  505. }
  506. function parseResponseXlinkListRec(_todoGraphData, json, typeName, parentNodeId, level) {
  507. DBG && console.log('DBG::parseResponseRec:XlinkList', {json:json, typeName:typeName, parentNodeId:parentNodeId, isString: p5Utils__isString(json), isArray: p5Utils__isArray(json), isObject: p5Utils__isObject(json)});
  508. if (p5Utils__isString(json)) { // xlink "https://biuro.biall-net.pl/wfs/default_db/BI_audit_ENERGA_RUM_KONTRAHENCI#BI_audit_ENERGA_RUM_KONTRAHENCI.9233",
  509. if ("default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object" === typeName) return;
  510. if ("default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row" === typeName) return;
  511. var nodeId = json.substr(json.indexOf('#') + 1)
  512. {
  513. // _graphData.nodes.add({ id: nodeId, label: nodeId })
  514. if (!_todoGraphData[level]) _todoGraphData[level] = { nodes: [], edges: [] }
  515. var nodeObject = dataMakeXlinkNode({
  516. xlink: json,
  517. typeName: typeName,
  518. })
  519. DBG && console.warn('DBG::parseResponseRec: xlink node.push', { id: nodeObject.id, parentNodeId, typeName, nodeObject });
  520. _todoGraphData[level].nodes.push(nodeObject)
  521. if (parentNodeId) {
  522. _todoGraphData[level].edges.push(dataMakeEdge(parentNodeId, nodeObject))
  523. }
  524. }
  525. } else if (p5Utils__isObject(json) && isP5LinkObject(json)) {
  526. parseResponseP5Link(_todoGraphData, json, typeName, parentNodeId, level)
  527. } else if (p5Utils__isObject(json)) {
  528. DBG && console.warn('TODO: Not implemented - parseResponseRec:XlinkList is object', {json:json, typeName:typeName, parentNodeId:parentNodeId, isString: p5Utils__isString(json), isArray: p5Utils__isArray(json), isObject: p5Utils__isObject(json)});
  529. parseResponseRec(_todoGraphData, json, typeName, parentNodeId, level + 1)
  530. } else {
  531. DBG && console.warn('TODO: Not implemented - parseResponseRec:XlinkList is not string and not object');
  532. }
  533. }
  534. function parseResponseP5Link(_todoGraphData, json, typeName, parentNodeId, level) {
  535. DBG && console.log('parseResponseRec isObject and P5Link - fetch more xlink object');
  536. // example json: { type: "next",
  537. // @backRefNS: "default_db/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA/BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA",
  538. // @backRefPK: "42",
  539. // @typeName: "default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_P…ow:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row",
  540. // @startIndex: "10" }
  541. if (!parentNodeId) throw "Missing parentNodeId for ref link object";
  542. var objectName = typeName.substr(typeName.indexOf(':') + 1)
  543. {
  544. // _graphData.nodes.add({ id: nodeId, label: nodeId })
  545. if (!_todoGraphData[level]) _todoGraphData[level] = { nodes: [], edges: [] }
  546. switch (json.type) {
  547. case 'next': {
  548. // TODO: add fetch next node
  549. // var nodeObject = dataMakeFetchMoreNode({
  550. // parentNodeId: parentNodeId,
  551. // type: json.type,
  552. // objectName: objectName,
  553. // ref: json,
  554. // })
  555. // _todoGraphData[level].nodes.push(nodeObject)
  556. // _todoGraphData[level].edges.push(dataMakeFetchMoreEdge(parentNodeId, nodeObject))
  557. } break;
  558. default: {
  559. DBG && console.log('TODO: Not implemented - parseResponseRec isObject with type "'+json.type+'" - fetch more xlink object');
  560. }
  561. }
  562. }
  563. }
  564. function parseResponseRec__row(_todoGraphData, json, typeName, parentNodeId, level) {
  565. var nodeObject = dataMakeNode({
  566. typeName: typeName,
  567. primaryKey: (json['ID']) ? json['ID'] : null, // TODO: get primaryKey from object
  568. })
  569. var nodeId = nodeObject.id
  570. // 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
  571. // 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  572. // 'default_db__x3A__BI_audit_KRS:BI_audit_KRS' --> Kontrahenci
  573. var rowObjectChildrens = []
  574. var rowTN = 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row'
  575. var rowObjTN = 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object'
  576. // { row: row_obj: [ { ID, kontr: [ "http...kontr.ID" ] }, { ID, kontr: [ "http...krs.ID" ] } ], ... }
  577. var rowJson = json
  578. if (rowJson[rowObjTN] && rowJson[rowObjTN].length > 1) {
  579. var pathItems = []
  580. rowJson[rowObjTN].forEach(function (rowObjJson) {
  581. Object.keys(rowObjJson)
  582. .filter(function (rowObjFld) { return (-1 !== rowObjFld.indexOf(':')); })
  583. .filter(function (rowObjRefFld) { return (rowObjJson[rowObjRefFld] && rowObjJson[rowObjRefFld].length); })
  584. .forEach(function (rowObjRefFld) {
  585. pathItems.push([ rowObjRefFld, rowObjJson[rowObjRefFld][0] ])
  586. })
  587. })
  588. }
  589. // console.log('node('+nodeId+') pathItems:', pathItems);
  590. var lastParentFid = null
  591. pathItems.reverse().forEach(function (pathItem) {
  592. var nodeObject = ('string' === typeof pathItem[1])
  593. ? dataMakeXlinkNode({
  594. xlink: pathItem[1],
  595. typeName: pathItem[0]
  596. })
  597. : dataMakeNode({
  598. typeName: pathItem[0],
  599. primaryKey: (pathItem[1]['ID']) ? pathItem[1]['ID'] : null,
  600. row: pathItem[1]
  601. })
  602. ;
  603. // _todoGraphData[todoLevel].nodes.push(nodeObject) // already added below
  604. if (lastParentFid) _todoGraphData[level].edges.push(dataMakeEdge(lastParentFid, nodeObject))
  605. lastParentFid = nodeObject.id
  606. })
  607. Object.keys(json).filter(function (fieldName) {
  608. return (fieldName.indexOf(':') > -1)
  609. })
  610. .forEach(function (fieldName) {
  611. var value = json[fieldName]
  612. parseResponseRec(_todoGraphData, value, fieldName, parentNodeId, level + 1)
  613. })
  614. }
  615. function parseGraphRec(items, featureType, parentFeatureId) { // TODO: not used
  616. var parentFeatureId = parentFeatureId || null
  617. var nodesArray = []
  618. var linksArray = []
  619. if (!items) return;
  620. items.forEach(function (item) {
  621. if ('string' === typeof item) {
  622. DBG && console.log('TODO: xlink "'+item+'": ', {item:item, parentFeatureId:parentFeatureId})
  623. return;
  624. }
  625. if (!item['ID']) {
  626. DBG && console.log('TODO: SKIP item('+featureType+') - missing ID: ', {item:item, parentFeatureId:parentFeatureId})
  627. return;
  628. }
  629. var id = item['ID']
  630. console.log('item('+featureType+'): ', {item:item, parentFeatureId:parentFeatureId})
  631. var featureId = featureType + '.' + id
  632. Object.keys(item).filter(function (fieldName) { return ('ID' !== fieldName); })
  633. .forEach(function (fieldName) {
  634. parseGraphRec(item[fieldName], fieldName, featureId)
  635. })
  636. })
  637. // items.forEach(element => {
  638. // const rowObject = hasTargetArray(element);
  639. // if (rowObject)
  640. // rowObject.array.forEach(objectElement => {
  641. // const trackNode = hasTargetArray(objectElement);
  642. // if (trackNode) {
  643. // let group = trackNode.name;
  644. // let expanded = false;
  645. // if (expansion && expansion.type && group === expansion.type) {
  646. // group = trackNode.array[0][expansion.criteria];
  647. // expanded = true;
  648. // }
  649. // nodes[group] = {expanded: expanded, type: trackNode.name};
  650. // instanceTypes[trackNode.array[0].ID] = group;
  651. // }
  652. // });
  653. // });
  654. return {
  655. nodes: nodesArray,
  656. links: linksArray
  657. }
  658. }
  659. function isP5LinkObject(json) {
  660. if ( !('type' in json) || !json['type'] ) return false;
  661. if ( !('value' in json) || !json['value'] ) return false;
  662. if ( !('@typeName' in json) || !json['@typeName'] ) return false;
  663. if ( !('@startIndex' in json) || !json['@startIndex'] ) return false;
  664. if ( !('@backRefPK' in json) || !json['@backRefPK'] ) return false;
  665. if ( !('@backRefNS' in json) || !json['@backRefNS'] ) return false;
  666. return true;
  667. }
  668. function dataMakeNode(params) {
  669. var objectName = params.typeName.substr(params.typeName.indexOf(':') + 1)
  670. var nodeId = objectName + '.' + params.primaryKey // TODO: primaryKey?
  671. var graphNode = {
  672. id: nodeId,
  673. name: nodeId,
  674. group: objectName,
  675. _loaded: true,
  676. typeName: params.typeName,
  677. primaryKey: params.primaryKey // TODO: _primaryKey
  678. }
  679. if (params.row) graphNode.row = params.row
  680. return graphAddNodeLabel(graphNode)
  681. }
  682. function dataMakeEdge(parentNodeId, nodeObject) {
  683. return {
  684. id: parentNodeId + nodeObject.id,
  685. source: parentNodeId,
  686. target: nodeObject.id,
  687. }
  688. }
  689. function dataMakeXlinkNode(params) {
  690. var objectName = params.typeName.substr(params.typeName.indexOf(':') + 1)
  691. var nodeId = params.xlink.substr(params.xlink.indexOf('#') + 1)
  692. var primaryKey = nodeId.substr(nodeId.lastIndexOf('.') + 1)
  693. var graphNode = {
  694. id: nodeId,
  695. name: nodeId,
  696. group: objectName,
  697. _loaded: false,
  698. typeName: params.typeName,
  699. primaryKey: primaryKey
  700. }
  701. return graphAddNodeLabel(graphNode)
  702. }
  703. function dataMakeFetchMoreNode(params) {
  704. // params = {
  705. // parentNodeId: parentNodeId,
  706. // type: json.type,
  707. // objectName: objectName,
  708. // ref: json,
  709. // }
  710. DBG && console.log('DBG dataMakeFetchMoreNode(params)', params)
  711. var nodeId = params.parentNodeId+'fetch-more-features-'+params.type+'-on-' + params.objectName;
  712. return {
  713. id: nodeId,
  714. label: 'Pobierz więcej (+)',
  715. group: 'fetch-more-data', // params.objectName,
  716. _loaded: false,
  717. _type: 'ref',
  718. parentNodeId: params.parentNodeId,
  719. ref: params.ref,
  720. // typeName: typeName,
  721. // primaryKey: nodeId.substr(nodeId.lastIndexOf('.') + 1)
  722. };
  723. }
  724. function dataMakeFetchMoreEdge(parentNodeId, fetchMoreNode) {
  725. // @param parentNodeId - from node id
  726. // @param fetchMoreNode - from dataMakeFetchMoreNode
  727. DBG && console.log('DBG dataMakeFetchMoreEdge(parentNodeId, fetchMoreNode)', {parentNodeId:parentNodeId, fetchMoreNode:fetchMoreNode})
  728. return {
  729. id: fetchMoreNode.id,
  730. from: parentNodeId,
  731. to: fetchMoreNode.id
  732. }
  733. }
  734. function makeShortLabel(label) { // TODO: shorter name
  735. // BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object.1234567
  736. if (label.length < 30) return label;
  737. var exLabel = label.split('.')
  738. if (exLabel.length !== 2) return label;
  739. return exLabel[0].substr(0, 24) + '...' + exLabel[0].substr(-10) + '.' + exLabel[1];
  740. }
  741. function graphAddNodeLabel(graphNode) {
  742. // var graphNode = {
  743. // id: nodeId,
  744. // name: nodeId,
  745. // group: objectName,
  746. // _loaded: true,
  747. // typeName: params.typeName,
  748. // primaryKey: params.primaryKey // TODO: _primaryKey
  749. // }
  750. var label = graphNode.id // TODO: get from schema assert @label attribute
  751. label = makeShortLabel(graphNode.id)
  752. switch (graphNode.typeName) {
  753. case 'default_db__x3A__BI_audit_KRS:BI_audit_KRS': {
  754. // <xs:assert test="@default_db__x3A__BI_audit_KRS:label = concat(nazwa, ' ', krs, ' ', S_miejscowosc)" id="I_audit_KRS___d6e76977-1">
  755. if (graphNode.row) label = [graphNode.row.nazwa, graphNode.row.krs, graphNode.row.S_miejscowosc].filter(function (val) { return val; }).join(' ');
  756. label = (label) ? label : makeShortLabel(graphNode.id)
  757. label = label + ' (krs)'
  758. } break;
  759. case 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY': {
  760. // <xs:assert id="_PRACOWNICY___d6e76324-1" test="@label = concat(imiona, ' ', nazwisko, ' ', miejscowosc)"/>
  761. if (graphNode.row) label = [graphNode.row.imiona, graphNode.row.nazwisko, graphNode.row.miejscowosc].filter(function (val) { return val; }).join(' ');
  762. label = (label) ? label : makeShortLabel(graphNode.id)
  763. label = label + ' (pracownicy)'
  764. } break;
  765. case 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI': {
  766. // <xs:assert id="KONTRAHENCI___d6e76526-1" test="@label = concat(substr(Pelna_nazwa_kontrahenta, 0, 20, '\n umów na kwotę ', @sum))"/>
  767. if (graphNode.row) label = [graphNode.row.Pelna_nazwa_kontrahenta].filter(function (val) { return val; }).join(' ');
  768. label = (label) ? label : makeShortLabel(graphNode.id)
  769. label = label + ' (kontrahent)'
  770. } break;
  771. case 'default_db__x3A__BI_audit_CEIDG:BI_audit_CEIDG': {
  772. // <xs:assert test="@label = concat(nazwisko, substring(firma, 1, 20))"/>
  773. if (graphNode.row) label = [graphNode.row.nazwisko, graphNode.row.firma].filter(function (val) { return val; }).join(' ');
  774. label = (label) ? label : makeShortLabel(graphNode.id)
  775. label = label + ' (ceidg)'
  776. } break;
  777. case 'default_db__x3A__BI_audit_MSIG:BI_audit_MSIG': {
  778. // <xs:assert test="@label = substring(nazwa, 1, 20)"/>
  779. if (graphNode.row) label = [graphNode.row.nazwa].filter(function (val) { return val; }).join(' ');
  780. label = (label) ? label : makeShortLabel(graphNode.id)
  781. label = label + ' (msig)'
  782. } break;
  783. }
  784. return Object.assign(graphNode, {
  785. label: label,
  786. })
  787. }
  788. module.exports = {
  789. graphShowHide: graphShowHide,
  790. graphRender: graphRender,
  791. graphRaportRender: graphRaportRender,
  792. /** @example: graphRaportRender({
  793. * msg: "Pobrano dane",
  794. * typeName: ('pracownicy' === nameSection) ? 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY' : 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI',
  795. * items: items
  796. * }, graphResultNode)
  797. */
  798. }