@weng-lab/genomebrowser-ui 0.4.0-beta.1 → 0.4.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.
@@ -0,0 +1,82 @@
1
+ import { InferBigBedRow } from "@weng-lab/genomebrowser";
2
+ import {
3
+ mohdAtacFdrPeaksSchema,
4
+ mohdAtacPseudorepPeaksSchema,
5
+ } from "./bigBedSchemas";
6
+
7
+ type MohdBigBedRow =
8
+ | InferBigBedRow<typeof mohdAtacFdrPeaksSchema>
9
+ | InferBigBedRow<typeof mohdAtacPseudorepPeaksSchema>;
10
+
11
+ function TooltipRow({
12
+ label,
13
+ value,
14
+ y,
15
+ }: {
16
+ label: string;
17
+ value: string;
18
+ y: number;
19
+ }) {
20
+ return (
21
+ <g transform={`translate(0, ${y})`}>
22
+ <text x={8} y={0} fontSize={10} fill="#888" dominantBaseline="hanging">
23
+ {label}
24
+ </text>
25
+ <text x={100} y={0} fontSize={10} fill="#333" dominantBaseline="hanging">
26
+ {value}
27
+ </text>
28
+ </g>
29
+ );
30
+ }
31
+
32
+ function formatValue(value: string | number | undefined) {
33
+ if (value === undefined) {
34
+ return "-";
35
+ }
36
+
37
+ return `${value}`;
38
+ }
39
+
40
+ export function MohdBigBedTooltip(rect: MohdBigBedRow) {
41
+ const rows = [
42
+ {
43
+ label: "Position",
44
+ value: `${rect.chr}:${rect.start.toLocaleString()}-${rect.end.toLocaleString()}`,
45
+ },
46
+ { label: "Name", value: formatValue(rect.name) },
47
+ { label: "Score", value: formatValue(rect.score) },
48
+ { label: "Strand", value: formatValue(rect.strand) },
49
+ { label: "Signal", value: formatValue(rect.signalValue) },
50
+ { label: "pValue", value: formatValue(rect.pValue) },
51
+ { label: "qValue", value: formatValue(rect.qValue) },
52
+ { label: "Peak", value: formatValue(rect.peak) },
53
+ ];
54
+ const pad = 8;
55
+ const lineH = 14;
56
+ const titleH = 18;
57
+ const width = 280;
58
+ const height = pad + titleH + rows.length * lineH + pad;
59
+
60
+ return (
61
+ <g>
62
+ <rect
63
+ width={width}
64
+ height={height}
65
+ fill="white"
66
+ rx={3}
67
+ style={{ filter: "drop-shadow(0px 0px 5px rgba(0,0,0,0.3))" }}
68
+ />
69
+ <text x={pad} y={pad + 12} fontSize={12} fontWeight="bold" fill="#333">
70
+ {rect.name || "MOHD peak"}
71
+ </text>
72
+ {rows.map((row, index) => (
73
+ <TooltipRow
74
+ key={row.label}
75
+ label={row.label}
76
+ value={row.value}
77
+ y={pad + titleH + index * lineH}
78
+ />
79
+ ))}
80
+ </g>
81
+ );
82
+ }
@@ -0,0 +1,34 @@
1
+ import { defineBigBedSchema } from "@weng-lab/genomebrowser";
2
+ import type { MohdFileRowInfo } from "./types";
3
+
4
+ export const mohdAtacFdrPeaksSchema = defineBigBedSchema({
5
+ name: "string",
6
+ score: "number",
7
+ strand: "string",
8
+ signalValue: "number",
9
+ pValue: "number",
10
+ qValue: "number",
11
+ peak: "number",
12
+ });
13
+
14
+ export const mohdAtacPseudorepPeaksSchema = defineBigBedSchema({
15
+ name: "string",
16
+ score: "number",
17
+ strand: "string",
18
+ signalValue: "number",
19
+ pValue: "number",
20
+ qValue: "number",
21
+ peak: "number",
22
+ });
23
+
24
+ export function getMohdBigBedSchema(row: MohdFileRowInfo) {
25
+ if (row.description === "FDR 0.05 peaks") {
26
+ return mohdAtacFdrPeaksSchema;
27
+ }
28
+
29
+ if (row.description === "Pseudorep peaks") {
30
+ return mohdAtacPseudorepPeaksSchema;
31
+ }
32
+
33
+ return undefined;
34
+ }
@@ -16,6 +16,13 @@ const sampleIdCol: GridColDef<MohdRowInfo> = {
16
16
  flex: 1,
17
17
  };
18
18
 
19
+ const kitIdCol: GridColDef<MohdRowInfo> = {
20
+ field: "kitId",
21
+ headerName: "Kit ID",
22
+ minWidth: 140,
23
+ flex: 1,
24
+ };
25
+
19
26
  const trackCategoryCol: GridColDef<MohdRowInfo> = {
20
27
  field: "trackCategory",
21
28
  headerName: "Track Type",
@@ -55,6 +62,7 @@ export const mohdColumns: GridColDef<MohdRowInfo>[] = [
55
62
  descriptionCol,
56
63
  trackCategoryCol,
57
64
  sampleIdCol,
65
+ kitIdCol,
58
66
  omeCol,
59
67
  siteCol,
60
68
  sexCol,
@@ -15,6 +15,7 @@ function createBaseRow(folderId: string, row: MohdDataFile[number]) {
15
15
  ome: getMohdOmeConfig(row.ome).label,
16
16
  site: row.site,
17
17
  sampleId: row.sample_id,
18
+ kitId: row.kit_id,
18
19
  sex: row.sex,
19
20
  status: row.status,
20
21
  };
@@ -2,6 +2,7 @@ import {
2
2
  BigBedConfig,
3
3
  BigWigConfig,
4
4
  DisplayMode,
5
+ InferBigBedRow,
5
6
  MethylCConfig,
6
7
  Track,
7
8
  TrackType,
@@ -9,7 +10,13 @@ import {
9
10
  } from "@weng-lab/genomebrowser";
10
11
  import type { FC } from "react";
11
12
  import { CreateTrackOptions } from "../../types";
13
+ import {
14
+ getMohdBigBedSchema,
15
+ mohdAtacFdrPeaksSchema,
16
+ mohdAtacPseudorepPeaksSchema,
17
+ } from "./bigBedSchemas";
12
18
  import { createMohdFileUrl, getMohdOmeConfig } from "./config";
19
+ import { MohdBigBedTooltip } from "./MohdBigBedTooltip";
13
20
  import { MohdRowInfo } from "./types";
14
21
 
15
22
  export type MohdTrackContext = {
@@ -47,6 +54,10 @@ const defaultMethylC: Omit<MethylCConfig, "id" | "title" | "urls"> = {
47
54
  },
48
55
  };
49
56
 
57
+ type MohdBigBedRow =
58
+ | InferBigBedRow<typeof mohdAtacFdrPeaksSchema>
59
+ | InferBigBedRow<typeof mohdAtacPseudorepPeaksSchema>;
60
+
50
61
  function createTrackTitle(row: MohdRowInfo) {
51
62
  return `${row.sampleId} ${row.description}`;
52
63
  }
@@ -157,6 +168,11 @@ export function createMohdTrack(
157
168
  title: createTrackTitle(row),
158
169
  url,
159
170
  color,
171
+ schema: getMohdBigBedSchema(row),
172
+ tooltip: MohdBigBedTooltip,
173
+ onClick: (rect: MohdBigBedRow) => {
174
+ console.log(rect);
175
+ },
160
176
  };
161
177
  }
162
178
 
@@ -11,6 +11,7 @@ export type MohdDataRow = {
11
11
  ome: string;
12
12
  site: string;
13
13
  sample_id: string;
14
+ kit_id?: string;
14
15
  file_type: string;
15
16
  filename: string;
16
17
  sex: string;
@@ -22,6 +23,7 @@ type MohdBaseRowInfo = {
22
23
  ome: MohdOme;
23
24
  site: string;
24
25
  sampleId: string;
26
+ kitId?: string;
25
27
  sex: string;
26
28
  status: string;
27
29
  description: string;
@@ -0,0 +1,50 @@
1
+ import { describe, expect, it, vi } from "vitest";
2
+ vi.mock("../src/TrackSelect/Folders/mohd/shared/MohdGroupingCell", () => ({
3
+ MohdGroupingCell: () => null,
4
+ }));
5
+ vi.mock("../src/TrackSelect/Folders/mohd/shared/MohdTreeItem", () => ({
6
+ MohdTreeItem: () => null,
7
+ }));
8
+ vi.mock("../src/TrackSelect/Folders/mohd/shared/MohdViewSelector", () => ({
9
+ MohdViewSelector: () => null,
10
+ }));
11
+ import { createMohdFolder } from "../src/TrackSelect/Folders/mohd/shared/createFolder";
12
+ import type { MohdDataFile } from "../src/TrackSelect/Folders/mohd/shared/types";
13
+
14
+ describe("MOHD folder", () => {
15
+ it("maps kit_id to kitId on normalized rows", () => {
16
+ const folder = createMohdFolder({
17
+ id: "mohd-test",
18
+ label: "MOHD",
19
+ data: [
20
+ {
21
+ ome: "atac",
22
+ site: "CCH",
23
+ sample_id: "MOHD_EA100001",
24
+ kit_id: "CCH_0001",
25
+ file_type: "Fold change signal",
26
+ filename: "MOHD_EA100001_signal-FC_GRCh38_v0.bigWig",
27
+ sex: "female",
28
+ status: "case",
29
+ },
30
+ ] as MohdDataFile,
31
+ });
32
+
33
+ expect(folder.rows[0]).toMatchObject({
34
+ sampleId: "MOHD_EA100001",
35
+ kitId: "CCH_0001",
36
+ });
37
+ });
38
+
39
+ it("includes a kit id column", () => {
40
+ const folder = createMohdFolder({
41
+ id: "mohd-test",
42
+ label: "MOHD",
43
+ data: [],
44
+ });
45
+
46
+ expect(folder.columns.some((column) => column.field === "kitId")).toBe(
47
+ true,
48
+ );
49
+ });
50
+ });