Public
Edited
Apr 27, 2023
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
rawRentIndexData = FileAttachment("Zip_zori_sm_month-2.csv").csv()
Insert cell
getPriceAverage = (rawDataset, newColumnName) => {
let res = rawDataset.map((d) => ({ ...d }));
// Determine which of the columns are date columns
const dateColumnNames = [];
for (const key of Object.keys(res[0])) {
// set "false" the strict mode flag to accept 1-digit months
if (moment(key, "MM/DD/YYYY", false).isValid()) {
dateColumnNames.push(key);
}
}
// console.log(dateColumnNames);

res.map((e) => {
let sumRent = 0;
let count = 0;
for (const date of dateColumnNames) {
console.log(date);
if (!isNaN(Number(e[date])) && Number(e[date] !== "")) {
count += 1;
sumRent += Number(e[date]);
}
delete e[date];
}
console.log("sum", sumRent);
let average = sumRent / count;
return (e[newColumnName] = average);
});

return res;
}
Insert cell
averageRentIndexData = getPriceAverage(rawRentIndexData, "averageRent")
Insert cell
bartstationaccessibility = FileAttachment("BartStationAccessibility.json").json()
Insert cell
bayAreaGeoJSON = FileAttachment("BayAreaZIPCodes_simplified.json").json()
Insert cell
// Merge geo-data to the main object
{
bayAreaGeoJSON.features.forEach((e) => {
const curZip = e.properties.zip;

// Merge BART accessibility
e.properties.bartRoutes = 0;
for (const bartInfo of bartstationaccessibility) {
if (bartInfo.zipCode === curZip) {
e.properties.bartRoutes = bartInfo.routesCount;
break;
}
}

// Merge rents
e.properties.rent = 0;
for (const rentInfo of averageRentIndexData) {
if (rentInfo.RegionName === curZip) {
e.properties.rent = rentInfo.averageRent;
break;
}
}

return e;
});
return bayAreaGeoJSON;
}
Insert cell
Insert cell
Insert cell
ChoroplethMap(bayAreaGeoJSON, {
// if no value is passsed, it will look for the first quant property, area in this case
// if no id is passed, it will assume that the features contain the properties
height: 600,
width: width,
interpolator: d3.interpolateReds,
strokeWidth: 0.1,
tooltip: (d) => d.properties["zip"],
value: (d) => {
return d.properties["bartRoutes"];
}
})
Insert cell
Insert cell
ChoroplethMap(bayAreaGeoJSON, {
// if no value is passsed, it will look for the first quant property, area in this case
// if no id is passed, it will assume that the features contain the properties
height: 600,
width: width,
strokeWidth: 0.1,
value: (d) => {
return d.properties["rent"];
}
})
Insert cell
Insert cell
ChoroplethMap(bayAreaGeoJSON, {
// if no value is passsed, it will look for the first quant property, area in this case
// if no id is passed, it will assume that the features contain the properties
height: 600,
width: width,
interpolator: d3.interpolatePurples,
strokeWidth: 0.1,
tooltip: (d) => d.properties["zip"],
value: (d) => {
if (d.properties["bartRoutes"] > 0) return d.properties["rent"];
else return 0;
},
title: "(f, d) => "
})
Insert cell
Insert cell
Insert cell
import { ChoroplethMap } from "bcf45090b3ba1513"
Insert cell
bayareazipcodes_simplified = FileAttachment("BayAreaZIPCodes_simplified.json").json()
Insert cell
moment = require("moment")
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more