Public
Edited
May 6
Insert cell
Insert cell
Insert cell
viewof selectedMonth = {
const form = html`<form>
<label><strong>Select Month:</strong></label>
<input type="range" min="0" max="23" step="1" value="0" />
<span id="month-label"></span>
</form>`;

const slider = form.querySelector("input");
const label = form.querySelector("#month-label");

const months = [];
for (let y = 2023; y <= 2024; y++) {
for (let m = 0; m < 12; m++) {
months.push({ year: y, month: m });
}
}

const formatLabel = d => new Date(d.year, d.month).toLocaleString("default", { month: "long", year: "numeric" });

function updateLabel(index) {
const current = months[index];
label.textContent = formatLabel(current);
form.value = current;
form.dispatchEvent(new CustomEvent("input"));
}

slider.addEventListener("input", () => updateLabel(+slider.value));
updateLabel(0);
return form;
}

Insert cell
viewof selectedArea = {
const areas = Array.from(new Set(rawData.map(d => d.area))).sort();
const select = html`<select style="padding: 4px;"></select>`;

select.appendChild(Object.assign(document.createElement("option"), {
textContent: "All Areas",
value: "All"
}));

for (const area of areas) {
select.appendChild(Object.assign(document.createElement("option"), {
textContent: area,
value: area
}));
}

select.value = "All";
select.oninput = () => select.dispatchEvent(new CustomEvent("input"));
return select;
}

Insert cell
rawData = {
const url = "https://raw.githubusercontent.com/Satviknayak2002/ObservableDataset/refs/heads/main/crime_data_2023_2024.csv";
const file = await d3.csv(url);

const parseDate = d => new Date(d["DATE OCC"]);

return file.map(d => ({
date: parseDate(d),
month: parseDate(d).getMonth(),
year: parseDate(d).getFullYear(),
area: d["AREA NAME"],
crime: d["Crm Cd Desc"]
}));
}



Insert cell
filteredData = rawData.filter(d =>
d.year === selectedMonth.year &&
d.month === selectedMonth.month &&
(selectedArea === "All" || d.area === selectedArea)
)


Insert cell
crimeTypeBar = Plot.plot({
width: 800,
height: 300,
marginBottom: 100,
x: {
label: null,
tickRotate: -45 // ✅ rotates category labels
},
y: { label: "Number of Reports" },
marks: [
Plot.barY(
d3.rollups(filteredData, v => v.length, d => d.crime)
.sort((a, b) => d3.descending(a[1], b[1]))
.slice(0, 10),
{
x: d => d[0],
y: d => d[1],
fill: "steelblue",
title: d => `${d[0]}: ${d[1]} reports`
}
)
]
})


Insert cell
areaBar = Plot.plot({
width: 800,
height: 300,
marginBottom: 100,
x: {
label: null,
tickRotate: -45 // ✅ rotates area names
},
y: { label: "Number of Reports" },
marks: [
Plot.barY(
d3.rollups(filteredData, v => v.length, d => d.area)
.sort((a, b) => d3.descending(a[1], b[1])),
{
x: d => d[0],
y: d => d[1],
fill: "orange",
title: d => `${d[0]}: ${d[1]} reports`
}
)
]
})


Insert cell
crimeTrendPlot = {
const crimesPerDay = d3.rollups(
filteredData,
v => v.length,
d => d3.timeDay(d.date) // group by day only
).map(([date, count]) => ({ date, count }));

return Plot.plot({
width: 800,
height: 300,
x: { label: "Date", type: "utc" },
y: { label: "Number of Crimes", nice: true },
marks: [
Plot.dot(crimesPerDay, {
x: "date",
y: "count",
r: 4,
fill: "darkred",
opacity: 0.7,
title: d => `${d.date.toDateString()}: ${d.count} crimes`
})
]
});
}


Insert cell
dashboard = {
const container = html`<div style="font-family: Arial, sans-serif; padding: 20px;"></div>`;

// --- Controls ---
const monthLabel = html`<h2 style="margin-bottom: 10px;">
📊 Crime Dashboard — ${selectedMonth.year}, ${new Date(selectedMonth.year, selectedMonth.month).toLocaleString("default", { month: "long" })}
</h2>`;
container.appendChild(monthLabel);
container.appendChild(viewof selectedMonth);
container.appendChild(html`<div style="margin: 10px 0;">Filter by Area:</div>`);
container.appendChild(viewof selectedArea);

// --- Top Row: Bar Charts ---
const topRow = html`<div style="display: flex; gap: 20px; margin-top: 20px;"></div>`;

const leftBox = html`<div style="flex: 1;"><h4>🔹 Top 10 Crime Types</h4></div>`;
leftBox.appendChild(crimeTypeBar);

const rightBox = html`<div style="flex: 1;"><h4>🟠 Crimes by Area</h4></div>`;
rightBox.appendChild(areaBar);

topRow.appendChild(leftBox);
topRow.appendChild(rightBox);

// --- Bottom Row: Trend Plot ---
const bottomBox = html`<div style="margin-top: 40px;"><h4>🔴 Daily Crime Trend</h4></div>`;
bottomBox.appendChild(crimeTrendPlot);

container.appendChild(topRow);
container.appendChild(bottomBox);

return container;
}

Insert cell
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