Skip to content

Commit 138034b

Browse files
committed
feat: aggiunta la sezione "Timeline sostenitori" nella pagina di dettaglio dell'iniziativa
1 parent a8f9ad6 commit 138034b

2 files changed

Lines changed: 73 additions & 1 deletion

File tree

LOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 2025-07-09
44

5+
* Aggiunta la sezione "Timeline sostenitori" nella pagina di dettaglio dell'iniziativa. Questa sezione mostra un grafico con l'andamento temporale del numero di sostenitori ed è visibile solo per le iniziative per cui sono disponibili dati storici.
56
* I valori della "Media sostenitori giornalieri" nella tabella e nel grafico lollipop della pagina Numeri sono ora arrotondati a numero intero (firme), senza decimali, per maggiore chiarezza e coerenza.
67

78
## 2025-07-08
@@ -94,4 +95,4 @@
9495
* Aggiunta la colonna "Data Apertura" nella visualizzazione tabellare delle iniziative.
9596
* Aggiunto il supporto per l'ordinamento e la visualizzazione del quorum nella tabella delle iniziative.
9697
* Aggiunto il componente Footer e integrato in tutte le pagine.
97-
* Aggiunte le informazioni sull'associazione onData nel footer.
98+
* Aggiunte le informazioni sull'associazione onData nel footer.

src/pages/initiative/[id].astro

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
LinkIcon,
1717
FlagIcon
1818
} from '@heroicons/react/24/outline';
19+
import fs from 'node:fs';
1920
2021
export const getStaticPaths: GetStaticPaths = async () => {
2122
const initiatives = await fetchInitiatives();
@@ -36,6 +37,11 @@ if (!initiative) {
3637
return Astro.redirect('/404');
3738
}
3839
40+
const timeLineRaw = fs.readFileSync('data/time_line.jsonl', 'utf8');
41+
const timeLineData = timeLineRaw.trim().split('\n').map(JSON.parse);
42+
const initiativeTimeLine = timeLineData.filter(d => d.id === initiative.id);
43+
const hasTimeLineData = initiativeTimeLine.length > 0;
44+
3945
// Always use the official URL with the initiative ID for signing
4046
const officialUrl = `https://firmereferendum.giustizia.it/referendum/open/dettaglio-open/${initiative.id}`;
4147
const title = String(initiative.titolo || 'Iniziativa');
@@ -233,6 +239,71 @@ const currentUrl = (() => {
233239
)}
234240
</div>
235241

242+
{hasTimeLineData && (
243+
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4 sm:p-8 mb-6 sm:mb-8">
244+
<h2 class="text-lg sm:text-xl font-semibold text-gray-900 mb-4">Timeline sostenitori</h2>
245+
<div id="chart" class="w-full overflow-x-auto"></div>
246+
<script type="module" define:vars={{ timelineData: initiativeTimeLine }}>
247+
import * as Plot from "https://cdn.jsdelivr.net/npm/@observablehq/plot@0.6/+esm";
248+
249+
const fmtIt = new Intl.NumberFormat("it-IT").format;
250+
const fmtDate = d => d.toLocaleDateString("it-IT", {
251+
day: "2-digit",
252+
month: "short",
253+
year: "2-digit"
254+
});
255+
256+
function draw() {
257+
const data = timelineData
258+
.map(d => ({ ...d, data: new Date(d.data) }))
259+
.sort((a, b) => a.data - b.data);
260+
261+
if (data.length === 0) return;
262+
263+
const container = document.getElementById("chart");
264+
if (!container) return;
265+
const { width } = container.getBoundingClientRect();
266+
267+
const chart = Plot.plot({
268+
width,
269+
marginLeft: 60,
270+
marginBottom: 40,
271+
x: {
272+
type: "utc",
273+
label: "Data",
274+
tickFormat: fmtDate
275+
},
276+
y: {
277+
label: "Sostenitori",
278+
tickFormat: fmtIt,
279+
ticks: 5,
280+
zero: true
281+
},
282+
marks: [
283+
Plot.line(data, { x: "data", y: "sostenitori", stroke: "#1f77b4" }),
284+
Plot.dot(data, {
285+
x: "data",
286+
y: "sostenitori",
287+
r: 4,
288+
fill: "#1f77b4",
289+
title: d => `sostenitori: ${fmtIt(d.sostenitori)}\n${fmtDate(d.data)}`
290+
})
291+
]
292+
});
293+
294+
container.innerHTML = "";
295+
container.append(chart);
296+
}
297+
298+
const chartContainer = document.getElementById("chart");
299+
if (chartContainer) {
300+
draw();
301+
new ResizeObserver(draw).observe(chartContainer);
302+
}
303+
</script>
304+
</div>
305+
)}
306+
236307
<!-- Links -->
237308
<div class="bg-white rounded-lg shadow-sm border border-gray-200 p-4 sm:p-8">
238309
<h2 class="text-lg sm:text-xl font-semibold text-gray-900 mb-3 sm:mb-4">Link utili</h2>

0 commit comments

Comments
 (0)