@weng-lab/genomebrowser-ui 0.3.6-beta.0 → 0.3.6
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/dist/TrackSelect/Custom/TfPeaks.d.ts +1 -2
- package/dist/TrackSelect/Custom/green-motifs.json.d.ts +20430 -0
- package/dist/genomebrowser-ui.es.js +1692 -1987
- package/dist/genomebrowser-ui.es.js.map +1 -1
- package/package.json +2 -2
- package/src/TrackSelect/Custom/TfPeaks.tsx +81 -60
- package/src/TrackSelect/Folders/index.ts +2 -2
- package/test/main.tsx +2 -2
- package/dist/TrackSelect/Custom/TF-ChIP-Canonical-Motifs-w-Trimmed.json.d.ts +0 -42210
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weng-lab/genomebrowser-ui",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.3.6
|
|
4
|
+
"version": "0.3.6",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"publishConfig": {
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"@mui/x-data-grid-premium": "^8.19.0",
|
|
24
24
|
"react": "^19.0.0",
|
|
25
25
|
"react-dom": "^19.0.0",
|
|
26
|
-
"@weng-lab/genomebrowser": "1.8.3
|
|
26
|
+
"@weng-lab/genomebrowser": "1.8.3"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"@eslint/js": "^9.34.0",
|
|
@@ -172,6 +172,10 @@ function TooltipRow({
|
|
|
172
172
|
function TfPeaksTooltip(rect: OverlayInteractionRect) {
|
|
173
173
|
const pwm = rect.pwm;
|
|
174
174
|
const label = tfDisplayName(rect.name);
|
|
175
|
+
const totalWidth = 340;
|
|
176
|
+
const pad = 8;
|
|
177
|
+
const lineH = 14;
|
|
178
|
+
const titleH = 18;
|
|
175
179
|
|
|
176
180
|
// Build metadata rows (single-value rows)
|
|
177
181
|
const metaRows: { label: string; value: string }[] = [];
|
|
@@ -181,33 +185,47 @@ function TfPeaksTooltip(rect: OverlayInteractionRect) {
|
|
|
181
185
|
label: "Position",
|
|
182
186
|
value: `${rect.chr ? rect.chr + ":" : ""}${rect.start.toLocaleString()}-${rect.end.toLocaleString()}`,
|
|
183
187
|
});
|
|
184
|
-
if (rect.expRatio) metaRows.push({ label: "Exps", value: rect.expRatio });
|
|
185
188
|
|
|
186
|
-
// Multi-value rows: split comma-separated cCREs, group
|
|
187
|
-
const
|
|
189
|
+
// Multi-value rows: split comma-separated cCREs, group 4 per row, cap at 5
|
|
190
|
+
const allCCREItems = rect.cCREId
|
|
188
191
|
? rect.cCREId
|
|
189
192
|
.split(",")
|
|
190
193
|
.map((s) => s.trim())
|
|
191
194
|
.filter(Boolean)
|
|
192
195
|
: [];
|
|
196
|
+
const maxCCREs = 5;
|
|
197
|
+
const cCREItems = allCCREItems.slice(0, maxCCREs);
|
|
198
|
+
const hiddenCCREs = Math.max(0, allCCREItems.length - maxCCREs);
|
|
193
199
|
const cCRERows: string[][] = [];
|
|
194
200
|
for (let i = 0; i < cCREItems.length; i += 4) {
|
|
195
201
|
cCRERows.push(cCREItems.slice(i, i + 4));
|
|
196
202
|
}
|
|
197
203
|
|
|
198
|
-
//
|
|
199
|
-
const
|
|
204
|
+
// Extract unique sorted biosamples from expSupport
|
|
205
|
+
const allBiosamples: string[] = [];
|
|
200
206
|
if (rect.expSupport) {
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
207
|
+
const seen = new Set<string>();
|
|
208
|
+
for (const cellLine of Object.keys(rect.expSupport)) {
|
|
209
|
+
if (!seen.has(cellLine)) {
|
|
210
|
+
seen.add(cellLine);
|
|
211
|
+
allBiosamples.push(cellLine);
|
|
204
212
|
}
|
|
205
213
|
}
|
|
214
|
+
allBiosamples.sort((a, b) => a.localeCompare(b));
|
|
206
215
|
}
|
|
207
|
-
|
|
208
|
-
const
|
|
209
|
-
const
|
|
210
|
-
const
|
|
216
|
+
const maxBiosamples = 12;
|
|
217
|
+
const biosampleItems = allBiosamples.slice(0, maxBiosamples);
|
|
218
|
+
const hiddenBiosamples = Math.max(0, allBiosamples.length - maxBiosamples);
|
|
219
|
+
const biosampleText = biosampleItems.join(", ");
|
|
220
|
+
const biosampleMoreText =
|
|
221
|
+
hiddenBiosamples > 0 ? ` ...and ${hiddenBiosamples} more` : "";
|
|
222
|
+
const biosampleCharsPerLine = Math.floor((totalWidth - 2 * pad) / 5.2);
|
|
223
|
+
const biosampleContentLines = Math.max(
|
|
224
|
+
1,
|
|
225
|
+
Math.ceil(
|
|
226
|
+
(biosampleText.length + biosampleMoreText.length) / biosampleCharsPerLine,
|
|
227
|
+
),
|
|
228
|
+
);
|
|
211
229
|
|
|
212
230
|
// Layout: compute y offsets upfront
|
|
213
231
|
const hasLogo = pwm && pwm.length > 0;
|
|
@@ -216,26 +234,25 @@ function TfPeaksTooltip(rect: OverlayInteractionRect) {
|
|
|
216
234
|
const logoSectionH = hasLogo ? logoHeight + 4 : 0;
|
|
217
235
|
const metaSectionH = metaRows.length * lineH;
|
|
218
236
|
|
|
219
|
-
// cCRE section: label row + one row per group of
|
|
237
|
+
// cCRE section: label row + one row per group of 4 + optional "+N more" row
|
|
220
238
|
const cCREGap = cCRERows.length > 0 ? 8 : 0;
|
|
221
239
|
const cCREHeaderH = cCRERows.length > 0 ? lineH : 0;
|
|
222
|
-
const
|
|
240
|
+
const cCREMoreH = hiddenCCREs > 0 ? lineH : 0;
|
|
241
|
+
const cCRESectionH = cCRERows.length * lineH + cCREMoreH;
|
|
223
242
|
|
|
224
|
-
//
|
|
225
|
-
const
|
|
226
|
-
const
|
|
227
|
-
const
|
|
243
|
+
// Biosamples section
|
|
244
|
+
const biosampleGap = biosampleContentLines > 0 ? 8 : 0;
|
|
245
|
+
const biosampleHeaderH = biosampleContentLines > 0 ? lineH : 0;
|
|
246
|
+
const biosampleSectionH = biosampleContentLines * lineH;
|
|
228
247
|
|
|
229
248
|
const titleY = pad;
|
|
230
249
|
const logoY = titleY + titleH;
|
|
231
250
|
const metaY = logoY + logoSectionH;
|
|
232
251
|
const cCREY = metaY + metaSectionH + cCREGap;
|
|
233
252
|
const cCREDataY = cCREY + cCREHeaderH;
|
|
234
|
-
const
|
|
235
|
-
const
|
|
236
|
-
const totalHeight =
|
|
237
|
-
|
|
238
|
-
const totalWidth = 340;
|
|
253
|
+
const biosampleY = cCREDataY + cCRESectionH + biosampleGap;
|
|
254
|
+
const biosampleDataY = biosampleY + biosampleHeaderH;
|
|
255
|
+
const totalHeight = biosampleDataY + biosampleSectionH + pad;
|
|
239
256
|
|
|
240
257
|
return (
|
|
241
258
|
<g>
|
|
@@ -306,60 +323,64 @@ function TfPeaksTooltip(rect: OverlayInteractionRect) {
|
|
|
306
323
|
{group.join(", ")}
|
|
307
324
|
</text>
|
|
308
325
|
))}
|
|
326
|
+
{hiddenCCREs > 0 && (
|
|
327
|
+
<text
|
|
328
|
+
x={pad}
|
|
329
|
+
y={cCREDataY + cCRERows.length * lineH + 2}
|
|
330
|
+
fontSize={9}
|
|
331
|
+
fill="#aaa"
|
|
332
|
+
dominantBaseline="hanging"
|
|
333
|
+
>
|
|
334
|
+
+{hiddenCCREs} more...
|
|
335
|
+
</text>
|
|
336
|
+
)}
|
|
309
337
|
</g>
|
|
310
338
|
)}
|
|
311
339
|
|
|
312
|
-
{/*
|
|
313
|
-
{
|
|
340
|
+
{/* Biosamples */}
|
|
341
|
+
{biosampleContentLines > 0 && (
|
|
314
342
|
<g>
|
|
315
343
|
<line
|
|
316
344
|
x1={pad}
|
|
317
345
|
x2={totalWidth - pad}
|
|
318
|
-
y1={
|
|
319
|
-
y2={
|
|
346
|
+
y1={biosampleY - 4}
|
|
347
|
+
y2={biosampleY - 4}
|
|
320
348
|
stroke="#ddd"
|
|
321
349
|
/>
|
|
322
350
|
<text
|
|
323
351
|
x={pad}
|
|
324
|
-
y={
|
|
352
|
+
y={biosampleY + 2}
|
|
325
353
|
fontSize={9}
|
|
326
354
|
fontWeight="bold"
|
|
327
355
|
fill="#666"
|
|
328
356
|
dominantBaseline="hanging"
|
|
329
357
|
>
|
|
330
|
-
|
|
358
|
+
Biosamples
|
|
331
359
|
</text>
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
fill="#666"
|
|
357
|
-
dominantBaseline="hanging"
|
|
358
|
-
>
|
|
359
|
-
{row.fileId}
|
|
360
|
-
</text>
|
|
361
|
-
</g>
|
|
362
|
-
))}
|
|
360
|
+
<foreignObject
|
|
361
|
+
x={pad}
|
|
362
|
+
y={biosampleDataY}
|
|
363
|
+
width={totalWidth - 2 * pad}
|
|
364
|
+
height={biosampleSectionH}
|
|
365
|
+
>
|
|
366
|
+
<div
|
|
367
|
+
style={{
|
|
368
|
+
color: "#333",
|
|
369
|
+
fontSize: "9px",
|
|
370
|
+
lineHeight: `${lineH}px`,
|
|
371
|
+
margin: 0,
|
|
372
|
+
padding: 0,
|
|
373
|
+
overflow: "hidden",
|
|
374
|
+
whiteSpace: "normal",
|
|
375
|
+
wordBreak: "break-word",
|
|
376
|
+
}}
|
|
377
|
+
>
|
|
378
|
+
{biosampleText}
|
|
379
|
+
{hiddenBiosamples > 0 && (
|
|
380
|
+
<span style={{ color: "#aaa" }}>{biosampleMoreText}</span>
|
|
381
|
+
)}
|
|
382
|
+
</div>
|
|
383
|
+
</foreignObject>
|
|
363
384
|
</g>
|
|
364
385
|
)}
|
|
365
386
|
</g>
|
|
@@ -27,6 +27,6 @@ export type { OtherTrackInfo } from "./other-tracks/shared/types";
|
|
|
27
27
|
* 2. Import and add it to the appropriate assembly array below
|
|
28
28
|
*/
|
|
29
29
|
export const foldersByAssembly: Record<Assembly, FolderDefinition[]> = {
|
|
30
|
-
GRCh38: [
|
|
31
|
-
mm10: [
|
|
30
|
+
GRCh38: [humanGenesFolder, humanBiosamplesFolder, humanOtherTracksFolder],
|
|
31
|
+
mm10: [mouseGenesFolder, mouseBiosamplesFolder],
|
|
32
32
|
};
|
package/test/main.tsx
CHANGED
|
@@ -38,7 +38,7 @@ import type { BiosampleRowInfo } from "../src/TrackSelect/Folders/biosamples/sha
|
|
|
38
38
|
import type { GeneRowInfo } from "../src/TrackSelect/Folders/genes/shared/types";
|
|
39
39
|
import type { OtherTrackInfo } from "../src/TrackSelect/Folders/other-tracks/shared/types";
|
|
40
40
|
import { Exon } from "@weng-lab/genomebrowser/dist/components/tracks/transcript/types";
|
|
41
|
-
import { tfPeaksTrack } from "
|
|
41
|
+
import { tfPeaksTrack } from "../src/TrackSelect/Custom/TfPeaks";
|
|
42
42
|
|
|
43
43
|
interface Transcript {
|
|
44
44
|
id: string;
|
|
@@ -87,7 +87,7 @@ function Main() {
|
|
|
87
87
|
const browserStore = createBrowserStoreMemo({
|
|
88
88
|
// chr7:19,695,494-19,699,803
|
|
89
89
|
// chr1:11103779-11262792
|
|
90
|
-
domain: { chromosome: "
|
|
90
|
+
domain: { chromosome: "chr12", start: 53380108, end: 53416378 },
|
|
91
91
|
marginWidth: 100,
|
|
92
92
|
trackWidth: 1400,
|
|
93
93
|
multiplier: 3,
|