@abi-software/map-side-bar 2.6.2 → 2.6.3-acupoints.1

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abi-software/map-side-bar",
3
- "version": "2.6.2",
3
+ "version": "2.6.3-acupoints.1",
4
4
  "files": [
5
5
  "dist/*",
6
6
  "src/*",
@@ -39,11 +39,12 @@
39
39
  },
40
40
  "dependencies": {
41
41
  "@abi-software/gallery": "^1.1.2",
42
- "@abi-software/map-utilities": "^1.3.1",
42
+ "@abi-software/map-utilities": "^1.3.2",
43
43
  "@abi-software/svg-sprite": "^1.0.1",
44
44
  "@element-plus/icons-vue": "^2.3.1",
45
45
  "algoliasearch": "^4.10.5",
46
46
  "element-plus": "2.8.4",
47
+ "js-base64": "^3.7.7",
47
48
  "marked": "^4.1.1",
48
49
  "mitt": "^3.0.1",
49
50
  "unplugin-vue-components": "^0.26.0",
package/src/App.vue CHANGED
@@ -16,6 +16,7 @@
16
16
  <el-button @click="keywordSearch">keyword search</el-button>
17
17
  <el-button @click="getFacets">Get facets</el-button>
18
18
  <el-button @click="toggleCreateData">Create Data/Annotation</el-button>
19
+ <el-button @click="searchAcupoints">Search Acupoints</el-button>
19
20
  </div>
20
21
  <SideBar
21
22
  :envVars="envVars"
@@ -25,6 +26,7 @@
25
26
  :tabs="tabs"
26
27
  :activeTabId="activeId"
27
28
  :annotationEntry="annotationEntry"
29
+ :acupointsInfoList="acupoints"
28
30
  :createData="createData"
29
31
  :connectivityInfo="connectivityInput"
30
32
  @tabClicked="tabClicked"
@@ -32,6 +34,8 @@
32
34
  @hover-changed="hoverChanged($event)"
33
35
  @connectivity-component-click="onConnectivityComponentClick"
34
36
  @actionClick="action"
37
+ @acupoints-clicked="onAcupointsClicked"
38
+ @acupoints-hovered="onAcupointsHovered"
35
39
  />
36
40
  </div>
37
41
  </template>
@@ -39,12 +43,14 @@
39
43
  <script>
40
44
  /* eslint-disable no-alert, no-console */
41
45
  // optionally import default styles
46
+ import { acupointEntries } from './acupoints.js'
42
47
  import SideBar from './components/SideBar.vue'
43
48
  import EventBus from './components/EventBus.js'
44
49
  import exampleConnectivityInput from './exampleConnectivityInput.js'
45
50
 
46
51
  const capitalise = (str) => str.charAt(0).toUpperCase() + str.slice(1);
47
52
 
53
+
48
54
  // let testContext = {
49
55
  // "description": "3D digital tracings of the enteric plexus obtained from seven subjects (M11, M16, M162, M163, M164, M168) are mapped randomly on mouse proximal colon. The data depicts individual neural wiring patterns in enteric microcircuits, and revealed both neuron and fiber units wired in a complex organization.",
50
56
  // "heading": "Digital tracings of enteric plexus",
@@ -105,6 +111,7 @@ export default {
105
111
  },
106
112
  data: function () {
107
113
  return {
114
+ acupoints: acupointEntries,
108
115
  annotationEntry: {
109
116
  featureId :"epicardium",
110
117
  resourceId: "https://mapcore-bucket1.s3-us-west-2.amazonaws.com/others/29_Jan_2020/heartICN_metadata.json","resource":"https://mapcore-bucket1.s3-us-west-2.amazonaws.com/others/29_Jan_2020/heartICN_metadata.json"
@@ -114,6 +121,7 @@ export default {
114
121
  { title: 'Flatmap', id: 1, type: 'search'},
115
122
  { title: 'Connectivity', id: 2, type: 'connectivity' },
116
123
  { title: 'Annotation', id: 3, type: 'annotation' },
124
+ {title: 'Acupoints', id: 4, type: 'acupoints' },
117
125
  ],
118
126
  sideBarVisibility: true,
119
127
  envVars: {
@@ -140,6 +148,12 @@ export default {
140
148
  }
141
149
  },
142
150
  methods: {
151
+ onAcupointsClicked: function (data) {
152
+ console.log("acupoints-clicked", data)
153
+ },
154
+ onAcupointsHovered: function (data) {
155
+ console.log("acupoints-hovered", data)
156
+ },
143
157
  hoverChanged: function (data) {
144
158
  console.log('hoverChanged', data)
145
159
  },
@@ -171,6 +185,9 @@ export default {
171
185
  'http://purl.obolibrary.org/obo/UBERON_0001103'
172
186
  )
173
187
  },
188
+ searchAcupoints: function() {
189
+ this.$refs.sideBar.openAcupointsSearch("GB 6")
190
+ },
174
191
  singleFacets: function () {
175
192
  this.$refs.sideBar.addFilter({
176
193
  facet: 'Cardiovascular system',
@@ -320,4 +337,4 @@ body {
320
337
  align-items: center;
321
338
  gap: 0.5rem;
322
339
  }
323
- </style>
340
+ </style>./acupoints.js
@@ -0,0 +1,32 @@
1
+ export const acupointEntries = {
2
+ "LU 1": {
3
+ "Acupoint": "LU 1",
4
+ "Label": "LU 1",
5
+ "Synonym": "Test data",
6
+ "UMLS CUI": "",
7
+ "Meridian": "LTest data",
8
+ "Chinese Name": "Zhongfu",
9
+ "English Name": "Central Treasury",
10
+ "Location": " z zxczc.",
11
+ "Reference": "Test data",
12
+ "Indications": "Test data",
13
+ "Acupuncture Method": "Test data",
14
+ "Vasculature": "Test data",
15
+ "Innervation": "Test data"
16
+ },
17
+ "LU 2": {
18
+ "Acupoint": "LU 2",
19
+ "Label": "LU 2",
20
+ "Synonym": "Test data",
21
+ "UMLS CUI": "",
22
+ "Meridian": "LTest data",
23
+ "Chinese Name": "Yunmen",
24
+ "English Name": "Cloud Gate",
25
+ "Location": " z zxczc.",
26
+ "Reference": "Test data",
27
+ "Indications": "Test data",
28
+ "Acupuncture Method": "Test data",
29
+ "Vasculature": "Test data",
30
+ "Innervation": "Test data"
31
+ }
32
+ }
@@ -40,6 +40,12 @@ export const facetPropPathMapping = [
40
40
  facetPropPath: 'attributes.subject.ageCategory.value',
41
41
  facetSubpropPath: 'attributes.subject.ageCategory.subcategory.name'
42
42
  },
43
+ {
44
+ label: 'Funding Program',
45
+ id: 'pennsieve.organization',
46
+ facetPropPath: 'pennsieve.organization.name',
47
+ facetSubpropPath: 'pennsieve.organization.subcategory.name'
48
+ },
43
49
  ]
44
50
 
45
51
  // Same as above, but these show on the sidebar filters
@@ -48,6 +54,7 @@ export const shownFilters = {
48
54
  'organisms.primary.species.name' : 'Species',
49
55
  'attributes.subject.sex.value' : 'Sex',
50
56
  'attributes.subject.ageCategory.value' : 'Age Categories',
57
+ 'pennsieve.organization.name' : 'Funding Program',
51
58
  'item.types.name' : 'Data type',
52
59
  }
53
60
 
@@ -60,9 +67,9 @@ export function getFilters(selectedFacetArray=undefined) {
60
67
  return 'NOT item.published.status:embargo'
61
68
  }
62
69
 
63
- // Switch the 'term' attribute to 'label' if 'label' does not exist
70
+ // Switch the 'term' attribute to 'label' if 'label' does not exist
64
71
  selectedFacetArray.forEach(f=>f.label=f.facet)
65
-
72
+
66
73
 
67
74
  let facets = removeShowAllFacets(selectedFacetArray)
68
75
 
@@ -0,0 +1,169 @@
1
+ <template>
2
+ <div class="dataset-card-container" ref="container">
3
+ <div class="dataset-card" ref="card">
4
+ <div class="seperator-path"></div>
5
+ <div class="card"
6
+ @click="cardClicked(entry)"
7
+ @mouseover="cardHovered(entry)"
8
+ @mouseleave="cardHovered(undefined)"
9
+ >
10
+ <div class="card-right">
11
+ <div class="title">Acupoint: {{ entry.Acupoint }}</div>
12
+ <template v-for="field in displayFields" :key="field">
13
+ <div class="details" v-if="entry[field]">
14
+ <strong>{{ field }}:</strong> {{ entry[field] }}
15
+ </div>
16
+ </template>
17
+ </div>
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script>
24
+ import EventBus from './EventBus.js'
25
+ /* eslint-disable no-alert, no-console */
26
+
27
+ export default {
28
+ data() {
29
+ return {
30
+ displayFields: [
31
+ "Synonym",
32
+ "Chinese Name",
33
+ "English Name",
34
+ "Reference",
35
+ "Indications",
36
+ "Acupuncture Method",
37
+ "Vasculature",
38
+ "Innervation"
39
+ ]
40
+ }
41
+ },
42
+ name: 'AcupointsCard',
43
+ props: {
44
+ /**
45
+ * Object containing information for
46
+ * the required viewing.
47
+ */
48
+ entry: {
49
+ type: Object,
50
+ default: () => {},
51
+ },
52
+ },
53
+ methods: {
54
+ cardClicked: function (data) {
55
+ EventBus.emit('acupoints-clicked', data);
56
+ },
57
+ cardHovered: function (data) {
58
+ EventBus.emit('acupoints-hovered', data);
59
+ },
60
+ }
61
+ }
62
+ </script>
63
+
64
+ <style lang="scss" scoped>
65
+ .dataset-card {
66
+ padding-left: 5px;
67
+ padding-right: 5px;
68
+ position: relative;
69
+ min-height: 17rem;
70
+ }
71
+
72
+ .title {
73
+ padding-bottom: 0.75rem;
74
+ font-family: Asap;
75
+ font-size: 14px;
76
+ font-weight: bold;
77
+ font-stretch: normal;
78
+ font-style: normal;
79
+ line-height: 1.5;
80
+ letter-spacing: 1.05px;
81
+ color: #484848;
82
+ cursor: pointer;
83
+ }
84
+ .card {
85
+ padding-top: 18px;
86
+ position: relative;
87
+ display: flex;
88
+ }
89
+
90
+ .card-left {
91
+ flex: 1;
92
+ }
93
+
94
+ .card-right {
95
+ flex: 1.3;
96
+ padding-left: 6px;
97
+ }
98
+
99
+ .button {
100
+ z-index: 10;
101
+ font-family: Asap;
102
+ font-size: 14px;
103
+ font-weight: normal;
104
+ font-stretch: normal;
105
+ font-style: normal;
106
+ line-height: normal;
107
+ letter-spacing: normal;
108
+ background-color: $app-primary-color;
109
+ border: $app-primary-color;
110
+ color: white;
111
+ cursor: pointer;
112
+ margin-top: 8px;
113
+ }
114
+
115
+ .button:hover {
116
+ background-color: $app-primary-color;
117
+ color: white;
118
+ }
119
+
120
+ .banner-img {
121
+ width: 128px;
122
+ height: 128px;
123
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.25);
124
+ background-color: #ffffff;
125
+ cursor: pointer;
126
+ }
127
+ .details {
128
+ font-family: Asap;
129
+ font-size: 14px;
130
+ font-weight: normal;
131
+ font-stretch: normal;
132
+ font-style: normal;
133
+ line-height: 1.5;
134
+ letter-spacing: 1.05px;
135
+ color: #484848;
136
+ }
137
+
138
+ .badges-container {
139
+ margin-top: 0.75rem;
140
+ }
141
+
142
+ .loading-icon {
143
+ z-index: 20;
144
+ width: 40px;
145
+ height: 40px;
146
+ left: 80px;
147
+ }
148
+
149
+ .loading-icon :deep(.el-loading-mask) {
150
+ background-color: rgba(117, 190, 218, 0) !important;
151
+ }
152
+
153
+ .loading-icon :deep(.el-loading-spinner .path) {
154
+ stroke: $app-primary-color;
155
+ }
156
+
157
+ .float-button-container {
158
+ position: absolute;
159
+ bottom: 8px;
160
+ right: 16px;
161
+ opacity: 0;
162
+ visibility: hidden;
163
+
164
+ .card:hover & {
165
+ opacity: 1;
166
+ visibility: visible;
167
+ }
168
+ }
169
+ </style>
@@ -0,0 +1,323 @@
1
+ <template>
2
+ <div v-if="entry" class="main">
3
+ <div class="header">
4
+ <el-input
5
+ class="search-input"
6
+ placeholder="Search"
7
+ v-model="searchInput"
8
+ @keyup="search(searchInput)"
9
+ clearable
10
+ @clear="clearSearchClicked"
11
+ ></el-input>
12
+ <el-button
13
+ v-show="false"
14
+ type="primary"
15
+ class="button"
16
+ @click="search(searchInput)"
17
+ size="large"
18
+ >
19
+ Search
20
+ </el-button>
21
+ </div>
22
+ <div class="content scrollbar" ref="content">
23
+ <div v-for="result in paginatedResults" :key="result.Acupoint" class="step-item">
24
+ <AcupointsCard
25
+ class="dataset-card"
26
+ :entry="result"
27
+ @mouseenter="hoverChanged(result)"
28
+ @mouseleave="hoverChanged(undefined)"
29
+ />
30
+ </div>
31
+ <el-pagination
32
+ class="pagination"
33
+ v-model:current-page="page"
34
+ hide-on-single-page
35
+ large
36
+ layout="prev, pager, next"
37
+ :page-size="numberPerPage"
38
+ :total="numberOfHits"
39
+ @current-change="pageChange"
40
+ ></el-pagination>
41
+ </div>
42
+ </div>
43
+ </template>
44
+
45
+ <script>
46
+ /* eslint-disable no-alert, no-console */
47
+ import {
48
+ ElButton as Button,
49
+ ElCard as Card,
50
+ ElDrawer as Drawer,
51
+ ElIcon as Icon,
52
+ ElInput as Input,
53
+ ElPagination as Pagination,
54
+ } from 'element-plus'
55
+ import AcupointsCard from './AcupointsCard.vue'
56
+
57
+ export default {
58
+ components: {
59
+ AcupointsCard,
60
+ Button,
61
+ Card,
62
+ Drawer,
63
+ Icon,
64
+ Input,
65
+ Pagination
66
+ },
67
+ name: 'AcupointsInfoSearch',
68
+ props: {
69
+ entry: {
70
+ type: Object,
71
+ default: () => initial_state,
72
+ },
73
+ },
74
+ data: function () {
75
+ return {
76
+ results: [],
77
+ paginatedResults: [],
78
+ searchInput: "",
79
+ lastSearch: "",
80
+ numberOfHits: 0,
81
+ numberPerPage: 10,
82
+ page: 1,
83
+ }
84
+ },
85
+ watch: {
86
+ entry: {
87
+ handler: function () {
88
+ this.search(
89
+ this.searchInput,
90
+ this.numberPerPage,
91
+ this.page
92
+ )
93
+ },
94
+ immediate: true,
95
+ deep: true,
96
+ },
97
+ },
98
+ methods: {
99
+ hoverChanged: function (data) {
100
+ this.$emit('hover-changed', data)
101
+ },
102
+ resetSearch: function () {
103
+ this.numberOfHits = 0
104
+ this.search(this.searchInput)
105
+ },
106
+ clearSearchClicked: function () {
107
+ this.searchInput = '';
108
+ this.search("");
109
+ },
110
+ search: function(input) {
111
+ this.results = []
112
+ if (input !== this.previousSearch) {
113
+ if (input === "") {
114
+ this.results = Object.values(this.entry)
115
+ } else {
116
+ const lowerCase = input.toLowerCase()
117
+ for (const value of Object.values(this.entry)) {
118
+ const searchFields = [
119
+ value["Acupoint"],
120
+ value["Synonym"],
121
+ value["Chinese Name"],
122
+ value["English Name"],
123
+ value["Reference"],
124
+ value["Indications"],
125
+ value["Acupuncture Method"],
126
+ value["Vasculature"],
127
+ value["Innervation"]
128
+ ];
129
+ const allstrings = searchFields.join();
130
+ const myJSON = allstrings.toLowerCase();
131
+ if (myJSON.includes(lowerCase)) {
132
+ this.results.push(value)
133
+ }
134
+ }
135
+ }
136
+ }
137
+ const start = this.numberPerPage * (this.page - 1)
138
+ this.paginatedResults = this.results.slice(start, start + this.numberPerPage)
139
+ this.numberOfHits = this.results.length
140
+ this.searchInput = input
141
+ this.lastSearch = input
142
+ console.log(this.numberOfHits)
143
+ },
144
+ numberPerPageUpdate: function (val) {
145
+ this.numberPerPage = val
146
+ this.pageChange(1)
147
+ },
148
+ pageChange: function (page) {
149
+ this.page = page
150
+ this.search( this.searchInput)
151
+ },
152
+ scrollToTop: function () {
153
+ if (this.$refs.content) {
154
+ this.$refs.content.scroll({ top: 0, behavior: 'smooth' })
155
+ }
156
+ },
157
+ resetPageNavigation: function () {
158
+ this.page = 1
159
+ },
160
+ },
161
+ }
162
+ </script>
163
+
164
+ <style lang="scss" scoped>
165
+ .dataset-card {
166
+ position: relative;
167
+
168
+ &::before {
169
+ content: "";
170
+ display: block;
171
+ width: calc(100% - 15px);
172
+ height: 100%;
173
+ position: absolute;
174
+ top: 7px;
175
+ left: 7px;
176
+ border-style: solid;
177
+ border-radius: 5px;
178
+ border-color: transparent;
179
+ }
180
+
181
+ &:hover {
182
+ &::before {
183
+ border-color: var(--el-color-primary);
184
+ }
185
+ }
186
+ }
187
+
188
+ .main {
189
+ font-size: 14px;
190
+ text-align: left;
191
+ line-height: 1.5em;
192
+ font-family: Asap, sans-serif, Helvetica;
193
+ font-weight: 400;
194
+ /* outline: thin red solid; */
195
+ overflow-y: auto;
196
+ scrollbar-width: thin;
197
+ min-width: 16rem;
198
+ background-color: #f7faff;
199
+ height: 100%;
200
+ border-left: 1px solid var(--el-border-color);
201
+ border-top: 1px solid var(--el-border-color);
202
+ display: flex;
203
+ flex-direction: column;
204
+ gap: 1.75rem;
205
+ padding: 1rem;
206
+ }
207
+
208
+ .step-item {
209
+ font-size: 14px;
210
+ margin-bottom: 18px;
211
+ text-align: left;
212
+ }
213
+
214
+ .search-input {
215
+ width: 298px !important;
216
+ height: 40px;
217
+ padding-right: 14px;
218
+
219
+ :deep(.el-input__inner) {
220
+ font-family: inherit;
221
+ }
222
+ }
223
+
224
+ .header {
225
+ .el-button {
226
+ font-family: inherit;
227
+
228
+ &:hover,
229
+ &:focus {
230
+ background: $app-primary-color;
231
+ box-shadow: -3px 2px 4px #00000040;
232
+ color: #fff;
233
+ }
234
+ }
235
+ }
236
+
237
+ .pagination {
238
+ padding-bottom: 16px;
239
+ background-color: white;
240
+ padding-left: 95px;
241
+ font-weight: bold;
242
+ }
243
+
244
+ .pagination :deep(button) {
245
+ background-color: white !important;
246
+ }
247
+ .pagination :deep(li) {
248
+ background-color: white !important;
249
+ }
250
+ .pagination :deep(li.is-active) {
251
+ color: $app-primary-color;
252
+ }
253
+
254
+ .error-feedback {
255
+ font-family: Asap;
256
+ font-size: 14px;
257
+ font-style: italic;
258
+ padding-top: 15px;
259
+ }
260
+
261
+ .content-card :deep(.el-card__header) {
262
+ background-color: #292b66;
263
+ padding: 1rem;
264
+ }
265
+
266
+ .content-card :deep(.el-card__body) {
267
+ background-color: #f7faff;
268
+ overflow-y: hidden;
269
+ padding: 1rem;
270
+ }
271
+
272
+ .content {
273
+ // width: 515px;
274
+ flex: 1 1 auto;
275
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.06);
276
+ border: solid 1px #e4e7ed;
277
+ background-color: #ffffff;
278
+ overflow-y: scroll;
279
+ scrollbar-width: thin;
280
+ border-radius: var(--el-border-radius-base);
281
+ }
282
+
283
+ .content :deep(.el-loading-spinner .path) {
284
+ stroke: $app-primary-color;
285
+ }
286
+
287
+ .content :deep(.step-item:first-child .seperator-path) {
288
+ display: none;
289
+ }
290
+
291
+ .content :deep(.step-item:not(:first-child) .seperator-path) {
292
+ width: 455px;
293
+ height: 0px;
294
+ border: solid 1px #e4e7ed;
295
+ background-color: #e4e7ed;
296
+ }
297
+
298
+ .scrollbar::-webkit-scrollbar-track {
299
+ border-radius: 10px;
300
+ background-color: #f5f5f5;
301
+ }
302
+
303
+ .scrollbar::-webkit-scrollbar {
304
+ width: 12px;
305
+ right: -12px;
306
+ background-color: #f5f5f5;
307
+ }
308
+
309
+ .scrollbar::-webkit-scrollbar-thumb {
310
+ border-radius: 4px;
311
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.06);
312
+ background-color: #979797;
313
+ }
314
+
315
+ :deep(.el-input__suffix) {
316
+ padding-right: 0px;
317
+ }
318
+
319
+ :deep(.my-drawer) {
320
+ background: rgba(0, 0, 0, 0);
321
+ box-shadow: none;
322
+ }
323
+ </style>
@@ -211,6 +211,7 @@
211
211
  <connectivity-graph
212
212
  :entry="entry.featureId[0]"
213
213
  :mapServer="envVars.FLATMAPAPI_LOCATION"
214
+ :sckanVersion="sckanVersion"
214
215
  @tap-node="onTapNode"
215
216
  ref="connectivityGraphRef"
216
217
  />
@@ -313,6 +314,7 @@ export default {
313
314
  timeoutID: undefined,
314
315
  graphViewLoaded: false,
315
316
  updatedCopyContent: '',
317
+ sckanVersion: '',
316
318
  }
317
319
  },
318
320
  watch: {
@@ -599,6 +601,7 @@ export default {
599
601
  },
600
602
  },
601
603
  mounted: function () {
604
+ this.sckanVersion = this.entry['knowledge-source'];
602
605
  this.updatedCopyContent = this.getUpdateCopyContent();
603
606
  EventBus.on('connectivity-graph-error', (errorInfo) => {
604
607
  this.pushConnectivityError(errorInfo);