diff --git a/functions/index.js b/functions/index.js index 4a52ff9..45e775e 100644 --- a/functions/index.js +++ b/functions/index.js @@ -7,36 +7,33 @@ const { calculateYearCounts } = require('./aggregator'); initializeApp(); const db = getFirestore(); -// Calculate and save aggregations +// Calculate and save aggregations async function calculateAggregatedCounts() { const publicationsSnapshot = await db.collection('publications').get(); - const publications = publicationsSnapshot.docs.map(doc => doc.data()); + const publications = publicationsSnapshot.docs.map((doc) => doc.data()); - // Count of docs by year + // Count of docs by year const aggregatedCounts = calculateYearCounts(publications); // Save the aggregation(s) - await db.collection('aggregations').doc('publicationCounts').set({ + await db.collection('aggregations').doc('publicationsByYear').set({ counts: aggregatedCounts, }); } // onDocumentWritten triggers on create, update, or delete -exports.aggregatePublicationsOnWrite = onDocumentWritten( - 'publications/{docId}', - async (event) => { - try { - // log before and after data - const beforeData = event.data.before.data(); - const afterData = event.data.after.data(); +exports.aggregatePublicationsOnWrite = onDocumentWritten('publications/{docId}', async (event) => { + try { + // log before and after data + const beforeData = event.data.before.data(); + const afterData = event.data.after.data(); - console.log(`Document written: ${event.params.docId}`); - console.log('Before data:', beforeData); - console.log('After data:', afterData); + console.log(`Document written: ${event.params.docId}`); + console.log('Before data:', beforeData); + console.log('After data:', afterData); - await calculateAggregatedCounts(); - } catch (error) { - console.error('Error recalculating counts on document write:', error); - } + await calculateAggregatedCounts(); + } catch (error) { + console.error('Error recalculating counts on document write:', error); } -); +}); diff --git a/src/components/BarChart.js b/src/components/BarChart.js index ce5cd34..52bb789 100644 --- a/src/components/BarChart.js +++ b/src/components/BarChart.js @@ -1,5 +1,6 @@ -import React from 'react'; +import React, { useEffect, useState } from 'react'; import { Vega } from 'react-vega'; +import { getAggregation } from '../utils/firebase.ts'; const bar_color = '#00c398'; // ccv green const bar_hover_color = '#ffc72c'; // ccv yellow @@ -431,44 +432,59 @@ const generateBarPlotWithCumuSum = (dataJson, xLabel) => { return spec; }; -const inputJson = [ - { label: '2008', count: 1 }, - { label: '2009', count: 2 }, - { label: '2010', count: 6 }, - { label: '2011', count: 3 }, - { label: '2012', count: 8 }, - { label: '2013', count: 18 }, - { label: '2014', count: 35 }, - { label: '2015', count: 41 }, - { label: '2016', count: 35 }, - { label: '2017', count: 60 }, - { label: '2018', count: 70 }, - { label: '2019', count: 60 }, - { label: '2020', count: 70 }, - { label: '2021', count: 58 }, - { label: '2022', count: 62 }, - { label: '2023', count: 80 }, - { label: '2024', count: 5 }, -]; - -export function CountsByYearPlot({ type }) { - let vegaSpec = {}; +export const CountsByYearPlot = ({ type }) => { const xLabel = 'Year'; - if (type === 'bar') { - vegaSpec = generateBarPlot({ - data: inputJson, - xLabel: xLabel, - yLabel: 'Publications', - }); - } else if (type === 'cumu-line') { - vegaSpec = generateCumuSumPlot({ - data: inputJson, - xLabel: xLabel, - yLabel: 'Cumulative Publications', - }); - } else if (type === 'bar-cumu-line') { - vegaSpec = generateBarPlotWithCumuSum(inputJson, xLabel); + const [vegaSpec, setVegaSpec] = useState(null); + const [loading, setLoading] = useState(true); + + useEffect(() => { + const fetchData = async () => { + try { + const fetchedData = await getAggregation({ documentName: 'publicationsByYear' }); + let spec; + if (type === 'bar') { + spec = generateBarPlot({ + data: fetchedData, + xLabel: xLabel, + yLabel: 'Publications', + }); + } else if (type === 'cumu-line') { + spec = generateCumuSumPlot({ + data: fetchedData, + xLabel: xLabel, + yLabel: 'Cumulative Publications', + }); + } else if (type === 'bar-cumu-line') { + spec = generateBarPlotWithCumuSum(fetchedData, xLabel); + } + setVegaSpec(spec); + } catch (error) { + console.error('Error fetching document:', error); + } finally { + setLoading(false); + } + }; + + fetchData(); + }, [type]); + + if (loading) { + return
Loading...
; } - return ; -} + if (!vegaSpec) { + return
Error: Invalid plot type specified
; + } + + return ( + + ); +}; diff --git a/src/utils/firebase.ts b/src/utils/firebase.ts index c69b3e7..7c33014 100644 --- a/src/utils/firebase.ts +++ b/src/utils/firebase.ts @@ -267,3 +267,15 @@ const getUser = async (email): Promise => { return docSnap.data() as User; }; + +export async function getAggregation({ documentName }) { + const docRef = doc(db, 'aggregations', documentName); + const docSnap = await getDoc(docRef); + + if (docSnap.exists()) { + return docSnap.data()['counts']; + } else { + console.log('Document not found.'); + return null; + } +}