diff --git a/frontend/index.html b/frontend/index.html
index 6ad5ef01..8c22035b 100644
--- a/frontend/index.html
+++ b/frontend/index.html
@@ -5,6 +5,12 @@
SWOT-DATA-VIEWER
+
diff --git a/frontend/src/components/DataQuality.vue b/frontend/src/components/DataQuality.vue
index 37395963..5b77cf4a 100644
--- a/frontend/src/components/DataQuality.vue
+++ b/frontend/src/components/DataQuality.vue
@@ -51,5 +51,15 @@ function qualityHasChanged() {
// stats are not shown after update of data quality
statsStore.toggleSeriesStatistics(showStatistics.value)
+ try {
+ window.heap.track('Data Quality Updated', {
+ selectedFlags: dataQualityFlags.value // Track the currently selected data quality flags
+ })
+ } catch (e) {
+ console.warn(
+ 'Heap is not available or an error occurred while tracking the Data Quality Updated event.',
+ e
+ )
+ }
}
diff --git a/frontend/src/components/DataViewDrawer.vue b/frontend/src/components/DataViewDrawer.vue
index b161c4ee..bd369d47 100644
--- a/frontend/src/components/DataViewDrawer.vue
+++ b/frontend/src/components/DataViewDrawer.vue
@@ -20,7 +20,7 @@
{
return featureStore?.activeFeature?.feature_type === 'Reach'
})
+const handlePlotClick = () => {
+ try {
+ window.heap.track('Plotted Event', {
+ featureId: featureStore.activeFeature.properties.reach_id,
+ featureType: featureStore.activeFeature.feature_type
+ })
+ } catch (e) {
+ console.warn('Heap is not available or an error occurred while tracking the Plotted Event.', e)
+ } finally {
+ router.push(`/plots/${featureStore.activeFeature.properties.reach_id}`)
+ }
+}
+
featureStore.$subscribe((mutation, state) => {
if (state.activeFeature !== null) {
// && typeof mutation.events.newValue === 'object'
diff --git a/frontend/src/components/PlotActions.vue b/frontend/src/components/PlotActions.vue
index 8c2e230f..e0455449 100644
--- a/frontend/src/components/PlotActions.vue
+++ b/frontend/src/components/PlotActions.vue
@@ -106,12 +106,28 @@ const getChartName = () => {
return `${identifier}.png`
}
+const trackDownloadEvent = (eventName, metadata = {}) => {
+ try {
+ window.heap.track(eventName, metadata)
+ } catch (e) {
+ console.warn(
+ `Heap is not available or an error occurred while tracking the ${eventName} event.`,
+ e
+ )
+ }
+}
+
const downloadChart = async () => {
downloading.value.chart = true
const filename = getChartName()
// change the chart background color to white
// props.chosenPlot.chart.canvas.style.backgroundColor = 'white'
+ trackDownloadEvent('Download Chart', {
+ filename: filename,
+ chartType: isNodeChart.value ? 'Node Chart' : 'Feature Chart'
+ })
+
const image = props.chosenPlot.chart.toBase64Image('image/png', 1)
const link = document.createElement('a')
link.href = image
@@ -122,6 +138,11 @@ const downloadChart = async () => {
const downCsv = async () => {
downloading.value.csv = true
+
+ trackDownloadEvent('Download CSV', {
+ chartType: isNodeChart.value ? 'Node Chart' : 'Feature Chart'
+ })
+
// determine whether to download the node or feature csv
if (isNodeChart.value) {
await downloadMultiNodesCsv()
@@ -133,6 +154,11 @@ const downCsv = async () => {
const downJson = async () => {
downloading.value.json = true
+
+ trackDownloadEvent('Download JSON', {
+ chartType: isNodeChart.value ? 'Node Chart' : 'Feature Chart'
+ })
+
// determine whether to download the node or feature
if (isNodeChart.value) {
await downloadMultiNodesJson()
diff --git a/frontend/src/components/StaticMetadata.vue b/frontend/src/components/StaticMetadata.vue
index f2b3601c..eb2af3f8 100644
--- a/frontend/src/components/StaticMetadata.vue
+++ b/frontend/src/components/StaticMetadata.vue
@@ -58,9 +58,9 @@
- Metadata
+
+ Metadata
+
Hide Extended Metadata
@@ -79,7 +79,22 @@ const props = defineProps({
const featureStore = useFeaturesStore()
const hydrologicStore = useHydrologicStore()
-let extended = ref(false)
+const extended = ref(false)
+
+const handleMetadataClick = (isExtended) => {
+ try {
+ window.heap.track('Metadata Extended Event', {
+ action: isExtended ? 'View Metadata' : 'Hide Metadata'
+ })
+ } catch (e) {
+ console.warn(
+ 'Heap is not available or an error occurred while tracking the Metadata Extended Event.',
+ e
+ )
+ } finally {
+ extended.value = isExtended
+ }
+}
if (props.reachId) {
featureStore.setActiveFeatureById(props.reachId)
diff --git a/frontend/src/components/TheLeafletMap.vue b/frontend/src/components/TheLeafletMap.vue
index 61983eb9..75669f07 100644
--- a/frontend/src/components/TheLeafletMap.vue
+++ b/frontend/src/components/TheLeafletMap.vue
@@ -386,7 +386,7 @@ onMounted(async () => {
})
/**/
- esriLeafletGeocoder
+ const geosearchControl = esriLeafletGeocoder
.geosearch({
position: 'topleft',
placeholder: 'Search for a location',
@@ -398,6 +398,19 @@ onMounted(async () => {
})
.addTo(leaflet)
+ geosearchControl.on('results', (data) => {
+ try {
+ const searchQuery = data.text
+ const searchResults = data.results.map((result) => result.properties.LongLabel || result.text)
+ window.heap.track('Map Search Event', {
+ searchQuery: searchQuery,
+ searchResults: searchResults
+ })
+ } catch (e) {
+ console.warn('Heap is not available or an error occurred while tracking the search event.', e)
+ }
+ })
+
// add zoom control again they are ordered in the order they are added
L.control
.zoom({
diff --git a/frontend/src/components/TimeRangeSelector.vue b/frontend/src/components/TimeRangeSelector.vue
index 9a62a041..2f9fb77e 100644
--- a/frontend/src/components/TimeRangeSelector.vue
+++ b/frontend/src/components/TimeRangeSelector.vue
@@ -47,6 +47,18 @@ const updatetimeRange = () => {
timeRange.value = dateRange.value.map((dateString) => {
return convertDateStringToSeconds(dateString)
})
+ try {
+ window.heap.track('Time Changed Event', {
+ startTime: dateRange.value[0],
+ endTime: dateRange.value[1]
+ })
+ } catch (e) {
+ console.warn(
+ 'Heap is not available or an error occurred while tracking the Time Changed Event.',
+ e
+ )
+ }
+
filterDatasetsToTimeRange()
}
diff --git a/frontend/src/views/AboutView.vue b/frontend/src/views/AboutView.vue
index 43155eed..71e3dd60 100644
--- a/frontend/src/views/AboutView.vue
+++ b/frontend/src/views/AboutView.vue
@@ -28,6 +28,11 @@ const tocItems = ref([]) // toc (table of contents) items
// fetch and process the markdown content
onMounted(async () => {
+ try {
+ window.heap.track('About Page Opened')
+ } catch (e) {
+ console.warn('Heap is not available or an error occurred while loading the page.', e)
+ }
const response = await fetch(about_page_url)
const markdownText = await response.text()
diff --git a/frontend/src/views/ChartsView.vue b/frontend/src/views/ChartsView.vue
index ddbb3e0a..bc8d95af 100644
--- a/frontend/src/views/ChartsView.vue
+++ b/frontend/src/views/ChartsView.vue
@@ -1,7 +1,14 @@
-
+
Reach Averaged
@@ -56,6 +63,18 @@ import { queryHydroCron, getNodeDataForReach } from '../_helpers/hydroCron'
import { ChartJS } from '@/_helpers/charts/charts' // eslint-disable-line
const props = defineProps({ reachId: String })
+
+const trackTabSelection = (newTab) => {
+ try {
+ if (newTab === 'timeseries') {
+ window.heap.track('Reach Average Selected')
+ } else if (newTab === 'distance') {
+ window.heap.track('Node Profile Selected')
+ }
+ } catch (e) {
+ console.warn('Heap is not available or an error occurred while tracking the event.', e)
+ }
+}
const router = useRouter()
const chartStore = useChartsStore()
diff --git a/frontend/src/views/DistanceCharts.vue b/frontend/src/views/DistanceCharts.vue
index 7d8d2c39..9d345446 100644
--- a/frontend/src/views/DistanceCharts.vue
+++ b/frontend/src/views/DistanceCharts.vue
@@ -4,7 +4,12 @@
Variables
-
+
{{ plt.name }}
@@ -72,6 +77,17 @@ const resetData = () => {
activeNodeChart.value.chart.data.datasets = nodeChartData.value.datasets
activeNodeChart.value.chart.update()
}
+
+const trackVariableSelection = (selectedVariable) => {
+ try {
+ window.heap.track('Variable Selected', {
+ variableName: selectedVariable.name,
+ variableAbbreviation: selectedVariable.abbreviation
+ })
+ } catch (e) {
+ console.warn('Heap is not available or an error occurred while tracking the event.', e)
+ }
+}