@abi-software/map-side-bar 2.3.1 → 2.4.0-isan-0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,18 +34,30 @@
34
34
  ref="searchHistory"
35
35
  @search="searchHistorySearch"
36
36
  ></SearchHistory>
37
+ pmr hits: {{ pmrNumberOfHits }}
37
38
  <div class="content scrollbar" v-loading="loadingCards" ref="content">
38
39
  <div class="error-feedback" v-if="results.length === 0 && !loadingCards">
39
40
  No results found - Please change your search / filter criteria.
40
41
  </div>
41
- <div v-for="result in results" :key="result.doi" class="step-item">
42
+ <div v-for="(result, i) in results" :key="result.doi || i" class="step-item">
42
43
  <DatasetCard
44
+ v-if="result.dataSource === 'SPARC'"
43
45
  class="dataset-card"
44
46
  :entry="result"
45
47
  :envVars="envVars"
46
48
  @mouseenter="hoverChanged(result)"
47
49
  @mouseleave="hoverChanged(undefined)"
48
- />
50
+ ></DatasetCard>
51
+ <PMRDatasetCard
52
+ v-else-if="result.dataSource === 'PMR'"
53
+ class="dataset-card"
54
+ :entry="result"
55
+ :envVars="envVars"
56
+ @flatmap-clicked="onFlatmapClicked"
57
+ @simulation-clicked="onSimulationClicked"
58
+ @mouseenter="hoverChanged(result)"
59
+ @mouseleave="hoverChanged(undefined)"
60
+ ></PMRDatasetCard>
49
61
  </div>
50
62
  <el-pagination
51
63
  class="pagination"
@@ -73,11 +85,17 @@ import {
73
85
  } from 'element-plus'
74
86
  import SearchFilters from './SearchFilters.vue'
75
87
  import SearchHistory from './SearchHistory.vue'
76
- import DatasetCard from './DatasetCard.vue'
77
88
  import EventBus from './EventBus.js'
78
89
 
90
+ import DatasetCard from "./DatasetCard.vue";
91
+ import PMRDatasetCard from "./PMRDatasetCard.vue";
92
+
79
93
  import { AlgoliaClient } from '../algolia/algolia.js'
80
94
  import { getFilters, facetPropPathMapping } from '../algolia/utils.js'
95
+ import FlatmapQueries from '../flatmapQueries/flatmapQueries.js'
96
+ import mixedPageCalculation from '../mixins/mixedPageCalculation.vue'
97
+
98
+ const RatioOfPMRResults = 0.2; // Ratio of PMR results to Sparc results
81
99
 
82
100
  // handleErrors: A custom fetch error handler to recieve messages from the server
83
101
  // even when an error is found
@@ -97,21 +115,26 @@ var initial_state = {
97
115
  searchInput: '',
98
116
  lastSearch: '',
99
117
  results: [],
100
- numberOfHits: 0,
118
+ pmrNumberOfHits: 0,
119
+ sparcNumberOfHits: 0,
101
120
  filter: [],
102
121
  loadingCards: false,
103
122
  numberPerPage: 10,
104
123
  page: 1,
105
- pageModel: 1,
106
- start: 0,
124
+ pmrResultsOnlyFlag: false,
107
125
  hasSearched: false,
108
126
  contextCardEnabled: false,
109
- }
127
+ pmrResults: [],
128
+ RatioOfPMRResults: RatioOfPMRResults,
129
+ };
130
+
131
+
110
132
 
111
133
  export default {
112
134
  components: {
113
135
  SearchFilters,
114
136
  DatasetCard,
137
+ PMRDatasetCard,
115
138
  SearchHistory,
116
139
  Button,
117
140
  Card,
@@ -121,6 +144,7 @@ export default {
121
144
  Pagination
122
145
  },
123
146
  name: 'SideBarContent',
147
+ mixins: [mixedPageCalculation],
124
148
  props: {
125
149
  visible: {
126
150
  type: Boolean,
@@ -158,21 +182,67 @@ export default {
158
182
  filterFacets: this.filter,
159
183
  }
160
184
  },
185
+ // npp_SPARC: Number per page for SPARC datasets
186
+ npp_SPARC: function () {
187
+ return Math.round(this.numberPerPage * (1 - RatioOfPMRResults))
188
+ },
189
+ // npp_PMR: Number per page for PMR datasets
190
+ npp_PMR: function () {
191
+ return Math.round(this.numberPerPage * RatioOfPMRResults)
192
+ },
193
+ numberOfHits: function () {
194
+ return this.sparcNumberOfHits + this.pmrNumberOfHits
195
+ },
196
+
161
197
  },
162
198
  methods: {
163
199
  hoverChanged: function (data) {
164
200
  this.$emit('hover-changed', data)
165
201
  },
202
+ onFlatmapClicked: function (data) {
203
+ this.$emit('flatmap-clicked', data);
204
+ },
205
+ onSimulationClicked: function (payload) {
206
+ this.$emit('simulation-clicked', payload)
207
+ },
208
+ // resetSearch: Resets the results, and page, and variable results ratio
209
+ // Does not: reset filters, search input, or search history
166
210
  resetSearch: function () {
167
- this.numberOfHits = 0
211
+ this.pmrNumberOfHits = 0
212
+ this.sparcNumberOfHits = 0
213
+ this.page = 1
214
+ this.calculateVariableRatio()
168
215
  this.discoverIds = []
169
216
  this._dois = []
170
217
  this.results = []
171
218
  this.loadingCards = false
172
219
  },
173
- openSearch: function (filter, search = '') {
220
+ // openSearch: Resets the results, populates dataset cards and filters. Will use Algolia and SciCrunch data uness pmr mode is set
221
+ openSearch: function(filter, search = '', resetSearch = true) {
222
+ if (resetSearch) {
223
+ this.resetSearch();
224
+ this.openAlgoliaSearch(filter, search);
225
+ } else {
226
+ this.searchAlgolia(filter, search);
227
+ }
228
+ this.openPMRSearch(filter, search)
229
+ },
230
+
231
+ // openPMRSearch: Resets the results, populates dataset cards and filters with PMR data.
232
+ openPMRSearch: function (filter, search = '') {
233
+ this.flatmapQueries.updateOffset(this.calculatePMROffest())
234
+ this.flatmapQueries.updateLimit(this.PMRLimit(this.pmrResultsOnlyFlag))
235
+ this.flatmapQueries.pmrSearch(filter, search).then((data) => {
236
+ data.forEach((result) => {
237
+ this.results.push(result)
238
+ })
239
+ this.pmrNumberOfHits = this.flatmapQueries.numberOfHits
240
+ })
241
+ },
242
+
243
+ // openAlgoliaSearch: Resets the results, populates dataset cards and filters with Algloia and SciCrunch data.
244
+ openAlgoliaSearch: function (filter, search = '') {
174
245
  this.searchInput = search
175
- this.resetPageNavigation()
176
246
  //Proceed normally if cascader is ready
177
247
  if (this.cascaderIsReady) {
178
248
  this.filter =
@@ -203,7 +273,7 @@ export default {
203
273
  },
204
274
  addFilter: function (filter) {
205
275
  if (this.cascaderIsReady) {
206
- this.resetPageNavigation()
276
+ this.resetSearch()
207
277
  if (filter) {
208
278
  if (this.$refs.filtersRef.addFilter(filter))
209
279
  this.$refs.filtersRef.initiateSearch()
@@ -222,33 +292,53 @@ export default {
222
292
  },
223
293
  clearSearchClicked: function () {
224
294
  this.searchInput = ''
225
- this.resetPageNavigation()
226
- this.searchAlgolia(this.filters, this.searchInput)
295
+ this.resetSearch()
296
+ this.openSearch(this.filter, this.searchInput)
227
297
  this.$refs.searchHistory.selectValue = 'Full search history'
228
298
  },
229
299
  searchEvent: function (event = false) {
230
300
  if (event.keyCode === 13 || event instanceof MouseEvent) {
231
- this.resetPageNavigation()
232
- this.searchAlgolia(this.filters, this.searchInput)
301
+ this.openSearch(this.filter, this.searchInput)
233
302
  this.$refs.searchHistory.selectValue = 'Full search history'
234
303
  this.$refs.searchHistory.addSearchToHistory(
235
- this.filters,
304
+ this.filter,
236
305
  this.searchInput
237
306
  )
238
307
  }
239
308
  },
309
+ updatePMROnlyFlag: function (filters) {
310
+ const pmrSearchObject = filters.find((tmp) => tmp.facet === 'PMR');
311
+ if (pmrSearchObject) {
312
+ this.pmrResultsOnlyFlag = true
313
+ } else {
314
+ this.pmrResultsOnlyFlag = false
315
+ }
316
+ },
240
317
  filterUpdate: function (filters) {
241
- this.filters = [...filters]
242
- this.resetPageNavigation()
318
+ this.filter = [...filters]
319
+
320
+ // Check if PMR is in the filters
321
+ this.updatePMROnlyFlag(filters)
322
+
323
+ // Note that we cannot use the openSearch function as that modifies filters
324
+ this.resetSearch()
243
325
  this.searchAlgolia(filters, this.searchInput)
326
+ this.openPMRSearch(filters, this.searchInput)
244
327
  this.$emit('search-changed', {
245
328
  value: filters,
246
329
  type: 'filter-update',
247
330
  })
248
331
  },
249
332
  searchAlgolia(filters, query = '') {
333
+
334
+ // Remove loading if we dont expect any results
335
+ if (this.SPARCLimit() === 0) {
336
+ this.loadingCards = false
337
+ return
338
+ }
339
+
250
340
  // Algolia search
251
-
341
+
252
342
  this.loadingCards = true
253
343
  this.algoliaClient
254
344
  .anatomyInSearch(getFilters(filters), query)
@@ -258,12 +348,17 @@ export default {
258
348
  EventBus.emit('number-of-datasets-for-anatomies', r.forScaffold)
259
349
  })
260
350
  this.algoliaClient
261
- .search(getFilters(filters), query, this.numberPerPage, this.page)
351
+ .search(getFilters(filters), query, this.calculateSPARCOffest(), this.SPARCLimit(this.pmrResultsOnlyFlag) )
262
352
  .then((searchData) => {
263
- this.numberOfHits = searchData.total
353
+ this.sparcNumberOfHits = searchData.total
264
354
  this.discoverIds = searchData.discoverIds
265
355
  this._dois = searchData.dois
266
- this.results = searchData.items
356
+ searchData.items.forEach((item) => {
357
+ item.detailsReady = false
358
+ this.results.push(item)
359
+ })
360
+ // add the items to the results
361
+ this.results.concat(searchData.items)
267
362
  this.loadingCards = false
268
363
  this.scrollToTop()
269
364
  this.$emit('search-changed', {
@@ -285,14 +380,10 @@ export default {
285
380
  this.pageChange(1)
286
381
  },
287
382
  pageChange: function (page) {
288
- this.start = (page - 1) * this.numberPerPage
289
383
  this.page = page
290
- this.searchAlgolia(
291
- this.filters,
292
- this.searchInput,
293
- this.numberPerPage,
294
- this.page
295
- )
384
+ this.results = []
385
+ this.calculateVariableRatio()
386
+ this.openSearch(this.filter, this.searchInput, false)
296
387
  },
297
388
  handleMissingData: function (doi) {
298
389
  let i = this.results.findIndex((res) => res.doi === doi)
@@ -334,7 +425,6 @@ export default {
334
425
  }
335
426
  },
336
427
  resetPageNavigation: function () {
337
- this.start = 0
338
428
  this.page = 1
339
429
  },
340
430
  resultsProcessing: function (data) {
@@ -448,7 +538,13 @@ export default {
448
538
  this.envVars.PENNSIEVE_API_LOCATION
449
539
  )
450
540
  this.algoliaClient.initIndex(this.envVars.ALGOLIA_INDEX)
451
- this.openSearch(this.filter, this.searchInput)
541
+
542
+ // initialise flatmap queries
543
+ this.flatmapQueries = new FlatmapQueries()
544
+ this.flatmapQueries.initialise(this.envVars.FLATMAP_API_LOCATION)
545
+
546
+ // open search
547
+ this.openSearch(this.filter, this.searchInput, this.mode )
452
548
  },
453
549
  created: function () {
454
550
  //Create non-reactive local variables
@@ -487,6 +583,17 @@ export default {
487
583
  display: flex;
488
584
  }
489
585
 
586
+ .data-type-select {
587
+ width: 90px;
588
+ margin-left: 10px;
589
+ }
590
+
591
+ .button {
592
+ background-color: $app-primary-color;
593
+ border: $app-primary-color;
594
+ color: white;
595
+ }
596
+
490
597
  .step-item {
491
598
  font-size: 14px;
492
599
  margin-bottom: 18px;
@@ -27,6 +27,7 @@ declare module 'vue' {
27
27
  ElTag: typeof import('element-plus/es')['ElTag']
28
28
  ExternalResourceCard: typeof import('./components/ExternalResourceCard.vue')['default']
29
29
  ImageGallery: typeof import('./components/ImageGallery.vue')['default']
30
+ PMRDatasetCard: typeof import('./components/PMRDatasetCard.vue')['default']
30
31
  SearchFilters: typeof import('./components/SearchFilters.vue')['default']
31
32
  SearchHistory: typeof import('./components/SearchHistory.vue')['default']
32
33
  SideBar: typeof import('./components/SideBar.vue')['default']
@@ -0,0 +1,221 @@
1
+ function transformKeyValueArrayToObject(data) {
2
+ try {
3
+ let result = data.values.map(valueArray =>
4
+ data.keys.reduce((acc, key, index) => {
5
+ acc[key] = valueArray[index];
6
+ return acc;
7
+ }, {})
8
+ )
9
+ return result
10
+ } catch (error) {
11
+ console.error(`Error occured during conversion of Key Value Array to Object: ${error}`)
12
+ return {}
13
+ }
14
+
15
+ }
16
+
17
+ // remove duplicates by stringifying the objects
18
+ const removeDuplicates = function (arrayOfAnything) {
19
+ if (!arrayOfAnything) return []
20
+ return [...new Set(arrayOfAnything.map((e) => JSON.stringify(e)))].map((e) =>
21
+ JSON.parse(e)
22
+ )
23
+ }
24
+
25
+
26
+ let FlatmapQueries = function () {
27
+ this.initialise = function (flatmapApi) {
28
+ this.flatmapApi = flatmapApi
29
+ this.features = []
30
+ this.limit = 10
31
+ this.offset = 0
32
+ this.numberOfHits = 0
33
+ this.sqlPreOffset = ''
34
+ this.lookup = {}
35
+ this.createLookup()
36
+ }
37
+
38
+ this.updateOffset = function (offset) {
39
+ this.offset = offset
40
+ }
41
+ this.updateLimit = function (limit) {
42
+ this.limit = limit
43
+ }
44
+
45
+ this.offsetText = function () {
46
+ return 'limit ' + this.limit + ' offset ' + this.offset
47
+ }
48
+
49
+ this.createTermSQL = function (terms) {
50
+ let sql = ''
51
+ let validFilter = false
52
+
53
+
54
+ if (terms && terms.length > 0) {
55
+ sql += 'and '
56
+ terms.forEach((t, i) => {
57
+ if (i == 0) {
58
+ sql += '('
59
+ }
60
+ if (t !== '') {
61
+ sql += `m.term='${t}'`
62
+ validFilter = true
63
+ if (i < terms.length - 1) {
64
+ sql += ' or '
65
+ }
66
+ }
67
+ if (i == terms.length - 1) {
68
+ sql += ') '
69
+ }
70
+ })
71
+ }
72
+ if (!validFilter) {
73
+ sql = ''
74
+ }
75
+ return sql
76
+ }
77
+
78
+
79
+ this.pmrSQL = function (terms=[], search='') {
80
+ let sql = 'select distinct m.term, m.exposure, m.score, m.workspace, d.metadata from pmr_text '
81
+ sql += 'as t left join pmr_metadata as d on t.entity=d.entity left join pmr_models as m on m.exposure=t.entity '
82
+ sql += 'where d.metadata is not null '
83
+
84
+ // add filters for the terms
85
+ const termsSql = this.createTermSQL(terms)
86
+ sql += termsSql
87
+
88
+ // Add the text search
89
+ if (search && search !== '') {
90
+ sql += `and (t.pmr_text match '${search}')`
91
+ }
92
+
93
+ // Add exposure and score filters if we aren't text searching
94
+ if (!search || search === '') {
95
+ sql += 'and m.exposure is not null and score > 0.69'
96
+ }
97
+
98
+ // group by exposure
99
+ sql += ' group by m.exposure'
100
+
101
+ this.sqlPreOffset = sql
102
+
103
+ // add the limit and offset for pagination
104
+ sql += ' ' + this.offsetText() + ';'
105
+
106
+ console.log(sql)
107
+ return sql
108
+ }
109
+
110
+ this.convertTermsToIds = function (terms) {
111
+ return terms.map(t => this.lookUpId(t))
112
+ }
113
+
114
+ this.labelSQL = function (){
115
+ return "select entity, label from labels"
116
+ }
117
+
118
+ this.countSQL = function (sql) {
119
+ sql = `select count(*) from (${sql})`
120
+ return sql
121
+ }
122
+
123
+
124
+ this.flatmapQuery = function (sql) {
125
+ const data = { sql: sql }
126
+ return fetch(`${this.flatmapApi}knowledge/query/`, {
127
+ method: 'POST',
128
+ headers: {
129
+ 'Content-Type': 'application/json',
130
+ },
131
+ body: JSON.stringify(data),
132
+ })
133
+ .then((response) => response.json())
134
+ .catch((error) => {
135
+ console.error('Error:', error)
136
+ })
137
+ }
138
+
139
+ this.processFilters = function (filters) {
140
+ let featureLabels = []
141
+ filters.forEach((f) => {
142
+ if (f.label !== 'Show all' && f.label !== 'PMR')
143
+ featureLabels.push(f.facet)
144
+ })
145
+ return featureLabels
146
+ }
147
+
148
+
149
+
150
+ this.pmrSearch = function (filters=[], search='') {
151
+ let features = this.processFilters(filters)
152
+ let featureIds = this.convertTermsToIds(features)
153
+ return new Promise((resolve, reject) => {
154
+ this.flatmapQuery(this.pmrSQL(featureIds, search))
155
+ .then(data => {
156
+ const pd = this.processPMRData(data, featureIds)
157
+ this.setAvailableFeatures(pd)
158
+
159
+ // get the number of hits for pagination
160
+ this.flatmapQuery(this.countSQL(this.sqlPreOffset)).then(data => {
161
+ this.numberOfHits = data.values[0][0]
162
+ resolve(pd);
163
+ })
164
+ })
165
+ .catch(reject);
166
+ });
167
+ }
168
+
169
+ // setAvailableFeatures returns the available features in the flatmap for filtering
170
+ // pd is the processed data from the flatmap
171
+ this.setAvailableFeatures = function (pd) {
172
+ pd.forEach((d) => {
173
+ Object.keys(d).forEach((key) => {
174
+ if (!this.features.includes(key)) {
175
+ this.features.push(key)
176
+ }
177
+ })
178
+ })
179
+ }
180
+
181
+
182
+ this.processPMRData = function (data, featureIds=[]) {
183
+ // Convert the flatmap data into an array of objects
184
+ let dataObj = transformKeyValueArrayToObject(data)
185
+
186
+ // Only use the results with metadata
187
+ let metadataResults = dataObj.filter(d => d.metadata)
188
+ let metadataOnly = metadataResults.map(d => {
189
+ let md = JSON.parse(d.metadata)
190
+ md.dataSource = 'PMR'
191
+ return md
192
+ })
193
+
194
+ // If there are featureIds, filter the results
195
+ if (featureIds.length > 0) {
196
+ metadataOnly = metadataOnly.filter(d => featureIds.includes(d.term))
197
+ }
198
+
199
+ // Remove duplicates
200
+ let uniqueResults = removeDuplicates(metadataOnly)
201
+ return uniqueResults
202
+ }
203
+
204
+ this.createLookup = function () {
205
+ this.flatmapQuery(this.labelSQL())
206
+ .then(data => {
207
+ data.values.forEach(d => {
208
+ if (d[1] && (typeof d[1] === 'string' || d[1] instanceof String)) {
209
+ this.lookup[d[1].toLowerCase()] = d[0]
210
+ }
211
+ })
212
+ })
213
+ }
214
+
215
+ this.lookUpId = function (label) {
216
+ return this.lookup[label.toLowerCase()]
217
+ }
218
+
219
+ }
220
+
221
+ export default FlatmapQueries
@@ -0,0 +1,102 @@
1
+ <script>
2
+ // The functions below are needed because the number of results shown on the page is dependent what is available from each index.
3
+ // We fix this by calcuting how many results we have shown before the requested page and then calculating the offset based on that.
4
+
5
+ // Note that this.RatioOfPMRResults is a number that determines how many PMR results are shown compared to SPARC results. It is grabbed from a constant in
6
+ // SidebarContent.vue.
7
+
8
+ export default {
9
+ methods: {
10
+
11
+ // Calculate Variable Ratio is used as a number to determine how the ratio of PMR results to SPARC results
12
+ // will be shown on the page. 1 means only PMR results, 0 means only SPARC results.
13
+ calculateVariableRatio: function () {
14
+ if (this.page === 1) {
15
+ this.variableRatio = this.RatioOfPMRResults
16
+
17
+ // Check if we have run out of Sparc results
18
+ } else if( this.npp_SPARC * (this.page -1) >= this.sparcNumberOfHits) {
19
+ this.variableRatio = 1
20
+
21
+ // Check if we have run out of PMR results
22
+ } else if(this.npp_PMR * (this.page - 1) >= this.pmrNumberOfHits) {
23
+ this.variableRatio = 0
24
+ } else {
25
+
26
+ // Set the ratio to the same as the previous page if both indeces have results
27
+ this.variableRatio = this.RatioOfPMRResults
28
+ }
29
+ },
30
+
31
+ // calculatePMROffest is used to calculate how many PMR results we have shown before the requested page
32
+ calculatePMROffest: function() {
33
+
34
+ // If variable ratio has not changed, we have not run out of results.
35
+ // we can use the the number per page PMR to calculate the offset
36
+ if (this.variableRatio === this.RatioOfPMRResults) {
37
+ return (this.page-1)*this.npp_PMR
38
+
39
+ // If we have run out of SPARC results, we need to calculate how many PMR results we have shown before the requested page
40
+ } else if (this.variableRatio === 1) {
41
+
42
+ // calculate how many results we showed before the requested page
43
+ // We want our offset to be the number of PMR results shown before the requested page
44
+ // This can be though of as numberOfPMRResultsShownInMixed + numberOfPMRResultsShownInPMROnly = offset
45
+ let pageWhereSPARCResultsRanOut = Math.ceil(this.sparcNumberOfHits / this.npp_SPARC)
46
+ let numberOfPMRResultsShownInMixed = this.npp_PMR * pageWhereSPARCResultsRanOut
47
+ let numberOfPMRResultsShownInPMROnly = (this.page - 1 - pageWhereSPARCResultsRanOut) * this.numberPerPage
48
+ return numberOfPMRResultsShownInMixed + numberOfPMRResultsShownInPMROnly
49
+ }
50
+ },
51
+
52
+ // calculateSPARCOffest is used to calculate how many SPARC results we have shown before the requested page. See above for details
53
+ calculateSPARCOffest: function() {
54
+ if(this.variableRatio === this.RatioOfPMRResults) {
55
+ return (this.page-1)*this.npp_SPARC
56
+ } else if (this.variableRatio === 0) {
57
+
58
+ // calculate how many results we showed before the requested page
59
+ let pageWherePMRResultsRanOut = Math.ceil(this.pmrNumberOfHits / this.npp_PMR)
60
+ let numberOfSPARCResultsShownInMixed = this.npp_SPARC * pageWherePMRResultsRanOut
61
+ let numberOfSPARCResultsShownInSPARCOnly = (this.page - 1 - pageWherePMRResultsRanOut) * this.numberPerPage
62
+ let offset = numberOfSPARCResultsShownInMixed + numberOfSPARCResultsShownInSPARCOnly
63
+ return offset
64
+ }
65
+ },
66
+
67
+ // PMRLimit is used to calculate how many PMR results we can show on the page.
68
+ PMRLimit: function(pmrResultsOnlyFlag=false) {
69
+ // If we only want PMR results, return the number per page
70
+ if (pmrResultsOnlyFlag) {
71
+ return this.numberPerPage
72
+ }
73
+ // If the variable ratio is the same as the ratio of PMR results, return the number per page set for PMR
74
+ if (this.variableRatio === this.RatioOfPMRResults) {
75
+ return this.npp_PMR
76
+
77
+ // if we have run out of sparc results, we want to show pmr results equal to the total number of results per page
78
+ } else if (this.variableRatio === 1) {
79
+ return this.numberPerPage
80
+
81
+ // if we have run out of pmr results, we want to show 0 pmr results
82
+ } else if (this.variableRatio === 0) {
83
+ return 0
84
+ }
85
+ },
86
+ SPARCLimit: function(pmrResultsOnlyFlag=false) {
87
+ if(pmrResultsOnlyFlag) {
88
+ return 0
89
+ }
90
+ if (this.variableRatio === this.RatioOfPMRResults) {
91
+ return this.npp_SPARC
92
+ } else if (this.variableRatio === 0) {
93
+ return this.numberPerPage
94
+ } else if (this.variableRatio === 1) {
95
+ return 0
96
+ }
97
+ },
98
+ }
99
+ };
100
+ </script>
101
+
102
+