Skip to content
Snippets Groups Projects
Commit 4f7f2e2d authored by RABEHI AMIRA p2312013's avatar RABEHI AMIRA p2312013
Browse files

fixed visualisation

parent 63cb95df
No related branches found
No related tags found
No related merge requests found
...@@ -7,10 +7,14 @@ ...@@ -7,10 +7,14 @@
<link rel="stylesheet" href="styles.css"> <link rel="stylesheet" href="styles.css">
</head> </head>
<body> <body>
<h1>Distance parcourue par semaine</h1> <h1>Radial Bar Chart by Person</h1>
<div id="chart-container"> <select class="dropdown" id="personDropdown">
<svg id="radial-chart"></svg> <option value="Distance_Anis">Anis</option>
</div> <option value="Distance_Maya">Maya</option>
<option value="Distance_Corentin">Corentin</option>
<option value="Distance_Amira">Amira</option>
</select>
<div id="chart"></div>
<script src="https://d3js.org/d3.v6.min.js"></script> <script src="https://d3js.org/d3.v6.min.js"></script>
<script src="script.js"></script> <script src="script.js"></script>
</body> </body>
......
fetch("../final_combined_with_all_data.json") fetch("../final_combined_with_all_data.json")
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
const width = 800; const width = 600;
const height = 800; const height = 600;
const innerRadius = 120; const innerRadius = 50;
const outerRadius = Math.min(width, height) / 2 - 50; const outerRadius = Math.min(width, height) / 2 - 100;
// Filtrer les données // Filter data
const filteredData = data.filter(d => { const filteredData = data.filter(d => {
const date = new Date(d.date); const date = new Date(d.date);
return date >= new Date("2023-10-01") && date <= new Date("2024-12-31"); return date >= new Date("2023-10-01") && date <= new Date("2024-12-31");
}); });
// Regrouper par semaine // Group data by ISO week
const groupedData = d3.group(filteredData, d => { const groupedData = d3.group(filteredData, d => {
const date = new Date(d.date); const date = new Date(d.date);
const weekNumber = getISOWeekNumber(date); const weekNumber = getISOWeekNumber(date);
return `${date.getFullYear()}-W${weekNumber}`; return `${date.getFullYear()}-W${weekNumber}`;
}); });
const processedData = Array.from(groupedData, ([week, records]) => { const processedData = Array.from(groupedData, ([week, records]) => {
const aggregated = { const aggregated = {
week: week, week: week,
Distance_Anis: d3.sum(records, d => d.Distance_Anis || 0), Distance_Anis: d3.sum(records, d => d.Distance_Anis || 0),
Distance_Maya: d3.sum(records, d => d.Distance_Maya || 0), Distance_Maya: d3.sum(records, d => d.Distance_Maya || 0),
Distance_Corentin: d3.sum(records, d => d.Distance_Corentin || 0), Distance_Corentin: d3.sum(records, d => d.Distance_Corentin || 0),
Distance_Amira: d3.sum(records, d => d.Distance_Amira || 0), Distance_Amira: d3.sum(records, d => d.Distance_Amira || 0),
}; Sleep_Anis: d3.mean(records, d => d.Sleep_Anis || 0),
return aggregated; 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;
});
console.log("Processed Data:", processedData); // Dropdown change event
const dropdown = document.getElementById("personDropdown");
dropdown.addEventListener("change", () => updateChart(dropdown.value));
const seriesKeys = ["Distance_Anis", "Distance_Maya", "Distance_Corentin", "Distance_Amira"]; // Initial chart rendering
const series = d3.stack() updateChart(dropdown.value);
.keys(seriesKeys)(processedData);
console.log("Stacked Series:", series); function updateChart(personKey) {
const sleepKey = personKey.replace("Distance", "Sleep");
d3.select("#chart").html(""); // Clear the previous chart
// Échelles 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() const x = d3.scaleBand()
.domain(processedData.map(d => d.week)) .domain(processedData.map(d => d.week))
.range([0, 2 * Math.PI]) .range([0, 2 * Math.PI])
.align(0); .align(0);
const y = d3.scaleRadial() const y = d3.scaleRadial()
.domain([0, d3.max(series, s => d3.max(s, d => d[1]))]) .domain([0, d3.max(processedData, d => d[personKey])])
.range([innerRadius, outerRadius]); .range([innerRadius, outerRadius]);
const color = d3.scaleOrdinal() const color = d3.scaleLinear()
.domain(seriesKeys) .domain([0, d3.max(processedData, d => d[sleepKey])])
.range(d3.schemeCategory10); .range(["lightblue", "darkblue"]);
// Créer le graphique SVG // Bars
const svg = d3.create("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;");
// Ajouter les barres
svg.append("g") svg.append("g")
.selectAll("g")
.data(series)
.join("g")
.attr("fill", d => color(d.key))
.selectAll("path") .selectAll("path")
.data(d => d.map(point => ({ ...point, key: d.key }))) .data(processedData)
.join("path") .join("path")
.attr("d", d3.arc() .attr("d", d3.arc()
.innerRadius(d => y(d[0])) .innerRadius(innerRadius)
.outerRadius(d => y(d[1])) .outerRadius(d => y(d[personKey]))
.startAngle(d => x(d.data.week)) .startAngle(d => x(d.week))
.endAngle(d => x(d.data.week) + x.bandwidth()) .endAngle(d => x(d.week) + x.bandwidth())
.padAngle(0.02) .padAngle(0.02)
.padRadius(innerRadius)) .padRadius(innerRadius))
.append("title") .attr("fill", d => color(d[sleepKey]))
.text(d => `${d.key}: ${d[1] - d[0]}`); .append("title")
.text(d => `${d.week}\nDistance: ${d[personKey].toFixed(2)}\nSleep: ${d[sleepKey].toFixed(2)}h`);
// Ajouter les étiquettes // Labels
svg.append("g") svg.append("g")
.selectAll("g") .selectAll("g")
.data(x.domain()) .data(x.domain())
.join("g") .join("g")
.attr("transform", d => ` .attr("transform", d => `
rotate(${((x(d) + x.bandwidth() / 2) * 180 / Math.PI - 90)}) rotate(${((x(d) + x.bandwidth() / 2) * 180 / Math.PI - 90)})
translate(${outerRadius + 10},0) translate(${outerRadius + 25},0)
`) `)
.call(g => g.append("text") .call(g => g.append("text")
.text(d => d) .text(d => d)
.attr("text-anchor", "middle")); .attr("text-anchor", "middle"));
// Ajouter la légende // Legend
svg.append("g") svg.append("g")
.selectAll("g") .selectAll("g")
.data(seriesKeys) .data(["Low Sleep", "High Sleep"])
.join("g") .join("g")
.attr("transform", (d, i) => `translate(-40,${(seriesKeys.length / 2 - i - 1) * 20})`) .attr("transform", (d, i) => `translate(-30,${(2 - i - 2) * 10})`)
.call(g => g.append("rect") .call(g => g.append("rect")
.attr("width", 18) .attr("width", 10)
.attr("height", 18) .attr("height", 10)
.attr("fill", color)) .attr("fill", (d, i) => i === 0 ? "lightblue" : "darkblue"))
.call(g => g.append("text") .call(g => g.append("text")
.text(d => d) .text(d => d)
.attr("x", 24) .attr("x", 20)
.attr("y", 9)); .attr("y", 9));
}
document.body.appendChild(svg.node());
function getISOWeekNumber(date) { function getISOWeekNumber(date) {
const tempDate = new Date(date); const tempDate = new Date(date);
tempDate.setDate(tempDate.getDate() + 4 - (tempDate.getDay() || 7)); tempDate.setDate(tempDate.getDate() + 4 - (tempDate.getDay() || 7));
const yearStart = new Date(tempDate.getFullYear(), 0, 1); const yearStart = new Date(tempDate.getFullYear(), 0, 1);
return Math.ceil(((tempDate - yearStart) / 86400000 + 1) / 7); return Math.ceil(((tempDate - yearStart) / 86400000 + 1) / 7);
} }
}) })
.catch(error => console.error("Error loading data:", error)); .catch(error => console.error("Error loading data:", error));
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment