CM works overall dashboard integrate with gcc_office_portal
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

875 lines
29 KiB

2 years ago
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
​
  1. <html xmlns:th="http://www.thymeleaf.org">
  2. <head th:replace="~{fragments/modules/base/head :: head}"></head>
  3. <style>
  4. .chart-container {
  5. width: 100%;
  6. height: 350px;
  7. font-size: 12px;
  8. }
  9. @media ( max-width : 768px) {
  10. .chart-container {
  11. height: 200px; /* Adjust height for mobile view */
  12. }
  13. }
  14. .highlight-red {
  15. color: red;
  16. }
  17. .scheme-count, .typeofwork-count {
  18. cursor: pointer;
  19. color:blue;
  20. }
  21. .scheme-count:hover, .typeofwork-count:hover {
  22. background-color: darkgrey; /* Change this color to your preference */
  23. }
  24. </style>
  25. <body>
  26. <link rel="stylesheet"
  27. href="/assets/node_modules/amcharts3/amcharts/plugins/export/export.css"
  28. type="text/css" media="all" />
  29. <!--[if lt IE 8]>
  30. <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
  31. <![endif]-->
  32. <div class="wrapper">
  33. <!-- header top menu Start -->
  34. <header th:replace="~{fragments/modules/base/header :: header}"></header>
  35. <!-- header top menu end -->
  36. <div class="page-wrap">
  37. <!--=============== Left Menu side Start ================-->
  38. <div th:replace="~{fragments/modules/base/menu :: menu}"></div>
  39. <!--=============== Left side End ================-->
  40. <div class="main-content">
  41. <div class="container-fluid">
  42. <div class="page-header mb-2">
  43. <div class="row align-items-end">
  44. <div class="col-lg-8">
  45. <div class="page-header-title">
  46. <i class="ik ik-bar-chart-2 bg-blue"></i>
  47. <div class="d-inline">
  48. <h5>Works</h5>
  49. <span>CM Works Dashboard</span>
  50. </div>
  51. </div>
  52. </div>
  53. <div class="col-lg-4">
  54. <nav class="breadcrumb-container" aria-label="breadcrumb">
  55. <ol class="breadcrumb">
  56. <li class="breadcrumb-item"><a href="/index"><i class="ik ik-home"></i></a></li>
  57. <li class="breadcrumb-item">CM Dashboard</li>
  58. <li class="breadcrumb-item active" aria-current="page">Dashboard2</li>
  59. </ol>
  60. </nav>
  61. </div>
  62. </div>
  63. </div>
  64. <div class="row">
  65. <div class="col-md-12">
  66. <div class="card sale-card">
  67. <div class="card-header">
  68. <h3>
  69. <i class="fas fa-chart-pie pr-2"></i><b>Works Analysis:</b>
  70. </h3>
  71. <br> <br>
  72. </div>
  73. <div class="card-block" style="text-align: center;">
  74. <div id="chart" class="row">
  75. <div class="col-sm-12 col-xl-6">
  76. <h6>
  77. <b>Over all Region wise works count</b>
  78. </h6>
  79. <div id="region-chartdiv" class="chart-shadow"
  80. style="height: 500px; width: 100%;"></div>
  81. </div>
  82. <hr>
  83. <div class="col-sm-12 col-xl-6">
  84. <h6>
  85. <b>Overall Zonewise works count</b>
  86. </h6>
  87. <div id="zone-chartdiv" class="chart-shadow"
  88. style="height: 500px; width: 100%;"></div>
  89. </div>
  90. <hr>
  91. <div class="col-sm-12 d-flex justify-content-center align-items-center mt-20 mb-20">
  92. <label for="region-select" class="pr-2"><b>Select Zone:</b></label>
  93. <select id="region-select" onchange="updateSchemeAndTypeOfWorkCharts()" class="form-select custom-select" style="width: 30%">
  94. <option value="all">--All--</option>
  95. <option value="B-Buildings">B-Buildings</option>
  96. <option value="BR-Bus Route Roads">BR-Bus Route Roads</option>
  97. <option value="D-Storm Water Drains">D-Storm Water Drains</option>
  98. <option value="J-Bridges">J-Bridges</option>
  99. <option value="L-Electrical">L-Electrical</option>
  100. <option value="P-Parks and Playfields">P-Parks and Playfields</option>
  101. <option value="Q-Solid Waste Management">Q-Solid Waste Management</option>
  102. <option value="SP-SPECIAL PROJECTS">SP-SPECIAL PROJECTS</option>
  103. <option value="01 - NA-THIRUVOTTIYUR">01 - NA-THIRUVOTTIYUR</option>
  104. <option value="02 - NB-MANALI">02 - NB-MANALI</option>
  105. <option value="03 - NC-MADHAVARAM">03 - NC-MADHAVARAM</option>
  106. <option value="04 - ND-TONDIARPET">04 - ND-TONDIARPET</option>
  107. <option value="05 - NE-ROYAPURAM">05 - NE-ROYAPURAM</option>
  108. <option value="06 - NF-THIRU-VI-KA NAGAR">06 - NF-THIRU-VI-KA NAGAR</option>
  109. <option value="07 - NG-AMBATTUR">07 - NG-AMBATTUR</option>
  110. <option value="08 - NH-ANNA NAGAR">08 - NH-ANNA NAGAR</option>
  111. <option value="09 - NJ-TEYNAMPET">09 - NJ-TEYNAMPET</option>
  112. <option value="10 - NK-KODAMBAKKAM">10 - NK-KODAMBAKKAM</option>
  113. <option value="11 - NL-VALASARAVAKKAM">11 - NL-VALASARAVAKKAM</option>
  114. <option value="12 - NM-ALANDUR">12 - NM-ALANDUR</option>
  115. <option value="13 - NN-ADYAR">13 - NN-ADYAR</option>
  116. <option value="14 - NP-PERUNGUDI">14 - NP-PERUNGUDI</option>
  117. <option value="15 - NQ-SHOZHINGANALLUR">15 - NQ-SHOZHINGANALLUR</option>
  118. </select>
  119. </div>
  120. <div class="col-sm-12 col-xl-6">
  121. <h6 id="scheme-title">
  122. <b><span id="scheme-region" class="highlight-red"></span>
  123. Scheme Names</b>
  124. </h6>
  125. <div id="scheme-chartdiv" class="chart-shadow"
  126. style="height: 400px; width: 100%;"></div>
  127. </div>
  128. <hr>
  129. <div class="col-sm-12 col-xl-6">
  130. <h6 id="workcategory-title">
  131. <b><span id="typeofwork-region" class="highlight-red"></span>
  132. Type of Works</b>
  133. </h6>
  134. <div id="typeOfWork-chartdiv" class="chart-shadow"
  135. style="height: 400px; width: 100%;"></div>
  136. </div>
  137. <hr>
  138. </div>
  139. </div>
  140. </div>
  141. </div>
  142. </div>
  143. </div>
  144. </div>
  145. <footer th:replace="~{fragments/modules/base/footer :: footer}"></footer>
  146. </div>
  147. </div>
  148. <!-- Modal -->
  149. <div class="modal fade" id="zoneDetailsModal" tabindex="-1"
  150. role="dialog" aria-labelledby="zoneDetailsModalLabel"
  151. aria-hidden="true" data-backdrop="static" data-keyboard="false">
  152. <div class="modal-dialog modal-lg" role="document">
  153. <div class="modal-content">
  154. <div id="zone-details-content"></div>
  155. </div>
  156. </div>
  157. </div>
  158. <div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
  159. <script th:replace="~{fragments/modules/base/script :: script}"></script>
  160. <script th:replace="~{fragments/modules/pgr/script :: script}"></script>
  161. <script src="/assets/node_modules/amcharts3/amcharts/amcharts.js"></script>
  162. <script src="/assets/node_modules/amcharts3/amcharts/serial.js"></script>
  163. <script src="/assets/node_modules/amcharts3/amcharts/plugins/export/export.min.js"></script>
  164. <script src="/assets/node_modules/amcharts3/amcharts/pie.js"></script>
  165. <script src="/assets/node_modules/amcharts3/amcharts/themes/light.js"></script>
  166. <script src="/assets/node_modules/amcharts3/amcharts/plugins/responsive/responsive.js"></script>
  167. <script src="/assets/node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
  168. <script>
  169. // Function to update the chart titles based on the selected region
  170. function updateChartTitles() {
  171. const regionSelect = document.getElementById("region-select");
  172. const selectedRegion = regionSelect.options[regionSelect.selectedIndex].text;
  173. const schemeRegion = document.getElementById("scheme-region");
  174. const typeofworkRegion = document.getElementById("typeofwork-region");
  175. schemeRegion.innerHTML = selectedRegion;
  176. typeofworkRegion.innerHTML = selectedRegion;
  177. }
  178. updateSchemeAndTypeOfWorkCharts();
  179. // Function to update scheme and type of work charts based on zone selection
  180. function updateSchemeAndTypeOfWorkCharts() {
  181. const zoneName = $("#region-select").val();
  182. console.log("Updating charts for zone in updateSchemeAndTypeOfWorkCharts:", zoneName); // Log the zone name
  183. updateChartTitles();
  184. $.ajax({
  185. url: '/gcc/api/cmdashboard/getCmDashboardReports',
  186. type: 'GET',
  187. data: { zonename: zoneName },
  188. success: function(response) {
  189. console.log('Data from API in updateSchemeAndTypeOfWorkCharts:', response);
  190. const { schemeData, typeOfWorkData } = processCombinedData(response);
  191. createSchemeChart('scheme-chartdiv', schemeData);
  192. createTypeofworkChart('typeOfWork-chartdiv', typeOfWorkData);
  193. },
  194. error: function(error) {
  195. console.error("Error fetching data in updateSchemeAndTypeOfWorkCharts:", error);
  196. console.error("Error details:", error.responseText);
  197. }
  198. });
  199. }
  200. // Function to fetch region counts on page load
  201. function fetchRegionCounts() {
  202. $.ajax({
  203. url: '/gcc/api/cmdashboard/getRegionCounts',
  204. type: 'GET',
  205. success: function(response) {
  206. console.log('Region Counts:', response);
  207. const regionData = processRegionData(response);
  208. createRegionChart('region-chartdiv', regionData);
  209. },
  210. error: function(error) {
  211. console.error("Error fetching region counts:", error);
  212. }
  213. });
  214. }
  215. // Function to fetch zone counts on page load
  216. function fetchZoneCounts() {
  217. const zoneName = $("#region-select").val();
  218. console.log("Selected zone from fetchZoneCounts:", zoneName); // Log the selected zone
  219. $.ajax({
  220. url: '/gcc/api/cmdashboard/getZoneCounts',
  221. type: 'GET',
  222. data: { zonename: zoneName },
  223. success: function(response) {
  224. console.log('Zone Counts:', response);
  225. const zoneData = processZoneData(response);
  226. createZoneChart('zone-chartdiv', zoneData);
  227. },
  228. error: function(error) {
  229. console.error("Error fetching zone counts:", error);
  230. }
  231. });
  232. }
  233. // Function to initialize charts on page load
  234. function initializeCharts() {
  235. fetchRegionCounts();
  236. fetchZoneCounts();
  237. updateSchemeAndTypeOfWorkCharts("all"); // Initialize with "all" parameter
  238. // Removed redundant call to updateSchemeAndTypeOfWorkCharts
  239. }
  240. $(document).ready(function () {
  241. initializeCharts();
  242. });
  243. //region work counts
  244. function processRegionData(data) {
  245. let regionData = []; // This gives the count of regions
  246. data.forEach(item => {
  247. if (item.regionname && item.region_count) {
  248. regionData.push({ title: item.regionname, value: item.region_count });
  249. }
  250. });
  251. return regionData;
  252. }
  253. //zone work counts
  254. function processZoneData(data) {
  255. let zoneData = [];
  256. data.forEach(item => {
  257. if (item.zonename && item.zone_count) {
  258. zoneData.push({ category: item.zonename, count: item.zone_count });
  259. }
  260. });
  261. zoneData.sort((a, b) => b.count - a.count);
  262. return zoneData;
  263. }
  264. //scheme and typeofwork work counts
  265. function processCombinedData(data) {
  266. let schemeData = [];
  267. let typeOfWorkData = [];
  268. data.forEach(item => {
  269. if (item.type === 'Scheme') {
  270. schemeData.push({ category: item.name, count: item.count });
  271. } else if (item.type === 'TypeOfWork') {
  272. typeOfWorkData.push({ category: item.name, count: item.count });
  273. }
  274. });
  275. schemeData.sort((a, b) => b.count - a.count);
  276. typeOfWorkData.sort((a, b) => b.count - a.count);
  277. return { schemeData, typeOfWorkData };
  278. }
  279. //function of random color for chart
  280. function getRandomDarkColor() {
  281. const letters = '0123456789ABCDEF';
  282. let color = '#';
  283. for (let i = 0; i < 6; i++) {
  284. color += letters[Math.floor(Math.random() * 16)];
  285. }
  286. return color;
  287. }
  288. //REGION CHART
  289. //creating region chart
  290. function createRegionChart(chartId, chartData) {
  291. chartData.forEach(data => {
  292. data.color = getRandomDarkColor();
  293. });
  294. AmCharts.makeChart(chartId, {
  295. "type": "pie",
  296. "theme": "dark",
  297. "dataProvider": chartData,
  298. "valueField": "value",
  299. "titleField": "title",
  300. "colorField": "color",
  301. "startEffect":"easeInSine",
  302. "innerRadius": "50%",
  303. "labelText": "[[[[value]]]]",
  304. "labelsEnabled": true,
  305. "gradientRatio": [-0.4, -0.4, -0.4, -0.4, -0.4, -0.4, 0, 0.1, 0.2, 0.1, 0, -0.2, -0.5],
  306. "balloonText": "[[[[title]]]]<br><span style='font-size:14px'><b>[[[[value]]]]</b> ([[[[percents]]]]%)</span>",
  307. "export": {
  308. "enabled": true,
  309. },
  310. "responsive": {
  311. "enabled": true,
  312. },
  313. "pullOutRadius":0,
  314. "legend": {
  315. "position": "bottom",
  316. "markerType": "diamond",
  317. "valueAlign": "left",
  318. "align": "center",
  319. "reversedOrder": true,
  320. "labelText": "[[[[title]]]] - ",
  321. "enabled": true
  322. },
  323. "listeners": [{
  324. "event": "clickSlice",
  325. "method": function(event) {
  326. let regionname = event.dataItem.dataContext.title;
  327. fetchRegionZoneDetails(regionname);
  328. }
  329. }]
  330. });
  331. }
  332. //fetching region details
  333. function fetchRegionZoneDetails(regionname) {
  334. $.ajax({
  335. url: '/gcc/api/cmdashboard/getRegionzones',
  336. type: 'GET',
  337. data: { regionname: regionname },
  338. success: function(response) {
  339. displayRegionZoneDetails(response, regionname);
  340. },
  341. error: function(error) {
  342. console.error("Error fetching region details:", error);
  343. }
  344. });
  345. }
  346. // display region details
  347. function displayRegionZoneDetails(data, regionname) {
  348. let totalValueOfWork = formatValue(data.totalValueOfWork);
  349. let totalWorkCounts = data.totalWorkCounts;
  350. let regionzonedetails=data.regionzonedetails;
  351. let regionZonesContent = '';
  352. regionzonedetails.forEach(item => {
  353. let formattedTotalValue = formatValue(item.totalValueOfWork);
  354. regionZonesContent += `<tr><td>${item.name}</td><td>${item.regionszones_count}</td><td>${formattedTotalValue}</td></tr>`;
  355. });
  356. let modalContent = `
  357. <div class="modal-header">
  358. <h5 class="modal-title"><b>Region: ${regionname}</b></h5>
  359. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  360. <span aria-hidden="true">&times;</span>
  361. </button>
  362. </div>
  363. <div class="modal-body">
  364. <table class="table table-striped table-bordered">
  365. <thead class="thead-dark">
  366. <tr>
  367. <th>Zone Name</th>
  368. <th>Works</th>
  369. <th>Total Value of Work</th>
  370. </tr>
  371. </thead>
  372. <tbody>
  373. ${regionZonesContent}
  374. </tbody>
  375. </table>
  376. <div class="d-flex justify-content-between">
  377. <h6><b>Total Work Counts: </b>${totalWorkCounts}</h6>
  378. <h6><b>Total Value of Work: </b>${totalValueOfWork}</h6>
  379. </div>
  380. </div>
  381. `;
  382. document.getElementById('zone-details-content').innerHTML = modalContent;
  383. // Show the modal
  384. $('#zoneDetailsModal').modal('show');
  385. }
  386. //ZONE CHART
  387. //creating zone chart
  388. function createZoneChart(chartId, chartData) {
  389. chartData.forEach(data => {
  390. data.color = getRandomDarkColor();
  391. });
  392. AmCharts.makeChart(chartId, {
  393. "type": "serial",
  394. "theme": "light",
  395. "valueField": "value",
  396. "titleField": "title",
  397. "colorField": "color",
  398. "dataProvider": chartData,
  399. "depth3D": 2,
  400. "angle": 10,
  401. "valueAxes": [{
  402. "gridColor": "#808080",
  403. "axisAlpha": 0,
  404. "gridAlpha": 0,
  405. "labelsEnabled": false,
  406. "dashLength": 0
  407. }],
  408. "startDuration": 1,
  409. "startEffect":"easeInSine",
  410. "graphs": [{
  411. "balloonText": "[[[[category]]]]<br><span style='font-size:14px'><b>[[[[count]]]]</b></span>",
  412. "fillAlphas": 0.8,
  413. "lineAlpha": 0.2,
  414. "topRadius": 1,
  415. "type": "column",
  416. "valueField": "count",
  417. "fillColorsField": "color",
  418. "labelText": "[[[[value]]]]",
  419. "labelColorField": "#ffffff",
  420. "lineThickness": 1,
  421. }],
  422. "chartCursor": {
  423. "valueLineEnabled": false,
  424. "valueLineBalloonEnabled": false,
  425. "cursorAlpha": 0,
  426. "valueLineAlpha": 0.2,
  427. "pan": false
  428. },
  429. "categoryField": "category",
  430. "categoryAxis": {
  431. "gridPosition": "start",
  432. "gridAlpha": 0,
  433. "autoWrap": false,
  434. "axisAlpha": 0,
  435. },
  436. "rotate": true,
  437. "export": {
  438. "enabled": true,
  439. "position": "bottom-right"
  440. },
  441. "listeners": [{
  442. "event": "clickGraphItem",
  443. "method": function(event) {
  444. let zoneName = event.item.category;
  445. fetchZoneDetails(zoneName);
  446. }
  447. }]
  448. });
  449. }
  450. function fetchZoneDetails(zoneName) {
  451. $.ajax({
  452. url: '/gcc/api/cmdashboard/getCmDashboardReports',
  453. type: 'GET',
  454. data: { zonename: zoneName },
  455. success: function(response) {
  456. displayZoneDetails(response, zoneName);
  457. },
  458. error: function(error) {
  459. console.error("Error fetching zone details:", error);
  460. }
  461. });
  462. }
  463. function displayZoneDetails(data, zoneName) {
  464. let schemeDetails = '';
  465. let workCategoryDetails = '';
  466. let typeOfWorkDetails = '';
  467. data.forEach(item => {
  468. if (item.type === 'Scheme') {
  469. schemeDetails += `<tr><td>${item.name}</td><td class="scheme-count" data-schemename="${item.name}" data-zonename="${zoneName}">${item.count}</td></tr>`;
  470. } else if (item.type === 'TypeOfWork') {
  471. typeOfWorkDetails += `<tr><td>${item.name}</td><td class="typeofwork-count" data-typeofwork="${item.name}" data-zonename="${zoneName}">${item.count}</td></tr>`;
  472. }
  473. });
  474. let modalContent = `
  475. <div class="modal-header">
  476. <h5 class="modal-title"><b>Zone: ${zoneName}</b></h5>
  477. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  478. <span aria-hidden="true">&times;</span>
  479. </button>
  480. </div>
  481. <div class="modal-body">
  482. <div class="row">
  483. <div class="col-sm-12 col-md-12 col-lg-6">
  484. <table class="table table-striped table-bordered">
  485. <thead class="thead-dark">
  486. <tr>
  487. <th>Scheme Names</th>
  488. <th>Works</th>
  489. </tr>
  490. </thead>
  491. <tbody>
  492. ${schemeDetails}
  493. </tbody>
  494. </table>
  495. </div>
  496. <div class="col-sm-12 col-md-12 col-lg-6">
  497. <table class="table table-striped table-bordered">
  498. <thead class="thead-dark">
  499. <tr>
  500. <th>Type of Works</th>
  501. <th>Works</th>
  502. </tr>
  503. </thead>
  504. <tbody>
  505. ${typeOfWorkDetails}
  506. </tbody>
  507. </table>
  508. </div>
  509. </div>
  510. </div>
  511. `;
  512. document.getElementById('zone-details-content').innerHTML = modalContent;
  513. // Show the modal
  514. $('#zoneDetailsModal').modal('show');
  515. // Add click event listeners
  516. addModalEventListeners();
  517. }
  518. function addModalEventListeners() {
  519. // Capture click event on scheme counts
  520. $(".scheme-count").click(function () {
  521. var schemename = $(this).data("schemename");
  522. var zonename = $(this).data("zonename");
  523. window.location.href = "/gcc/dashboards/all-list?zonename=" + zonename + "&schemename=" + schemename;
  524. });
  525. // Capture click event on typeofwork counts
  526. $(".typeofwork-count").click(function () {
  527. var typeofwork = $(this).data("typeofwork");
  528. var zonename = $(this).data("zonename");
  529. window.location.href = "/gcc/dashboards/all-list?zonename=" + zonename + "&typeofwork=" + typeofwork;
  530. });
  531. }
  532. function createSchemeChart(chartId, chartData) {
  533. chartData.forEach(data => {
  534. data.color = getRandomDarkColor();
  535. });
  536. AmCharts.makeChart(chartId, {
  537. "type": "serial",
  538. "theme": "light",
  539. "valueField": "value",
  540. "titleField": "title",
  541. "colorField": "color",
  542. "dataProvider": chartData,
  543. "depth3D": 3,
  544. "angle": 10,
  545. "valueAxes": [{
  546. "gridColor": "#808080",
  547. "axisAlpha": 0,
  548. "gridAlpha": 0,
  549. "labelsEnabled": false,
  550. "dashLength": 0
  551. }],
  552. "startDuration": 1,
  553. "startEffect":"easeInSine",
  554. "graphs": [{
  555. "balloonText": "[[[[category]]]]<br><span style='font-size:14px'><b>[[[[count]]]]</b></span>",
  556. "fillAlphas": 0.8,
  557. "lineAlpha": 0.2,
  558. "topRadius": 1,
  559. "type": "column",
  560. "valueField": "count",
  561. "fillColorsField": "color",
  562. "labelText": "[[[[value]]]]",
  563. "labelColorField": "#ffffff",
  564. "lineThickness": 1,
  565. }],
  566. "chartCursor": {
  567. "valueLineEnabled": false,
  568. "valueLineBalloonEnabled": false,
  569. "cursorAlpha": 0,
  570. "valueLineAlpha": 0.2,
  571. "pan": false
  572. },
  573. "categoryField": "category",
  574. "categoryAxis": {
  575. "gridPosition": "start",
  576. "gridAlpha": 0,
  577. "autoWrap": false,
  578. "axisAlpha": 0,
  579. },
  580. "rotate": true,
  581. "export": {
  582. "enabled": true,
  583. },
  584. "listeners": [{
  585. "event": "clickGraphItem",
  586. "method": function(event) {
  587. let schemename = event.item.category;
  588. let zonename = $("#region-select").val();
  589. fetchSchemeDetails(schemename, zonename);
  590. }
  591. }]
  592. });
  593. }
  594. //Function for Formatting the valueofwork
  595. function formatValue(value) {
  596. value = Number(value); // Ensure the value is a number
  597. if (value >= 1e9) {
  598. return (value / 1e9).toFixed(2) + ' Billion';
  599. } else if (value >= 1e6) {
  600. return (value / 1e6).toFixed(2) + ' Million';
  601. } else if (value >= 1e5) {
  602. return (value / 1e5).toFixed(2) + ' Lakh';
  603. } else if (value >= 1e4) {
  604. return (value / 1e4).toFixed(2) + ' Thousand';
  605. }
  606. return value.toFixed(2);
  607. }
  608. function fetchSchemeDetails(schemename, zonename) {
  609. $.ajax({
  610. url: '/gcc/api/cmdashboard/getSchemeDetails',
  611. type: 'GET',
  612. data: { schemename: schemename, zonename: zonename },
  613. success: function(response) {
  614. displaySchemeDetails(response, schemename);
  615. },
  616. error: function(error) {
  617. console.error("Error fetching scheme details:", error);
  618. }
  619. });
  620. }
  621. function displaySchemeDetails(data, schemename) {
  622. let totalValueOfWork = formatValue(data.totalValueOfWork);
  623. let totalWorkCounts = data.totalWorkCounts; // get totalWorkCounts
  624. let typeOfWorkDetails = data.typeOfWorkDetails;
  625. let typeOfWorkContent = '';
  626. typeOfWorkDetails.forEach(item => {
  627. let formattedTotalValue = formatValue(item.totalValueOfWork);
  628. typeOfWorkContent += `<tr><td>${item.name}</td><td>${item.count}</td><td>${formattedTotalValue}</td></tr>`;
  629. });
  630. let modalContent = `
  631. <div class="modal-header">
  632. <h5 class="modal-title"><b>Scheme: ${schemename}</b></h5>
  633. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  634. <span aria-hidden="true">&times;</span>
  635. </button>
  636. </div>
  637. <div class="modal-body">
  638. <table class="table table-striped table-bordered">
  639. <thead class="thead-dark">
  640. <tr>
  641. <th>Type of Work</th>
  642. <th>Works</th>
  643. <th>Cost</th>
  644. </tr>
  645. </thead>
  646. <tbody>
  647. ${typeOfWorkContent}
  648. </tbody>
  649. </table>
  650. <div class="d-flex justify-content-between">
  651. <h6><b>Total Work Counts: </b>${totalWorkCounts}</h6>
  652. <h6><b>Total Value of Work: </b>${totalValueOfWork}</h6>
  653. </div>
  654. </div>
  655. `;
  656. document.getElementById('zone-details-content').innerHTML = modalContent;
  657. // Show the modal
  658. $('#zoneDetailsModal').modal('show');
  659. }
  660. function createTypeofworkChart(chartId, chartData) {
  661. chartData.forEach(data => {
  662. data.color = getRandomDarkColor();
  663. });
  664. AmCharts.makeChart(chartId, {
  665. "type": "serial",
  666. "theme": "light",
  667. "valueField": "value",
  668. "titleField": "title",
  669. "colorField": "color",
  670. "dataProvider": chartData,
  671. "depth3D": 3,
  672. "angle": 10,
  673. "valueAxes": [{
  674. "gridColor": "#808080",
  675. "axisAlpha": 0,
  676. "gridAlpha": 0,
  677. "labelsEnabled": false,
  678. "dashLength": 0,
  679. "position": "top",
  680. "reversed":true
  681. }],
  682. "startDuration": 1,
  683. "startEffect":"easeInSine",
  684. "graphs": [{
  685. "balloonText": "[[[[category]]]]<br><span style='font-size:14px'><b>[[[[count]]]]</b></span>",
  686. "fillAlphas": 0.8,
  687. "lineAlpha": 0.2,
  688. "topRadius": 1,
  689. "type": "column",
  690. "valueField": "count",
  691. "fillColorsField": "color",
  692. "labelText": "[[[[value]]]]",
  693. "labelColorField": "#ffffff",
  694. "lineThickness": 1,
  695. }],
  696. "chartCursor": {
  697. "valueLineEnabled": false,
  698. "valueLineBalloonEnabled": false,
  699. "cursorAlpha": 0,
  700. "valueLineAlpha": 0.2,
  701. "pan": false
  702. },
  703. "categoryField": "category",
  704. "categoryAxis": {
  705. "gridPosition": "start",
  706. "gridAlpha": 0,
  707. "autoWrap": false,
  708. "axisAlpha": 0,
  709. "reversed":true,
  710. "position": "right",
  711. },
  712. "rotate": true,
  713. "export": {
  714. "enabled": true,
  715. },
  716. "listeners": [{
  717. "event": "clickGraphItem",
  718. "method": function(event) {
  719. let typeofwork = event.item.category;
  720. let zonename = $("#region-select").val();
  721. fetchTypeOfWorkDetails(typeofwork, zonename);
  722. }
  723. }]
  724. });
  725. }
  726. function fetchTypeOfWorkDetails(typeofwork, zonename) {
  727. $.ajax({
  728. url: '/gcc/api/cmdashboard/getTypeOfWorkDetails',
  729. type: 'GET',
  730. data: { typeofwork: typeofwork, zonename: zonename },
  731. success: function(response) {
  732. displayTypeOfWorkDetails(response, typeofwork);
  733. },
  734. error: function(error) {
  735. console.error("Error fetching typeofwork details:", error);
  736. }
  737. });
  738. }
  739. function displayTypeOfWorkDetails(data, typeofwork) {
  740. let totalValueOfWork = formatValue(data.totalValueOfWork);
  741. let totalWorkCounts = data.totalWorkCounts; // get totalWorkCounts
  742. let schemeNameDetails = data.schemeNameDetails;
  743. let schemeNameContent = '';
  744. schemeNameDetails.forEach(item => {
  745. let formattedTotalValue = formatValue(item.totalValueOfWork);
  746. schemeNameContent += `<tr><td>${item.name}</td><td>${item.count}</td><td>${formattedTotalValue}</td></tr>`;
  747. });
  748. let modalContent = `
  749. <div class="modal-header">
  750. <h5 class="modal-title"><b>TypeOfWork: ${typeofwork}</b></h5>
  751. <button type="button" class="close" data-dismiss="modal" aria-label="Close">
  752. <span aria-hidden="true">&times;</span>
  753. </button>
  754. </div>
  755. <div class="modal-body">
  756. <table class="table table-striped table-bordered">
  757. <thead class="thead-dark">
  758. <tr>
  759. <th>Scheme Name</th>
  760. <th>Works</th>
  761. <th>Total Cost</th>
  762. </tr>
  763. </thead>
  764. <tbody>
  765. ${schemeNameContent}
  766. </tbody>
  767. </table>
  768. <div class="d-flex justify-content-between">
  769. <h6><b>Total Work Counts: </b>${totalWorkCounts}</h6>
  770. <h6><b>Total Value of Work: </b>${totalValueOfWork}</h6>
  771. </div>
  772. </div>
  773. `;
  774. document.getElementById('zone-details-content').innerHTML = modalContent;
  775. // Show the modal
  776. $('#zoneDetailsModal').modal('show');
  777. }
  778. </script>
  779. </body>
  780. </html>