oncoprintjs 5.0.3 → 6.0.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/README.md +34 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.es.js +14746 -0
- package/dist/index.es.js.map +1 -0
- package/dist/index.js +14760 -0
- package/dist/index.js.map +1 -0
- package/dist/js/CachedProperty.d.ts +10 -10
- package/dist/js/binarysearch.d.ts +1 -1
- package/dist/js/bucketsort.d.ts +16 -16
- package/dist/js/clustering.d.ts +14 -14
- package/dist/js/extractrgba.d.ts +4 -4
- package/dist/js/haselementsininterval.d.ts +1 -1
- package/dist/js/heatmapcolors.d.ts +5 -4
- package/dist/js/makesvgelement.d.ts +1 -1
- package/dist/js/modelutils.d.ts +7 -7
- package/dist/js/oncoprint.d.ts +168 -170
- package/dist/js/oncoprintheaderview.d.ts +23 -22
- package/dist/js/oncoprintlabelview.d.ts +79 -78
- package/dist/js/oncoprintlegendrenderer.d.ts +32 -31
- package/dist/js/oncoprintminimapview.d.ts +69 -68
- package/dist/js/oncoprintmodel.d.ts +403 -398
- package/dist/js/oncoprintruleset.d.ts +176 -177
- package/dist/js/oncoprintshape.d.ts +67 -67
- package/dist/js/oncoprintshapetosvg.d.ts +2 -2
- package/dist/js/oncoprintshapetovertexes.d.ts +5 -5
- package/dist/js/oncoprinttooltip.d.ts +23 -22
- package/dist/js/oncoprinttrackinfoview.d.ts +40 -39
- package/dist/js/oncoprinttrackoptionsview.d.ts +58 -57
- package/dist/js/oncoprintwebglcellview.d.ts +168 -167
- package/dist/js/oncoprintzoomslider.d.ts +28 -27
- package/dist/js/polyfill.d.ts +4 -4
- package/dist/js/precomputedcomparator.d.ts +13 -13
- package/dist/js/shaders.d.ts +2 -2
- package/dist/js/svgfactory.d.ts +24 -23
- package/dist/js/utils.d.ts +16 -16
- package/dist/js/workers/clustering-worker.d.ts +19 -20
- package/dist/test/gradientCategoricalRuleset.spec.d.ts +1 -1
- package/dist/test/monolith.spec.d.ts +1 -1
- package/jest.config.ts +2 -0
- package/package.json +20 -26
- package/rollup.config.ts +14 -0
- package/rules/geneticrules.ts +344 -305
- package/server.js +11 -0
- package/src/img/menudots.svg +9 -9
- package/src/img/zoomtofit.svg +12 -12
- package/src/index.tsx +13 -0
- package/src/js/CachedProperty.ts +6 -7
- package/src/js/binarysearch.ts +8 -3
- package/src/js/bucketsort.ts +89 -47
- package/src/js/clustering.ts +22 -10
- package/src/js/extractrgba.ts +16 -12
- package/src/js/haselementsininterval.ts +8 -4
- package/src/js/heatmapcolors.ts +515 -515
- package/src/js/main.js +1 -1
- package/src/js/makesvgelement.ts +2 -2
- package/src/js/modelutils.ts +11 -8
- package/src/js/oncoprint.ts +706 -385
- package/src/js/oncoprintheaderview.ts +165 -125
- package/src/js/oncoprintlabelview.ts +388 -170
- package/src/js/oncoprintlegendrenderer.ts +203 -72
- package/src/js/oncoprintminimapview.ts +965 -423
- package/src/js/oncoprintmodel.ts +905 -532
- package/src/js/oncoprintruleset.ts +694 -379
- package/src/js/oncoprintshape.ts +240 -97
- package/src/js/oncoprintshapetosvg.ts +77 -26
- package/src/js/oncoprintshapetovertexes.ts +153 -48
- package/src/js/oncoprinttooltip.ts +58 -27
- package/src/js/oncoprinttrackinfoview.ts +115 -59
- package/src/js/oncoprinttrackoptionsview.ts +354 -187
- package/src/js/oncoprintwebglcellview.ts +951 -415
- package/src/js/oncoprintzoomslider.ts +172 -107
- package/src/js/polyfill.ts +7 -3
- package/src/js/precomputedcomparator.ts +133 -50
- package/src/js/shaders.ts +2 -4
- package/src/js/svgfactory.ts +128 -73
- package/src/js/utils.ts +51 -31
- package/src/js/workers/clustering-worker.ts +50 -42
- package/src/test/gradientCategoricalRuleset.spec.ts +55 -38
- package/src/test/monolith.spec.ts +718 -285
- package/test/generate_data.py +108 -0
- package/test/glyphmap-data.js +1041 -0
- package/test/heatmap-data.js +1027 -0
- package/test/index.html +21 -0
- package/test/oncoprint-glyphmap.js +79 -0
- package/test/oncoprint-heatmap.js +123 -0
- package/tsconfig.json +4 -10
- package/tsconfig.test.json +11 -0
- package/.idea/misc.xml +0 -6
- package/.idea/modules.xml +0 -8
- package/.idea/oncoprintjs.iml +0 -12
- package/.idea/vcs.xml +0 -6
- package/.idea/workspace.xml +0 -105
- package/dist/.gitkeep +0 -0
- package/dist/js/minimaputils.d.ts +0 -0
- package/dist/oncoprint.bundle.js +0 -44313
- package/jest.config.js +0 -12
- package/src/js/minimaputils.ts +0 -0
- package/typings/custom.d.ts +0 -7
- package/typings/missing.d.ts +0 -7
- package/webpack.config.js +0 -43
package/src/js/oncoprintmodel.ts
CHANGED
|
@@ -3,17 +3,22 @@
|
|
|
3
3
|
import binarysearch from './binarysearch';
|
|
4
4
|
import hasElementsInInterval from './haselementsininterval';
|
|
5
5
|
import CachedProperty from './CachedProperty';
|
|
6
|
-
import {hclusterColumns, hclusterTracks} from './clustering';
|
|
6
|
+
import { hclusterColumns, hclusterTracks } from './clustering';
|
|
7
7
|
import $ from 'jquery';
|
|
8
|
-
import * as BucketSort from
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
import
|
|
16
|
-
import {
|
|
8
|
+
import * as BucketSort from './bucketsort';
|
|
9
|
+
import {
|
|
10
|
+
cloneShallow,
|
|
11
|
+
doesCellIntersectPixel,
|
|
12
|
+
ifndef,
|
|
13
|
+
z_comparator,
|
|
14
|
+
} from './utils';
|
|
15
|
+
import _ from 'lodash';
|
|
16
|
+
import { RuleSet, RuleSetParams, RuleWithId } from './oncoprintruleset';
|
|
17
|
+
import { InitParams } from './oncoprint';
|
|
18
|
+
import { ComputedShapeParams } from './oncoprintshape';
|
|
19
|
+
import { CaseItem, EntityItem } from './workers/clustering-worker';
|
|
20
|
+
import PrecomputedComparator from './precomputedcomparator';
|
|
21
|
+
import { calculateHeaderTops, calculateTrackTops } from './modelutils';
|
|
17
22
|
|
|
18
23
|
export type ColumnId = string;
|
|
19
24
|
export type ColumnIndex = number;
|
|
@@ -21,49 +26,67 @@ export type TrackId = number;
|
|
|
21
26
|
export type Datum = any;
|
|
22
27
|
export type RuleSetId = number;
|
|
23
28
|
export type TrackGroupHeader = {
|
|
24
|
-
label:{
|
|
25
|
-
text:string;
|
|
29
|
+
label: {
|
|
30
|
+
text: string;
|
|
26
31
|
// more styling options can go here
|
|
27
32
|
};
|
|
28
|
-
options:CustomTrackGroupOption[]; // for options menu dropdown
|
|
33
|
+
options: CustomTrackGroupOption[]; // for options menu dropdown
|
|
29
34
|
};
|
|
30
35
|
export type TrackGroup = {
|
|
31
|
-
header?:TrackGroupHeader;
|
|
32
|
-
tracks:TrackId[];
|
|
33
|
-
}
|
|
36
|
+
header?: TrackGroupHeader;
|
|
37
|
+
tracks: TrackId[];
|
|
38
|
+
};
|
|
34
39
|
export type TrackGroupIndex = number;
|
|
35
|
-
export type TrackSortDirection = 0|1
|
|
36
|
-
export type TrackSortComparator<D> = (d1:D, d2:D)=>number
|
|
37
|
-
export type TrackSortVector<D> = (d:D)=>(number|string)[]; // maps data to vector used for bucket sort - types of elements in each position must be same, i.e. Kth element must always be a number, or always be a string
|
|
38
|
-
export type TrackTooltipFn<D> = (cell_data:D[])=>HTMLElement|string|any;
|
|
40
|
+
export type TrackSortDirection = 0 | 1 | -1;
|
|
41
|
+
export type TrackSortComparator<D> = (d1: D, d2: D) => number; //returns (0|1|2|-1|-2); for comparison-based sort, where 2 and -2 mean force to end or beginning (resp) no matter what direction sorted in
|
|
42
|
+
export type TrackSortVector<D> = (d: D) => (number | string)[]; // maps data to vector used for bucket sort - types of elements in each position must be same, i.e. Kth element must always be a number, or always be a string
|
|
43
|
+
export type TrackTooltipFn<D> = (cell_data: D[]) => HTMLElement | string | any;
|
|
39
44
|
export type TrackSortSpecificationComparators<D> = {
|
|
40
|
-
mandatory:TrackSortComparator<D>; // specifies the mandatory order for the track
|
|
41
|
-
preferred:TrackSortComparator<D>; // specifies the preferred order for the track (can be overridden by mandatory order of higher track)
|
|
42
|
-
isVector?:false;
|
|
45
|
+
mandatory: TrackSortComparator<D>; // specifies the mandatory order for the track
|
|
46
|
+
preferred: TrackSortComparator<D>; // specifies the preferred order for the track (can be overridden by mandatory order of higher track)
|
|
47
|
+
isVector?: false;
|
|
43
48
|
};
|
|
44
49
|
export type TrackSortSpecificationVectors<D> = {
|
|
45
50
|
mandatory: TrackSortVector<D>; // specifies the mandatory order for the track
|
|
46
51
|
preferred: TrackSortVector<D>; // specifies the preferred order for the track (can be overridden by mandatory order of higher track)
|
|
47
52
|
isVector: true;
|
|
48
|
-
compareEquals?:TrackSortComparator<D>; // specifies a comparator to be applied to sort among equal sort vectors in the *preferred* order (optional). eg sort by sample id if all else equal
|
|
53
|
+
compareEquals?: TrackSortComparator<D>; // specifies a comparator to be applied to sort among equal sort vectors in the *preferred* order (optional). eg sort by sample id if all else equal
|
|
54
|
+
};
|
|
55
|
+
export type TrackSortSpecification<D> =
|
|
56
|
+
| TrackSortSpecificationComparators<D>
|
|
57
|
+
| TrackSortSpecificationVectors<D>;
|
|
58
|
+
export type ActiveRules = { [ruleId: number]: boolean };
|
|
59
|
+
export type ActiveRulesCount = { [ruleId: number]: number };
|
|
60
|
+
export type TrackSortDirectionChangeCallback = (
|
|
61
|
+
track_id: TrackId,
|
|
62
|
+
dir: number
|
|
63
|
+
) => void;
|
|
64
|
+
export type TrackGapChangeCallBack = (track_id: TrackId, on: boolean) => void;
|
|
65
|
+
export type CustomTrackOption = {
|
|
66
|
+
label?: string;
|
|
67
|
+
separator?: boolean;
|
|
68
|
+
onClick?: (id: TrackId) => void;
|
|
69
|
+
weight?: string;
|
|
70
|
+
disabled?: boolean;
|
|
71
|
+
};
|
|
72
|
+
export type CustomTrackGroupOption = {
|
|
73
|
+
label?: string;
|
|
74
|
+
separator?: boolean;
|
|
75
|
+
onClick?: (id: TrackGroupIndex) => void;
|
|
76
|
+
weight?: () => string;
|
|
77
|
+
disabled?: () => boolean;
|
|
49
78
|
};
|
|
50
|
-
export type TrackSortSpecification<D> = TrackSortSpecificationComparators<D> | TrackSortSpecificationVectors<D>;
|
|
51
|
-
export type ActiveRules = {[ruleId:number]:boolean};
|
|
52
|
-
export type ActiveRulesCount = {[ruleId:number]:number};
|
|
53
|
-
export type TrackSortDirectionChangeCallback = (track_id:TrackId, dir:number)=>void;
|
|
54
|
-
export type CustomTrackOption = {label?:string, separator?: boolean, onClick?:(id:TrackId)=>void, weight?:string, disabled?:boolean};
|
|
55
|
-
export type CustomTrackGroupOption = {label?:string, separator?: boolean, onClick?:(id:TrackGroupIndex)=>void, weight?:()=>string, disabled?:()=>boolean};
|
|
56
79
|
export type UserTrackSpec<D> = {
|
|
57
|
-
target_group?:TrackGroupIndex;
|
|
80
|
+
target_group?: TrackGroupIndex;
|
|
58
81
|
cell_height?: number;
|
|
59
82
|
track_padding?: number;
|
|
60
83
|
has_column_spacing?: boolean;
|
|
61
84
|
data_id_key?: string & keyof D;
|
|
62
85
|
tooltipFn?: TrackTooltipFn<D>;
|
|
63
|
-
movable?:boolean;
|
|
64
|
-
removable?:boolean;
|
|
65
|
-
removeCallback?:(track_id:TrackId)=>void;
|
|
66
|
-
onClickRemoveInTrackMenu?:(track_id:TrackId)=>void;
|
|
86
|
+
movable?: boolean;
|
|
87
|
+
removable?: boolean;
|
|
88
|
+
removeCallback?: (track_id: TrackId) => void;
|
|
89
|
+
onClickRemoveInTrackMenu?: (track_id: TrackId) => void;
|
|
67
90
|
label?: string;
|
|
68
91
|
sublabel?: string;
|
|
69
92
|
html_label?: string;
|
|
@@ -73,65 +96,74 @@ export type UserTrackSpec<D> = {
|
|
|
73
96
|
track_label_left_padding?: number;
|
|
74
97
|
link_url?: string;
|
|
75
98
|
description?: string;
|
|
76
|
-
track_info?:string;
|
|
77
|
-
sortCmpFn:TrackSortSpecification<D>;
|
|
78
|
-
sort_direction_changeable?:boolean;
|
|
79
|
-
onSortDirectionChange?:TrackSortDirectionChangeCallback;
|
|
80
|
-
|
|
81
|
-
|
|
99
|
+
track_info?: string;
|
|
100
|
+
sortCmpFn: TrackSortSpecification<D>;
|
|
101
|
+
sort_direction_changeable?: boolean;
|
|
102
|
+
onSortDirectionChange?: TrackSortDirectionChangeCallback;
|
|
103
|
+
onGapChange?: TrackGapChangeCallBack;
|
|
104
|
+
init_sort_direction?: TrackSortDirection;
|
|
105
|
+
data?: D[];
|
|
82
106
|
rule_set_params?: RuleSetParams;
|
|
83
107
|
expansion_of?: TrackId;
|
|
84
108
|
expandCallback?: (id: TrackId) => void;
|
|
85
109
|
expandButtonTextGetter?: (is_expanded: boolean) => string;
|
|
86
|
-
important_ids?:string[];
|
|
87
|
-
custom_track_options?:CustomTrackOption[];
|
|
88
|
-
$track_info_tooltip_elt?:JQuery;
|
|
89
|
-
track_can_show_gaps?:boolean;
|
|
110
|
+
important_ids?: string[];
|
|
111
|
+
custom_track_options?: CustomTrackOption[];
|
|
112
|
+
$track_info_tooltip_elt?: JQuery;
|
|
113
|
+
track_can_show_gaps?: boolean;
|
|
114
|
+
show_gaps_on_init?: boolean;
|
|
115
|
+
};
|
|
116
|
+
export type LibraryTrackSpec<D> = UserTrackSpec<D> & {
|
|
117
|
+
rule_set: RuleSet;
|
|
118
|
+
track_id: TrackId;
|
|
90
119
|
};
|
|
91
|
-
export type LibraryTrackSpec<D> = UserTrackSpec<D> & { rule_set:RuleSet, track_id:TrackId};
|
|
92
120
|
export type TrackOverlappingCells = {
|
|
93
|
-
ids:ColumnId[]
|
|
94
|
-
track:TrackId
|
|
95
|
-
top:number
|
|
96
|
-
left:number
|
|
121
|
+
ids: ColumnId[];
|
|
122
|
+
track: TrackId;
|
|
123
|
+
top: number;
|
|
124
|
+
left: number;
|
|
97
125
|
};
|
|
98
126
|
|
|
99
|
-
export type SortConfig =
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
127
|
+
export type SortConfig =
|
|
128
|
+
| {
|
|
129
|
+
type: 'alphabetical';
|
|
130
|
+
}
|
|
131
|
+
| {
|
|
132
|
+
type: 'order';
|
|
133
|
+
order: string[];
|
|
134
|
+
}
|
|
135
|
+
| {
|
|
136
|
+
type: 'cluster';
|
|
137
|
+
track_group_index: number;
|
|
138
|
+
clusterValueFn: (datum: any) => number;
|
|
139
|
+
}
|
|
140
|
+
| { type?: '' };
|
|
109
141
|
|
|
110
142
|
export type IdentifiedShapeList = {
|
|
111
|
-
id:ColumnId;
|
|
112
|
-
shape_list:ComputedShapeParams[];
|
|
143
|
+
id: ColumnId;
|
|
144
|
+
shape_list: ComputedShapeParams[];
|
|
113
145
|
};
|
|
114
146
|
|
|
115
147
|
export type ClusterSortResult = {
|
|
116
|
-
track_group_index:TrackGroupIndex;
|
|
117
|
-
track_id_order:TrackId[];
|
|
148
|
+
track_group_index: TrackGroupIndex;
|
|
149
|
+
track_id_order: TrackId[];
|
|
118
150
|
};
|
|
119
151
|
|
|
120
152
|
export type ColumnLabel = {
|
|
121
|
-
left_padding_percent?:number;
|
|
122
|
-
text_color?:string;
|
|
123
|
-
circle_color?:string;
|
|
124
|
-
angle_in_degrees?:number;
|
|
125
|
-
text:string;
|
|
153
|
+
left_padding_percent?: number;
|
|
154
|
+
text_color?: string;
|
|
155
|
+
circle_color?: string;
|
|
156
|
+
angle_in_degrees?: number;
|
|
157
|
+
text: string;
|
|
126
158
|
};
|
|
127
159
|
|
|
128
160
|
class UnionOfSets {
|
|
129
161
|
// a set, to be passed in as argument, is an object where the values are truthy
|
|
130
|
-
private union_count:{[key:string]:number} = {};
|
|
131
|
-
private sets:{[setId:string]:{[key:string]:boolean}} = {};
|
|
162
|
+
private union_count: { [key: string]: number } = {};
|
|
163
|
+
private sets: { [setId: string]: { [key: string]: boolean } } = {};
|
|
132
164
|
|
|
133
|
-
private setOfKeys(obj:{[key:string]:any}) {
|
|
134
|
-
const set:{[key:string]:boolean} = {};
|
|
165
|
+
private setOfKeys(obj: { [key: string]: any }) {
|
|
166
|
+
const set: { [key: string]: boolean } = {};
|
|
135
167
|
for (const k of Object.keys(obj)) {
|
|
136
168
|
if (typeof obj[k] !== 'undefined') {
|
|
137
169
|
set[k] = true;
|
|
@@ -140,7 +172,7 @@ class UnionOfSets {
|
|
|
140
172
|
return set;
|
|
141
173
|
}
|
|
142
174
|
|
|
143
|
-
public putSet(id:string, set:{[key:string]:boolean}) {
|
|
175
|
+
public putSet(id: string, set: { [key: string]: boolean }) {
|
|
144
176
|
this.removeSet(id);
|
|
145
177
|
this.sets[id] = set;
|
|
146
178
|
|
|
@@ -152,7 +184,7 @@ class UnionOfSets {
|
|
|
152
184
|
}
|
|
153
185
|
}
|
|
154
186
|
|
|
155
|
-
public removeSet(id:string) {
|
|
187
|
+
public removeSet(id: string) {
|
|
156
188
|
const union_count = this.union_count;
|
|
157
189
|
const old_set = this.sets[id] || {};
|
|
158
190
|
for (const k of Object.keys(old_set)) {
|
|
@@ -171,10 +203,10 @@ class UnionOfSets {
|
|
|
171
203
|
}
|
|
172
204
|
}
|
|
173
205
|
|
|
174
|
-
function arrayUnique(arr:string[]) {
|
|
175
|
-
const present:{[elt:string]:boolean} = {};
|
|
206
|
+
function arrayUnique(arr: string[]) {
|
|
207
|
+
const present: { [elt: string]: boolean } = {};
|
|
176
208
|
const unique = [];
|
|
177
|
-
for (let i=0; i<arr.length; i++) {
|
|
209
|
+
for (let i = 0; i < arr.length; i++) {
|
|
178
210
|
if (typeof present[arr[i]] === 'undefined') {
|
|
179
211
|
present[arr[i]] = true;
|
|
180
212
|
unique.push(arr[i]);
|
|
@@ -183,125 +215,132 @@ function arrayUnique(arr:string[]) {
|
|
|
183
215
|
return unique;
|
|
184
216
|
}
|
|
185
217
|
|
|
186
|
-
function copyShallowObject<T>(obj:{[key:string]:T}) {
|
|
187
|
-
const copy:{[key:string]:T} = {};
|
|
218
|
+
function copyShallowObject<T>(obj: { [key: string]: T }) {
|
|
219
|
+
const copy: { [key: string]: T } = {};
|
|
188
220
|
for (const key of Object.keys(obj)) {
|
|
189
221
|
copy[key] = obj[key];
|
|
190
222
|
}
|
|
191
223
|
return copy;
|
|
192
224
|
}
|
|
193
225
|
|
|
194
|
-
function clamp(x:number, lower:number, upper:number) {
|
|
226
|
+
function clamp(x: number, lower: number, upper: number) {
|
|
195
227
|
return Math.min(upper, Math.max(lower, x));
|
|
196
228
|
}
|
|
197
229
|
|
|
198
230
|
const MIN_ZOOM_PIXELS = 100;
|
|
199
231
|
const MIN_CELL_HEIGHT_PIXELS = 3;
|
|
200
232
|
|
|
201
|
-
export type TrackProp<T> = {[trackId:number]:T};
|
|
202
|
-
export type TrackGroupProp<T> = {[trackGroupIndex:number]:T};
|
|
203
|
-
export type ColumnProp<T> = {[columnId:string]:T};
|
|
204
|
-
export type ColumnIdSet = {[columnId:string]:any};
|
|
233
|
+
export type TrackProp<T> = { [trackId: number]: T };
|
|
234
|
+
export type TrackGroupProp<T> = { [trackGroupIndex: number]: T };
|
|
235
|
+
export type ColumnProp<T> = { [columnId: string]: T };
|
|
236
|
+
export type ColumnIdSet = { [columnId: string]: any };
|
|
205
237
|
|
|
206
238
|
export default class OncoprintModel {
|
|
207
|
-
|
|
208
239
|
// Global properties
|
|
209
|
-
private sort_config:SortConfig;
|
|
210
|
-
public rendering_suppressed_depth:number;
|
|
240
|
+
private sort_config: SortConfig;
|
|
241
|
+
public rendering_suppressed_depth: number;
|
|
211
242
|
public keep_sorted = false;
|
|
212
243
|
|
|
213
244
|
// Rendering properties
|
|
214
|
-
public readonly max_height:number;
|
|
215
|
-
private cell_width:number;
|
|
216
|
-
private horz_zoom:number;
|
|
217
|
-
private vert_zoom:number;
|
|
218
|
-
private horz_scroll:number;
|
|
219
|
-
private vert_scroll:number;
|
|
220
|
-
private bottom_padding:number;
|
|
221
|
-
private track_group_padding:number;
|
|
222
|
-
private cell_padding:number;
|
|
223
|
-
private cell_padding_on:boolean;
|
|
224
|
-
private cell_padding_off_cell_width_threshold:number;
|
|
225
|
-
private cell_padding_off_because_of_zoom:boolean;
|
|
226
|
-
private id_order:ColumnId[];
|
|
227
|
-
private hidden_ids:ColumnProp<boolean>;
|
|
228
|
-
private highlighted_ids:ColumnId[];
|
|
229
|
-
private highlighted_tracks:TrackId[];
|
|
230
|
-
private track_group_legend_order:TrackGroupIndex[];
|
|
231
|
-
private show_track_sublabels:boolean;
|
|
232
|
-
private show_track_labels:boolean;
|
|
233
|
-
private column_labels:ColumnProp<ColumnLabel>;
|
|
245
|
+
public readonly max_height: number;
|
|
246
|
+
private cell_width: number;
|
|
247
|
+
private horz_zoom: number;
|
|
248
|
+
private vert_zoom: number;
|
|
249
|
+
private horz_scroll: number;
|
|
250
|
+
private vert_scroll: number;
|
|
251
|
+
private bottom_padding: number;
|
|
252
|
+
private track_group_padding: number;
|
|
253
|
+
private cell_padding: number;
|
|
254
|
+
private cell_padding_on: boolean;
|
|
255
|
+
private cell_padding_off_cell_width_threshold: number;
|
|
256
|
+
private cell_padding_off_because_of_zoom: boolean;
|
|
257
|
+
private id_order: ColumnId[];
|
|
258
|
+
private hidden_ids: ColumnProp<boolean>;
|
|
259
|
+
private highlighted_ids: ColumnId[];
|
|
260
|
+
private highlighted_tracks: TrackId[];
|
|
261
|
+
private track_group_legend_order: TrackGroupIndex[];
|
|
262
|
+
private show_track_sublabels: boolean;
|
|
263
|
+
private show_track_labels: boolean;
|
|
264
|
+
private column_labels: ColumnProp<ColumnLabel>;
|
|
234
265
|
|
|
235
266
|
// Track properties
|
|
236
|
-
private track_important_ids:TrackProp<ColumnProp<boolean
|
|
237
|
-
private track_label:TrackProp<string>;
|
|
238
|
-
private track_label_color:TrackProp<string>;
|
|
239
|
-
private track_label_circle_color:TrackProp<string>;
|
|
240
|
-
private track_label_font_weight:TrackProp<string>;
|
|
241
|
-
private track_label_left_padding:TrackProp<number>;
|
|
242
|
-
private track_sublabel:TrackProp<string>;
|
|
243
|
-
private track_html_label:TrackProp<string>;
|
|
244
|
-
private track_link_url:TrackProp<string>;
|
|
245
|
-
private track_description:TrackProp<string>;
|
|
246
|
-
private cell_height:TrackProp<number>;
|
|
247
|
-
private track_padding:TrackProp<number>;
|
|
248
|
-
private track_data_id_key:TrackProp<string>;
|
|
249
|
-
private track_tooltip_fn:TrackProp<TrackTooltipFn<any>>;
|
|
250
|
-
private track_movable:TrackProp<boolean>;
|
|
251
|
-
private track_removable:TrackProp<boolean>;
|
|
252
|
-
private track_remove_callback:TrackProp<(track_id:TrackId)=>void>;
|
|
253
|
-
private track_remove_option_callback:TrackProp<
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
private
|
|
257
|
-
private
|
|
258
|
-
private
|
|
259
|
-
private
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
private
|
|
263
|
-
private
|
|
264
|
-
private
|
|
265
|
-
private
|
|
266
|
-
private
|
|
267
|
-
|
|
268
|
-
private
|
|
269
|
-
private
|
|
270
|
-
private
|
|
271
|
-
private
|
|
267
|
+
private track_important_ids: TrackProp<ColumnProp<boolean>>; // set of "important" ids - only these ids will cause a used rule to become active and thus shown in the legend
|
|
268
|
+
private track_label: TrackProp<string>;
|
|
269
|
+
private track_label_color: TrackProp<string>;
|
|
270
|
+
private track_label_circle_color: TrackProp<string>;
|
|
271
|
+
private track_label_font_weight: TrackProp<string>;
|
|
272
|
+
private track_label_left_padding: TrackProp<number>;
|
|
273
|
+
private track_sublabel: TrackProp<string>;
|
|
274
|
+
private track_html_label: TrackProp<string>;
|
|
275
|
+
private track_link_url: TrackProp<string>;
|
|
276
|
+
private track_description: TrackProp<string>;
|
|
277
|
+
private cell_height: TrackProp<number>;
|
|
278
|
+
private track_padding: TrackProp<number>;
|
|
279
|
+
private track_data_id_key: TrackProp<string>;
|
|
280
|
+
private track_tooltip_fn: TrackProp<TrackTooltipFn<any>>;
|
|
281
|
+
private track_movable: TrackProp<boolean>;
|
|
282
|
+
private track_removable: TrackProp<boolean>;
|
|
283
|
+
private track_remove_callback: TrackProp<(track_id: TrackId) => void>;
|
|
284
|
+
private track_remove_option_callback: TrackProp<
|
|
285
|
+
(track_id: TrackId) => void
|
|
286
|
+
>;
|
|
287
|
+
private track_sort_cmp_fn: TrackProp<TrackSortSpecification<Datum>>;
|
|
288
|
+
private track_sort_direction_changeable: TrackProp<boolean>;
|
|
289
|
+
private track_sort_direction: TrackProp<TrackSortDirection>;
|
|
290
|
+
private track_sort_direction_change_callback: TrackProp<
|
|
291
|
+
TrackSortDirectionChangeCallback
|
|
292
|
+
>;
|
|
293
|
+
private track_gap_change_callback: TrackProp<TrackGapChangeCallBack>;
|
|
294
|
+
private track_data: TrackProp<Datum[]>;
|
|
295
|
+
private track_rule_set_id: TrackProp<RuleSetId>;
|
|
296
|
+
private track_active_rules: TrackProp<ActiveRules>;
|
|
297
|
+
private track_info: TrackProp<string>;
|
|
298
|
+
private $track_info_tooltip_elt: TrackProp<JQuery>;
|
|
299
|
+
private track_has_column_spacing: TrackProp<boolean>;
|
|
300
|
+
private track_expansion_enabled: TrackProp<boolean>;
|
|
301
|
+
private track_expand_callback: TrackProp<(trackId: TrackId) => void>;
|
|
302
|
+
private track_expand_button_getter: TrackProp<
|
|
303
|
+
(is_expanded: boolean) => string
|
|
304
|
+
>;
|
|
305
|
+
public track_expansion_tracks: TrackProp<TrackId[]>;
|
|
306
|
+
private track_expansion_parent: TrackProp<TrackId>;
|
|
307
|
+
private track_custom_options: TrackProp<CustomTrackOption[]>;
|
|
308
|
+
private track_can_show_gaps: TrackProp<boolean>;
|
|
309
|
+
private track_show_gaps: TrackProp<boolean>;
|
|
272
310
|
|
|
273
311
|
// Rule set properties
|
|
274
|
-
private rule_sets:{[ruleSetId:number]:RuleSet};
|
|
275
|
-
private rule_set_active_rules:{[ruleSetId:number]:ActiveRulesCount};
|
|
312
|
+
private rule_sets: { [ruleSetId: number]: RuleSet };
|
|
313
|
+
private rule_set_active_rules: { [ruleSetId: number]: ActiveRulesCount };
|
|
276
314
|
|
|
277
315
|
// Cached and recomputed properties
|
|
278
|
-
private visible_id_order:CachedProperty<ColumnId[]>;
|
|
279
|
-
private track_id_to_datum:CachedProperty<TrackProp<ColumnProp<Datum>>>;
|
|
280
|
-
private track_present_ids:CachedProperty<UnionOfSets>;
|
|
281
|
-
private present_ids:CachedProperty<ColumnProp<boolean>>;
|
|
282
|
-
private id_to_index:CachedProperty<ColumnProp<number>>;
|
|
283
|
-
private visible_id_to_index:CachedProperty<ColumnProp<number>>;
|
|
284
|
-
private track_tops:CachedProperty<TrackProp<number>>;
|
|
285
|
-
private cell_tops:CachedProperty<TrackProp<number>>;
|
|
286
|
-
private label_tops:CachedProperty<TrackProp<number>>;
|
|
287
|
-
private track_tops_zoomed:CachedProperty<TrackProp<number>>;
|
|
288
|
-
private header_tops_zoomed:CachedProperty<TrackProp<number>>;
|
|
289
|
-
private cell_tops_zoomed:CachedProperty<TrackProp<number>>;
|
|
290
|
-
private label_tops_zoomed:CachedProperty<TrackProp<number>>;
|
|
291
|
-
private column_left:CachedProperty<ColumnProp<number>>;
|
|
292
|
-
private column_left_always_with_padding:CachedProperty<ColumnProp<number>>;
|
|
293
|
-
private zoomed_column_left:CachedProperty<ColumnProp<number>>;
|
|
294
|
-
private column_left_no_padding:CachedProperty<ColumnProp<number>>;
|
|
295
|
-
private precomputed_comparator:CachedProperty<
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
private
|
|
300
|
-
|
|
301
|
-
private
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
316
|
+
private visible_id_order: CachedProperty<ColumnId[]>;
|
|
317
|
+
private track_id_to_datum: CachedProperty<TrackProp<ColumnProp<Datum>>>;
|
|
318
|
+
private track_present_ids: CachedProperty<UnionOfSets>;
|
|
319
|
+
private present_ids: CachedProperty<ColumnProp<boolean>>;
|
|
320
|
+
private id_to_index: CachedProperty<ColumnProp<number>>;
|
|
321
|
+
private visible_id_to_index: CachedProperty<ColumnProp<number>>;
|
|
322
|
+
private track_tops: CachedProperty<TrackProp<number>>;
|
|
323
|
+
private cell_tops: CachedProperty<TrackProp<number>>;
|
|
324
|
+
private label_tops: CachedProperty<TrackProp<number>>;
|
|
325
|
+
private track_tops_zoomed: CachedProperty<TrackProp<number>>;
|
|
326
|
+
private header_tops_zoomed: CachedProperty<TrackProp<number>>;
|
|
327
|
+
private cell_tops_zoomed: CachedProperty<TrackProp<number>>;
|
|
328
|
+
private label_tops_zoomed: CachedProperty<TrackProp<number>>;
|
|
329
|
+
private column_left: CachedProperty<ColumnProp<number>>;
|
|
330
|
+
private column_left_always_with_padding: CachedProperty<ColumnProp<number>>;
|
|
331
|
+
private zoomed_column_left: CachedProperty<ColumnProp<number>>;
|
|
332
|
+
private column_left_no_padding: CachedProperty<ColumnProp<number>>;
|
|
333
|
+
private precomputed_comparator: CachedProperty<
|
|
334
|
+
TrackProp<PrecomputedComparator<Datum>>
|
|
335
|
+
>;
|
|
336
|
+
private ids_after_a_gap: CachedProperty<ColumnIdSet>;
|
|
337
|
+
private column_indexes_after_a_gap: CachedProperty<number[]>;
|
|
338
|
+
|
|
339
|
+
private track_groups: TrackGroup[];
|
|
340
|
+
private unclustered_track_group_order?: TrackId[];
|
|
341
|
+
private track_group_sort_priority: TrackGroupIndex[];
|
|
342
|
+
|
|
343
|
+
constructor(params: InitParams) {
|
|
305
344
|
const model = this;
|
|
306
345
|
|
|
307
346
|
this.sort_config = {};
|
|
@@ -317,8 +356,12 @@ export default class OncoprintModel {
|
|
|
317
356
|
this.track_group_padding = ifndef(params.init_track_group_padding, 10);
|
|
318
357
|
this.cell_padding = ifndef(params.init_cell_padding, 3);
|
|
319
358
|
this.cell_padding_on = ifndef(params.init_cell_padding_on, true);
|
|
320
|
-
this.cell_padding_off_cell_width_threshold = ifndef(
|
|
321
|
-
|
|
359
|
+
this.cell_padding_off_cell_width_threshold = ifndef(
|
|
360
|
+
params.cell_padding_off_cell_width_threshold,
|
|
361
|
+
2
|
|
362
|
+
);
|
|
363
|
+
this.cell_padding_off_because_of_zoom =
|
|
364
|
+
this.getCellWidth() < this.cell_padding_off_cell_width_threshold;
|
|
322
365
|
this.id_order = [];
|
|
323
366
|
this.hidden_ids = {};
|
|
324
367
|
this.highlighted_ids = [];
|
|
@@ -351,6 +394,7 @@ export default class OncoprintModel {
|
|
|
351
394
|
this.track_sort_direction_changeable = {};
|
|
352
395
|
this.track_sort_direction = {}; // 1: ascending, -1: descending, 0: not
|
|
353
396
|
this.track_sort_direction_change_callback = {};
|
|
397
|
+
this.track_gap_change_callback = {};
|
|
354
398
|
this.track_data = {};
|
|
355
399
|
this.track_rule_set_id = {}; // track id -> rule set id
|
|
356
400
|
this.track_active_rules = {}; // from track id to active rule map (map with rule ids as keys)
|
|
@@ -371,19 +415,24 @@ export default class OncoprintModel {
|
|
|
371
415
|
this.rule_set_active_rules = {}; // map from rule set id to map from rule id to use count
|
|
372
416
|
|
|
373
417
|
// Cached and Recomputed Properties
|
|
374
|
-
this.visible_id_order = new CachedProperty([], function
|
|
418
|
+
this.visible_id_order = new CachedProperty([], function(
|
|
419
|
+
model: OncoprintModel
|
|
420
|
+
) {
|
|
375
421
|
const hidden_ids = model.hidden_ids;
|
|
376
|
-
return model.id_order.filter(function
|
|
422
|
+
return model.id_order.filter(function(id) {
|
|
377
423
|
return !hidden_ids[id];
|
|
378
424
|
});
|
|
379
425
|
});
|
|
380
|
-
this.track_id_to_datum = new CachedProperty({}, function(
|
|
426
|
+
this.track_id_to_datum = new CachedProperty({}, function(
|
|
427
|
+
model,
|
|
428
|
+
track_id
|
|
429
|
+
) {
|
|
381
430
|
const curr = model.track_id_to_datum.get();
|
|
382
431
|
if (model.getContainingTrackGroup(track_id) !== null) {
|
|
383
|
-
const map:ColumnProp<Datum> = {};
|
|
432
|
+
const map: ColumnProp<Datum> = {};
|
|
384
433
|
const data = model.getTrackData(track_id) || [];
|
|
385
434
|
const data_id_key = model.getTrackDataIdKey(track_id) || '';
|
|
386
|
-
for (let i=0; i<data.length; i++) {
|
|
435
|
+
for (let i = 0; i < data.length; i++) {
|
|
387
436
|
map[data[i][data_id_key] as string] = data[i];
|
|
388
437
|
}
|
|
389
438
|
curr[track_id] = map;
|
|
@@ -392,10 +441,13 @@ export default class OncoprintModel {
|
|
|
392
441
|
}
|
|
393
442
|
return curr;
|
|
394
443
|
});
|
|
395
|
-
this.track_present_ids = new CachedProperty(new UnionOfSets(), function(
|
|
444
|
+
this.track_present_ids = new CachedProperty(new UnionOfSets(), function(
|
|
445
|
+
model,
|
|
446
|
+
track_id
|
|
447
|
+
) {
|
|
396
448
|
const union = model.track_present_ids.get();
|
|
397
449
|
if (model.getContainingTrackGroup(track_id) !== null) {
|
|
398
|
-
const ids:ColumnProp<boolean> = {};
|
|
450
|
+
const ids: ColumnProp<boolean> = {};
|
|
399
451
|
const data = model.getTrackData(track_id) || [];
|
|
400
452
|
const data_id_key = model.getTrackDataIdKey(track_id) || '';
|
|
401
453
|
for (let i = 0; i < data.length; i++) {
|
|
@@ -413,17 +465,17 @@ export default class OncoprintModel {
|
|
|
413
465
|
this.track_present_ids.addBoundProperty(this.present_ids);
|
|
414
466
|
|
|
415
467
|
this.id_to_index = new CachedProperty({}, function() {
|
|
416
|
-
const id_to_index:ColumnProp<number> = {};
|
|
468
|
+
const id_to_index: ColumnProp<number> = {};
|
|
417
469
|
const id_order = model.getIdOrder(true);
|
|
418
|
-
for (let i=0; i<id_order.length; i++) {
|
|
470
|
+
for (let i = 0; i < id_order.length; i++) {
|
|
419
471
|
id_to_index[id_order[i]] = i;
|
|
420
472
|
}
|
|
421
473
|
return id_to_index;
|
|
422
474
|
});
|
|
423
475
|
this.visible_id_to_index = new CachedProperty({}, function() {
|
|
424
|
-
const id_to_index:ColumnProp<number> = {};
|
|
476
|
+
const id_to_index: ColumnProp<number> = {};
|
|
425
477
|
const id_order = model.getIdOrder();
|
|
426
|
-
for (let i=0; i<id_order.length; i++) {
|
|
478
|
+
for (let i = 0; i < id_order.length; i++) {
|
|
427
479
|
id_to_index[id_order[i]] = i;
|
|
428
480
|
}
|
|
429
481
|
return id_to_index;
|
|
@@ -433,16 +485,17 @@ export default class OncoprintModel {
|
|
|
433
485
|
this.track_groups = [];
|
|
434
486
|
this.track_group_sort_priority = [];
|
|
435
487
|
|
|
436
|
-
this.track_tops = new CachedProperty({}, function
|
|
488
|
+
this.track_tops = new CachedProperty({}, function() {
|
|
437
489
|
return calculateTrackTops(model, false);
|
|
438
490
|
});
|
|
439
491
|
this.cell_tops = new CachedProperty({}, function() {
|
|
440
492
|
const track_ids = model.getTracks();
|
|
441
493
|
const track_tops = model.track_tops.get();
|
|
442
|
-
const cell_tops:TrackProp<number> = {};
|
|
494
|
+
const cell_tops: TrackProp<number> = {};
|
|
443
495
|
for (const id of track_ids) {
|
|
444
496
|
if (id in track_tops) {
|
|
445
|
-
cell_tops[id] =
|
|
497
|
+
cell_tops[id] =
|
|
498
|
+
track_tops[id] + model.getTrackPadding(id, true);
|
|
446
499
|
}
|
|
447
500
|
}
|
|
448
501
|
return cell_tops;
|
|
@@ -454,7 +507,7 @@ export default class OncoprintModel {
|
|
|
454
507
|
this.track_tops.addBoundProperty(this.cell_tops);
|
|
455
508
|
this.cell_tops.addBoundProperty(this.label_tops);
|
|
456
509
|
|
|
457
|
-
this.track_tops_zoomed = new CachedProperty({}, function
|
|
510
|
+
this.track_tops_zoomed = new CachedProperty({}, function() {
|
|
458
511
|
return calculateTrackTops(model, true);
|
|
459
512
|
});
|
|
460
513
|
this.header_tops_zoomed = new CachedProperty({}, function() {
|
|
@@ -463,7 +516,7 @@ export default class OncoprintModel {
|
|
|
463
516
|
this.cell_tops_zoomed = new CachedProperty({}, function() {
|
|
464
517
|
const track_ids = model.getTracks();
|
|
465
518
|
const track_tops = model.track_tops_zoomed.get();
|
|
466
|
-
const cell_tops:TrackProp<number> = {};
|
|
519
|
+
const cell_tops: TrackProp<number> = {};
|
|
467
520
|
for (const id of track_ids) {
|
|
468
521
|
if (id in track_tops) {
|
|
469
522
|
cell_tops[id] = track_tops[id] + model.getTrackPadding(id);
|
|
@@ -480,26 +533,37 @@ export default class OncoprintModel {
|
|
|
480
533
|
this.track_tops_zoomed.addBoundProperty(this.header_tops_zoomed);
|
|
481
534
|
this.cell_tops_zoomed.addBoundProperty(this.label_tops_zoomed);
|
|
482
535
|
|
|
483
|
-
|
|
484
|
-
|
|
536
|
+
this.precomputed_comparator = new CachedProperty({}, function(
|
|
537
|
+
model: OncoprintModel,
|
|
538
|
+
track_id: TrackId
|
|
539
|
+
) {
|
|
485
540
|
const curr_precomputed_comparator = model.precomputed_comparator.get();
|
|
486
|
-
curr_precomputed_comparator[track_id] = new PrecomputedComparator(
|
|
541
|
+
curr_precomputed_comparator[track_id] = new PrecomputedComparator(
|
|
542
|
+
model.getTrackData(track_id),
|
|
487
543
|
model.getTrackSortComparator(track_id),
|
|
488
544
|
model.getTrackSortDirection(track_id),
|
|
489
|
-
model.getTrackDataIdKey(track_id)
|
|
545
|
+
model.getTrackDataIdKey(track_id)
|
|
546
|
+
);
|
|
490
547
|
return curr_precomputed_comparator;
|
|
491
|
-
})
|
|
548
|
+
}); // track_id -> PrecomputedComparator
|
|
492
549
|
|
|
493
|
-
this.ids_after_a_gap = new CachedProperty({}, function(
|
|
494
|
-
|
|
550
|
+
this.ids_after_a_gap = new CachedProperty({}, function(
|
|
551
|
+
model: OncoprintModel
|
|
552
|
+
) {
|
|
553
|
+
const gapIds: { [columnId: string]: boolean } = {};
|
|
495
554
|
const precomputedComparator = model.precomputed_comparator.get();
|
|
496
|
-
const trackIdsWithGaps = model
|
|
555
|
+
const trackIdsWithGaps = model
|
|
556
|
+
.getTracks()
|
|
557
|
+
.filter(trackId => model.getTrackShowGaps(trackId));
|
|
497
558
|
const ids = model.visible_id_order.get();
|
|
498
559
|
|
|
499
|
-
for (let i=1; i<ids.length; i++) {
|
|
560
|
+
for (let i = 1; i < ids.length; i++) {
|
|
500
561
|
for (const trackId of trackIdsWithGaps) {
|
|
501
562
|
const comparator = precomputedComparator[trackId];
|
|
502
|
-
if (
|
|
563
|
+
if (
|
|
564
|
+
comparator.getSortValue(ids[i - 1]).mandatory !==
|
|
565
|
+
comparator.getSortValue(ids[i]).mandatory
|
|
566
|
+
) {
|
|
503
567
|
gapIds[ids[i]] = true;
|
|
504
568
|
}
|
|
505
569
|
}
|
|
@@ -510,10 +574,12 @@ export default class OncoprintModel {
|
|
|
510
574
|
this.visible_id_order.addBoundProperty(this.ids_after_a_gap);
|
|
511
575
|
this.precomputed_comparator.addBoundProperty(this.ids_after_a_gap);
|
|
512
576
|
|
|
513
|
-
this.column_indexes_after_a_gap = new CachedProperty([], function(
|
|
577
|
+
this.column_indexes_after_a_gap = new CachedProperty([], function(
|
|
578
|
+
model: OncoprintModel
|
|
579
|
+
) {
|
|
514
580
|
const ids_after_a_gap = model.ids_after_a_gap.get();
|
|
515
581
|
const id_to_index = model.getVisibleIdToIndexMap();
|
|
516
|
-
return Object.keys(ids_after_a_gap).map(id=>id_to_index[id]);
|
|
582
|
+
return Object.keys(ids_after_a_gap).map(id => id_to_index[id]);
|
|
517
583
|
});
|
|
518
584
|
this.ids_after_a_gap.addBoundProperty(this.column_indexes_after_a_gap);
|
|
519
585
|
|
|
@@ -522,7 +588,7 @@ export default class OncoprintModel {
|
|
|
522
588
|
const gap_size = model.getGapSize();
|
|
523
589
|
const ids_after_a_gap = model.ids_after_a_gap.get();
|
|
524
590
|
const cell_padding = model.getCellPadding(true);
|
|
525
|
-
const left:ColumnProp<number> = {};
|
|
591
|
+
const left: ColumnProp<number> = {};
|
|
526
592
|
const ids = model.getIdOrder();
|
|
527
593
|
let current_left = 0;
|
|
528
594
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -536,23 +602,26 @@ export default class OncoprintModel {
|
|
|
536
602
|
});
|
|
537
603
|
this.ids_after_a_gap.addBoundProperty(this.column_left);
|
|
538
604
|
|
|
539
|
-
this.column_left_always_with_padding = new CachedProperty(
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
605
|
+
this.column_left_always_with_padding = new CachedProperty(
|
|
606
|
+
{},
|
|
607
|
+
function() {
|
|
608
|
+
const cell_width = model.getCellWidth(true);
|
|
609
|
+
const gap_size = model.getGapSize();
|
|
610
|
+
const ids_after_a_gap = model.ids_after_a_gap.get();
|
|
611
|
+
const cell_padding = model.getCellPadding(true, true);
|
|
612
|
+
const left: ColumnProp<number> = {};
|
|
613
|
+
const ids = model.getIdOrder();
|
|
614
|
+
let current_left = 0;
|
|
615
|
+
for (let i = 0; i < ids.length; i++) {
|
|
616
|
+
if (ids_after_a_gap[ids[i]]) {
|
|
617
|
+
current_left += gap_size;
|
|
618
|
+
}
|
|
619
|
+
left[ids[i]] = current_left;
|
|
620
|
+
current_left += cell_width + cell_padding;
|
|
550
621
|
}
|
|
551
|
-
left
|
|
552
|
-
current_left += cell_width + cell_padding;
|
|
622
|
+
return left;
|
|
553
623
|
}
|
|
554
|
-
|
|
555
|
-
});
|
|
624
|
+
);
|
|
556
625
|
this.column_left.addBoundProperty(this.column_left_always_with_padding);
|
|
557
626
|
|
|
558
627
|
this.zoomed_column_left = new CachedProperty({}, function() {
|
|
@@ -560,7 +629,7 @@ export default class OncoprintModel {
|
|
|
560
629
|
const gap_size = model.getGapSize();
|
|
561
630
|
const ids_after_a_gap = model.ids_after_a_gap.get();
|
|
562
631
|
const cell_padding = model.getCellPadding();
|
|
563
|
-
const left:ColumnProp<number> = {};
|
|
632
|
+
const left: ColumnProp<number> = {};
|
|
564
633
|
const ids = model.getIdOrder();
|
|
565
634
|
let current_left = 0;
|
|
566
635
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -579,7 +648,7 @@ export default class OncoprintModel {
|
|
|
579
648
|
const cell_width = model.getCellWidth(true);
|
|
580
649
|
const gap_size = model.getGapSize();
|
|
581
650
|
const ids_after_a_gap = model.ids_after_a_gap.get();
|
|
582
|
-
const left:ColumnProp<number> = {};
|
|
651
|
+
const left: ColumnProp<number> = {};
|
|
583
652
|
const ids = model.getIdOrder();
|
|
584
653
|
let current_left = 0;
|
|
585
654
|
for (let i = 0; i < ids.length; i++) {
|
|
@@ -595,17 +664,17 @@ export default class OncoprintModel {
|
|
|
595
664
|
this.column_left.addBoundProperty(this.column_left_no_padding);
|
|
596
665
|
}
|
|
597
666
|
|
|
598
|
-
public setTrackShowGaps(trackId:TrackId, show:boolean) {
|
|
667
|
+
public setTrackShowGaps(trackId: TrackId, show: boolean) {
|
|
599
668
|
this.track_show_gaps[trackId] = show;
|
|
600
|
-
|
|
669
|
+
this.track_gap_change_callback[trackId](trackId, show);
|
|
601
670
|
this.ids_after_a_gap.update(this);
|
|
602
671
|
}
|
|
603
672
|
|
|
604
|
-
public getTrackShowGaps(trackId:TrackId) {
|
|
673
|
+
public getTrackShowGaps(trackId: TrackId) {
|
|
605
674
|
return this.track_show_gaps[trackId];
|
|
606
675
|
}
|
|
607
676
|
|
|
608
|
-
public getTrackCanShowGaps(trackId:TrackId) {
|
|
677
|
+
public getTrackCanShowGaps(trackId: TrackId) {
|
|
609
678
|
return this.track_can_show_gaps[trackId];
|
|
610
679
|
}
|
|
611
680
|
|
|
@@ -613,13 +682,16 @@ export default class OncoprintModel {
|
|
|
613
682
|
return this.column_indexes_after_a_gap.get();
|
|
614
683
|
}
|
|
615
684
|
|
|
616
|
-
public setTrackGroupHeader(
|
|
685
|
+
public setTrackGroupHeader(
|
|
686
|
+
index: TrackGroupIndex,
|
|
687
|
+
header?: TrackGroupHeader
|
|
688
|
+
) {
|
|
617
689
|
this.ensureTrackGroupExists(index);
|
|
618
690
|
this.getTrackGroups()[index].header = header;
|
|
619
691
|
this.track_tops.update();
|
|
620
692
|
}
|
|
621
693
|
|
|
622
|
-
public getTrackGroupHeaderHeight(trackGroup:TrackGroup) {
|
|
694
|
+
public getTrackGroupHeaderHeight(trackGroup: TrackGroup) {
|
|
623
695
|
// TODO?: depends on text style settings
|
|
624
696
|
// TODO?: depends on zoom? i dont think it should
|
|
625
697
|
if (trackGroup.header) {
|
|
@@ -635,48 +707,80 @@ export default class OncoprintModel {
|
|
|
635
707
|
return this.cell_padding_on;
|
|
636
708
|
}
|
|
637
709
|
|
|
638
|
-
public getCellPadding(base?:boolean, dont_consider_zoom?:boolean) {
|
|
639
|
-
return (
|
|
710
|
+
public getCellPadding(base?: boolean, dont_consider_zoom?: boolean) {
|
|
711
|
+
return (
|
|
712
|
+
this.cell_padding *
|
|
713
|
+
(base ? 1 : this.horz_zoom) *
|
|
714
|
+
+this.cell_padding_on *
|
|
715
|
+
(dont_consider_zoom ? 1 : +!this.cell_padding_off_because_of_zoom)
|
|
716
|
+
);
|
|
640
717
|
}
|
|
641
718
|
|
|
642
719
|
public getHorzZoom() {
|
|
643
720
|
return this.horz_zoom;
|
|
644
721
|
}
|
|
645
722
|
|
|
646
|
-
public getIdsInZoomedLeftInterval(left:number, right:number) {
|
|
723
|
+
public getIdsInZoomedLeftInterval(left: number, right: number) {
|
|
647
724
|
const leftIdIndex = this.getClosestColumnIndexToLeft(left, true);
|
|
648
|
-
const rightIdIndex = this.getClosestColumnIndexToLeft(
|
|
725
|
+
const rightIdIndex = this.getClosestColumnIndexToLeft(
|
|
726
|
+
right,
|
|
727
|
+
true,
|
|
728
|
+
true
|
|
729
|
+
);
|
|
649
730
|
return this.getIdOrder().slice(leftIdIndex, rightIdIndex);
|
|
650
731
|
}
|
|
651
732
|
|
|
652
|
-
public getHorzZoomToFitCols(
|
|
733
|
+
public getHorzZoomToFitCols(
|
|
734
|
+
width: number,
|
|
735
|
+
left_col_incl: ColumnIndex,
|
|
736
|
+
right_col_excl: ColumnIndex
|
|
737
|
+
) {
|
|
653
738
|
// in the end, the zoomed width is:
|
|
654
739
|
// W = z*(right_col_excl - left_col_incl)*baseColumnWidth + #gaps*gapSize
|
|
655
740
|
// -> z = (width - #gaps*gapSize)/(right_col_excl - left_col_incl)*baseColumnWidth
|
|
656
741
|
|
|
657
742
|
// numerator calculations
|
|
658
743
|
const allGaps = this.getColumnIndexesAfterAGap();
|
|
659
|
-
const gapsBetween = allGaps.filter(
|
|
660
|
-
|
|
744
|
+
const gapsBetween = allGaps.filter(
|
|
745
|
+
g => g >= left_col_incl && g < right_col_excl
|
|
746
|
+
);
|
|
747
|
+
const numerator = width - gapsBetween.length * this.getGapSize();
|
|
661
748
|
|
|
662
749
|
// denominator calculations
|
|
663
|
-
const columnWidthWithPadding =
|
|
750
|
+
const columnWidthWithPadding =
|
|
751
|
+
this.getCellWidth(true) + this.getCellPadding(true, true);
|
|
664
752
|
const columnWidthNoPadding = this.getCellWidth(true);
|
|
665
753
|
|
|
666
|
-
const denominatorWithPadding =
|
|
667
|
-
|
|
754
|
+
const denominatorWithPadding =
|
|
755
|
+
(right_col_excl - left_col_incl) * columnWidthWithPadding;
|
|
756
|
+
const denominatorNoPadding =
|
|
757
|
+
(right_col_excl - left_col_incl) * columnWidthNoPadding;
|
|
668
758
|
|
|
669
759
|
// put them together
|
|
670
|
-
const zoom_if_cell_padding_on = clamp(
|
|
671
|
-
|
|
760
|
+
const zoom_if_cell_padding_on = clamp(
|
|
761
|
+
numerator / denominatorWithPadding,
|
|
762
|
+
0,
|
|
763
|
+
1
|
|
764
|
+
);
|
|
765
|
+
const zoom_if_cell_padding_off = clamp(
|
|
766
|
+
numerator / denominatorNoPadding,
|
|
767
|
+
0,
|
|
768
|
+
1
|
|
769
|
+
);
|
|
672
770
|
|
|
673
771
|
let zoom;
|
|
674
772
|
if (!this.cell_padding_on) {
|
|
675
773
|
zoom = zoom_if_cell_padding_off;
|
|
676
774
|
} else {
|
|
677
775
|
const cell_width = this.getCellWidth(true);
|
|
678
|
-
if (
|
|
679
|
-
|
|
776
|
+
if (
|
|
777
|
+
cell_width * zoom_if_cell_padding_on <
|
|
778
|
+
this.cell_padding_off_cell_width_threshold
|
|
779
|
+
) {
|
|
780
|
+
if (
|
|
781
|
+
cell_width * zoom_if_cell_padding_off >=
|
|
782
|
+
this.cell_padding_off_cell_width_threshold
|
|
783
|
+
) {
|
|
680
784
|
// Because of cell padding toggling there's no way to get exactly the desired number of columns.
|
|
681
785
|
// We can see this by contradiction: if we assume that cell padding is on, and try to fit exactly
|
|
682
786
|
// our number of columns, we end up turning cell padding off (outer if statement). If we assume that
|
|
@@ -694,20 +798,22 @@ export default class OncoprintModel {
|
|
|
694
798
|
return zoom;
|
|
695
799
|
}
|
|
696
800
|
|
|
697
|
-
public getHorzZoomToFit(width:number, ids:ColumnId[]) {
|
|
801
|
+
public getHorzZoomToFit(width: number, ids: ColumnId[]) {
|
|
698
802
|
ids = ids || [];
|
|
699
803
|
if (ids.length === 0) {
|
|
700
804
|
return 1;
|
|
701
805
|
}
|
|
702
806
|
const id_to_index_map = this.getVisibleIdToIndexMap();
|
|
703
|
-
const indexes = ids.map(function(id) {
|
|
807
|
+
const indexes = ids.map(function(id) {
|
|
808
|
+
return id_to_index_map[id];
|
|
809
|
+
});
|
|
704
810
|
let max = Number.NEGATIVE_INFINITY;
|
|
705
811
|
let min = Number.POSITIVE_INFINITY;
|
|
706
|
-
for (let i=0; i<indexes.length; i++) {
|
|
812
|
+
for (let i = 0; i < indexes.length; i++) {
|
|
707
813
|
max = Math.max(indexes[i], max);
|
|
708
814
|
min = Math.min(indexes[i], min);
|
|
709
815
|
}
|
|
710
|
-
return this.getHorzZoomToFitCols(width, min, max+1);
|
|
816
|
+
return this.getHorzZoomToFitCols(width, min, max + 1);
|
|
711
817
|
}
|
|
712
818
|
|
|
713
819
|
public getMinHorzZoom() {
|
|
@@ -725,15 +831,15 @@ export default class OncoprintModel {
|
|
|
725
831
|
}
|
|
726
832
|
}
|
|
727
833
|
|
|
728
|
-
public setHorzScroll(s:number) {
|
|
834
|
+
public setHorzScroll(s: number) {
|
|
729
835
|
this.horz_scroll = Math.max(0, s);
|
|
730
836
|
return this.horz_scroll;
|
|
731
837
|
}
|
|
732
|
-
public setVertScroll(s:number) {
|
|
838
|
+
public setVertScroll(s: number) {
|
|
733
839
|
this.vert_scroll = Math.max(0, s);
|
|
734
840
|
return this.vert_scroll;
|
|
735
841
|
}
|
|
736
|
-
public setScroll(h:number, v:number) {
|
|
842
|
+
public setScroll(h: number, v: number) {
|
|
737
843
|
this.setHorzScroll(h);
|
|
738
844
|
this.setVertScroll(v);
|
|
739
845
|
}
|
|
@@ -743,22 +849,28 @@ export default class OncoprintModel {
|
|
|
743
849
|
public getVertScroll() {
|
|
744
850
|
return this.vert_scroll;
|
|
745
851
|
}
|
|
746
|
-
public setZoom(zoom_x:number, zoom_y:number) {
|
|
852
|
+
public setZoom(zoom_x: number, zoom_y: number) {
|
|
747
853
|
this.setHorzZoom(zoom_x);
|
|
748
854
|
this.setVertZoom(zoom_y);
|
|
749
855
|
}
|
|
750
|
-
private setCellPaddingOffBecauseOfZoom(val:boolean) {
|
|
856
|
+
private setCellPaddingOffBecauseOfZoom(val: boolean) {
|
|
751
857
|
this.cell_padding_off_because_of_zoom = val;
|
|
752
858
|
this.column_left.update();
|
|
753
859
|
}
|
|
754
|
-
public setHorzZoom(z:number) {
|
|
860
|
+
public setHorzZoom(z: number) {
|
|
755
861
|
const min_zoom = this.getMinHorzZoom();
|
|
756
862
|
this.horz_zoom = clamp(z, min_zoom, 1);
|
|
757
863
|
this.column_left.update();
|
|
758
864
|
|
|
759
|
-
if (
|
|
865
|
+
if (
|
|
866
|
+
this.getCellWidth() < this.cell_padding_off_cell_width_threshold &&
|
|
867
|
+
!this.cell_padding_off_because_of_zoom
|
|
868
|
+
) {
|
|
760
869
|
this.setCellPaddingOffBecauseOfZoom(true);
|
|
761
|
-
} else if (
|
|
870
|
+
} else if (
|
|
871
|
+
this.getCellWidth() >= this.cell_padding_off_cell_width_threshold &&
|
|
872
|
+
this.cell_padding_off_because_of_zoom
|
|
873
|
+
) {
|
|
762
874
|
this.setCellPaddingOffBecauseOfZoom(false);
|
|
763
875
|
}
|
|
764
876
|
return this.horz_zoom;
|
|
@@ -768,14 +880,14 @@ export default class OncoprintModel {
|
|
|
768
880
|
return this.vert_zoom;
|
|
769
881
|
}
|
|
770
882
|
|
|
771
|
-
public setVertZoom(z:number) {
|
|
883
|
+
public setVertZoom(z: number) {
|
|
772
884
|
const min_zoom = this.getMinVertZoom();
|
|
773
885
|
this.vert_zoom = clamp(z, min_zoom, 1);
|
|
774
886
|
this.track_tops.update();
|
|
775
887
|
return this.vert_zoom;
|
|
776
888
|
}
|
|
777
889
|
|
|
778
|
-
public setShowTrackLabels(s:boolean) {
|
|
890
|
+
public setShowTrackLabels(s: boolean) {
|
|
779
891
|
this.show_track_labels = s;
|
|
780
892
|
}
|
|
781
893
|
|
|
@@ -783,27 +895,29 @@ export default class OncoprintModel {
|
|
|
783
895
|
return this.show_track_labels;
|
|
784
896
|
}
|
|
785
897
|
|
|
786
|
-
public hideTrackLegends(track_ids:TrackId[]) {
|
|
898
|
+
public hideTrackLegends(track_ids: TrackId[]) {
|
|
787
899
|
track_ids = [].concat(track_ids);
|
|
788
|
-
for (let i=0; i<track_ids.length; i++) {
|
|
900
|
+
for (let i = 0; i < track_ids.length; i++) {
|
|
789
901
|
this.getRuleSet(track_ids[i]).exclude_from_legend = true;
|
|
790
902
|
}
|
|
791
903
|
}
|
|
792
904
|
|
|
793
|
-
public showTrackLegends(track_ids:TrackId[]) {
|
|
905
|
+
public showTrackLegends(track_ids: TrackId[]) {
|
|
794
906
|
track_ids = [].concat(track_ids);
|
|
795
|
-
for (let i=0; i<track_ids.length; i++) {
|
|
907
|
+
for (let i = 0; i < track_ids.length; i++) {
|
|
796
908
|
this.getRuleSet(track_ids[i]).exclude_from_legend = false;
|
|
797
909
|
}
|
|
798
910
|
}
|
|
799
911
|
|
|
800
|
-
private clearTrackActiveRules(track_id:TrackId) {
|
|
912
|
+
private clearTrackActiveRules(track_id: TrackId) {
|
|
801
913
|
const rule_set_id = this.track_rule_set_id[track_id];
|
|
802
914
|
const track_active_rules = this.track_active_rules[track_id];
|
|
803
915
|
const rule_set_active_rules = this.rule_set_active_rules[rule_set_id];
|
|
804
916
|
|
|
805
|
-
const track_active_rule_ids = Object.keys(track_active_rules).map(x=>
|
|
806
|
-
|
|
917
|
+
const track_active_rule_ids = Object.keys(track_active_rules).map(x =>
|
|
918
|
+
parseInt(x, 10)
|
|
919
|
+
);
|
|
920
|
+
for (let i = 0; i < track_active_rule_ids.length; i++) {
|
|
807
921
|
const rule_id = track_active_rule_ids[i];
|
|
808
922
|
if (rule_set_active_rules.hasOwnProperty(rule_id)) {
|
|
809
923
|
rule_set_active_rules[rule_id] -= 1;
|
|
@@ -813,80 +927,101 @@ export default class OncoprintModel {
|
|
|
813
927
|
}
|
|
814
928
|
}
|
|
815
929
|
this.track_active_rules[track_id] = {};
|
|
816
|
-
}
|
|
930
|
+
}
|
|
817
931
|
|
|
818
|
-
private setTrackActiveRules(track_id:TrackId, active_rules:ActiveRules) {
|
|
932
|
+
private setTrackActiveRules(track_id: TrackId, active_rules: ActiveRules) {
|
|
819
933
|
this.clearTrackActiveRules(track_id);
|
|
820
934
|
this.track_active_rules[track_id] = active_rules;
|
|
821
935
|
const rule_set_id = this.track_rule_set_id[track_id];
|
|
822
936
|
const rule_set_active_rules = this.rule_set_active_rules[rule_set_id];
|
|
823
937
|
|
|
824
|
-
const track_active_rule_ids = Object.keys(active_rules).map(x=>
|
|
825
|
-
|
|
938
|
+
const track_active_rule_ids = Object.keys(active_rules).map(x =>
|
|
939
|
+
parseInt(x, 0)
|
|
940
|
+
);
|
|
941
|
+
for (let i = 0; i < track_active_rule_ids.length; i++) {
|
|
826
942
|
const rule_id = track_active_rule_ids[i];
|
|
827
|
-
rule_set_active_rules[rule_id] =
|
|
943
|
+
rule_set_active_rules[rule_id] =
|
|
944
|
+
rule_set_active_rules[rule_id] || 0;
|
|
828
945
|
rule_set_active_rules[rule_id] += 1;
|
|
829
946
|
}
|
|
830
|
-
}
|
|
947
|
+
}
|
|
831
948
|
|
|
832
949
|
public getTrackUniversalShapes(
|
|
833
|
-
track_id:TrackId,
|
|
834
|
-
use_base_size:boolean
|
|
835
|
-
):ComputedShapeParams[] {
|
|
950
|
+
track_id: TrackId,
|
|
951
|
+
use_base_size: boolean
|
|
952
|
+
): ComputedShapeParams[] {
|
|
836
953
|
const ruleSet = this.getRuleSet(track_id);
|
|
837
954
|
const spacing = this.getTrackHasColumnSpacing(track_id);
|
|
838
|
-
const width =
|
|
955
|
+
const width =
|
|
956
|
+
this.getCellWidth(use_base_size) +
|
|
957
|
+
(!spacing ? this.getCellPadding(use_base_size, true) : 0);
|
|
839
958
|
const height = this.getCellHeight(track_id, use_base_size);
|
|
840
959
|
|
|
841
960
|
return ruleSet.getUniversalShapes(width, height);
|
|
842
961
|
}
|
|
843
962
|
|
|
844
963
|
public getSpecificShapesForData(
|
|
845
|
-
track_id:TrackId,
|
|
846
|
-
use_base_size:boolean
|
|
847
|
-
):IdentifiedShapeList[] {
|
|
964
|
+
track_id: TrackId,
|
|
965
|
+
use_base_size: boolean
|
|
966
|
+
): IdentifiedShapeList[] {
|
|
848
967
|
const active_rules = {};
|
|
849
968
|
const data = this.getTrackData(track_id);
|
|
850
969
|
const id_key = this.getTrackDataIdKey(track_id);
|
|
851
970
|
const spacing = this.getTrackHasColumnSpacing(track_id);
|
|
852
|
-
const width =
|
|
971
|
+
const width =
|
|
972
|
+
this.getCellWidth(use_base_size) +
|
|
973
|
+
(!spacing ? this.getCellPadding(use_base_size, true) : 0);
|
|
853
974
|
const shapes = this.getRuleSet(track_id).getSpecificShapesForDatum(
|
|
854
|
-
data,
|
|
975
|
+
data,
|
|
976
|
+
width,
|
|
977
|
+
this.getCellHeight(track_id, use_base_size),
|
|
978
|
+
active_rules,
|
|
979
|
+
id_key,
|
|
980
|
+
this.getTrackImportantIds(track_id)
|
|
855
981
|
);
|
|
856
982
|
|
|
857
983
|
this.setTrackActiveRules(track_id, active_rules);
|
|
858
984
|
|
|
859
|
-
return shapes.map(function(
|
|
985
|
+
return shapes.map(function(
|
|
986
|
+
shape_list: ComputedShapeParams[],
|
|
987
|
+
index: number
|
|
988
|
+
) {
|
|
860
989
|
return {
|
|
861
990
|
id: data[index][id_key],
|
|
862
|
-
shape_list: shape_list
|
|
991
|
+
shape_list: shape_list,
|
|
863
992
|
};
|
|
864
993
|
});
|
|
865
994
|
}
|
|
866
995
|
|
|
867
|
-
public getActiveRules(rule_set_id:RuleSetId) {
|
|
996
|
+
public getActiveRules(rule_set_id: RuleSetId) {
|
|
868
997
|
const rule_set_active_rules = this.rule_set_active_rules[rule_set_id];
|
|
869
998
|
if (rule_set_active_rules) {
|
|
870
|
-
return this.rule_sets[rule_set_id]
|
|
871
|
-
|
|
872
|
-
|
|
999
|
+
return this.rule_sets[rule_set_id]
|
|
1000
|
+
.getSpecificRulesForDatum()
|
|
1001
|
+
.filter(function(rule_with_id: RuleWithId) {
|
|
1002
|
+
return !!rule_set_active_rules[rule_with_id.id];
|
|
1003
|
+
});
|
|
873
1004
|
} else {
|
|
874
1005
|
return [];
|
|
875
1006
|
}
|
|
876
1007
|
}
|
|
877
1008
|
|
|
878
|
-
public setTrackImportantIds(track_id:TrackId, ids?:ColumnId[]) {
|
|
1009
|
+
public setTrackImportantIds(track_id: TrackId, ids?: ColumnId[]) {
|
|
879
1010
|
if (!ids) {
|
|
880
1011
|
this.track_important_ids[track_id] = undefined;
|
|
881
1012
|
} else {
|
|
882
|
-
this.track_important_ids[track_id] = ids.reduce(function(
|
|
1013
|
+
this.track_important_ids[track_id] = ids.reduce(function(
|
|
1014
|
+
map: ColumnProp<boolean>,
|
|
1015
|
+
next_id: ColumnId
|
|
1016
|
+
) {
|
|
883
1017
|
map[next_id] = true;
|
|
884
1018
|
return map;
|
|
885
|
-
},
|
|
1019
|
+
},
|
|
1020
|
+
{});
|
|
886
1021
|
}
|
|
887
1022
|
}
|
|
888
1023
|
|
|
889
|
-
public getTrackImportantIds(track_id:TrackId) {
|
|
1024
|
+
public getTrackImportantIds(track_id: TrackId) {
|
|
890
1025
|
return this.track_important_ids[track_id];
|
|
891
1026
|
}
|
|
892
1027
|
|
|
@@ -894,70 +1029,87 @@ export default class OncoprintModel {
|
|
|
894
1029
|
// return rule sets, in track group legend order
|
|
895
1030
|
const self = this;
|
|
896
1031
|
const legend_order = this.getTrackGroupLegendOrder();
|
|
897
|
-
const used_track_groups:{[trackGroupIndex:number]:boolean} = {};
|
|
1032
|
+
const used_track_groups: { [trackGroupIndex: number]: boolean } = {};
|
|
898
1033
|
const track_groups = this.getTrackGroups();
|
|
899
1034
|
const sorted_track_groups = [];
|
|
900
|
-
for (let i=0; i<legend_order.length; i++) {
|
|
1035
|
+
for (let i = 0; i < legend_order.length; i++) {
|
|
901
1036
|
// add track groups in legend order
|
|
902
1037
|
used_track_groups[legend_order[i]] = true;
|
|
903
1038
|
if (track_groups[legend_order[i]]) {
|
|
904
1039
|
sorted_track_groups.push(track_groups[legend_order[i]]);
|
|
905
1040
|
}
|
|
906
1041
|
}
|
|
907
|
-
for (let i=0; i<track_groups.length; i++) {
|
|
1042
|
+
for (let i = 0; i < track_groups.length; i++) {
|
|
908
1043
|
// add groups not in legend order to end
|
|
909
1044
|
if (!used_track_groups[i] && track_groups[i]) {
|
|
910
1045
|
sorted_track_groups.push(track_groups[i]);
|
|
911
1046
|
}
|
|
912
1047
|
}
|
|
913
|
-
const sorted_tracks:TrackId[] = sorted_track_groups.reduce(function(
|
|
914
|
-
|
|
1048
|
+
const sorted_tracks: TrackId[] = sorted_track_groups.reduce(function(
|
|
1049
|
+
acc: TrackId[],
|
|
1050
|
+
next
|
|
1051
|
+
) {
|
|
1052
|
+
return acc.concat(next.tracks);
|
|
1053
|
+
},
|
|
1054
|
+
[]);
|
|
1055
|
+
const rule_set_ids: number[] = sorted_tracks.map(function(
|
|
1056
|
+
track_id: TrackId
|
|
1057
|
+
) {
|
|
915
1058
|
return self.track_rule_set_id[track_id];
|
|
916
1059
|
});
|
|
917
|
-
const unique_rule_set_ids = arrayUnique(
|
|
1060
|
+
const unique_rule_set_ids = arrayUnique(
|
|
1061
|
+
rule_set_ids.map(x => x.toString())
|
|
1062
|
+
);
|
|
918
1063
|
return unique_rule_set_ids.map(function(rule_set_id) {
|
|
919
1064
|
return self.rule_sets[parseInt(rule_set_id, 10)];
|
|
920
1065
|
});
|
|
921
1066
|
}
|
|
922
1067
|
|
|
923
|
-
public getTrackHasColumnSpacing(track_id:TrackId) {
|
|
924
|
-
return !!
|
|
1068
|
+
public getTrackHasColumnSpacing(track_id: TrackId) {
|
|
1069
|
+
return !!this.track_has_column_spacing[track_id];
|
|
925
1070
|
}
|
|
926
1071
|
|
|
927
1072
|
public getGapSize() {
|
|
928
1073
|
return this.getCellWidth(true);
|
|
929
1074
|
}
|
|
930
1075
|
|
|
931
|
-
public getCellWidth(base?:boolean) {
|
|
1076
|
+
public getCellWidth(base?: boolean) {
|
|
932
1077
|
return this.cell_width * (base ? 1 : this.horz_zoom);
|
|
933
1078
|
}
|
|
934
1079
|
|
|
935
|
-
public getCellHeight(track_id:TrackId, base?:boolean) {
|
|
1080
|
+
public getCellHeight(track_id: TrackId, base?: boolean) {
|
|
936
1081
|
return this.cell_height[track_id] * (base ? 1 : this.vert_zoom);
|
|
937
1082
|
}
|
|
938
1083
|
|
|
939
|
-
public getTrackInfo(track_id:TrackId) {
|
|
1084
|
+
public getTrackInfo(track_id: TrackId) {
|
|
940
1085
|
return this.track_info[track_id];
|
|
941
1086
|
}
|
|
942
1087
|
|
|
943
|
-
public setTrackInfo(track_id:TrackId, msg:string) {
|
|
1088
|
+
public setTrackInfo(track_id: TrackId, msg: string) {
|
|
944
1089
|
this.track_info[track_id] = msg;
|
|
945
1090
|
}
|
|
946
1091
|
|
|
947
|
-
public getTrackHeight(track_id:TrackId, base?:boolean) {
|
|
948
|
-
return
|
|
1092
|
+
public getTrackHeight(track_id: TrackId, base?: boolean) {
|
|
1093
|
+
return (
|
|
1094
|
+
this.getCellHeight(track_id, base) +
|
|
1095
|
+
2 * this.getTrackPadding(track_id, base)
|
|
1096
|
+
);
|
|
949
1097
|
}
|
|
950
1098
|
|
|
951
|
-
public getTrackPadding(track_id:TrackId, base?:boolean) {
|
|
1099
|
+
public getTrackPadding(track_id: TrackId, base?: boolean) {
|
|
952
1100
|
return this.track_padding[track_id] * (base ? 1 : this.vert_zoom);
|
|
953
1101
|
}
|
|
954
1102
|
public getBottomPadding() {
|
|
955
1103
|
return this.bottom_padding;
|
|
956
1104
|
}
|
|
957
|
-
public getTrackSortDirection(track_id:TrackId) {
|
|
1105
|
+
public getTrackSortDirection(track_id: TrackId) {
|
|
958
1106
|
return this.track_sort_direction[track_id];
|
|
959
1107
|
}
|
|
960
|
-
public setTrackSortDirection(
|
|
1108
|
+
public setTrackSortDirection(
|
|
1109
|
+
track_id: TrackId,
|
|
1110
|
+
dir: TrackSortDirection,
|
|
1111
|
+
no_callback?: boolean
|
|
1112
|
+
) {
|
|
961
1113
|
// see above for dir options
|
|
962
1114
|
this.track_sort_direction[track_id] = dir;
|
|
963
1115
|
if (!no_callback) {
|
|
@@ -965,7 +1117,7 @@ export default class OncoprintModel {
|
|
|
965
1117
|
}
|
|
966
1118
|
this.precomputed_comparator.update(this, track_id);
|
|
967
1119
|
}
|
|
968
|
-
public resetSortableTracksSortDirection(no_callback?:boolean) {
|
|
1120
|
+
public resetSortableTracksSortDirection(no_callback?: boolean) {
|
|
969
1121
|
const allTracks = this.getTracks();
|
|
970
1122
|
for (const trackId of allTracks) {
|
|
971
1123
|
if (this.isTrackSortDirectionChangeable(trackId)) {
|
|
@@ -974,32 +1126,33 @@ export default class OncoprintModel {
|
|
|
974
1126
|
}
|
|
975
1127
|
}
|
|
976
1128
|
|
|
977
|
-
public setCellPaddingOn(cell_padding_on:boolean) {
|
|
1129
|
+
public setCellPaddingOn(cell_padding_on: boolean) {
|
|
978
1130
|
this.cell_padding_on = cell_padding_on;
|
|
979
1131
|
this.column_left.update();
|
|
980
1132
|
}
|
|
981
|
-
public getIdOrder(all?:boolean) {
|
|
1133
|
+
public getIdOrder(all?: boolean) {
|
|
982
1134
|
if (all) {
|
|
983
1135
|
return this.id_order; // TODO: should be read-only
|
|
984
1136
|
} else {
|
|
985
1137
|
return this.visible_id_order.get();
|
|
986
1138
|
}
|
|
987
1139
|
}
|
|
988
|
-
public getClosestColumnIndexToLeft(
|
|
989
|
-
|
|
1140
|
+
public getClosestColumnIndexToLeft(
|
|
1141
|
+
left: number,
|
|
1142
|
+
zoomed?: boolean,
|
|
1143
|
+
roundUp?: boolean
|
|
1144
|
+
) {
|
|
1145
|
+
const idToLeft = zoomed
|
|
1146
|
+
? this.getZoomedColumnLeft()
|
|
1147
|
+
: this.getColumnLeft();
|
|
990
1148
|
const ids = this.getIdOrder();
|
|
991
|
-
const lastId = ids[ids.length-1];
|
|
1149
|
+
const lastId = ids[ids.length - 1];
|
|
992
1150
|
if (left > idToLeft[lastId] + this.getCellWidth()) {
|
|
993
1151
|
return ids.length;
|
|
994
1152
|
} else if (left < idToLeft[ids[0]]) {
|
|
995
1153
|
return 0;
|
|
996
1154
|
} else {
|
|
997
|
-
const index = binarysearch(
|
|
998
|
-
ids,
|
|
999
|
-
left,
|
|
1000
|
-
id=>idToLeft[id],
|
|
1001
|
-
true
|
|
1002
|
-
);
|
|
1155
|
+
const index = binarysearch(ids, left, id => idToLeft[id], true);
|
|
1003
1156
|
const id = ids[index];
|
|
1004
1157
|
const columnLeft = idToLeft[id];
|
|
1005
1158
|
if (roundUp && left !== columnLeft) {
|
|
@@ -1019,27 +1172,32 @@ export default class OncoprintModel {
|
|
|
1019
1172
|
|
|
1020
1173
|
public getHiddenIds() {
|
|
1021
1174
|
const hidden_ids = this.hidden_ids;
|
|
1022
|
-
return this.id_order.filter(function
|
|
1175
|
+
return this.id_order.filter(function(id) {
|
|
1023
1176
|
return !!hidden_ids[id];
|
|
1024
1177
|
});
|
|
1025
1178
|
}
|
|
1026
1179
|
|
|
1027
|
-
public isSortAffected(
|
|
1180
|
+
public isSortAffected(
|
|
1181
|
+
modified_ids: TrackId | TrackId[],
|
|
1182
|
+
group_or_track: 'track' | 'group'
|
|
1183
|
+
) {
|
|
1028
1184
|
modified_ids = [].concat(modified_ids);
|
|
1029
1185
|
let group_indexes;
|
|
1030
1186
|
const self = this;
|
|
1031
|
-
if (group_or_track ===
|
|
1187
|
+
if (group_or_track === 'track') {
|
|
1032
1188
|
group_indexes = modified_ids.map(function(id) {
|
|
1033
1189
|
return self.getContainingTrackGroupIndex(id);
|
|
1034
1190
|
});
|
|
1035
1191
|
} else {
|
|
1036
1192
|
group_indexes = modified_ids;
|
|
1037
1193
|
}
|
|
1038
|
-
return (
|
|
1039
|
-
|
|
1194
|
+
return (
|
|
1195
|
+
this.sort_config.type !== 'cluster' ||
|
|
1196
|
+
group_indexes.indexOf(this.sort_config.track_group_index) > -1
|
|
1197
|
+
);
|
|
1040
1198
|
}
|
|
1041
1199
|
|
|
1042
|
-
public setIdOrder(ids:ColumnId[]) {
|
|
1200
|
+
public setIdOrder(ids: ColumnId[]) {
|
|
1043
1201
|
this.id_order = ids.slice();
|
|
1044
1202
|
Object.freeze(this.id_order);
|
|
1045
1203
|
this.id_to_index.update();
|
|
@@ -1047,7 +1205,7 @@ export default class OncoprintModel {
|
|
|
1047
1205
|
this.column_left.update();
|
|
1048
1206
|
}
|
|
1049
1207
|
|
|
1050
|
-
public hideIds(to_hide:ColumnId[], show_others?:boolean) {
|
|
1208
|
+
public hideIds(to_hide: ColumnId[], show_others?: boolean) {
|
|
1051
1209
|
if (show_others) {
|
|
1052
1210
|
this.hidden_ids = {};
|
|
1053
1211
|
}
|
|
@@ -1058,39 +1216,48 @@ export default class OncoprintModel {
|
|
|
1058
1216
|
this.column_left.update();
|
|
1059
1217
|
}
|
|
1060
1218
|
|
|
1061
|
-
public setHighlightedTracks(track_ids:TrackId[]) {
|
|
1219
|
+
public setHighlightedTracks(track_ids: TrackId[]) {
|
|
1062
1220
|
this.highlighted_tracks = track_ids;
|
|
1063
1221
|
}
|
|
1064
1222
|
|
|
1065
1223
|
public getHighlightedTracks() {
|
|
1066
1224
|
const realTracks = _.keyBy(this.getTracks());
|
|
1067
|
-
return this.highlighted_tracks.filter(trackId=>
|
|
1225
|
+
return this.highlighted_tracks.filter(trackId => trackId in realTracks);
|
|
1068
1226
|
}
|
|
1069
1227
|
|
|
1070
|
-
public setHighlightedIds(ids:ColumnId[]) {
|
|
1228
|
+
public setHighlightedIds(ids: ColumnId[]) {
|
|
1071
1229
|
this.highlighted_ids = ids;
|
|
1072
1230
|
}
|
|
1073
1231
|
|
|
1074
1232
|
public getVisibleHighlightedIds() {
|
|
1075
1233
|
const visibleIds = this.getVisibleIdToIndexMap();
|
|
1076
|
-
return this.highlighted_ids.filter(uid=>
|
|
1234
|
+
return this.highlighted_ids.filter(uid => uid in visibleIds);
|
|
1077
1235
|
}
|
|
1078
1236
|
|
|
1079
1237
|
public restoreClusteredTrackGroupOrder() {
|
|
1080
|
-
if (
|
|
1238
|
+
if (
|
|
1239
|
+
this.sort_config.type === 'cluster' &&
|
|
1240
|
+
this.unclustered_track_group_order
|
|
1241
|
+
) {
|
|
1081
1242
|
const trackGroupIndex = this.sort_config.track_group_index;
|
|
1082
|
-
this.setTrackGroupOrder(
|
|
1243
|
+
this.setTrackGroupOrder(
|
|
1244
|
+
trackGroupIndex,
|
|
1245
|
+
this.unclustered_track_group_order
|
|
1246
|
+
);
|
|
1083
1247
|
}
|
|
1084
1248
|
this.unclustered_track_group_order = undefined;
|
|
1085
1249
|
}
|
|
1086
1250
|
|
|
1087
|
-
public setTrackGroupOrder(index:TrackGroupIndex, track_order:TrackId[]) {
|
|
1251
|
+
public setTrackGroupOrder(index: TrackGroupIndex, track_order: TrackId[]) {
|
|
1088
1252
|
this.track_groups[index].tracks = track_order;
|
|
1089
1253
|
|
|
1090
1254
|
this.track_tops.update();
|
|
1091
1255
|
}
|
|
1092
1256
|
|
|
1093
|
-
public moveTrackGroup(
|
|
1257
|
+
public moveTrackGroup(
|
|
1258
|
+
from_index: TrackGroupIndex,
|
|
1259
|
+
to_index: TrackGroupIndex
|
|
1260
|
+
) {
|
|
1094
1261
|
const new_groups = [];
|
|
1095
1262
|
const new_headers = [];
|
|
1096
1263
|
const group_to_move = this.track_groups[from_index];
|
|
@@ -1107,7 +1274,7 @@ export default class OncoprintModel {
|
|
|
1107
1274
|
return this.track_groups;
|
|
1108
1275
|
}
|
|
1109
1276
|
|
|
1110
|
-
public async addTracks(params_list:LibraryTrackSpec<Datum>[]) {
|
|
1277
|
+
public async addTracks(params_list: LibraryTrackSpec<Datum>[]) {
|
|
1111
1278
|
for (let i = 0; i < params_list.length; i++) {
|
|
1112
1279
|
const params = params_list[i];
|
|
1113
1280
|
this.addTrack(params);
|
|
@@ -1123,46 +1290,88 @@ export default class OncoprintModel {
|
|
|
1123
1290
|
private addTrack(params: LibraryTrackSpec<Datum>) {
|
|
1124
1291
|
const track_id = params.track_id;
|
|
1125
1292
|
this.$track_info_tooltip_elt[track_id] = params.$track_info_tooltip_elt;
|
|
1126
|
-
this.track_custom_options[track_id] = ifndef(
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
this.
|
|
1293
|
+
this.track_custom_options[track_id] = ifndef(
|
|
1294
|
+
params.custom_track_options,
|
|
1295
|
+
[]
|
|
1296
|
+
);
|
|
1297
|
+
this.track_label[track_id] = ifndef(params.label, 'Label');
|
|
1298
|
+
this.track_sublabel[track_id] = ifndef(params.sublabel, '');
|
|
1299
|
+
this.track_label_color[track_id] = ifndef(
|
|
1300
|
+
params.track_label_color,
|
|
1301
|
+
'black'
|
|
1302
|
+
);
|
|
1303
|
+
this.track_label_circle_color[track_id] =
|
|
1304
|
+
params.track_label_circle_color;
|
|
1131
1305
|
this.track_label_font_weight[track_id] = params.track_label_font_weight;
|
|
1132
|
-
this.track_label_left_padding[track_id] = ifndef(
|
|
1306
|
+
this.track_label_left_padding[track_id] = ifndef(
|
|
1307
|
+
params.track_label_left_padding,
|
|
1308
|
+
0
|
|
1309
|
+
);
|
|
1133
1310
|
this.track_link_url[track_id] = ifndef(params.link_url, null);
|
|
1134
|
-
this.track_description[track_id] = ifndef(params.description,
|
|
1311
|
+
this.track_description[track_id] = ifndef(params.description, '');
|
|
1135
1312
|
this.cell_height[track_id] = ifndef(params.cell_height, 23);
|
|
1136
1313
|
this.track_padding[track_id] = ifndef(params.track_padding, 5);
|
|
1137
|
-
this.track_has_column_spacing[track_id] = ifndef(
|
|
1314
|
+
this.track_has_column_spacing[track_id] = ifndef(
|
|
1315
|
+
params.has_column_spacing,
|
|
1316
|
+
true
|
|
1317
|
+
);
|
|
1138
1318
|
|
|
1139
|
-
this.track_tooltip_fn[track_id] = ifndef(params.tooltipFn, function
|
|
1319
|
+
this.track_tooltip_fn[track_id] = ifndef(params.tooltipFn, function(d) {
|
|
1140
1320
|
return d + '';
|
|
1141
1321
|
});
|
|
1142
1322
|
this.track_movable[track_id] = ifndef(params.movable, true);
|
|
1143
1323
|
this.track_removable[track_id] = ifndef(params.removable, false);
|
|
1144
|
-
this.track_remove_callback[track_id] = ifndef(
|
|
1145
|
-
|
|
1324
|
+
this.track_remove_callback[track_id] = ifndef(
|
|
1325
|
+
params.removeCallback,
|
|
1326
|
+
function() {}
|
|
1327
|
+
);
|
|
1328
|
+
this.track_remove_option_callback[
|
|
1329
|
+
track_id
|
|
1330
|
+
] = ifndef(params.onClickRemoveInTrackMenu, function() {});
|
|
1146
1331
|
|
|
1147
1332
|
if (typeof params.expandCallback !== 'undefined') {
|
|
1148
1333
|
this.track_expand_callback[track_id] = params.expandCallback;
|
|
1149
1334
|
this.track_expansion_enabled[track_id] = true;
|
|
1150
1335
|
}
|
|
1151
1336
|
if (typeof params.expandButtonTextGetter !== 'undefined') {
|
|
1152
|
-
this.track_expand_button_getter[track_id] =
|
|
1337
|
+
this.track_expand_button_getter[track_id] =
|
|
1338
|
+
params.expandButtonTextGetter;
|
|
1153
1339
|
}
|
|
1154
1340
|
|
|
1155
|
-
this.
|
|
1156
|
-
|
|
1341
|
+
this.track_sort_direction[track_id] = ifndef(
|
|
1342
|
+
params.init_sort_direction,
|
|
1343
|
+
1
|
|
1344
|
+
);
|
|
1345
|
+
|
|
1346
|
+
this.track_can_show_gaps[track_id] = ifndef(
|
|
1347
|
+
params.track_can_show_gaps,
|
|
1348
|
+
false
|
|
1349
|
+
);
|
|
1350
|
+
|
|
1351
|
+
const trackShowGaps = ifndef(params.show_gaps_on_init, false);
|
|
1352
|
+
this.track_show_gaps[track_id] = trackShowGaps;
|
|
1353
|
+
const trackNotSorted = this.track_sort_direction[track_id] === 0;
|
|
1354
|
+
if (trackShowGaps && trackNotSorted) {
|
|
1355
|
+
this.track_sort_direction[track_id] = 1;
|
|
1356
|
+
}
|
|
1157
1357
|
|
|
1158
1358
|
this.track_sort_cmp_fn[track_id] = params.sortCmpFn;
|
|
1159
1359
|
|
|
1160
|
-
this.track_sort_direction_changeable[track_id] = ifndef(
|
|
1161
|
-
|
|
1360
|
+
this.track_sort_direction_changeable[track_id] = ifndef(
|
|
1361
|
+
params.sort_direction_changeable,
|
|
1362
|
+
false
|
|
1363
|
+
);
|
|
1364
|
+
this.track_sort_direction_change_callback[
|
|
1365
|
+
track_id
|
|
1366
|
+
] = ifndef(params.onSortDirectionChange, function() {});
|
|
1367
|
+
this.track_gap_change_callback[track_id] = ifndef(
|
|
1368
|
+
params.onGapChange,
|
|
1369
|
+
function() {}
|
|
1370
|
+
);
|
|
1162
1371
|
this.track_data[track_id] = ifndef(params.data, []);
|
|
1163
1372
|
this.track_data_id_key[track_id] = ifndef(params.data_id_key, 'id');
|
|
1164
1373
|
|
|
1165
|
-
this.track_info[track_id] = ifndef(params.track_info,
|
|
1374
|
+
this.track_info[track_id] = ifndef(params.track_info, '');
|
|
1166
1375
|
|
|
1167
1376
|
if (typeof params.html_label !== 'undefined') {
|
|
1168
1377
|
this.track_html_label[track_id] = params.html_label;
|
|
@@ -1179,32 +1388,39 @@ export default class OncoprintModel {
|
|
|
1179
1388
|
this.setTrackImportantIds(track_id, params.important_ids);
|
|
1180
1389
|
}
|
|
1181
1390
|
|
|
1182
|
-
this.track_sort_direction[track_id] = ifndef(params.init_sort_direction, 1);
|
|
1183
|
-
|
|
1184
1391
|
params.target_group = ifndef(params.target_group, 0);
|
|
1185
1392
|
this.ensureTrackGroupExists(params.target_group);
|
|
1186
1393
|
|
|
1187
1394
|
// add track to target group
|
|
1188
1395
|
const group_arrays = [this.track_groups[params.target_group].tracks];
|
|
1189
|
-
if (
|
|
1396
|
+
if (
|
|
1397
|
+
this.sort_config.type === 'cluster' &&
|
|
1190
1398
|
this.sort_config.track_group_index === params.target_group
|
|
1191
1399
|
) {
|
|
1192
1400
|
// if target group is clustered, also add track to unclustered order
|
|
1193
1401
|
group_arrays.push(this.unclustered_track_group_order);
|
|
1194
1402
|
}
|
|
1195
1403
|
for (const group_array of group_arrays) {
|
|
1196
|
-
const target_index =
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1404
|
+
const target_index =
|
|
1405
|
+
params.expansion_of !== undefined
|
|
1406
|
+
? group_array.indexOf(
|
|
1407
|
+
this.getLastExpansion(params.expansion_of)
|
|
1408
|
+
) + 1
|
|
1409
|
+
: group_array.length;
|
|
1200
1410
|
group_array.splice(target_index, 0, track_id);
|
|
1201
1411
|
}
|
|
1202
1412
|
|
|
1203
1413
|
if (params.expansion_of !== undefined) {
|
|
1204
|
-
if (
|
|
1414
|
+
if (
|
|
1415
|
+
!this.track_expansion_tracks.hasOwnProperty(params.expansion_of)
|
|
1416
|
+
) {
|
|
1205
1417
|
this.track_expansion_tracks[params.expansion_of] = [];
|
|
1206
1418
|
}
|
|
1207
|
-
if (
|
|
1419
|
+
if (
|
|
1420
|
+
this.track_expansion_tracks[params.expansion_of].indexOf(
|
|
1421
|
+
track_id
|
|
1422
|
+
) !== -1
|
|
1423
|
+
) {
|
|
1208
1424
|
throw new Error('Illegal state: duplicate expansion track ID');
|
|
1209
1425
|
}
|
|
1210
1426
|
this.track_expansion_parent[track_id] = params.expansion_of;
|
|
@@ -1229,7 +1445,7 @@ export default class OncoprintModel {
|
|
|
1229
1445
|
this.track_tops.update();
|
|
1230
1446
|
}
|
|
1231
1447
|
|
|
1232
|
-
private ensureTrackGroupExists(index:TrackGroupIndex) {
|
|
1448
|
+
private ensureTrackGroupExists(index: TrackGroupIndex) {
|
|
1233
1449
|
while (index >= this.track_groups.length) {
|
|
1234
1450
|
this.track_groups.push({ tracks: [] });
|
|
1235
1451
|
}
|
|
@@ -1237,9 +1453,15 @@ export default class OncoprintModel {
|
|
|
1237
1453
|
|
|
1238
1454
|
// get a reference to the array that stores the order of tracks in
|
|
1239
1455
|
// the same group
|
|
1240
|
-
private _getMajorTrackGroup(
|
|
1241
|
-
|
|
1242
|
-
|
|
1456
|
+
private _getMajorTrackGroup(
|
|
1457
|
+
track_id: TrackId,
|
|
1458
|
+
return_index: true
|
|
1459
|
+
): number | null;
|
|
1460
|
+
private _getMajorTrackGroup(
|
|
1461
|
+
track_id: TrackId,
|
|
1462
|
+
return_index?: false
|
|
1463
|
+
): TrackGroup | null;
|
|
1464
|
+
private _getMajorTrackGroup(track_id: TrackId, return_index?: boolean) {
|
|
1243
1465
|
let group;
|
|
1244
1466
|
let i;
|
|
1245
1467
|
for (i = 0; i < this.track_groups.length; i++) {
|
|
@@ -1255,16 +1477,20 @@ export default class OncoprintModel {
|
|
|
1255
1477
|
}
|
|
1256
1478
|
}
|
|
1257
1479
|
// get an array listing the track IDs that a track can move around
|
|
1258
|
-
private _getEffectiveTrackGroupTracks(track_id:TrackId) {
|
|
1480
|
+
private _getEffectiveTrackGroupTracks(track_id: TrackId) {
|
|
1259
1481
|
const self = this;
|
|
1260
1482
|
let group,
|
|
1261
1483
|
parent_id = this.track_expansion_parent[track_id];
|
|
1262
1484
|
if (parent_id === undefined) {
|
|
1263
|
-
group = (function(major_group:TrackGroup) {
|
|
1264
|
-
return
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1485
|
+
group = (function(major_group: TrackGroup) {
|
|
1486
|
+
return major_group === null
|
|
1487
|
+
? null
|
|
1488
|
+
: major_group.tracks.filter(function(sibling_id) {
|
|
1489
|
+
return (
|
|
1490
|
+
self.track_expansion_parent[sibling_id] ===
|
|
1491
|
+
undefined
|
|
1492
|
+
);
|
|
1493
|
+
});
|
|
1268
1494
|
})(this._getMajorTrackGroup(track_id) as TrackGroup);
|
|
1269
1495
|
} else {
|
|
1270
1496
|
group = this.track_expansion_tracks[parent_id];
|
|
@@ -1272,10 +1498,10 @@ export default class OncoprintModel {
|
|
|
1272
1498
|
return group ? group.slice() : null;
|
|
1273
1499
|
}
|
|
1274
1500
|
|
|
1275
|
-
private isRuleSetUsed(rule_set_id:RuleSetId) {
|
|
1501
|
+
private isRuleSetUsed(rule_set_id: RuleSetId) {
|
|
1276
1502
|
let used = false;
|
|
1277
1503
|
const tracks = this.getTracks();
|
|
1278
|
-
for (let i=0; i<tracks.length; i++) {
|
|
1504
|
+
for (let i = 0; i < tracks.length; i++) {
|
|
1279
1505
|
if (this.track_rule_set_id[tracks[i]] === rule_set_id) {
|
|
1280
1506
|
used = true;
|
|
1281
1507
|
break;
|
|
@@ -1284,12 +1510,12 @@ export default class OncoprintModel {
|
|
|
1284
1510
|
return used;
|
|
1285
1511
|
}
|
|
1286
1512
|
|
|
1287
|
-
private removeRuleSet(rule_set_id:RuleSetId) {
|
|
1513
|
+
private removeRuleSet(rule_set_id: RuleSetId) {
|
|
1288
1514
|
delete this.rule_sets[rule_set_id];
|
|
1289
1515
|
delete this.rule_set_active_rules[rule_set_id];
|
|
1290
|
-
}
|
|
1516
|
+
}
|
|
1291
1517
|
|
|
1292
|
-
public removeTrack(track_id:TrackId) {
|
|
1518
|
+
public removeTrack(track_id: TrackId) {
|
|
1293
1519
|
const rule_set_id = this.track_rule_set_id[track_id];
|
|
1294
1520
|
|
|
1295
1521
|
// subtract this tracks active rules from usage count,
|
|
@@ -1322,19 +1548,31 @@ export default class OncoprintModel {
|
|
|
1322
1548
|
delete this.track_label_font_weight[track_id];
|
|
1323
1549
|
delete this.track_label_left_padding[track_id];
|
|
1324
1550
|
|
|
1325
|
-
const containing_track_group = this._getMajorTrackGroup(
|
|
1551
|
+
const containing_track_group = this._getMajorTrackGroup(
|
|
1552
|
+
track_id
|
|
1553
|
+
) as TrackGroup;
|
|
1326
1554
|
if (containing_track_group !== null) {
|
|
1327
1555
|
containing_track_group.tracks.splice(
|
|
1328
|
-
containing_track_group.tracks.indexOf(track_id),
|
|
1556
|
+
containing_track_group.tracks.indexOf(track_id),
|
|
1557
|
+
1
|
|
1558
|
+
);
|
|
1329
1559
|
}
|
|
1330
1560
|
// remove listing of the track as an expansion of its parent track
|
|
1331
|
-
const expansion_group = this.track_expansion_tracks[
|
|
1561
|
+
const expansion_group = this.track_expansion_tracks[
|
|
1562
|
+
this.track_expansion_parent[track_id]
|
|
1563
|
+
];
|
|
1332
1564
|
if (expansion_group) {
|
|
1333
1565
|
expansion_group.splice(expansion_group.indexOf(track_id), 1);
|
|
1334
1566
|
}
|
|
1335
1567
|
// remove this track from unclustered order
|
|
1336
|
-
if (
|
|
1337
|
-
this.unclustered_track_group_order
|
|
1568
|
+
if (
|
|
1569
|
+
this.unclustered_track_group_order &&
|
|
1570
|
+
this.unclustered_track_group_order.indexOf(track_id) > -1
|
|
1571
|
+
) {
|
|
1572
|
+
this.unclustered_track_group_order.splice(
|
|
1573
|
+
this.unclustered_track_group_order.indexOf(track_id),
|
|
1574
|
+
1
|
|
1575
|
+
);
|
|
1338
1576
|
}
|
|
1339
1577
|
delete this.track_expansion_parent[track_id];
|
|
1340
1578
|
this.track_tops.update();
|
|
@@ -1348,14 +1586,26 @@ export default class OncoprintModel {
|
|
|
1348
1586
|
if (!rule_set_used) {
|
|
1349
1587
|
this.removeRuleSet(rule_set_id);
|
|
1350
1588
|
}
|
|
1351
|
-
}
|
|
1589
|
+
}
|
|
1352
1590
|
|
|
1353
|
-
public getOverlappingCells(
|
|
1591
|
+
public getOverlappingCells(
|
|
1592
|
+
x: number,
|
|
1593
|
+
y: number
|
|
1594
|
+
): TrackOverlappingCells | null {
|
|
1354
1595
|
// First, see if it's in a column
|
|
1355
1596
|
const id_order = this.getIdOrder();
|
|
1356
|
-
const zoomed_column_left = this.getZoomedColumnLeft() as ColumnProp<
|
|
1597
|
+
const zoomed_column_left = this.getZoomedColumnLeft() as ColumnProp<
|
|
1598
|
+
number
|
|
1599
|
+
>;
|
|
1357
1600
|
// this gets the nearest lower index
|
|
1358
|
-
const nearest_id_index = binarysearch(
|
|
1601
|
+
const nearest_id_index = binarysearch(
|
|
1602
|
+
id_order,
|
|
1603
|
+
x,
|
|
1604
|
+
function(id) {
|
|
1605
|
+
return zoomed_column_left[id];
|
|
1606
|
+
},
|
|
1607
|
+
true
|
|
1608
|
+
);
|
|
1359
1609
|
if (nearest_id_index === -1) {
|
|
1360
1610
|
return null;
|
|
1361
1611
|
}
|
|
@@ -1363,9 +1613,14 @@ export default class OncoprintModel {
|
|
|
1363
1613
|
// Next, see if it's in a track
|
|
1364
1614
|
const tracks = this.getTracks();
|
|
1365
1615
|
const cell_tops = this.getCellTops() as TrackProp<number>;
|
|
1366
|
-
const nearest_track_index = binarysearch(
|
|
1367
|
-
|
|
1368
|
-
|
|
1616
|
+
const nearest_track_index = binarysearch(
|
|
1617
|
+
tracks,
|
|
1618
|
+
y,
|
|
1619
|
+
function(track) {
|
|
1620
|
+
return cell_tops[track];
|
|
1621
|
+
},
|
|
1622
|
+
true
|
|
1623
|
+
);
|
|
1369
1624
|
if (nearest_track_index === -1) {
|
|
1370
1625
|
return null;
|
|
1371
1626
|
}
|
|
@@ -1383,21 +1638,34 @@ export default class OncoprintModel {
|
|
|
1383
1638
|
if (!this.getTrackHasColumnSpacing(nearest_track)) {
|
|
1384
1639
|
hitzone_width += this.getCellPadding();
|
|
1385
1640
|
}
|
|
1386
|
-
for (let i=nearest_id_index; i<id_order.length; i++) {
|
|
1641
|
+
for (let i = nearest_id_index; i < id_order.length; i++) {
|
|
1387
1642
|
// if hitzone of cell touches the pixel [x,x+1), then include it
|
|
1388
|
-
if (
|
|
1643
|
+
if (
|
|
1644
|
+
doesCellIntersectPixel(
|
|
1645
|
+
[
|
|
1646
|
+
zoomed_column_left[id_order[i]],
|
|
1647
|
+
zoomed_column_left[id_order[i]] + hitzone_width,
|
|
1648
|
+
],
|
|
1649
|
+
x
|
|
1650
|
+
)
|
|
1651
|
+
) {
|
|
1389
1652
|
ids.push(id_order[i]);
|
|
1390
|
-
} else if (zoomed_column_left[id_order[i]] > x+1) {
|
|
1653
|
+
} else if (zoomed_column_left[id_order[i]] > x + 1) {
|
|
1391
1654
|
break;
|
|
1392
1655
|
}
|
|
1393
1656
|
}
|
|
1394
1657
|
if (ids.length > 0) {
|
|
1395
|
-
return {
|
|
1658
|
+
return {
|
|
1659
|
+
ids: ids,
|
|
1660
|
+
track: nearest_track,
|
|
1661
|
+
top: cell_tops[nearest_track],
|
|
1662
|
+
left: zoomed_column_left[ids[0]],
|
|
1663
|
+
};
|
|
1396
1664
|
}
|
|
1397
1665
|
return null;
|
|
1398
|
-
}
|
|
1666
|
+
}
|
|
1399
1667
|
|
|
1400
|
-
public getTrackDatum(track_id:TrackId, id:ColumnId) {
|
|
1668
|
+
public getTrackDatum(track_id: TrackId, id: ColumnId) {
|
|
1401
1669
|
const datumById = this.track_id_to_datum.get()[track_id];
|
|
1402
1670
|
if (!datumById) {
|
|
1403
1671
|
return null;
|
|
@@ -1406,9 +1674,9 @@ export default class OncoprintModel {
|
|
|
1406
1674
|
return datumById[id] || null;
|
|
1407
1675
|
}
|
|
1408
1676
|
|
|
1409
|
-
public getTrackTops():TrackProp<number>;
|
|
1410
|
-
public getTrackTops(desired_track_id:TrackId):number;
|
|
1411
|
-
public getTrackTops(desired_track_id?:TrackId) {
|
|
1677
|
+
public getTrackTops(): TrackProp<number>;
|
|
1678
|
+
public getTrackTops(desired_track_id: TrackId): number;
|
|
1679
|
+
public getTrackTops(desired_track_id?: TrackId) {
|
|
1412
1680
|
if (typeof desired_track_id === 'undefined') {
|
|
1413
1681
|
return copyShallowObject(this.track_tops.get());
|
|
1414
1682
|
} else {
|
|
@@ -1416,9 +1684,9 @@ export default class OncoprintModel {
|
|
|
1416
1684
|
}
|
|
1417
1685
|
}
|
|
1418
1686
|
|
|
1419
|
-
public getZoomedTrackTops():TrackProp<number>;
|
|
1420
|
-
public getZoomedTrackTops(desired_track_id:TrackId):number;
|
|
1421
|
-
public getZoomedTrackTops(desired_track_id?:TrackId) {
|
|
1687
|
+
public getZoomedTrackTops(): TrackProp<number>;
|
|
1688
|
+
public getZoomedTrackTops(desired_track_id: TrackId): number;
|
|
1689
|
+
public getZoomedTrackTops(desired_track_id?: TrackId) {
|
|
1422
1690
|
if (typeof desired_track_id === 'undefined') {
|
|
1423
1691
|
return copyShallowObject(this.track_tops_zoomed.get());
|
|
1424
1692
|
} else {
|
|
@@ -1426,9 +1694,9 @@ export default class OncoprintModel {
|
|
|
1426
1694
|
}
|
|
1427
1695
|
}
|
|
1428
1696
|
|
|
1429
|
-
public getZoomedHeaderTops():TrackGroupProp<number>;
|
|
1430
|
-
public getZoomedHeaderTops(track_group_index:TrackGroupIndex):number;
|
|
1431
|
-
public getZoomedHeaderTops(track_group_index?:TrackGroupIndex) {
|
|
1697
|
+
public getZoomedHeaderTops(): TrackGroupProp<number>;
|
|
1698
|
+
public getZoomedHeaderTops(track_group_index: TrackGroupIndex): number;
|
|
1699
|
+
public getZoomedHeaderTops(track_group_index?: TrackGroupIndex) {
|
|
1432
1700
|
if (typeof track_group_index === 'undefined') {
|
|
1433
1701
|
return copyShallowObject(this.header_tops_zoomed.get());
|
|
1434
1702
|
} else {
|
|
@@ -1436,31 +1704,42 @@ export default class OncoprintModel {
|
|
|
1436
1704
|
}
|
|
1437
1705
|
}
|
|
1438
1706
|
|
|
1439
|
-
public getCellTops(
|
|
1440
|
-
|
|
1441
|
-
|
|
1707
|
+
public getCellTops(
|
|
1708
|
+
desired_track_id?: undefined,
|
|
1709
|
+
base?: boolean
|
|
1710
|
+
): TrackProp<number>;
|
|
1711
|
+
public getCellTops(desired_track_id: TrackId, base?: boolean): number;
|
|
1712
|
+
public getCellTops(desired_track_id?: TrackId, base?: boolean) {
|
|
1442
1713
|
if (typeof desired_track_id === 'undefined') {
|
|
1443
|
-
return copyShallowObject(
|
|
1714
|
+
return copyShallowObject(
|
|
1715
|
+
(base ? this.cell_tops : this.cell_tops_zoomed).get()
|
|
1716
|
+
);
|
|
1444
1717
|
} else {
|
|
1445
|
-
return (base ? this.cell_tops : this.cell_tops_zoomed).get()[
|
|
1718
|
+
return (base ? this.cell_tops : this.cell_tops_zoomed).get()[
|
|
1719
|
+
desired_track_id
|
|
1720
|
+
];
|
|
1446
1721
|
}
|
|
1447
1722
|
}
|
|
1448
1723
|
|
|
1449
|
-
public getLabelTops():TrackProp<number>;
|
|
1450
|
-
public getLabelTops(desired_track_id:TrackId):number;
|
|
1451
|
-
public getLabelTops(desired_track_id?:TrackId, base?:boolean) {
|
|
1724
|
+
public getLabelTops(): TrackProp<number>;
|
|
1725
|
+
public getLabelTops(desired_track_id: TrackId): number;
|
|
1726
|
+
public getLabelTops(desired_track_id?: TrackId, base?: boolean) {
|
|
1452
1727
|
if (typeof desired_track_id === 'undefined') {
|
|
1453
|
-
return copyShallowObject(
|
|
1728
|
+
return copyShallowObject(
|
|
1729
|
+
(base ? this.label_tops : this.label_tops_zoomed).get()
|
|
1730
|
+
);
|
|
1454
1731
|
} else {
|
|
1455
|
-
return (base ? this.label_tops : this.label_tops_zoomed).get()[
|
|
1732
|
+
return (base ? this.label_tops : this.label_tops_zoomed).get()[
|
|
1733
|
+
desired_track_id
|
|
1734
|
+
];
|
|
1456
1735
|
}
|
|
1457
1736
|
}
|
|
1458
1737
|
|
|
1459
|
-
public getContainingTrackGroup(track_id:TrackId) {
|
|
1738
|
+
public getContainingTrackGroup(track_id: TrackId) {
|
|
1460
1739
|
return this._getEffectiveTrackGroupTracks(track_id);
|
|
1461
1740
|
}
|
|
1462
1741
|
|
|
1463
|
-
public getContainingTrackGroupIndex(track_id:TrackId) {
|
|
1742
|
+
public getContainingTrackGroupIndex(track_id: TrackId) {
|
|
1464
1743
|
return this._getMajorTrackGroup(track_id, true);
|
|
1465
1744
|
}
|
|
1466
1745
|
|
|
@@ -1477,9 +1756,9 @@ export default class OncoprintModel {
|
|
|
1477
1756
|
return ret;
|
|
1478
1757
|
}
|
|
1479
1758
|
|
|
1480
|
-
public getColumnLeft():ColumnProp<number>;
|
|
1481
|
-
public getColumnLeft(id:ColumnId):number;
|
|
1482
|
-
public getColumnLeft(id?:ColumnId) {
|
|
1759
|
+
public getColumnLeft(): ColumnProp<number>;
|
|
1760
|
+
public getColumnLeft(id: ColumnId): number;
|
|
1761
|
+
public getColumnLeft(id?: ColumnId) {
|
|
1483
1762
|
if (typeof id === 'undefined') {
|
|
1484
1763
|
return this.column_left.get();
|
|
1485
1764
|
} else {
|
|
@@ -1487,9 +1766,9 @@ export default class OncoprintModel {
|
|
|
1487
1766
|
}
|
|
1488
1767
|
}
|
|
1489
1768
|
|
|
1490
|
-
public getColumnLeftNoPadding():ColumnProp<number>;
|
|
1491
|
-
public getColumnLeftNoPadding(id:ColumnId):number;
|
|
1492
|
-
public getColumnLeftNoPadding(id?:ColumnId) {
|
|
1769
|
+
public getColumnLeftNoPadding(): ColumnProp<number>;
|
|
1770
|
+
public getColumnLeftNoPadding(id: ColumnId): number;
|
|
1771
|
+
public getColumnLeftNoPadding(id?: ColumnId) {
|
|
1493
1772
|
if (typeof id === 'undefined') {
|
|
1494
1773
|
return this.column_left_no_padding.get();
|
|
1495
1774
|
} else {
|
|
@@ -1497,9 +1776,9 @@ export default class OncoprintModel {
|
|
|
1497
1776
|
}
|
|
1498
1777
|
}
|
|
1499
1778
|
|
|
1500
|
-
public getZoomedColumnLeft():ColumnProp<number>;
|
|
1501
|
-
public getZoomedColumnLeft(id:ColumnId):number;
|
|
1502
|
-
public getZoomedColumnLeft(id?:ColumnId) {
|
|
1779
|
+
public getZoomedColumnLeft(): ColumnProp<number>;
|
|
1780
|
+
public getZoomedColumnLeft(id: ColumnId): number;
|
|
1781
|
+
public getZoomedColumnLeft(id?: ColumnId) {
|
|
1503
1782
|
if (typeof id === 'undefined') {
|
|
1504
1783
|
return this.zoomed_column_left.get();
|
|
1505
1784
|
} else {
|
|
@@ -1507,42 +1786,57 @@ export default class OncoprintModel {
|
|
|
1507
1786
|
}
|
|
1508
1787
|
}
|
|
1509
1788
|
|
|
1510
|
-
|
|
1511
|
-
public getOncoprintHeight(base?:boolean) {
|
|
1789
|
+
public getOncoprintHeight(base?: boolean) {
|
|
1512
1790
|
const tracks = this.getTracks();
|
|
1513
|
-
const last_track = tracks[tracks.length-1];
|
|
1514
|
-
return (
|
|
1515
|
-
|
|
1791
|
+
const last_track = tracks[tracks.length - 1];
|
|
1792
|
+
return (
|
|
1793
|
+
(base
|
|
1794
|
+
? (this.getTrackTops(last_track) as number)
|
|
1795
|
+
: (this.getZoomedTrackTops(last_track) as number)) +
|
|
1796
|
+
this.getTrackHeight(last_track, base) +
|
|
1797
|
+
this.getBottomPadding()
|
|
1798
|
+
);
|
|
1516
1799
|
}
|
|
1517
1800
|
|
|
1518
|
-
public getOncoprintWidth(base?:boolean) {
|
|
1801
|
+
public getOncoprintWidth(base?: boolean) {
|
|
1519
1802
|
const idOrder = this.getIdOrder();
|
|
1520
|
-
const lastId = idOrder[idOrder.length-1];
|
|
1521
|
-
const lastIdLeft = base
|
|
1522
|
-
|
|
1803
|
+
const lastId = idOrder[idOrder.length - 1];
|
|
1804
|
+
const lastIdLeft = base
|
|
1805
|
+
? this.getColumnLeft(lastId)
|
|
1806
|
+
: this.getZoomedColumnLeft(lastId);
|
|
1807
|
+
return lastIdLeft + this.getCellWidth(base) + 1; // this fixes some edge case issues with scrolling
|
|
1523
1808
|
}
|
|
1524
1809
|
|
|
1525
1810
|
public getOncoprintWidthNoColumnPaddingNoGaps() {
|
|
1526
|
-
return this.getIdOrder().length*this.getCellWidth(true);
|
|
1811
|
+
return this.getIdOrder().length * this.getCellWidth(true);
|
|
1527
1812
|
}
|
|
1528
1813
|
|
|
1529
1814
|
public getColumnLabels() {
|
|
1530
1815
|
return this.column_labels;
|
|
1531
1816
|
}
|
|
1532
1817
|
|
|
1533
|
-
public setColumnLabels(labels:ColumnProp<ColumnLabel>) {
|
|
1818
|
+
public setColumnLabels(labels: ColumnProp<ColumnLabel>) {
|
|
1534
1819
|
this.column_labels = labels;
|
|
1535
1820
|
}
|
|
1536
1821
|
|
|
1537
|
-
public moveTrack(track_id:TrackId, new_previous_track:TrackId) {
|
|
1538
|
-
|
|
1539
|
-
|
|
1822
|
+
public moveTrack(track_id: TrackId, new_previous_track: TrackId) {
|
|
1823
|
+
function moveContiguousValues<T>(
|
|
1824
|
+
uniqArray: T[],
|
|
1825
|
+
first_value: T,
|
|
1826
|
+
last_value: T,
|
|
1827
|
+
new_predecessor: T
|
|
1828
|
+
) {
|
|
1540
1829
|
const old_start_index = uniqArray.indexOf(first_value),
|
|
1541
1830
|
old_end_index = uniqArray.indexOf(last_value);
|
|
1542
1831
|
const values = uniqArray.slice(old_start_index, old_end_index + 1);
|
|
1543
1832
|
uniqArray.splice(old_start_index, values.length);
|
|
1544
|
-
const new_position =
|
|
1545
|
-
|
|
1833
|
+
const new_position =
|
|
1834
|
+
new_predecessor === null
|
|
1835
|
+
? 0
|
|
1836
|
+
: uniqArray.indexOf(new_predecessor) + 1;
|
|
1837
|
+
uniqArray.splice
|
|
1838
|
+
.bind(uniqArray, new_position, 0)
|
|
1839
|
+
.apply(null, values);
|
|
1546
1840
|
}
|
|
1547
1841
|
|
|
1548
1842
|
const track_group = this._getMajorTrackGroup(track_id) as TrackGroup,
|
|
@@ -1560,22 +1854,32 @@ export default class OncoprintModel {
|
|
|
1560
1854
|
} else {
|
|
1561
1855
|
flat_previous_track = this.getLastExpansion(new_previous_track);
|
|
1562
1856
|
}
|
|
1563
|
-
moveContiguousValues(
|
|
1857
|
+
moveContiguousValues(
|
|
1858
|
+
track_group.tracks,
|
|
1859
|
+
track_id,
|
|
1860
|
+
this.getLastExpansion(track_id),
|
|
1861
|
+
flat_previous_track
|
|
1862
|
+
);
|
|
1564
1863
|
}
|
|
1565
1864
|
|
|
1566
1865
|
// keep the order of expansion siblings up-to-date as well
|
|
1567
1866
|
if (this.track_expansion_parent[track_id] !== undefined) {
|
|
1568
|
-
moveContiguousValues(
|
|
1867
|
+
moveContiguousValues(
|
|
1868
|
+
this.track_expansion_tracks[expansion_parent],
|
|
1869
|
+
track_id,
|
|
1870
|
+
track_id,
|
|
1871
|
+
new_previous_track
|
|
1872
|
+
);
|
|
1569
1873
|
}
|
|
1570
1874
|
|
|
1571
1875
|
this.track_tops.update();
|
|
1572
|
-
}
|
|
1876
|
+
}
|
|
1573
1877
|
|
|
1574
|
-
public getTrackLabel(track_id:TrackId) {
|
|
1878
|
+
public getTrackLabel(track_id: TrackId) {
|
|
1575
1879
|
return this.track_label[track_id];
|
|
1576
1880
|
}
|
|
1577
1881
|
|
|
1578
|
-
public getTrackSublabel(track_id:TrackId) {
|
|
1882
|
+
public getTrackSublabel(track_id: TrackId) {
|
|
1579
1883
|
return this.track_sublabel[track_id];
|
|
1580
1884
|
}
|
|
1581
1885
|
|
|
@@ -1583,99 +1887,108 @@ export default class OncoprintModel {
|
|
|
1583
1887
|
return this.show_track_sublabels;
|
|
1584
1888
|
}
|
|
1585
1889
|
|
|
1586
|
-
public setShowTrackSublabels(show:boolean) {
|
|
1587
|
-
return this.show_track_sublabels = show;
|
|
1890
|
+
public setShowTrackSublabels(show: boolean) {
|
|
1891
|
+
return (this.show_track_sublabels = show);
|
|
1588
1892
|
}
|
|
1589
1893
|
|
|
1590
|
-
public getTrackLabelColor(track_id:TrackId) {
|
|
1894
|
+
public getTrackLabelColor(track_id: TrackId) {
|
|
1591
1895
|
return this.track_label_color[track_id];
|
|
1592
1896
|
}
|
|
1593
1897
|
|
|
1594
|
-
public getTrackLabelCircleColor(track_id:TrackId) {
|
|
1898
|
+
public getTrackLabelCircleColor(track_id: TrackId) {
|
|
1595
1899
|
return this.track_label_circle_color[track_id];
|
|
1596
1900
|
}
|
|
1597
1901
|
|
|
1598
|
-
public getTrackLabelFontWeight(track_id:TrackId) {
|
|
1902
|
+
public getTrackLabelFontWeight(track_id: TrackId) {
|
|
1599
1903
|
return this.track_label_font_weight[track_id];
|
|
1600
1904
|
}
|
|
1601
1905
|
|
|
1602
|
-
public getTrackLabelLeftPadding(track_id:TrackId) {
|
|
1906
|
+
public getTrackLabelLeftPadding(track_id: TrackId) {
|
|
1603
1907
|
return this.track_label_left_padding[track_id];
|
|
1604
1908
|
}
|
|
1605
1909
|
|
|
1606
|
-
public getOptionalHtmlTrackLabel(track_id:TrackId) {
|
|
1910
|
+
public getOptionalHtmlTrackLabel(track_id: TrackId) {
|
|
1607
1911
|
return this.track_html_label[track_id];
|
|
1608
1912
|
}
|
|
1609
1913
|
|
|
1610
|
-
public getTrackLinkUrl(track_id:TrackId) {
|
|
1914
|
+
public getTrackLinkUrl(track_id: TrackId) {
|
|
1611
1915
|
return this.track_link_url[track_id];
|
|
1612
1916
|
}
|
|
1613
1917
|
|
|
1614
|
-
public getTrackDescription(track_id:TrackId) {
|
|
1918
|
+
public getTrackDescription(track_id: TrackId) {
|
|
1615
1919
|
return this.track_description[track_id];
|
|
1616
1920
|
}
|
|
1617
1921
|
|
|
1618
|
-
public getTrackTooltipFn(track_id:TrackId) {
|
|
1922
|
+
public getTrackTooltipFn(track_id: TrackId) {
|
|
1619
1923
|
return this.track_tooltip_fn[track_id];
|
|
1620
1924
|
}
|
|
1621
|
-
public setTrackTooltipFn(
|
|
1925
|
+
public setTrackTooltipFn(
|
|
1926
|
+
track_id: TrackId,
|
|
1927
|
+
tooltipFn: TrackTooltipFn<Datum>
|
|
1928
|
+
) {
|
|
1622
1929
|
this.track_tooltip_fn[track_id] = tooltipFn;
|
|
1623
1930
|
}
|
|
1624
1931
|
|
|
1625
|
-
public getTrackDataIdKey(track_id:TrackId) {
|
|
1932
|
+
public getTrackDataIdKey(track_id: TrackId) {
|
|
1626
1933
|
return this.track_data_id_key[track_id];
|
|
1627
1934
|
}
|
|
1628
1935
|
|
|
1629
|
-
public getTrackGroupPadding(base?:boolean) {
|
|
1936
|
+
public getTrackGroupPadding(base?: boolean) {
|
|
1630
1937
|
return this.track_group_padding * (base ? 1 : this.vert_zoom);
|
|
1631
1938
|
}
|
|
1632
1939
|
|
|
1633
|
-
public isTrackRemovable(track_id:TrackId) {
|
|
1940
|
+
public isTrackRemovable(track_id: TrackId) {
|
|
1634
1941
|
return this.track_removable[track_id];
|
|
1635
1942
|
}
|
|
1636
1943
|
|
|
1637
|
-
public getTrackRemoveOptionCallback(track_id:TrackId) {
|
|
1944
|
+
public getTrackRemoveOptionCallback(track_id: TrackId) {
|
|
1638
1945
|
return this.track_remove_option_callback[track_id];
|
|
1639
1946
|
}
|
|
1640
1947
|
|
|
1641
|
-
public isTrackSortDirectionChangeable(track_id:TrackId) {
|
|
1948
|
+
public isTrackSortDirectionChangeable(track_id: TrackId) {
|
|
1642
1949
|
return this.track_sort_direction_changeable[track_id];
|
|
1643
1950
|
}
|
|
1644
1951
|
|
|
1645
|
-
public isTrackExpandable(track_id:TrackId) {
|
|
1952
|
+
public isTrackExpandable(track_id: TrackId) {
|
|
1646
1953
|
// return true if the flag is defined and true
|
|
1647
1954
|
return Boolean(this.track_expansion_enabled[track_id]);
|
|
1648
1955
|
}
|
|
1649
1956
|
|
|
1650
|
-
public expandTrack(track_id:TrackId) {
|
|
1957
|
+
public expandTrack(track_id: TrackId) {
|
|
1651
1958
|
return this.track_expand_callback[track_id](track_id);
|
|
1652
1959
|
}
|
|
1653
1960
|
|
|
1654
|
-
public disableTrackExpansion(track_id:TrackId) {
|
|
1961
|
+
public disableTrackExpansion(track_id: TrackId) {
|
|
1655
1962
|
this.track_expansion_enabled[track_id] = false;
|
|
1656
1963
|
}
|
|
1657
1964
|
|
|
1658
|
-
public enableTrackExpansion(track_id:TrackId) {
|
|
1965
|
+
public enableTrackExpansion(track_id: TrackId) {
|
|
1659
1966
|
if (!this.track_expand_callback.hasOwnProperty(track_id)) {
|
|
1660
|
-
throw new Error("Track '" + track_id +"' has no expandCallback");
|
|
1967
|
+
throw new Error("Track '" + track_id + "' has no expandCallback");
|
|
1661
1968
|
}
|
|
1662
1969
|
this.track_expansion_enabled[track_id] = true;
|
|
1663
1970
|
}
|
|
1664
1971
|
|
|
1665
|
-
public isTrackExpanded(track_id:TrackId) {
|
|
1666
|
-
return
|
|
1667
|
-
this.track_expansion_tracks
|
|
1972
|
+
public isTrackExpanded(track_id: TrackId) {
|
|
1973
|
+
return (
|
|
1974
|
+
this.track_expansion_tracks.hasOwnProperty(track_id) &&
|
|
1975
|
+
this.track_expansion_tracks[track_id].length > 0
|
|
1976
|
+
);
|
|
1668
1977
|
}
|
|
1669
1978
|
|
|
1670
|
-
public getExpandButtonText(track_id:TrackId) {
|
|
1979
|
+
public getExpandButtonText(track_id: TrackId) {
|
|
1671
1980
|
const self = this;
|
|
1672
|
-
const getExpandButtonFunction = function
|
|
1673
|
-
return (
|
|
1674
|
-
|
|
1981
|
+
const getExpandButtonFunction = function(track_id: TrackId) {
|
|
1982
|
+
return (
|
|
1983
|
+
self.track_expand_button_getter[track_id] ||
|
|
1984
|
+
function(is_expanded) {
|
|
1675
1985
|
return is_expanded ? 'Expand more' : 'Expand';
|
|
1676
|
-
}
|
|
1986
|
+
}
|
|
1987
|
+
);
|
|
1677
1988
|
};
|
|
1678
|
-
return getExpandButtonFunction(track_id)(
|
|
1989
|
+
return getExpandButtonFunction(track_id)(
|
|
1990
|
+
this.isTrackExpanded(track_id)
|
|
1991
|
+
);
|
|
1679
1992
|
}
|
|
1680
1993
|
|
|
1681
1994
|
/**
|
|
@@ -1684,9 +1997,13 @@ export default class OncoprintModel {
|
|
|
1684
1997
|
* @param {number} expansion_track_id - the ID of the track to check
|
|
1685
1998
|
* @param {number} set_track_id - the ID of the track it may be an expansion of
|
|
1686
1999
|
*/
|
|
1687
|
-
public isExpansionOf(expansion_track_id:TrackId, set_track_id:TrackId) {
|
|
1688
|
-
return
|
|
1689
|
-
this.track_expansion_tracks
|
|
2000
|
+
public isExpansionOf(expansion_track_id: TrackId, set_track_id: TrackId) {
|
|
2001
|
+
return (
|
|
2002
|
+
this.track_expansion_tracks.hasOwnProperty(set_track_id) &&
|
|
2003
|
+
this.track_expansion_tracks[set_track_id].indexOf(
|
|
2004
|
+
expansion_track_id
|
|
2005
|
+
) !== -1
|
|
2006
|
+
);
|
|
1690
2007
|
}
|
|
1691
2008
|
|
|
1692
2009
|
/**
|
|
@@ -1695,7 +2012,7 @@ export default class OncoprintModel {
|
|
|
1695
2012
|
* @param track_id - the ID of the track to start from
|
|
1696
2013
|
* @returns the ID of its last expansion, or the unchanged param if none
|
|
1697
2014
|
*/
|
|
1698
|
-
public getLastExpansion(track_id:TrackId) {
|
|
2015
|
+
public getLastExpansion(track_id: TrackId) {
|
|
1699
2016
|
let direct_children = this.track_expansion_tracks[track_id];
|
|
1700
2017
|
while (direct_children && direct_children.length) {
|
|
1701
2018
|
track_id = direct_children[direct_children.length - 1];
|
|
@@ -1704,37 +2021,45 @@ export default class OncoprintModel {
|
|
|
1704
2021
|
return track_id;
|
|
1705
2022
|
}
|
|
1706
2023
|
|
|
1707
|
-
public getTrackCustomOptions(track_id:TrackId) {
|
|
2024
|
+
public getTrackCustomOptions(track_id: TrackId) {
|
|
1708
2025
|
return this.track_custom_options[track_id];
|
|
1709
2026
|
}
|
|
1710
2027
|
|
|
1711
|
-
public setTrackCustomOptions(
|
|
2028
|
+
public setTrackCustomOptions(
|
|
2029
|
+
track_id: TrackId,
|
|
2030
|
+
options: CustomTrackOption[] | undefined
|
|
2031
|
+
) {
|
|
1712
2032
|
this.track_custom_options[track_id] = options;
|
|
1713
2033
|
}
|
|
1714
2034
|
|
|
1715
|
-
public setTrackInfoTooltip(
|
|
2035
|
+
public setTrackInfoTooltip(
|
|
2036
|
+
track_id: TrackId,
|
|
2037
|
+
$tooltip_elt: JQuery | undefined
|
|
2038
|
+
) {
|
|
1716
2039
|
this.$track_info_tooltip_elt[track_id] = $tooltip_elt;
|
|
1717
2040
|
}
|
|
1718
2041
|
|
|
1719
|
-
public $getTrackInfoTooltip(track_id:TrackId) {
|
|
2042
|
+
public $getTrackInfoTooltip(track_id: TrackId) {
|
|
1720
2043
|
return this.$track_info_tooltip_elt[track_id];
|
|
1721
2044
|
}
|
|
1722
2045
|
|
|
1723
|
-
public getRuleSet(track_id:TrackId) {
|
|
2046
|
+
public getRuleSet(track_id: TrackId) {
|
|
1724
2047
|
return this.rule_sets[this.track_rule_set_id[track_id]];
|
|
1725
2048
|
}
|
|
1726
2049
|
|
|
1727
|
-
public shareRuleSet(source_track_id:TrackId, target_track_id:TrackId) {
|
|
2050
|
+
public shareRuleSet(source_track_id: TrackId, target_track_id: TrackId) {
|
|
1728
2051
|
this.setTrackActiveRules(target_track_id, {});
|
|
1729
2052
|
|
|
1730
2053
|
const old_rule_set_id = this.track_rule_set_id[target_track_id];
|
|
1731
|
-
this.track_rule_set_id[target_track_id] = this.track_rule_set_id[
|
|
2054
|
+
this.track_rule_set_id[target_track_id] = this.track_rule_set_id[
|
|
2055
|
+
source_track_id
|
|
2056
|
+
];
|
|
1732
2057
|
if (!this.isRuleSetUsed(old_rule_set_id)) {
|
|
1733
2058
|
this.removeRuleSet(old_rule_set_id);
|
|
1734
2059
|
}
|
|
1735
2060
|
}
|
|
1736
2061
|
|
|
1737
|
-
public setRuleSet(track_id:TrackId, rule_set:RuleSet) {
|
|
2062
|
+
public setRuleSet(track_id: TrackId, rule_set: RuleSet) {
|
|
1738
2063
|
this.setTrackActiveRules(track_id, {});
|
|
1739
2064
|
|
|
1740
2065
|
const curr_rule_set_id = this.track_rule_set_id[track_id];
|
|
@@ -1748,40 +2073,47 @@ export default class OncoprintModel {
|
|
|
1748
2073
|
}
|
|
1749
2074
|
}
|
|
1750
2075
|
|
|
1751
|
-
public getTrackSortComparator(track_id:TrackId) {
|
|
2076
|
+
public getTrackSortComparator(track_id: TrackId) {
|
|
1752
2077
|
return this.track_sort_cmp_fn[track_id];
|
|
1753
2078
|
}
|
|
1754
2079
|
|
|
1755
|
-
public setTrackSortComparator(
|
|
2080
|
+
public setTrackSortComparator(
|
|
2081
|
+
track_id: TrackId,
|
|
2082
|
+
sortCmpFn: TrackSortSpecification<Datum>
|
|
2083
|
+
) {
|
|
1756
2084
|
this.track_sort_cmp_fn[track_id] = sortCmpFn;
|
|
1757
2085
|
this.precomputed_comparator.update(this, track_id);
|
|
1758
2086
|
}
|
|
1759
2087
|
|
|
1760
|
-
public getTrackData(track_id:TrackId) {
|
|
2088
|
+
public getTrackData(track_id: TrackId) {
|
|
1761
2089
|
return this.track_data[track_id];
|
|
1762
2090
|
}
|
|
1763
2091
|
|
|
1764
|
-
public clusterTrackGroup(
|
|
2092
|
+
public clusterTrackGroup(
|
|
2093
|
+
track_group_index: TrackGroupIndex,
|
|
2094
|
+
clusterValueFn: (d: Datum) => number
|
|
2095
|
+
): Promise<void | ClusterSortResult> {
|
|
1765
2096
|
const sort_config_at_call = cloneShallow(this.sort_config);
|
|
1766
2097
|
// Prepare input
|
|
1767
2098
|
const self = this;
|
|
1768
2099
|
//@ts-ignore
|
|
1769
2100
|
const def = new $.Deferred();
|
|
1770
|
-
const cluster_input:ColumnProp<TrackProp<number>> = {};
|
|
2101
|
+
const cluster_input: ColumnProp<TrackProp<number>> = {};
|
|
1771
2102
|
|
|
1772
2103
|
// Use data from tracks on the same level of expansion as the first one
|
|
1773
2104
|
// in the track group as input, i.e. the outer level excluding any
|
|
1774
2105
|
// expansions
|
|
1775
2106
|
const track_group = this.getTrackGroups()[track_group_index];
|
|
1776
|
-
let track_ids:TrackId[] = [];
|
|
2107
|
+
let track_ids: TrackId[] = [];
|
|
1777
2108
|
if (track_group !== undefined) {
|
|
1778
|
-
track_ids =
|
|
2109
|
+
track_ids =
|
|
2110
|
+
this._getEffectiveTrackGroupTracks(track_group.tracks[0]) || [];
|
|
1779
2111
|
}
|
|
1780
2112
|
for (let i = 0; i < track_ids.length; i++) {
|
|
1781
2113
|
const track_id = track_ids[i];
|
|
1782
2114
|
const data_id_key = this.getTrackDataIdKey(track_id);
|
|
1783
2115
|
const data = this.getTrackData(track_id);
|
|
1784
|
-
for (let j=0; j<data.length; j++) {
|
|
2116
|
+
for (let j = 0; j < data.length; j++) {
|
|
1785
2117
|
const id = data[j][data_id_key];
|
|
1786
2118
|
const value = clusterValueFn(data[j]);
|
|
1787
2119
|
cluster_input[id] = cluster_input[id] || {};
|
|
@@ -1799,21 +2131,31 @@ export default class OncoprintModel {
|
|
|
1799
2131
|
});*/
|
|
1800
2132
|
|
|
1801
2133
|
//do hierarchical clustering in background:
|
|
1802
|
-
$.when(hclusterColumns(cluster_input), hclusterTracks(cluster_input))
|
|
1803
|
-
function
|
|
2134
|
+
$.when(hclusterColumns(cluster_input), hclusterTracks(cluster_input))
|
|
2135
|
+
.then(function(
|
|
2136
|
+
columnClusterOrder: CaseItem[],
|
|
2137
|
+
trackClusterOrder: EntityItem[]
|
|
2138
|
+
) {
|
|
1804
2139
|
// cancel if sort config is no longer what it was
|
|
1805
2140
|
if (!_.isEqual(self.sort_config, sort_config_at_call)) {
|
|
1806
2141
|
return;
|
|
1807
2142
|
}
|
|
1808
2143
|
// set clustered column order
|
|
1809
|
-
self.setIdOrder(
|
|
2144
|
+
self.setIdOrder(
|
|
2145
|
+
columnClusterOrder.map(function(c) {
|
|
2146
|
+
return c.caseId;
|
|
2147
|
+
})
|
|
2148
|
+
); // TODO
|
|
1810
2149
|
// determine clustered row order
|
|
1811
|
-
const clustered_track_id_order = trackClusterOrder.map(function
|
|
2150
|
+
const clustered_track_id_order = trackClusterOrder.map(function(
|
|
2151
|
+
entity
|
|
2152
|
+
) {
|
|
2153
|
+
// TODO
|
|
1812
2154
|
return parseInt(entity.entityId, 10);
|
|
1813
2155
|
});
|
|
1814
2156
|
// re-insert any expansions below each clustered track
|
|
1815
|
-
const full_track_id_order:TrackId[] = [];
|
|
1816
|
-
clustered_track_id_order.forEach(function
|
|
2157
|
+
const full_track_id_order: TrackId[] = [];
|
|
2158
|
+
clustered_track_id_order.forEach(function(track_id: TrackId) {
|
|
1817
2159
|
full_track_id_order.push(track_id);
|
|
1818
2160
|
Array.prototype.push.apply(
|
|
1819
2161
|
full_track_id_order,
|
|
@@ -1826,11 +2168,12 @@ export default class OncoprintModel {
|
|
|
1826
2168
|
}
|
|
1827
2169
|
def.resolve({
|
|
1828
2170
|
track_group_index: track_group_index,
|
|
1829
|
-
track_id_order: full_track_id_order
|
|
2171
|
+
track_id_order: full_track_id_order,
|
|
1830
2172
|
});
|
|
1831
|
-
})
|
|
1832
|
-
|
|
1833
|
-
|
|
2173
|
+
})
|
|
2174
|
+
.fail(function() {
|
|
2175
|
+
def.reject();
|
|
2176
|
+
});
|
|
1834
2177
|
return def.promise();
|
|
1835
2178
|
}
|
|
1836
2179
|
|
|
@@ -1842,7 +2185,11 @@ export default class OncoprintModel {
|
|
|
1842
2185
|
* @param {string} data_id_key - name of the property of the
|
|
1843
2186
|
* data objects to use as the (column) key
|
|
1844
2187
|
*/
|
|
1845
|
-
public setTrackData(
|
|
2188
|
+
public setTrackData(
|
|
2189
|
+
track_id: TrackId,
|
|
2190
|
+
data: Datum[],
|
|
2191
|
+
data_id_key: string & keyof Datum
|
|
2192
|
+
) {
|
|
1846
2193
|
this.track_data[track_id] = data;
|
|
1847
2194
|
this.track_data_id_key[track_id] = data_id_key;
|
|
1848
2195
|
this.track_id_to_datum.update(this, track_id);
|
|
@@ -1851,7 +2198,7 @@ export default class OncoprintModel {
|
|
|
1851
2198
|
this.precomputed_comparator.update(this, track_id);
|
|
1852
2199
|
}
|
|
1853
2200
|
|
|
1854
|
-
public setTrackGroupLegendOrder(group_order:TrackGroupIndex[]) {
|
|
2201
|
+
public setTrackGroupLegendOrder(group_order: TrackGroupIndex[]) {
|
|
1855
2202
|
this.track_group_legend_order = group_order.slice();
|
|
1856
2203
|
}
|
|
1857
2204
|
|
|
@@ -1859,13 +2206,13 @@ export default class OncoprintModel {
|
|
|
1859
2206
|
return this.track_group_legend_order;
|
|
1860
2207
|
}
|
|
1861
2208
|
|
|
1862
|
-
public setTrackGroupSortPriority(priority:TrackGroupIndex[]) {
|
|
2209
|
+
public setTrackGroupSortPriority(priority: TrackGroupIndex[]) {
|
|
1863
2210
|
this.track_group_sort_priority = priority;
|
|
1864
2211
|
this.sort();
|
|
1865
2212
|
}
|
|
1866
2213
|
private sortAlphabetical() {
|
|
1867
2214
|
const id_order = this.getIdOrder(true).slice();
|
|
1868
|
-
id_order.sort(function(a,b) {
|
|
2215
|
+
id_order.sort(function(a, b) {
|
|
1869
2216
|
return a.localeCompare(b);
|
|
1870
2217
|
});
|
|
1871
2218
|
this.setIdOrder(id_order);
|
|
@@ -1873,26 +2220,33 @@ export default class OncoprintModel {
|
|
|
1873
2220
|
private sortByTracks() {
|
|
1874
2221
|
const track_group_sort_priority = this.track_group_sort_priority;
|
|
1875
2222
|
const track_groups = this.getTrackGroups();
|
|
1876
|
-
let track_groups_in_sort_order:TrackGroup[];
|
|
2223
|
+
let track_groups_in_sort_order: TrackGroup[];
|
|
1877
2224
|
|
|
1878
2225
|
if (track_group_sort_priority.length < track_groups.length) {
|
|
1879
2226
|
track_groups_in_sort_order = track_groups;
|
|
1880
2227
|
} else {
|
|
1881
|
-
track_groups_in_sort_order = track_group_sort_priority.map(function(
|
|
2228
|
+
track_groups_in_sort_order = track_group_sort_priority.map(function(
|
|
2229
|
+
x
|
|
2230
|
+
) {
|
|
1882
2231
|
return track_groups[x];
|
|
1883
2232
|
});
|
|
1884
2233
|
}
|
|
1885
2234
|
|
|
1886
|
-
const track_sort_priority:TrackId[] = track_groups_in_sort_order.reduce(
|
|
1887
|
-
|
|
1888
|
-
|
|
2235
|
+
const track_sort_priority: TrackId[] = track_groups_in_sort_order.reduce(
|
|
2236
|
+
function(acc: TrackId[], next) {
|
|
2237
|
+
return acc.concat(next.tracks);
|
|
2238
|
+
},
|
|
2239
|
+
[]
|
|
2240
|
+
);
|
|
1889
2241
|
|
|
1890
2242
|
const precomputed_comparator = this.precomputed_comparator.get();
|
|
1891
|
-
function getVector(id:ColumnId) {
|
|
2243
|
+
function getVector(id: ColumnId) {
|
|
1892
2244
|
const mandatory_values = [];
|
|
1893
2245
|
const preferred_values = [];
|
|
1894
|
-
for (let i=0; i<track_sort_priority.length; i++) {
|
|
1895
|
-
const sort_value = precomputed_comparator[
|
|
2246
|
+
for (let i = 0; i < track_sort_priority.length; i++) {
|
|
2247
|
+
const sort_value = precomputed_comparator[
|
|
2248
|
+
track_sort_priority[i]
|
|
2249
|
+
].getSortValue(id);
|
|
1896
2250
|
mandatory_values.push(sort_value.mandatory);
|
|
1897
2251
|
preferred_values.push(sort_value.preferred);
|
|
1898
2252
|
}
|
|
@@ -1902,25 +2256,39 @@ export default class OncoprintModel {
|
|
|
1902
2256
|
const ids_with_vectors = this.getAllIds().map(function(id) {
|
|
1903
2257
|
return {
|
|
1904
2258
|
id: id,
|
|
1905
|
-
vector: getVector(id)
|
|
2259
|
+
vector: getVector(id),
|
|
1906
2260
|
};
|
|
1907
2261
|
});
|
|
1908
|
-
const order = BucketSort.bucketSort(ids_with_vectors, function(d:
|
|
1909
|
-
|
|
2262
|
+
const order = BucketSort.bucketSort(ids_with_vectors, function(d: {
|
|
2263
|
+
id: ColumnId;
|
|
2264
|
+
vector: (string | number)[];
|
|
2265
|
+
}) {
|
|
2266
|
+
return d.vector;
|
|
2267
|
+
});
|
|
2268
|
+
this.setIdOrder(
|
|
2269
|
+
order.map(function(d: {
|
|
2270
|
+
id: ColumnId;
|
|
2271
|
+
vector: (string | number)[];
|
|
2272
|
+
}) {
|
|
2273
|
+
return d.id;
|
|
2274
|
+
})
|
|
2275
|
+
);
|
|
1910
2276
|
}
|
|
1911
|
-
public sort():Promise<void|ClusterSortResult> {
|
|
2277
|
+
public sort(): Promise<void | ClusterSortResult> {
|
|
1912
2278
|
//@ts-ignore
|
|
1913
2279
|
const def = new $.Deferred();
|
|
1914
2280
|
this.sort_config = this.sort_config || {};
|
|
1915
|
-
if (this.sort_config.type ===
|
|
2281
|
+
if (this.sort_config.type === 'alphabetical') {
|
|
1916
2282
|
this.sortAlphabetical();
|
|
1917
2283
|
def.resolve();
|
|
1918
|
-
} else if (this.sort_config.type ===
|
|
2284
|
+
} else if (this.sort_config.type === 'order') {
|
|
1919
2285
|
this.setIdOrder(this.sort_config.order);
|
|
1920
2286
|
def.resolve();
|
|
1921
|
-
} else if (this.sort_config.type ===
|
|
1922
|
-
this.clusterTrackGroup(
|
|
1923
|
-
this.sort_config.
|
|
2287
|
+
} else if (this.sort_config.type === 'cluster') {
|
|
2288
|
+
this.clusterTrackGroup(
|
|
2289
|
+
this.sort_config.track_group_index,
|
|
2290
|
+
this.sort_config.clusterValueFn
|
|
2291
|
+
).then(function(x) {
|
|
1924
2292
|
def.resolve(x);
|
|
1925
2293
|
});
|
|
1926
2294
|
} else {
|
|
@@ -1930,9 +2298,11 @@ export default class OncoprintModel {
|
|
|
1930
2298
|
return def.promise();
|
|
1931
2299
|
}
|
|
1932
2300
|
|
|
1933
|
-
public setSortConfig(params:SortConfig) {
|
|
1934
|
-
if (
|
|
1935
|
-
|
|
2301
|
+
public setSortConfig(params: SortConfig) {
|
|
2302
|
+
if (
|
|
2303
|
+
this.sort_config.type === 'cluster' &&
|
|
2304
|
+
(params.type !== 'cluster' ||
|
|
2305
|
+
params.track_group_index !== this.sort_config.track_group_index)
|
|
1936
2306
|
) {
|
|
1937
2307
|
// restore order of currently clustered track group if it will no longer be clustered
|
|
1938
2308
|
this.restoreClusteredTrackGroupOrder();
|
|
@@ -1940,16 +2310,19 @@ export default class OncoprintModel {
|
|
|
1940
2310
|
this.sort_config = params;
|
|
1941
2311
|
}
|
|
1942
2312
|
|
|
1943
|
-
public getTrackMovable(track_id:TrackId) {
|
|
2313
|
+
public getTrackMovable(track_id: TrackId) {
|
|
1944
2314
|
return this.track_movable[track_id];
|
|
1945
2315
|
}
|
|
1946
2316
|
|
|
1947
|
-
public setTrackMovable(track_id:TrackId, movable:boolean) {
|
|
2317
|
+
public setTrackMovable(track_id: TrackId, movable: boolean) {
|
|
1948
2318
|
this.track_movable[track_id] = movable;
|
|
1949
2319
|
}
|
|
1950
2320
|
|
|
1951
|
-
public isTrackInClusteredGroup(track_id:TrackId) {
|
|
1952
|
-
return
|
|
1953
|
-
|
|
2321
|
+
public isTrackInClusteredGroup(track_id: TrackId) {
|
|
2322
|
+
return (
|
|
2323
|
+
this.sort_config.type === 'cluster' &&
|
|
2324
|
+
this.sort_config.track_group_index ===
|
|
2325
|
+
this.getContainingTrackGroupIndex(track_id)
|
|
2326
|
+
);
|
|
1954
2327
|
}
|
|
1955
|
-
}
|
|
2328
|
+
}
|