diff --git a/package-lock.json b/package-lock.json index 89e09e211..e15b8d097 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@types/intro.js": "^3.0.0", "bootstrap": "^4.6.0", "bootstrap-vue": "^2.22.0", + "chart.js": "^4.4.7", "core-js": "^3.6.5", "cypress-axe": "^0.14.0", "cypress-firebase": "^2.2.2", @@ -25,6 +26,7 @@ "node-fetch": "^2.6.7", "pdfjs-dist": "^3.5.141", "vue": "^3.2.19", + "vue-chartjs": "^5.3.2", "vue-gtag-next": "^1.14.0", "vue-router": "^4.0.6", "vuedraggable": "^4.0.0", @@ -3886,6 +3888,11 @@ "node": ">=v12.0.0" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", @@ -7130,6 +7137,17 @@ "is-regex": "^1.0.3" } }, + "node_modules/chart.js": { + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.4.7.tgz", + "integrity": "sha512-pwkcKfdzTMAU/+jNosKhNL2bHtJc/sSmYgVbuGTEDhzkrhmyihmP7vUc/5ZK9WopidMDHNe3Wm7jOd/WhuHWuw==", + "dependencies": { + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" + } + }, "node_modules/check-more-types": { "version": "2.24.0", "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", @@ -20900,6 +20918,15 @@ "@vue/shared": "3.2.19" } }, + "node_modules/vue-chartjs": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.2.tgz", + "integrity": "sha512-NrkbRRoYshbXbWqJkTN6InoDVwVb90C0R7eAVgMWcB9dPikbruaOoTFjFYHE/+tNPdIe6qdLCDjfjPHQ0fw4jw==", + "peerDependencies": { + "chart.js": "^4.1.1", + "vue": "^3.0.0-0 || ^2.7.0" + } + }, "node_modules/vue-eslint-parser": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-8.0.1.tgz", diff --git a/package.json b/package.json index 59aecfeba..602d8a255 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@types/intro.js": "^3.0.0", "bootstrap": "^4.6.0", "bootstrap-vue": "^2.22.0", + "chart.js": "^4.4.7", "core-js": "^3.6.5", "cypress-axe": "^0.14.0", "cypress-firebase": "^2.2.2", @@ -42,6 +43,7 @@ "node-fetch": "^2.6.7", "pdfjs-dist": "^3.5.141", "vue": "^3.2.19", + "vue-chartjs": "^5.3.2", "vue-gtag-next": "^1.14.0", "vue-router": "^4.0.6", "vuedraggable": "^4.0.0", diff --git a/src/containers/Analytics.vue b/src/containers/Analytics.vue index c5f4e7ea7..e8ea315e2 100644 --- a/src/containers/Analytics.vue +++ b/src/containers/Analytics.vue @@ -4,6 +4,14 @@
Data last retrieved at: {{ analyticsTimestamp }}
{{ analyticsData }}
+
+

Graduation Year Frequencies

+ + + +
Back to home
@@ -16,10 +24,11 @@ import { defineComponent } from 'vue'; import CustomFooter from '@/components/Footer.vue'; import TopBar from '@/components/TopBar.vue'; +import PieChart from '@/containers/PieChart.vue'; // Import PieChart Component import { retrieveAnalytics } from '@/global-firestore-data'; export default defineComponent({ - components: { CustomFooter, TopBar }, + components: { CustomFooter, TopBar, PieChart }, mounted() { this.retrieveData(); }, @@ -27,6 +36,7 @@ export default defineComponent({ return { analyticsData: '', analyticsTimestamp: '', + gradYearFrequencies: {} as Record, // Add property for hash map }; }, methods: { @@ -34,10 +44,32 @@ export default defineComponent({ const analyticsObject = await retrieveAnalytics(); this.analyticsData = analyticsObject.data; this.analyticsTimestamp = analyticsObject.timestamp; + + // Extract gradYearFrequencies once data is retrieved + this.gradYearFrequencies = this.extractGradYearFrequencies(); }, hasData() { return this.analyticsData.length > 2; }, + extractGradYearFrequencies() { + const startKey = '"gradYearFrequencies": {'; + const endKey = '}'; + + // Find the part of the string containing gradYearFrequencies + const startIndex = this.analyticsData.indexOf(startKey) + startKey.length; + const endIndex = this.analyticsData.indexOf(endKey, startIndex); + const gradYearFrequenciesString = this.analyticsData.substring(startIndex, endIndex).trim(); + + // Convert the extracted string to a hash map + const hashMap: Record = {}; // Explicit typing for hash map + const pairs = gradYearFrequenciesString.split(',').map(pair => pair.trim()); + for (const pair of pairs) { + const [key, value] = pair.split(':').map(item => item.trim().replace(/["']/g, '')); // Remove quotes + hashMap[key] = parseInt(value, 10); // Convert value to an integer + } + + return hashMap; + }, }, }); @@ -91,4 +123,15 @@ a.back_to_home_link { padding: 0 0 0 3.125rem; } } +.hash-map-display { + margin-top: 2rem; + padding: 1rem; + background-color: #f9f9f9; + border: 1px solid #ddd; + border-radius: 5px; +} + +.hash-map-display h3 { + margin-bottom: 1rem; +} diff --git a/src/containers/PieChart.vue b/src/containers/PieChart.vue new file mode 100644 index 000000000..114b09881 --- /dev/null +++ b/src/containers/PieChart.vue @@ -0,0 +1,65 @@ + + +