diff --git a/src/services/chartFormatter.js b/src/services/chartFormatter.js index db5a84c..05a307e 100644 --- a/src/services/chartFormatter.js +++ b/src/services/chartFormatter.js @@ -230,14 +230,24 @@ class ChartFormatter { // Create labels (months) sorted chronologically const labels = Object.keys(monthData).sort(); + // Get topCount from parsedQuery - if null/undefined, show all areas + const topCount = parsedQuery?.topCount; + // Create datasets for each area const datasets = []; const areaColors = [ '#3B82F6', '#EF4444', '#10B981', '#F59E0B', '#8B5CF6', - '#EC4899', '#06B6D4', '#84CC16', '#F97316', '#6366F1' + '#EC4899', '#06B6D4', '#84CC16', '#F97316', '#6366F1', + '#F43F5E', '#8B5A2B', '#64748B', '#0EA5E9', '#A855F7', + '#14B8A6', '#EAB308', '#FBBF24', '#22C55E', '#06B6D4' ]; - Array.from(areas).slice(0, 10).forEach((area, index) => { // Limit to 10 areas for readability + // If topCount is specified, limit; otherwise show all areas + const areasToShow = topCount !== null && topCount !== undefined + ? Array.from(areas).slice(0, topCount) + : Array.from(areas); + + areasToShow.forEach((area, index) => { const areaData = labels.map(month => monthData[month][area] || null); datasets.push({ @@ -521,6 +531,7 @@ class ChartFormatter { const counts = data.map(row => { const count = row.transaction_count || + row.total_offplan_transactions || row.count || row.rental_count || row.commercial_count || diff --git a/src/services/contextAwareSQLGenerator.js b/src/services/contextAwareSQLGenerator.js index 214439a..7b73a4c 100644 --- a/src/services/contextAwareSQLGenerator.js +++ b/src/services/contextAwareSQLGenerator.js @@ -125,7 +125,7 @@ class ContextAwareSQLGenerator { limit: parsedQuery.refinements?.limit || 10, roomType: null, projectName: parsedQuery.projectName || null, - topCount: parsedQuery.topCount || 5 + topCount: parsedQuery.topCount !== undefined && parsedQuery.topCount !== null ? parsedQuery.topCount : null }; // Extract room type for BHK queries diff --git a/src/services/queryTemplates.js b/src/services/queryTemplates.js index 21c3fe4..8cd74ea 100644 --- a/src/services/queryTemplates.js +++ b/src/services/queryTemplates.js @@ -311,45 +311,60 @@ class QueryTemplates { }, // Q10: Avg price of 3BHK apartment by area (monthly grouping, top 5) - bhk_apartment_price: (params) => ({ - sql: ` - WITH monthly_avg AS ( - SELECT - DATE_FORMAT(start_date, '%Y-%m') AS month, - area_en, - AVG(annual_amount) AS avg_price, - COUNT(*) AS transaction_count, - AVG(actual_area) AS avg_area - FROM rents - WHERE rooms = ? - AND (prop_sub_type_en = 'flat' OR prop_sub_type_en = 'villa') - AND start_date >= ? - AND area_en IS NOT NULL - AND annual_amount IS NOT NULL - AND annual_amount > 0 + bhk_apartment_price: (params) => { + const topCount = params.topCount; + // If topCount is specified, use it; otherwise show all areas + const limitClause = topCount !== null && topCount !== undefined ? `LIMIT ${topCount}` : ''; + + return { + sql: ` + WITH monthly_avg AS ( + SELECT + DATE_FORMAT(start_date, '%Y-%m') AS month, + area_en, + AVG(annual_amount) AS avg_price, + COUNT(*) AS transaction_count, + AVG(actual_area) AS avg_area + FROM rents + WHERE rooms = ? + AND (prop_sub_type_en = 'flat' OR prop_sub_type_en = 'villa') + AND start_date >= ? + AND area_en IS NOT NULL + AND annual_amount IS NOT NULL + AND annual_amount > 0 GROUP BY month, area_en HAVING transaction_count >= 1 ), - ranked_areas AS ( + top_areas AS ( SELECT - month, area_en, - avg_price, - transaction_count, - ROW_NUMBER() OVER (PARTITION BY month ORDER BY avg_price DESC) AS rn + SUM(transaction_count) AS total_transactions, + AVG(avg_price) AS overall_avg_price FROM monthly_avg + GROUP BY area_en + ORDER BY total_transactions DESC, overall_avg_price DESC + ${limitClause} + ), + filtered_monthly AS ( + SELECT + ma.month, + ma.area_en, + ma.avg_price, + ma.transaction_count + FROM monthly_avg ma + INNER JOIN top_areas ta ON ma.area_en = ta.area_en ) SELECT month, area_en, ROUND(avg_price, 2) AS avg_price, transaction_count - FROM ranked_areas - WHERE rn <= 5 - ORDER BY month DESC, avg_price DESC + FROM filtered_monthly + ORDER BY month ASC, avg_price DESC `, params: [params.roomType, params.startDate] - }), + }; + }, // Filtered property queries (transactions with area + property type) filtered_transactions: (params) => ({