Skip to content

Commit

Permalink
Refactor column names and handle missing values in buy_dataframe.py
Browse files Browse the repository at this point in the history
Implement JS popup shit, fucking nightmare
  • Loading branch information
perfectly-preserved-pie committed Sep 3, 2024
1 parent 4664166 commit 30518a6
Show file tree
Hide file tree
Showing 2 changed files with 269 additions and 12 deletions.
276 changes: 265 additions & 11 deletions assets/javascript/popup.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,273 @@ window.dash_props = Object.assign({}, window.dash_props, {
module: {
on_each_feature: function(feature, layer, context) {
if (!feature.properties) {
return
return;
}
if (feature.properties.popup) {
layer.bindPopup(feature.properties.popup, {
// Here you can customize the popup
// https://leafletjs.com/reference.html#popup-option
//autoPan: false,
//closeButton: false,
// Set the maxHeight to 375px if the device is mobile, otherwise use the default value
maxHeight: window.innerWidth < 768 ? 375 : 650,
// Set the maxWidth to 175px if the device is mobile, otherwise use the default value
if (feature.properties.data) {
const data = feature.properties.data; // Get the dataframe rows from the GeoJSON feature properties
const context = feature.properties.context; // Get the type of page (lease or buy) from the GeoJSON feature properties
const selected_subtypes = data.subtype; // Get the selected subtype(s) from the GeoJSON feature properties

// Log the context object to debug
console.log('Context:', context);
console.log('Data:', data);

// Function to handle MLS number hyperlink
function getListingUrlBlock(data) {
if (!data.listing_url) {
return `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Listing ID (MLS#)</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">Not Available</td>
</tr>
`;
}
return `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Listing ID (MLS#)</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">
<a href='${data.listing_url}' referrerPolicy='noreferrer' target='_blank'>${data.mls_number}</a>
</td>
</tr>
`;
}

// Function to format date string
function formatDate(dateString) {
if (!dateString) return "Unknown";
const date = new Date(dateString);
return date.toISOString().split('T')[0];
}

// Conditionally format the listing URL as a hyperlink or plain text
const listingUrlBlock = getListingUrlBlock(data);

// Conditionally include the property image row if the image URL is available
const imageRow = data.image_url ? `
<a href="${data.listing_url}" target="_blank" referrerPolicy="noreferrer">
<img src="${data.image_url}" alt="Property Image" style="width:100%;height:auto;">
</a>
` : '';

// Conditionally format the phone number as a tel: link or plain text
const phoneNumberBlock = data.phone_number ? `
<a href="tel:${data.phone_number}">${data.phone_number}</a>
` : 'Unknown';

// Function to generate popup content for lease page
function generateLeasePopupContent(data) {
return `
<div>
${imageRow}
<div style="text-align: center;">
<h5>${data.address}</h5>
</div>
<table style="width:100%;border-collapse:collapse;">
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Listed Date</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${formatDate(data.listed_date)}</td>
</tr>
${listingUrlBlock}
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">List Office Phone</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${phoneNumberBlock}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Rental Price</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">$${data.list_price.toLocaleString()}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Security Deposit</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.security_deposit ? `$${data.security_deposit.toLocaleString()}` : "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Pet Deposit</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.pet_deposit ? `$${data.pet_deposit.toLocaleString()}` : "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Key Deposit</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.key_deposit ? `$${data.key_deposit.toLocaleString()}` : "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Other Deposit</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.other_deposit ? `$${data.other_deposit.toLocaleString()}` : "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Square Feet</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.sqft ? `${data.sqft.toLocaleString()}` : "Unknown"} sq. ft</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Price Per Square Foot</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.ppsqft ? `$${data.ppsqft.toLocaleString()}` : "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Bedrooms/Bathrooms</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.bedrooms}/${data.bathrooms}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Garage Spaces</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.garage_spaces || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Pets Allowed?</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.pet_policy || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Furnished?</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.furnished || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Laundry Features</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.laundry || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Senior Community</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.senior_community || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Year Built</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.year_built || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Rental Terms</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.terms || "Unknown"}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Physical Sub Type</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.subtype || "Unknown"}</td>
</tr>
</table>
</div>
`;
}

// Function to generate popup content for buy page
function generateBuyPopupContent(data, selected_subtypes) {
// Conditionally include the park name row if the property subtype is MH or has MH in the selected subtypes
let parkNameBlock = '';
if (selected_subtypes.includes('MH')) {
parkNameBlock = `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Park Name</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.park_name || "Unknown"}</td>
</tr>
`;
}

// Conditionally include the pet policy row if the property subtype is MH or has MH in the selected subtypes
let petsAllowedBlock = '';
if (selected_subtypes.includes('MH')) {
petsAllowedBlock = `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Pets Allowed?</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.pets_allowed || "Unknown"}</td>
</tr>
`;
}

// Condtionally include the Senior Community row if the property subtype is MH or has MH in the selected subtypes
let seniorCommunityBlock = '';
if (selected_subtypes.includes('MH')) {
seniorCommunityBlock = `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Senior Community</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.senior_community || "Unknown"}</td>
</tr>
`;
}

// Conditionally include the space rent row if the property subtype is MH or has MH in the selected subtypes
let spaceRentBlock = '';
if (selected_subtypes.includes('MH')) {
spaceRentBlock = `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Space Rent</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.space_rent ? `$${data.space_rent.toLocaleString()}` : "Unknown"}</td>
</tr>
`;
}

// Conditionally include the HOA Fee row if the property subtype is not MH or has MH in the selected subtypes
let hoaFeeBlock = '';
if (!selected_subtypes.includes('MH')) {
hoaFeeBlock = `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">HOA Fee</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.hoa_fee ? `$${data.hoa_fee.toLocaleString()}` : "Unknown"}</td>
</tr>
`;
}

// Conditionally include the HOA Fee Frequency row if the property subtype is not MH or has MH in the selected subtypes
let hoaFeeFrequencyBlock = '';
if (!selected_subtypes.includes('MH')) {
hoaFeeFrequencyBlock = `
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">HOA Fee Frequency</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.hoa_fee_frequency || "Unknown"}</td>
</tr>
`;
}

return `
<div>
${imageRow}
<div style="text-align: center;">
<h5>${data.address}</h5>
</div>
<table style="width:100%;border-collapse:collapse;">
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Listed Date</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${formatDate(data.listed_date)}</td>
</tr>
${listingUrlBlock}
${parkNameBlock}
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">List Price</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">$${data.list_price.toLocaleString()}</td>
</tr>
${hoaFeeBlock}
${hoaFeeFrequencyBlock}
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Square Feet</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.sqft ? `${data.sqft.toLocaleString()}` : "Unknown"} sq. ft</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Price Per Square Foot</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.ppsqft ? `$${data.ppsqft.toLocaleString()}` : "Unknown"}</td>
</tr>
${spaceRentBlock}
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Bedrooms/Bathrooms</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.bedrooms_bathrooms}</td>
</tr>
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Year Built</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.year_built || "Unknown"}</td>
</tr>
${petsAllowedBlock}
${seniorCommunityBlock}
<tr>
<th style="text-align:left;padding:8px;border-bottom:1px solid #ddd;">Physical Sub Type</th>
<td style="padding:8px;border-bottom:1px solid #ddd;">${data.subtype || "Unknown"}</td>
</tr>
</table>
</div>
`;
}

// Determine which popup content to generate based on context
let popupContent = '';
if (context.pageType === 'lease') {
popupContent = generateLeasePopupContent(data);
} else if (context.pageType === 'buy') {
popupContent = generateBuyPopupContent(data, selected_subtypes);
}

layer.bindPopup(popupContent, {
maxHeight: window.innerWidth < 768 ? 375 : 650,
maxWidth: window.innerWidth < 768 ? 175 : 300,
})
});
}
}
}
Expand Down
5 changes: 4 additions & 1 deletion buy_dataframe.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,9 @@
df['Half Bathrooms'] = (df['Br/Ba'].str.split('/', expand=True)[1]).str.split(',', expand=True)[2]
df['Three Quarter Bathrooms'] = (df['Br/Ba'].str.split('/', expand=True)[1]).str.split(',', expand=True)[3]

# Rename the Br/Ba column to bedrooms_bathrooms
df.rename(columns={'Br/Ba': 'bedrooms_bathrooms'}, inplace=True)

# Convert a few columns into int64
# pd.to_numeric will convert into int64 or float64 automatically, which is cool
# These columns are assumed to have NO MISSING DATA, so we can cast them as int64 instead of floats (ints can't handle NaNs)
Expand All @@ -205,7 +208,7 @@
# Convert date_processed into DateTime
df['date_processed'] = pd.to_datetime(df['date_processed'], errors='coerce', format='%Y-%m-%d')

cols = ['Full Bathrooms', 'Bedrooms', 'year_built', 'Sqft', 'list_price', 'Total Bathrooms', 'space_rent', 'ppsqft', 'hoa_fee']
cols = ['Full Bathrooms', 'Bedrooms', 'year_built', 'Sqft', 'list_price', 'Total Bathrooms', 'space_rent', 'ppsqft', 'hoa_fee', 'bedrooms_bathrooms']
# Convert columns to string type for string operations
df[cols] = df[cols].astype(str)
# Remove commas and other non-numeric characters
Expand Down

0 comments on commit 30518a6

Please sign in to comment.