Toronto Shelter System — year-to-date cumulative trends
Year-to-date (YTD) comparison of Toronto’s shelter system — see whether the YTD selected in the dropdown is tracking above or below prior years on the inflow/outflow categories: Newly Identified and Moved to Permanent Housing.
Author
Miriam Marling
data =FileAttachment("../data/shelter_flow.json").json()
MON = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]fmtN = d => d.toLocaleString()// Month dropdown: display "March 2026", return "2026-03-01", default = most recent.reportingMonthOptions = data.filter(d => d.population_group==="All Population").sort((a, b) => b.flow_date.localeCompare(a.flow_date)).map(d => {const [y, m] = d.flow_date.split("-").map(Number)return {label:newDate(y, m -1,15).toLocaleString("default", {month:"long",year:"numeric"}),value: d.flow_date } })
viewof reportingDate = Inputs.select(reportingMonthOptions, {label:"Reporting Month",format: d => d.label,value: reportingMonthOptions[0]})
reportingYear =+reportingDate.value.slice(0,4)reportingMonth =+reportingDate.value.slice(5,7)// YTD cumulative sums for current year and prior year through selected month.ytdComputed = {const rows = data.filter(d => d.population_group==="All Population").filter(d => {const y =+d.flow_date.slice(0,4)const m =+d.flow_date.slice(5,7)return (y === reportingYear || y === reportingYear -1) && m <= reportingMonth }).sort((a, b) => a.flow_date.localeCompare(b.flow_date))const accNI = {}, accMH = {}return rows.map(d => {const y =+d.flow_date.slice(0,4)const m =+d.flow_date.slice(5,7) accNI[y] = (accNI[y] ||0) + d.newly_identified accMH[y] = (accMH[y] ||0) + d.moved_to_housingreturn {year: y,month: m,monthLabel: MON[m -1],yearLabel:String(y),isCurrentYear: y === reportingYear,ytd_ni: accNI[y],ytd_mh: accMH[y] } })}// Sort: by month, prior year first within each month — creates visual bar groupingytdSorted = ytdComputed.sort((a, b) => a.month- b.month|| a.year- b.year).map(d => ({...d,barLabel:`${d.monthLabel}${d.yearLabel}`}))ytdDomain = ytdSorted.map(d => d.barLabel)
This dashboard is also available as an Oracle APEX dashboard built on the same database — useful if you want to see how the same data renders in Oracle’s native low-code platform, or if you’re curious about the SQL and APEX configuration behind it.
Key terms
Inflow categories (people entering the shelter system this month):
Newly Identified. People entering the shelter system for the first time. One exception for the “Chronic” group: in that row, this column counts people who became chronically homeless during the reporting month, regardless of how long they’d already been using the shelter system.
Outflow categories (people leaving the shelter system this month):
Moved to Permanent Housing. People who left the shelter system for permanent housing.