|
|
<html xmlns:th="http://www.thymeleaf.org"><head th:replace="~{fragments/modules/base/head :: head}"></head>
<style>.chart-container { width: 100%; height: 350px; font-size: 12px;}
@media ( max-width : 768px) { .chart-container { height: 200px; /* Adjust height for mobile view */ }}
.highlight-red { color: red;}
.scheme-count, .typeofwork-count { cursor: pointer; color:blue; }
.scheme-count:hover, .typeofwork-count:hover { background-color: darkgrey; /* Change this color to your preference */ }
</style><body> <link rel="stylesheet" href="/assets/node_modules/amcharts3/amcharts/plugins/export/export.css" type="text/css" media="all" /> <!--[if lt IE 8]>
<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> <![endif]-->
<div class="wrapper"> <!-- header top menu Start --> <header th:replace="~{fragments/modules/base/header :: header}"></header> <!-- header top menu end -->
<div class="page-wrap"> <!--=============== Left Menu side Start ================--> <div th:replace="~{fragments/modules/base/menu :: menu}"></div> <!--=============== Left side End ================--> <div class="main-content"> <div class="container-fluid"> <div class="page-header mb-2"> <div class="row align-items-end"> <div class="col-lg-8"> <div class="page-header-title"> <i class="ik ik-bar-chart-2 bg-blue"></i> <div class="d-inline"> <h5>Works</h5> <span>CM Works Dashboard</span> </div> </div> </div> <div class="col-lg-4"> <nav class="breadcrumb-container" aria-label="breadcrumb"> <ol class="breadcrumb"> <li class="breadcrumb-item"><a href="/index"><i class="ik ik-home"></i></a></li> <li class="breadcrumb-item">CM Dashboard</li> <li class="breadcrumb-item active" aria-current="page">Dashboard2</li> </ol> </nav> </div> </div> </div> <div class="row"> <div class="col-md-12"> <div class="card sale-card"> <div class="card-header"> <h3> <i class="fas fa-chart-pie pr-2"></i><b>Works Analysis:</b> </h3> <br> <br> </div>
<div class="card-block" style="text-align: center;"> <div id="chart" class="row">
<div class="col-sm-12 col-xl-6"> <h6> <b>Over all Region wise works count</b> </h6> <div id="region-chartdiv" class="chart-shadow" style="height: 500px; width: 100%;"></div> </div> <hr>
<div class="col-sm-12 col-xl-6"> <h6> <b>Overall Zonewise works count</b> </h6> <div id="zone-chartdiv" class="chart-shadow" style="height: 500px; width: 100%;"></div> </div> <hr> <div class="col-sm-12 d-flex justify-content-center align-items-center mt-20 mb-20"> <label for="region-select" class="pr-2"><b>Select Zone:</b></label> <select id="region-select" onchange="updateSchemeAndTypeOfWorkCharts()" class="form-select custom-select" style="width: 30%"> <option value="all">--All--</option> <option value="B-Buildings">B-Buildings</option> <option value="BR-Bus Route Roads">BR-Bus Route Roads</option> <option value="D-Storm Water Drains">D-Storm Water Drains</option> <option value="J-Bridges">J-Bridges</option> <option value="L-Electrical">L-Electrical</option> <option value="P-Parks and Playfields">P-Parks and Playfields</option> <option value="Q-Solid Waste Management">Q-Solid Waste Management</option> <option value="SP-SPECIAL PROJECTS">SP-SPECIAL PROJECTS</option> <option value="01 - NA-THIRUVOTTIYUR">01 - NA-THIRUVOTTIYUR</option> <option value="02 - NB-MANALI">02 - NB-MANALI</option> <option value="03 - NC-MADHAVARAM">03 - NC-MADHAVARAM</option> <option value="04 - ND-TONDIARPET">04 - ND-TONDIARPET</option> <option value="05 - NE-ROYAPURAM">05 - NE-ROYAPURAM</option> <option value="06 - NF-THIRU-VI-KA NAGAR">06 - NF-THIRU-VI-KA NAGAR</option> <option value="07 - NG-AMBATTUR">07 - NG-AMBATTUR</option> <option value="08 - NH-ANNA NAGAR">08 - NH-ANNA NAGAR</option> <option value="09 - NJ-TEYNAMPET">09 - NJ-TEYNAMPET</option> <option value="10 - NK-KODAMBAKKAM">10 - NK-KODAMBAKKAM</option> <option value="11 - NL-VALASARAVAKKAM">11 - NL-VALASARAVAKKAM</option> <option value="12 - NM-ALANDUR">12 - NM-ALANDUR</option> <option value="13 - NN-ADYAR">13 - NN-ADYAR</option> <option value="14 - NP-PERUNGUDI">14 - NP-PERUNGUDI</option> <option value="15 - NQ-SHOZHINGANALLUR">15 - NQ-SHOZHINGANALLUR</option> </select> </div>
<div class="col-sm-12 col-xl-6"> <h6 id="scheme-title"> <b><span id="scheme-region" class="highlight-red"></span> Scheme Names</b> </h6> <div id="scheme-chartdiv" class="chart-shadow" style="height: 400px; width: 100%;"></div> </div>
<hr> <div class="col-sm-12 col-xl-6"> <h6 id="workcategory-title"> <b><span id="typeofwork-region" class="highlight-red"></span> Type of Works</b> </h6> <div id="typeOfWork-chartdiv" class="chart-shadow" style="height: 400px; width: 100%;"></div> </div>
<hr>
</div>
</div>
</div> </div>
</div> </div> </div>
<footer th:replace="~{fragments/modules/base/footer :: footer}"></footer> </div> </div>
<!-- Modal --> <div class="modal fade" id="zoneDetailsModal" tabindex="-1" role="dialog" aria-labelledby="zoneDetailsModalLabel" aria-hidden="true" data-backdrop="static" data-keyboard="false"> <div class="modal-dialog modal-lg" role="document"> <div class="modal-content"> <div id="zone-details-content"></div> </div> </div> </div>
<div th:replace="~{fragments/modules/base/app_module_menu_box :: div}"></div>
<script th:replace="~{fragments/modules/base/script :: script}"></script> <script th:replace="~{fragments/modules/pgr/script :: script}"></script>
<script src="/assets/node_modules/amcharts3/amcharts/amcharts.js"></script> <script src="/assets/node_modules/amcharts3/amcharts/serial.js"></script> <script src="/assets/node_modules/amcharts3/amcharts/plugins/export/export.min.js"></script> <script src="/assets/node_modules/amcharts3/amcharts/pie.js"></script> <script src="/assets/node_modules/amcharts3/amcharts/themes/light.js"></script>
<script src="/assets/node_modules/amcharts3/amcharts/plugins/responsive/responsive.js"></script> <script src="/assets/node_modules/tempusdominus-bootstrap-4/build/js/tempusdominus-bootstrap-4.min.js"></script>
<script> // Function to update the chart titles based on the selected region function updateChartTitles() { const regionSelect = document.getElementById("region-select"); const selectedRegion = regionSelect.options[regionSelect.selectedIndex].text;
const schemeRegion = document.getElementById("scheme-region"); const typeofworkRegion = document.getElementById("typeofwork-region");
schemeRegion.innerHTML = selectedRegion; typeofworkRegion.innerHTML = selectedRegion; }
updateSchemeAndTypeOfWorkCharts();
// Function to update scheme and type of work charts based on zone selection function updateSchemeAndTypeOfWorkCharts() { const zoneName = $("#region-select").val(); console.log("Updating charts for zone in updateSchemeAndTypeOfWorkCharts:", zoneName); // Log the zone name
updateChartTitles(); $.ajax({ url: '/gcc/api/cmdashboard/getCmDashboardReports', type: 'GET', data: { zonename: zoneName }, success: function(response) { console.log('Data from API in updateSchemeAndTypeOfWorkCharts:', response); const { schemeData, typeOfWorkData } = processCombinedData(response); createSchemeChart('scheme-chartdiv', schemeData); createTypeofworkChart('typeOfWork-chartdiv', typeOfWorkData); }, error: function(error) { console.error("Error fetching data in updateSchemeAndTypeOfWorkCharts:", error); console.error("Error details:", error.responseText); } }); }
// Function to fetch region counts on page load function fetchRegionCounts() { $.ajax({ url: '/gcc/api/cmdashboard/getRegionCounts', type: 'GET', success: function(response) { console.log('Region Counts:', response);
const regionData = processRegionData(response); createRegionChart('region-chartdiv', regionData); }, error: function(error) { console.error("Error fetching region counts:", error); } }); }
// Function to fetch zone counts on page load function fetchZoneCounts() { const zoneName = $("#region-select").val(); console.log("Selected zone from fetchZoneCounts:", zoneName); // Log the selected zone $.ajax({ url: '/gcc/api/cmdashboard/getZoneCounts', type: 'GET', data: { zonename: zoneName }, success: function(response) { console.log('Zone Counts:', response);
const zoneData = processZoneData(response); createZoneChart('zone-chartdiv', zoneData); }, error: function(error) { console.error("Error fetching zone counts:", error); } }); }
// Function to initialize charts on page load function initializeCharts() { fetchRegionCounts(); fetchZoneCounts(); updateSchemeAndTypeOfWorkCharts("all"); // Initialize with "all" parameter // Removed redundant call to updateSchemeAndTypeOfWorkCharts }
$(document).ready(function () { initializeCharts(); });
//region work countsfunction processRegionData(data) { let regionData = []; // This gives the count of regions data.forEach(item => { if (item.regionname && item.region_count) { regionData.push({ title: item.regionname, value: item.region_count }); } }); return regionData;}
//zone work countsfunction processZoneData(data) { let zoneData = []; data.forEach(item => { if (item.zonename && item.zone_count) { zoneData.push({ category: item.zonename, count: item.zone_count }); } }); zoneData.sort((a, b) => b.count - a.count); return zoneData;}
//scheme and typeofwork work countsfunction processCombinedData(data) { let schemeData = []; let typeOfWorkData = [];
data.forEach(item => { if (item.type === 'Scheme') { schemeData.push({ category: item.name, count: item.count }); } else if (item.type === 'TypeOfWork') { typeOfWorkData.push({ category: item.name, count: item.count }); } }); schemeData.sort((a, b) => b.count - a.count); typeOfWorkData.sort((a, b) => b.count - a.count); return { schemeData, typeOfWorkData };}
//function of random color for chartfunction getRandomDarkColor() { const letters = '0123456789ABCDEF'; let color = '#'; for (let i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color;}
//REGION CHART//creating region chartfunction createRegionChart(chartId, chartData) { chartData.forEach(data => { data.color = getRandomDarkColor(); }); AmCharts.makeChart(chartId, { "type": "pie", "theme": "dark", "dataProvider": chartData, "valueField": "value", "titleField": "title", "colorField": "color", "startEffect":"easeInSine", "innerRadius": "50%", "labelText": "[[[[value]]]]", "labelsEnabled": true, "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], "balloonText": "[[[[title]]]]<br><span style='font-size:14px'><b>[[[[value]]]]</b> ([[[[percents]]]]%)</span>", "export": { "enabled": true, }, "responsive": { "enabled": true, }, "pullOutRadius":0, "legend": { "position": "bottom", "markerType": "diamond", "valueAlign": "left", "align": "center", "reversedOrder": true, "labelText": "[[[[title]]]] - ", "enabled": true }, "listeners": [{ "event": "clickSlice", "method": function(event) { let regionname = event.dataItem.dataContext.title; fetchRegionZoneDetails(regionname); } }] });}
//fetching region detailsfunction fetchRegionZoneDetails(regionname) { $.ajax({ url: '/gcc/api/cmdashboard/getRegionzones', type: 'GET', data: { regionname: regionname }, success: function(response) { displayRegionZoneDetails(response, regionname); }, error: function(error) { console.error("Error fetching region details:", error); } });}// display region detailsfunction displayRegionZoneDetails(data, regionname) { let totalValueOfWork = formatValue(data.totalValueOfWork); let totalWorkCounts = data.totalWorkCounts; let regionzonedetails=data.regionzonedetails;
let regionZonesContent = ''; regionzonedetails.forEach(item => { let formattedTotalValue = formatValue(item.totalValueOfWork); regionZonesContent += `<tr><td>${item.name}</td><td>${item.regionszones_count}</td><td>${formattedTotalValue}</td></tr>`; });
let modalContent = ` <div class="modal-header"> <h5 class="modal-title"><b>Region: ${regionname}</b></h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th>Zone Name</th> <th>Works</th> <th>Total Value of Work</th> </tr> </thead> <tbody> ${regionZonesContent} </tbody> </table> <div class="d-flex justify-content-between"> <h6><b>Total Work Counts: </b>${totalWorkCounts}</h6> <h6><b>Total Value of Work: </b>${totalValueOfWork}</h6> </div> </div> `;
document.getElementById('zone-details-content').innerHTML = modalContent;
// Show the modal $('#zoneDetailsModal').modal('show');}
//ZONE CHART//creating zone chartfunction createZoneChart(chartId, chartData) { chartData.forEach(data => { data.color = getRandomDarkColor(); }); AmCharts.makeChart(chartId, { "type": "serial", "theme": "light", "valueField": "value", "titleField": "title", "colorField": "color", "dataProvider": chartData, "depth3D": 2, "angle": 10, "valueAxes": [{ "gridColor": "#808080", "axisAlpha": 0, "gridAlpha": 0, "labelsEnabled": false, "dashLength": 0 }], "startDuration": 1, "startEffect":"easeInSine", "graphs": [{ "balloonText": "[[[[category]]]]<br><span style='font-size:14px'><b>[[[[count]]]]</b></span>", "fillAlphas": 0.8, "lineAlpha": 0.2, "topRadius": 1, "type": "column", "valueField": "count", "fillColorsField": "color", "labelText": "[[[[value]]]]", "labelColorField": "#ffffff", "lineThickness": 1, }], "chartCursor": { "valueLineEnabled": false, "valueLineBalloonEnabled": false, "cursorAlpha": 0, "valueLineAlpha": 0.2, "pan": false }, "categoryField": "category", "categoryAxis": { "gridPosition": "start", "gridAlpha": 0, "autoWrap": false, "axisAlpha": 0, }, "rotate": true, "export": { "enabled": true, "position": "bottom-right" }, "listeners": [{ "event": "clickGraphItem", "method": function(event) { let zoneName = event.item.category; fetchZoneDetails(zoneName); } }] });}
function fetchZoneDetails(zoneName) { $.ajax({ url: '/gcc/api/cmdashboard/getCmDashboardReports', type: 'GET', data: { zonename: zoneName }, success: function(response) { displayZoneDetails(response, zoneName); }, error: function(error) { console.error("Error fetching zone details:", error); } });}function displayZoneDetails(data, zoneName) { let schemeDetails = ''; let workCategoryDetails = ''; let typeOfWorkDetails = '';
data.forEach(item => { if (item.type === 'Scheme') { schemeDetails += `<tr><td>${item.name}</td><td class="scheme-count" data-schemename="${item.name}" data-zonename="${zoneName}">${item.count}</td></tr>`; } else if (item.type === 'TypeOfWork') { typeOfWorkDetails += `<tr><td>${item.name}</td><td class="typeofwork-count" data-typeofwork="${item.name}" data-zonename="${zoneName}">${item.count}</td></tr>`; } });
let modalContent = ` <div class="modal-header"> <h5 class="modal-title"><b>Zone: ${zoneName}</b></h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <div class="row"> <div class="col-sm-12 col-md-12 col-lg-6"> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th>Scheme Names</th> <th>Works</th> </tr> </thead> <tbody> ${schemeDetails} </tbody> </table> </div> <div class="col-sm-12 col-md-12 col-lg-6"> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th>Type of Works</th> <th>Works</th> </tr> </thead> <tbody> ${typeOfWorkDetails} </tbody> </table> </div> </div> </div>`;
document.getElementById('zone-details-content').innerHTML = modalContent;
// Show the modal $('#zoneDetailsModal').modal('show'); // Add click event listeners addModalEventListeners();}
function addModalEventListeners() { // Capture click event on scheme counts $(".scheme-count").click(function () { var schemename = $(this).data("schemename"); var zonename = $(this).data("zonename"); window.location.href = "/gcc/dashboards/all-list?zonename=" + zonename + "&schemename=" + schemename; });
// Capture click event on typeofwork counts $(".typeofwork-count").click(function () { var typeofwork = $(this).data("typeofwork"); var zonename = $(this).data("zonename"); window.location.href = "/gcc/dashboards/all-list?zonename=" + zonename + "&typeofwork=" + typeofwork; });}
function createSchemeChart(chartId, chartData) { chartData.forEach(data => { data.color = getRandomDarkColor(); }); AmCharts.makeChart(chartId, { "type": "serial", "theme": "light", "valueField": "value", "titleField": "title", "colorField": "color", "dataProvider": chartData, "depth3D": 3, "angle": 10, "valueAxes": [{ "gridColor": "#808080", "axisAlpha": 0, "gridAlpha": 0, "labelsEnabled": false, "dashLength": 0 }], "startDuration": 1, "startEffect":"easeInSine", "graphs": [{ "balloonText": "[[[[category]]]]<br><span style='font-size:14px'><b>[[[[count]]]]</b></span>", "fillAlphas": 0.8, "lineAlpha": 0.2, "topRadius": 1, "type": "column", "valueField": "count", "fillColorsField": "color", "labelText": "[[[[value]]]]", "labelColorField": "#ffffff", "lineThickness": 1, }], "chartCursor": { "valueLineEnabled": false, "valueLineBalloonEnabled": false, "cursorAlpha": 0, "valueLineAlpha": 0.2, "pan": false }, "categoryField": "category", "categoryAxis": { "gridPosition": "start", "gridAlpha": 0, "autoWrap": false, "axisAlpha": 0, }, "rotate": true, "export": { "enabled": true, }, "listeners": [{ "event": "clickGraphItem", "method": function(event) { let schemename = event.item.category; let zonename = $("#region-select").val(); fetchSchemeDetails(schemename, zonename); } }] });}//Function for Formatting the valueofworkfunction formatValue(value) { value = Number(value); // Ensure the value is a number
if (value >= 1e9) { return (value / 1e9).toFixed(2) + ' Billion'; } else if (value >= 1e6) { return (value / 1e6).toFixed(2) + ' Million'; } else if (value >= 1e5) { return (value / 1e5).toFixed(2) + ' Lakh'; } else if (value >= 1e4) { return (value / 1e4).toFixed(2) + ' Thousand'; } return value.toFixed(2);}function fetchSchemeDetails(schemename, zonename) { $.ajax({ url: '/gcc/api/cmdashboard/getSchemeDetails', type: 'GET', data: { schemename: schemename, zonename: zonename }, success: function(response) { displaySchemeDetails(response, schemename); }, error: function(error) { console.error("Error fetching scheme details:", error); } });}
function displaySchemeDetails(data, schemename) { let totalValueOfWork = formatValue(data.totalValueOfWork); let totalWorkCounts = data.totalWorkCounts; // get totalWorkCounts let typeOfWorkDetails = data.typeOfWorkDetails;
let typeOfWorkContent = ''; typeOfWorkDetails.forEach(item => { let formattedTotalValue = formatValue(item.totalValueOfWork); typeOfWorkContent += `<tr><td>${item.name}</td><td>${item.count}</td><td>${formattedTotalValue}</td></tr>`; });
let modalContent = ` <div class="modal-header"> <h5 class="modal-title"><b>Scheme: ${schemename}</b></h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th>Type of Work</th> <th>Works</th> <th>Cost</th> </tr> </thead> <tbody> ${typeOfWorkContent} </tbody> </table> <div class="d-flex justify-content-between"> <h6><b>Total Work Counts: </b>${totalWorkCounts}</h6> <h6><b>Total Value of Work: </b>${totalValueOfWork}</h6> </div> </div> `;
document.getElementById('zone-details-content').innerHTML = modalContent;
// Show the modal $('#zoneDetailsModal').modal('show');}
function createTypeofworkChart(chartId, chartData) { chartData.forEach(data => { data.color = getRandomDarkColor(); }); AmCharts.makeChart(chartId, { "type": "serial", "theme": "light", "valueField": "value", "titleField": "title", "colorField": "color", "dataProvider": chartData, "depth3D": 3, "angle": 10, "valueAxes": [{ "gridColor": "#808080", "axisAlpha": 0, "gridAlpha": 0, "labelsEnabled": false, "dashLength": 0, "position": "top", "reversed":true }], "startDuration": 1, "startEffect":"easeInSine", "graphs": [{ "balloonText": "[[[[category]]]]<br><span style='font-size:14px'><b>[[[[count]]]]</b></span>", "fillAlphas": 0.8, "lineAlpha": 0.2, "topRadius": 1, "type": "column", "valueField": "count", "fillColorsField": "color", "labelText": "[[[[value]]]]", "labelColorField": "#ffffff", "lineThickness": 1, }], "chartCursor": { "valueLineEnabled": false, "valueLineBalloonEnabled": false, "cursorAlpha": 0, "valueLineAlpha": 0.2, "pan": false }, "categoryField": "category", "categoryAxis": { "gridPosition": "start", "gridAlpha": 0, "autoWrap": false, "axisAlpha": 0, "reversed":true, "position": "right", }, "rotate": true, "export": { "enabled": true, }, "listeners": [{ "event": "clickGraphItem", "method": function(event) { let typeofwork = event.item.category; let zonename = $("#region-select").val(); fetchTypeOfWorkDetails(typeofwork, zonename); } }] });}function fetchTypeOfWorkDetails(typeofwork, zonename) { $.ajax({ url: '/gcc/api/cmdashboard/getTypeOfWorkDetails', type: 'GET', data: { typeofwork: typeofwork, zonename: zonename }, success: function(response) { displayTypeOfWorkDetails(response, typeofwork); }, error: function(error) { console.error("Error fetching typeofwork details:", error); } });}function displayTypeOfWorkDetails(data, typeofwork) { let totalValueOfWork = formatValue(data.totalValueOfWork); let totalWorkCounts = data.totalWorkCounts; // get totalWorkCounts let schemeNameDetails = data.schemeNameDetails;
let schemeNameContent = ''; schemeNameDetails.forEach(item => { let formattedTotalValue = formatValue(item.totalValueOfWork); schemeNameContent += `<tr><td>${item.name}</td><td>${item.count}</td><td>${formattedTotalValue}</td></tr>`; });
let modalContent = ` <div class="modal-header"> <h5 class="modal-title"><b>TypeOfWork: ${typeofwork}</b></h5> <button type="button" class="close" data-dismiss="modal" aria-label="Close"> <span aria-hidden="true">×</span> </button> </div> <div class="modal-body"> <table class="table table-striped table-bordered"> <thead class="thead-dark"> <tr> <th>Scheme Name</th> <th>Works</th> <th>Total Cost</th> </tr> </thead> <tbody> ${schemeNameContent} </tbody> </table> <div class="d-flex justify-content-between"> <h6><b>Total Work Counts: </b>${totalWorkCounts}</h6> <h6><b>Total Value of Work: </b>${totalValueOfWork}</h6> </div> </div> `;
document.getElementById('zone-details-content').innerHTML = modalContent;
// Show the modal $('#zoneDetailsModal').modal('show');}
</script>
</body></html>
|