From 4f7f2e2da67c988d31f8bceec2503c2718163f05 Mon Sep 17 00:00:00 2001 From: p2312013 <amira.rabehi@etu.univ-lyon1.fr> Date: Fri, 3 Jan 2025 11:07:32 +0100 Subject: [PATCH] fixed visualisation --- question3/visu2/index.html | 12 ++- question3/visu2/script.js | 179 +++++++++++++++++++------------------ 2 files changed, 99 insertions(+), 92 deletions(-) diff --git a/question3/visu2/index.html b/question3/visu2/index.html index 1201268..687b146 100644 --- a/question3/visu2/index.html +++ b/question3/visu2/index.html @@ -7,10 +7,14 @@ <link rel="stylesheet" href="styles.css"> </head> <body> - <h1>Distance parcourue par semaine</h1> - <div id="chart-container"> - <svg id="radial-chart"></svg> - </div> + <h1>Radial Bar Chart by Person</h1> + <select class="dropdown" id="personDropdown"> + <option value="Distance_Anis">Anis</option> + <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="script.js"></script> </body> diff --git a/question3/visu2/script.js b/question3/visu2/script.js index c2a64ee..adbb90e 100644 --- a/question3/visu2/script.js +++ b/question3/visu2/script.js @@ -1,118 +1,121 @@ fetch("../final_combined_with_all_data.json") - .then(response => response.json()) - .then(data => { - const width = 800; - const height = 800; - const innerRadius = 120; - const outerRadius = Math.min(width, height) / 2 - 50; +.then(response => response.json()) +.then(data => { + const width = 600; + const height = 600; + const innerRadius = 50; + const outerRadius = Math.min(width, height) / 2 - 100; - // Filtrer les données - const filteredData = data.filter(d => { - const date = new Date(d.date); - return date >= new Date("2023-10-01") && date <= new Date("2024-12-31"); - }); + // 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"); + }); - // Regrouper par semaine - const groupedData = d3.group(filteredData, d => { - const date = new Date(d.date); - const weekNumber = getISOWeekNumber(date); - return `${date.getFullYear()}-W${weekNumber}`; - }); + // 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), - }; - return aggregated; - }); + 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; + }); - 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"]; - const series = d3.stack() - .keys(seriesKeys)(processedData); + // Initial chart rendering + updateChart(dropdown.value); - 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() .domain(processedData.map(d => d.week)) .range([0, 2 * Math.PI]) .align(0); 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]); - const color = d3.scaleOrdinal() - .domain(seriesKeys) - .range(d3.schemeCategory10); + const color = d3.scaleLinear() + .domain([0, d3.max(processedData, d => d[sleepKey])]) + .range(["lightblue", "darkblue"]); - // Créer le graphique SVG - 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 + // Bars svg.append("g") - .selectAll("g") - .data(series) - .join("g") - .attr("fill", d => color(d.key)) .selectAll("path") - .data(d => d.map(point => ({ ...point, key: d.key }))) + .data(processedData) .join("path") - .attr("d", d3.arc() - .innerRadius(d => y(d[0])) - .outerRadius(d => y(d[1])) - .startAngle(d => x(d.data.week)) - .endAngle(d => x(d.data.week) + x.bandwidth()) - .padAngle(0.02) - .padRadius(innerRadius)) - .append("title") - .text(d => `${d.key}: ${d[1] - d[0]}`); + .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`); - // Ajouter les étiquettes + // Labels svg.append("g") .selectAll("g") .data(x.domain()) .join("g") - .attr("transform", d => ` - rotate(${((x(d) + x.bandwidth() / 2) * 180 / Math.PI - 90)}) - translate(${outerRadius + 10},0) - `) - .call(g => g.append("text") - .text(d => d) - .attr("text-anchor", "middle")); + .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")); - // Ajouter la légende + // Legend svg.append("g") .selectAll("g") - .data(seriesKeys) + .data(["Low Sleep", "High Sleep"]) .join("g") - .attr("transform", (d, i) => `translate(-40,${(seriesKeys.length / 2 - i - 1) * 20})`) - .call(g => g.append("rect") - .attr("width", 18) - .attr("height", 18) - .attr("fill", color)) - .call(g => g.append("text") - .text(d => d) - .attr("x", 24) - .attr("y", 9)); - - document.body.appendChild(svg.node()); + .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)); + 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)); \ No newline at end of file -- GitLab