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