Newer
Older
fetch("../final_combined_with_all_data.json")
.then(response => response.json())
.then(data => {
const width = 600;
const height = 600;
const innerRadius = 50;
const outerRadius = Math.min(width, height) / 2 - 100;
// Filter data
const filteredData = data.filter(d => {
const date = new Date(d.date);
return date >= new Date("2023-10-01") && date <= new Date("2024-12-31");
});
// Group data by ISO week
const groupedData = d3.group(filteredData, d => {
const date = new Date(d.date);
const weekNumber = getISOWeekNumber(date);
return `${date.getFullYear()}-W${weekNumber}`;
});
const processedData = Array.from(groupedData, ([week, records]) => {
const aggregated = {
week: week,
Distance_Anis: d3.sum(records, d => d.Distance_Anis || 0),
Distance_Maya: d3.sum(records, d => d.Distance_Maya || 0),
Distance_Corentin: d3.sum(records, d => d.Distance_Corentin || 0),
Distance_Amira: d3.sum(records, d => d.Distance_Amira || 0),
Sleep_Anis: d3.mean(records, d => d.Sleep_Anis || 0),
Sleep_Maya: d3.mean(records, d => d.Sleep_Maya || 0),
Sleep_Corentin: d3.mean(records, d => d.Sleep_Corentin || 0),
Sleep_Amira: d3.mean(records, d => d.Sleep_Amira || 0),
};
return aggregated;
});
// Dropdown change event
const dropdown = document.getElementById("personDropdown");
dropdown.addEventListener("change", () => updateChart(dropdown.value));
// Initial chart rendering
updateChart(dropdown.value);
function updateChart(personKey) {
const sleepKey = personKey.replace("Distance", "Sleep");
d3.select("#chart").html(""); // Clear the previous chart
const svg = d3.select("#chart")
.append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", [-width / 2, -height / 2, width, height])
.attr("style", "width: 100%; height: auto; font: 10px sans-serif;");
// Scales
const x = d3.scaleBand()
.domain(processedData.map(d => d.week))
.range([0, 2 * Math.PI])
.align(0);
const y = d3.scaleRadial()
.domain([0, d3.max(processedData, d => d[personKey])])
const color = d3.scaleLinear()
.domain([0, d3.max(processedData, d => d[sleepKey])])
.range(["lightblue", "darkblue"]);
.attr("d", d3.arc()
.innerRadius(innerRadius)
.outerRadius(d => y(d[personKey]))
.startAngle(d => x(d.week))
.endAngle(d => x(d.week) + x.bandwidth())
.padAngle(0.02)
.padRadius(innerRadius))
.attr("fill", d => color(d[sleepKey]))
.append("title")
.text(d => `${d.week}\nDistance: ${d[personKey].toFixed(2)}\nSleep: ${d[sleepKey].toFixed(2)}h`);
.attr("transform", d => `
rotate(${((x(d) + x.bandwidth() / 2) * 180 / Math.PI - 90)})
translate(${outerRadius + 25},0)
`)
.call(g => g.append("text")
.text(d => d)
.attr("text-anchor", "middle"));
.attr("transform", (d, i) => `translate(-30,${(2 - i - 2) * 10})`)
.call(g => g.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("fill", (d, i) => i === 0 ? "lightblue" : "darkblue"))
.call(g => g.append("text")
.text(d => d)
.attr("x", 20)
.attr("y", 9));
}
function getISOWeekNumber(date) {
const tempDate = new Date(date);
tempDate.setDate(tempDate.getDate() + 4 - (tempDate.getDay() || 7));
const yearStart = new Date(tempDate.getFullYear(), 0, 1);
return Math.ceil(((tempDate - yearStart) / 86400000 + 1) / 7);
}
})
.catch(error => console.error("Error loading data:", error));