Spaces:
Sleeping
Sleeping
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>कृषी बाजार विश्लेषण | Crop Market Analysis</title> | |
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css" rel="stylesheet"> | |
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script> | |
<style> | |
:root { | |
--primary-color: #4CAF50; | |
--secondary-color: #45a049; | |
--background-color: #f9f9f9; | |
--text-color: #333; | |
--card-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
--border-radius: 8px; | |
} | |
body { | |
background-color: var(--background-color); | |
color: var(--text-color); | |
font-family: 'Arial', sans-serif; | |
line-height: 1.6; | |
} | |
.container { | |
max-width: 1200px; | |
margin: 0 auto; | |
padding: 20px; | |
} | |
.header { | |
text-align: center; | |
margin-bottom: 30px; | |
padding: 20px 0; | |
} | |
.header h1 { | |
color: var(--primary-color); | |
font-weight: bold; | |
margin: 0; | |
font-size: 2.5rem; | |
} | |
.language-toggle { | |
position: fixed; | |
top: 20px; | |
right: 20px; | |
z-index: 1000; | |
} | |
.form-section { | |
background: white; | |
padding: 25px; | |
border-radius: var(--border-radius); | |
box-shadow: var(--card-shadow); | |
margin-bottom: 30px; | |
} | |
.chart-container { | |
background: white; | |
padding: 25px; | |
border-radius: var(--border-radius); | |
box-shadow: var(--card-shadow); | |
margin-bottom: 30px; | |
} | |
.insights-container { | |
background: white; | |
padding: 25px; | |
border-radius: var(--border-radius); | |
box-shadow: var(--card-shadow); | |
margin-bottom: 30px; | |
border-left: 5px solid var(--primary-color); | |
} | |
.insights-container h3 { | |
color: var(--primary-color); | |
margin-bottom: 20px; | |
} | |
.loading { | |
display: none; | |
text-align: center; | |
padding: 20px; | |
background: rgba(255, 255, 255, 0.9); | |
position: fixed; | |
top: 50%; | |
left: 50%; | |
transform: translate(-50%, -50%); | |
border-radius: var(--border-radius); | |
box-shadow: var(--card-shadow); | |
z-index: 1000; | |
} | |
.btn-custom { | |
background-color: var(--primary-color); | |
color: white; | |
border: none; | |
padding: 8px 16px; | |
border-radius: 4px; | |
transition: background-color 0.3s ease; | |
} | |
.btn-custom:hover { | |
background-color: var(--secondary-color); | |
color: white; | |
} | |
.form-control { | |
border-radius: 4px; | |
border: 1px solid #ddd; | |
padding: 8px 12px; | |
height: auto; | |
} | |
.form-control:focus { | |
border-color: var(--primary-color); | |
box-shadow: 0 0 0 0.2rem rgba(76, 175, 80, 0.25); | |
} | |
label { | |
font-weight: 500; | |
margin-bottom: 8px; | |
color: var(--text-color); | |
} | |
#barChart, #lineChart, #boxChart { | |
width: 100%; | |
margin-bottom: 20px; | |
} | |
#aiInsights { | |
line-height: 1.8; | |
font-size: 1.1rem; | |
} | |
.alert { | |
border-radius: var(--border-radius); | |
padding: 15px 20px; | |
margin-bottom: 20px; | |
} | |
.spinner-border { | |
width: 3rem; | |
height: 3rem; | |
color: var(--primary-color); | |
} | |
#marketData { | |
height: 100px; /* Set the height to a fixed value */ | |
overflow-y:scroll; /* Add vertical scrolling */ | |
} | |
.insights-container { | |
background: white; | |
padding: 25px; | |
border-radius: 8px; | |
box-shadow: 0 2px 4px rgba(0,0,0,0.1); | |
margin-bottom: 30px; | |
} | |
.insights-header { | |
background: #4CAF50; | |
color: white; | |
padding: 15px 20px; | |
border-radius: 8px 8px 0 0; | |
margin: -25px -25px 20px -25px; | |
} | |
.insights-header h3 { | |
margin: 0; | |
color: white; | |
} | |
.insight-section { | |
background: #f8f9fa; | |
border-radius: 8px; | |
padding: 20px; | |
margin-bottom: 20px; | |
border-left: 4px solid #4CAF50; | |
} | |
.insight-section h4 { | |
color: #2E7D32; | |
margin-bottom: 15px; | |
font-size: 1.2rem; | |
font-weight: bold; | |
} | |
.insight-card { | |
background: white; | |
border-radius: 6px; | |
padding: 15px; | |
margin-bottom: 15px; | |
box-shadow: 0 1px 3px rgba(0,0,0,0.1); | |
} | |
.insight-card h5 { | |
color: #1B5E20; | |
margin-bottom: 10px; | |
font-size: 1.1rem; | |
} | |
.insight-list { | |
list-style: none; | |
padding-left: 0; | |
margin-bottom: 0; | |
} | |
.insight-list li { | |
position: relative; | |
padding-left: 20px; | |
margin-bottom: 8px; | |
line-height: 1.5; | |
} | |
.insight-list li:before { | |
content: "•"; | |
color: #4CAF50; | |
font-size: 1.2em; | |
position: absolute; | |
left: 0; | |
top: -2px; | |
} | |
.price-highlight { | |
color: #2E7D32; | |
font-weight: bold; | |
} | |
.percentage-up { | |
color: #2E7D32; | |
font-weight: bold; | |
} | |
.percentage-down { | |
color: #c62828; | |
font-weight: bold; | |
} | |
.action-box { | |
background: #E8F5E9; | |
border-radius: 6px; | |
padding: 15px; | |
margin-top: 20px; | |
border: 1px dashed #4CAF50; | |
} | |
.action-box h5 { | |
color: #2E7D32; | |
margin-bottom: 10px; | |
font-size: 1.1rem; | |
} | |
.action-list { | |
list-style: none; | |
padding-left: 0; | |
margin-bottom: 0; | |
} | |
.action-list li { | |
position: relative; | |
padding-left: 25px; | |
margin-bottom: 8px; | |
line-height: 1.5; | |
} | |
.action-list li:before { | |
content: "✓"; | |
color: #4CAF50; | |
position: absolute; | |
left: 0; | |
font-weight: bold; | |
} | |
/* Responsive adjustments */ | |
@media (max-width: 768px) { | |
.insights-container { | |
padding: 15px; | |
} | |
.insights-header { | |
padding: 12px 15px; | |
margin: -15px -15px 15px -15px; | |
} | |
.insight-section { | |
padding: 15px; | |
} | |
} | |
@media (max-width: 768px) { | |
.container { | |
padding: 10px; | |
} | |
.header h1 { | |
font-size: 2rem; | |
} | |
.form-row { | |
flex-direction: column; | |
} | |
.form-group { | |
margin-bottom: 15px; | |
} | |
.language-toggle { | |
position: static; | |
text-align: center; | |
margin-bottom: 20px; | |
} | |
.btn-custom { | |
width: 100%; | |
} | |
.insights-container { | |
padding: 15px; | |
} | |
#aiInsights { | |
font-size: 1rem; | |
} | |
} | |
select { | |
max-height: 200px; /* Adjust height as needed */ | |
overflow-y: auto; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="language-toggle"> | |
<button class="btn btn-custom" onclick="toggleLanguage()" id="langToggle"> | |
भाषा बदला | Change Language | |
</button> | |
</div> | |
<div class="container"> | |
<div class="header"> | |
<h1 class="en">Crop Market Analysis</h1> | |
<h1 class="mr" style="display:none;">कृषी बाजार विश्लेषण</h1> | |
</div> | |
<div class="form-section"> | |
<form id="filterForm"> | |
<div class="form-row"> | |
<div class="form-group col-md-3"> | |
<label for="state" class="label-state">State</label> | |
<select class="form-control" id="state" name="state"> | |
<option value="">Select State</option> | |
{% for state in states %} | |
<option value="{{ state }}">{{ state }}</option> | |
{% endfor %} | |
</select> | |
</div> | |
<div class="form-group col-md-3"> | |
<label for="district" class="label-district">District</label> | |
<select class="form-control" id="district" name="district" disabled> | |
<option value="">Select District</option> | |
</select> | |
</div> | |
<div class="form-group col-md-3"> | |
<label for="market" class="label-market">Market</label> | |
<select class="form-control" id="market" name="market" disabled> | |
<option value="">Select Market</option> | |
</select> | |
</div> | |
<div class="form-group col-md-3"> | |
<label for="commodity" class="label-commodity">Commodity</label> | |
<select class="form-control" id="commodity" name="commodity" disabled> | |
<option value="">Select Commodity</option> | |
</select> | |
</div> | |
</div> | |
</form> | |
</div> | |
<div class="loading" id="loadingIndicator"> | |
<div class="spinner-border" role="status"> | |
<span class="sr-only">Loading...</span> | |
</div> | |
</div> | |
<div class="chart-container"> | |
<div id="barChart"></div> | |
<div id="lineChart"></div> | |
<div id="boxChart"></div> | |
</div> | |
<!-- Add this after the chart-container div --> | |
<div class="market-data-container"> | |
<div class="row"> | |
<div class="col-md-12 mb-4"> | |
<div class="card"> | |
<div class="card-header"> | |
<h4 class="en">Market Statistics</h4> | |
<h4 class="mr" style="display:none;">बाजार आकडेवारी</h4> | |
</div> | |
<div class="card-body"> | |
<div class="row"> | |
<div class="col-md-3"> | |
<div class="stat-item"> | |
<h6 class="en">Total Commodities</h6> | |
<h6 class="mr" style="display:none;">एकूण पिके</h6> | |
<span id="totalCommodities"></span> | |
</div> | |
</div> | |
<div class="col-md-3"> | |
<div class="stat-item"> | |
<h6 class="en">Average Price</h6> | |
<h6 class="mr" style="display:none;">सरासरी किंमत</h6> | |
<span id="avgPrice"></span> | |
</div> | |
</div> | |
<div class="col-md-3"> | |
<div class="stat-item"> | |
<h6 class="en">Price Range</h6> | |
<h6 class="mr" style="display:none;">किंमत श्रेणी</h6> | |
<span id="priceRange"></span> | |
</div> | |
</div> | |
<div class="col-md-3"> | |
<div class="stat-item"> | |
<h6 class="en">Total Markets</h6> | |
<h6 class="mr" style="display:none;">एकूण बाजार</h6> | |
<span id="totalMarkets"></span> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="row"> | |
<div class="col-md-6 mb-4"> | |
<div class="card"> | |
<div class="card-header"> | |
<h4 class="en">Top 5 Cheapest Crops</h4> | |
<h4 class="mr" style="display:none;">सर्वात स्वस्त 5 पिके</h4> | |
</div> | |
<div class="card-body" id="cheapestCrops"> | |
</div> | |
</div> | |
</div> | |
<div class="col-md-6 mb-4"> | |
<div class="card"> | |
<div class="card-header"> | |
<h4 class="en">Top 5 Costliest Crops</h4> | |
<h4 class="mr" style="display:none;">सर्वात महाग 5 पिके</h4> | |
</div> | |
<div class="card-body" id="costliestCrops"> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="card mb-4"> | |
<div class="card-header"> | |
<h4 class="en">Market Data</h4> | |
<h4 class="mr" style="display:none;">बाजार माहिती</h4> | |
</div> | |
<div class="card-body" id="marketData"> | |
</div> | |
</div> | |
</div> | |
<div class="insights-container"> | |
<div id="aiInsights"></div> | |
</div> | |
</div> | |
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script> | |
<script> | |
let currentLang = 'en'; | |
function updateLabels(translations) { | |
if (currentLang === 'mr') { | |
Object.keys(translations).forEach(key => { | |
$(`.label-${key}`).text(translations[key]); | |
}); | |
$('.en').hide(); | |
$('.mr').show(); | |
} else { | |
$('.label-state').text('State'); | |
$('.label-district').text('District'); | |
$('.label-market').text('Market'); | |
$('.label-commodity').text('Commodity'); | |
$('.en').show(); | |
$('.mr').hide(); | |
} | |
} | |
function toggleLanguage() { | |
currentLang = currentLang === 'en' ? 'mr' : 'en'; | |
$('#langToggle').text(currentLang === 'en' ? 'भाषा बदला | Change Language' : 'भाषा बदला | Change Language'); | |
updateContent(); | |
} | |
function showLoading() { | |
$('#loadingIndicator').show(); | |
} | |
function hideLoading() { | |
$('#loadingIndicator').hide(); | |
} | |
function enableSelect(selectId) { | |
$(`#${selectId}`).prop('disabled', false); | |
} | |
function disableSelect(selectId) { | |
$(`#${selectId}`).prop('disabled', true); | |
} | |
function updateContent() { | |
showLoading(); | |
const formData = new FormData($('#filterForm')[0]); | |
formData.append('language', currentLang); | |
$.ajax({ | |
url: '/filter_data', | |
method: 'POST', | |
data: formData, | |
processData: false, | |
contentType: false, | |
success: function(response) { | |
if (response.success) { | |
// Update plots | |
if (response.plots.bar) $('#barChart').html(response.plots.bar); | |
if (response.plots.line) $('#lineChart').html(response.plots.line); | |
if (response.plots.box) $('#boxChart').html(response.plots.box); | |
// Update market statistics | |
$('#totalCommodities').text(response.market_stats.total_commodities); | |
$('#avgPrice').text(response.market_stats.avg_modal_price); | |
$('#priceRange').text(response.market_stats.price_range); | |
$('#totalMarkets').text(response.market_stats.total_markets); | |
// Update tables | |
$('#marketData').html(response.market_html); | |
$('#cheapestCrops').html(response.cheapest_html); | |
$('#costliestCrops').html(response.costliest_html); | |
// Only show insights section if state and district are selected | |
if (response.hasStateDistrict) { | |
$('.insights-container').show(); | |
$('#aiInsights').html(response.insights); | |
} else { | |
$('.insights-container').hide(); | |
$('#aiInsights').html(''); | |
} | |
// Update translations | |
updateLabels(response.translations); | |
console.log(response.translations); | |
} else { | |
const message = currentLang === 'en' ? | |
'Please select both state and district to view analysis' : | |
'कृपया विश्लेषण पाहण्यासाठी राज्य आणि जिल्हा निवडा'; | |
alert(message); | |
} | |
hideLoading(); | |
}, | |
error: function() { | |
alert(currentLang === 'en' ? 'Error loading data' : 'माहिती लोड करताना त्रुटी'); | |
hideLoading(); | |
} | |
}); | |
} | |
// Cascade dropdowns | |
$('#state').change(function() { | |
const state = $(this).val(); | |
// Reset and disable dependent dropdowns | |
$('#district, #market, #commodity').html('<option value="">Select</option>').prop('disabled', true); | |
if (state) { | |
showLoading(); | |
$.post('/get_districts', { state: state }, function(districts) { | |
$('#district').html('<option value="">Select District</option>'); | |
districts.forEach(district => { | |
$('#district').append(`<option value="${district}">${district}</option>`); | |
}); | |
enableSelect('district'); | |
hideLoading(); | |
}); | |
} | |
updateContent(); | |
}); | |
$('#district').change(function() { | |
const district = $(this).val(); | |
// Reset and disable dependent dropdowns | |
$('#market, #commodity').html('<option value="">Select</option>').prop('disabled', true); | |
if (district) { | |
showLoading(); | |
$.post('/get_markets', { district: district }, function(markets) { | |
$('#market').html('<option value="">Select Market</option>'); | |
markets.forEach(market => { | |
$('#market').append(`<option value="${market}">${market}</option>`); | |
}); | |
enableSelect('market'); | |
hideLoading(); | |
}); | |
} | |
updateContent(); | |
}); | |
$('#market').change(function() { | |
const market = $(this).val(); | |
// Reset commodity dropdown | |
$('#commodity').html('<option value="">Select</option>').prop('disabled', true); | |
if (market) { | |
showLoading(); | |
$.post('/get_commodities', { market: market }, function(commodities) { | |
$('#commodity').html('<option value="">Select Commodity</option>'); | |
commodities.forEach(commodity => { | |
$('#commodity').append(`<option value="${commodity}">${commodity}</option>`); | |
}); | |
enableSelect('commodity'); | |
hideLoading(); | |
}); | |
} | |
updateContent(); | |
}); | |
$('#commodity').change(function() { | |
updateContent(); | |
}); | |
// Initial setup | |
$(document).ready(function() { | |
$('.insights-container').hide(); | |
updateContent(); | |
}); | |
</script> | |
</body> | |
</html> |