Skip to content

Commit 80186f1

Browse files
feat(wip): integrate backend and custom table
1 parent f2bb54e commit 80186f1

File tree

7 files changed

+433
-70
lines changed

7 files changed

+433
-70
lines changed

src/App.svelte

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
<script lang="ts">
22
import options from './config/options.json';
3-
import { genderHeaders, measures } from './config/environment';
4-
import type { LensDataPasser } from '@samply/lens';
3+
import { measures } from './config/environment';
4+
import type { LensDataPasser, QueryEvent } from '@samply/lens';
55
import { catalogueText, getStaticCatalogue } from './services/catalogue.service';
6+
import ResultTable from './components/ResultTable.svelte';
7+
import { backendCall } from './services/backend.service';
68
79
let catalogueopen = false;
810
let catalogueCollapsable = true;
@@ -60,6 +62,18 @@
6062
if (window.innerWidth >= 1024) {
6163
catalogueCollapsable = false;
6264
}
65+
66+
/**
67+
* This event listener is triggered when the user clicks the search button
68+
*/
69+
70+
let response: void;
71+
72+
window.addEventListener('emit-lens-query', (e) => {
73+
const event = e as QueryEvent;
74+
const { ast, updateResponse, abortController } = event.detail;
75+
response = backendCall(ast, updateResponse, abortController);
76+
});
6377
</script>
6478

6579
<header>
@@ -123,16 +137,15 @@
123137

124138
<div class="chart-wrapper">
125139
<lens-chart
126-
title="Geschlecht"
127-
catalogueGroupCode="gender"
140+
title="Studies per Collection"
141+
catalogueGroupCode="Studies"
128142
chartType="pie"
129143
displayLegends="{true}"
130-
headers="{genderHeaders}"
131144
></lens-chart>
132145
</div>
133146

134147
<div class="chart-wrapper result-table">
135-
<lens-result-table pageSize="10"> </lens-result-table>
148+
<ResultTable options="{options.tableOptions}" {response} />
136149
</div>
137150
</div>
138151
</div>

src/app.css

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,7 @@ lens-search-button {
241241
@media screen and (min-width: 1024px) {
242242
.charts {
243243
grid-template-columns: repeat(3, 1fr);
244+
grid-template-rows: max-content;
244245
}
245246
}
246247

@@ -259,6 +260,7 @@ lens-search-button {
259260

260261
.result-table {
261262
grid-column: span 2;
263+
grid-template-rows: min-content;
262264
}
263265

264266
}
@@ -273,11 +275,6 @@ lens-search-button {
273275
margin: 0;
274276
}
275277

276-
277-
footer {
278-
justify-content: center;
279-
}
280-
281278
footer .logo {
282279
background-color: var(--blue);
283280
padding: var(--gap-s);
@@ -311,6 +308,9 @@ footer .links {
311308
lens-search-bar-multiple::part(lens-searchbar-chip) {
312309
background-color: var(--light-blue);
313310
}
311+
lens-search-bar-multiple::part(lens-searchbar-or-indicator) {
312+
color: var(--white);
313+
}
314314

315315
lens-search-bar-multiple::part(info-button),
316316
lens-search-bar::part(info-button) {

src/components/ResultTable.svelte

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
<script lang="ts">
2+
export let options = {
3+
headerData: [],
4+
claimedText: ''
5+
};
6+
7+
export let response: Provider[] = [];
8+
9+
type Provider = {
10+
provider: string;
11+
provider_icon: string;
12+
collections: CollectionItem[];
13+
};
14+
15+
type CollectionItem = {
16+
name: string;
17+
id: string;
18+
provider_icon?: string;
19+
provider?: string;
20+
studies_count: number;
21+
subjects_count: number;
22+
age_range: {
23+
min: number;
24+
max: number;
25+
};
26+
gender: string[];
27+
modality: string[];
28+
body_parts: string[];
29+
description: string;
30+
};
31+
32+
// let providers: Provider[] = [
33+
// {
34+
// provider: 'ProCancer1',
35+
// provider_icon: 'provider-icon.svg',
36+
// collections: [
37+
// {
38+
// name: 'Collection1',
39+
// id: '02865f6d-15b1-4775-ab15-7bc7d95700a9',
40+
// studies_count: 320,
41+
// subjects_count: 322,
42+
// age_range: {
43+
// min: 40,
44+
// max: 70
45+
// },
46+
// gender: ['Male', 'Unknown'],
47+
// modality: ['MRI', 'PET-CT'],
48+
// body_parts: ['Rectum', 'Prostate', 'Pelvis'],
49+
// description: 'Example Collection 1 from ProCancer1'
50+
// },
51+
// {
52+
// name: 'Collection2',
53+
// id: 'b0e24524-0dc7-4de1-b058-8b27aff39f27',
54+
// studies_count: 15,
55+
// subjects_count: 24,
56+
// age_range: {
57+
// min: 20,
58+
// max: 40
59+
// },
60+
// gender: ['Male'],
61+
// modality: ['MRI'],
62+
// body_parts: ['Rectum', 'Prostate', 'Pelvis'],
63+
// description: 'Example Collection 2 from ProCancer1'
64+
// },
65+
// {
66+
// name: 'Collection3',
67+
// id: '578a6d9f-3f4d-4670-9245-cb44a7716932',
68+
// studies_count: 10,
69+
// subjects_count: 4322,
70+
// age_range: {
71+
// min: 20,
72+
// max: 70
73+
// },
74+
// gender: ['Female'],
75+
// modality: ['MRI'],
76+
// body_parts: ['Breast', 'Lung'],
77+
// description: 'Example Collection 3 from ProCancer1'
78+
// },
79+
// {
80+
// name: 'Collection4',
81+
// id: '7c0a05b9-80a7-4122-8836-d75ce16f4be3',
82+
// studies_count: 5,
83+
// subjects_count: 7,
84+
// age_range: {
85+
// min: 10,
86+
// max: 20
87+
// },
88+
// gender: ['Male', 'Female'],
89+
// modality: ['PET'],
90+
// body_parts: ['Colon'],
91+
// description: 'Example Collection 4 from ProCancer1'
92+
// }
93+
// ]
94+
// }
95+
// ];
96+
let expanded: boolean[] = new Array(1).fill(false);
97+
98+
const toggleExpand = (index: number) => {
99+
expanded[index] = !expanded[index];
100+
const img: HTMLElement | null = document.getElementById(`expand-button-img-${index}`);
101+
if (!img) return;
102+
img.classList.toggle('expand-button-img-rotate');
103+
};
104+
105+
/**
106+
* watches the responseStore for changes to update the table
107+
*/
108+
</script>
109+
110+
<table class="result-table">
111+
<thead class="table-header">
112+
<tr class="table-header-row">
113+
{#each options.headerData as header}
114+
<th class="table-header-cell table-header-datatype">
115+
{header.title}
116+
</th>
117+
{/each}
118+
<th class="expand-header"></th>
119+
</tr>
120+
</thead>
121+
<tbody class="table-body">
122+
{#each response as provider}
123+
{#each provider.collections as tableRow, index}
124+
<tr class="table-row">
125+
<td class="table-cell table-cell-name">{tableRow.name}</td>
126+
<td class="table-cell">
127+
{#if provider.provider_icon}
128+
<img src="{provider.provider_icon}" alt="" />
129+
{/if}
130+
{provider.provider}</td
131+
>
132+
<td class="table-cell">{tableRow.studies_count}</td>
133+
<td class="table-cell">{tableRow.subjects_count}</td>
134+
<td class="table-cell">
135+
<button class="expand-button" on:click="{() => toggleExpand(index)}"
136+
><img
137+
class="expand-button-img expand-button-img-rotate"
138+
id="expand-button-img-{index}"
139+
src="right-arrow-svgrepo-com.svg"
140+
alt="toggle additional information icon"
141+
/></button
142+
>
143+
</td>
144+
</tr>
145+
{#if expanded[index]}
146+
<tr class="table-row">
147+
<td class="table-cell-hidden" colspan="5">
148+
<div class="table-cell-hidden-data-wrapper">
149+
<div>
150+
Age range: {tableRow.age_range.min} to {tableRow.age_range.max}
151+
</div>
152+
<div>
153+
Gender: {tableRow.gender}
154+
</div>
155+
<div>
156+
Modality: {tableRow.modality}
157+
</div>
158+
<div>
159+
Body parts: {tableRow.body_parts}
160+
</div>
161+
<div>
162+
Description: {tableRow.description}
163+
</div>
164+
</div>
165+
</td>
166+
</tr>
167+
{/if}
168+
{/each}
169+
{/each}
170+
</tbody>
171+
</table>
172+
173+
<style>
174+
.table-cell,
175+
th {
176+
text-align: left;
177+
}
178+
.table-cell-name {
179+
color: var(--orange);
180+
}
181+
.table-cell-hidden {
182+
border-bottom: solid var(--gray) 1px;
183+
}
184+
.table-cell-hidden-data-wrapper {
185+
margin: 10px 0 10px 30px;
186+
padding: 0px 10px;
187+
}
188+
.expand-button {
189+
background-color: transparent;
190+
border: none;
191+
cursor: pointer;
192+
}
193+
.expand-button-img {
194+
width: 20px;
195+
height: 20px;
196+
rotate: -90deg;
197+
transition: all 0.3s;
198+
}
199+
.expand-button-img-rotate {
200+
rotate: 90deg;
201+
}
202+
</style>

src/config/options.json

Lines changed: 14 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -176,24 +176,20 @@
176176
"tableOptions": {
177177
"headerData": [
178178
{
179-
"title": "Standorte",
180-
"dataKey": "site"
179+
"title": "Collections",
180+
"dataKey": "collections"
181181
},
182182
{
183-
"title": "Patienten",
184-
"dataKey": "patients"
183+
"title": "Provider",
184+
"dataKey": "provider"
185185
},
186186
{
187-
"title": "Bioproben*",
188-
"aggregatedDataKeys": [
189-
{
190-
"groupCode": "specimen"
191-
},
192-
{
193-
"stratifierCode": "Histologies",
194-
"stratumCode": "1"
195-
}
196-
]
187+
"title": "Studies",
188+
"dataKey": "studies_count"
189+
},
190+
{
191+
"title": "Subjects",
192+
"dataKey": "subject_count"
197193
}
198194
],
199195
"claimedText": "Processing..."
@@ -211,58 +207,19 @@
211207
}
212208
]
213209
},
214-
"backends": {
215-
"spots": [
210+
"spots": [
216211
{
217212
"name": "DKTK",
218213
"backendMeasures": "DKTK_STRAT_DEF_IN_INITIAL_POPULATION",
219-
"url": "http://localhost:8055",
214+
"url": "",
220215
"sites": [
221-
"berlin-test",
222-
"dresden",
223-
"essen",
224-
"frankfurt",
225-
"freiburg",
226-
"hannover",
227-
"mainz",
228-
"muenchen-lmu",
229-
"muenchen-tum",
230-
"ulm",
231-
"wuerzburg",
232-
"mannheim",
233-
"hamburg"
234216
],
235217
"catalogueKeyToResponseKeyMap": [
236218
[
237-
"gender",
238-
"Gender"
239-
],
240-
[
241-
"age_at_diagnosis",
242-
"Age"
243-
],
244-
[
245-
"diagnosis",
246-
"diagnosis"
247-
],
248-
[
249-
"medicationStatements",
250-
"MedicationType"
251-
],
252-
[
253-
"sample_kind",
254-
"sample_kind"
255-
],
256-
[
257-
"therapy_of_tumor",
258-
"ProcedureType"
259-
],
260-
[
261-
"75186-7",
262-
"75186-7"
219+
"Studies",
220+
"Studies"
263221
]
264222
]
265223
}
266224
]
267-
}
268225
}

src/routes/+page.svelte

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
<head>
22
<meta charset='utf-8'>
3-
<link rel="icon" type="image/svg+xml" href="/favicon-dktk.png" />
43
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
54
<title>Lens Demo</title>
65
</head>

0 commit comments

Comments
 (0)