oncoprintjs 5.0.4 → 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 -68
- 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 +965 -423
- package/src/js/oncoprintmodel.ts +892 -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 -105
- 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;
|
|
@@ -1229,7 +1434,7 @@ export default class OncoprintModel {
|
|
|
1229
1434
|
this.track_tops.update();
|
|
1230
1435
|
}
|
|
1231
1436
|
|
|
1232
|
-
private ensureTrackGroupExists(index:TrackGroupIndex) {
|
|
1437
|
+
private ensureTrackGroupExists(index: TrackGroupIndex) {
|
|
1233
1438
|
while (index >= this.track_groups.length) {
|
|
1234
1439
|
this.track_groups.push({ tracks: [] });
|
|
1235
1440
|
}
|
|
@@ -1237,9 +1442,15 @@ export default class OncoprintModel {
|
|
|
1237
1442
|
|
|
1238
1443
|
// get a reference to the array that stores the order of tracks in
|
|
1239
1444
|
// the same group
|
|
1240
|
-
private _getMajorTrackGroup(
|
|
1241
|
-
|
|
1242
|
-
|
|
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) {
|
|
1243
1454
|
let group;
|
|
1244
1455
|
let i;
|
|
1245
1456
|
for (i = 0; i < this.track_groups.length; i++) {
|
|
@@ -1255,16 +1466,20 @@ export default class OncoprintModel {
|
|
|
1255
1466
|
}
|
|
1256
1467
|
}
|
|
1257
1468
|
// get an array listing the track IDs that a track can move around
|
|
1258
|
-
private _getEffectiveTrackGroupTracks(track_id:TrackId) {
|
|
1469
|
+
private _getEffectiveTrackGroupTracks(track_id: TrackId) {
|
|
1259
1470
|
const self = this;
|
|
1260
1471
|
let group,
|
|
1261
1472
|
parent_id = this.track_expansion_parent[track_id];
|
|
1262
1473
|
if (parent_id === undefined) {
|
|
1263
|
-
group = (function(major_group:TrackGroup) {
|
|
1264
|
-
return
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
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
|
+
});
|
|
1268
1483
|
})(this._getMajorTrackGroup(track_id) as TrackGroup);
|
|
1269
1484
|
} else {
|
|
1270
1485
|
group = this.track_expansion_tracks[parent_id];
|
|
@@ -1272,10 +1487,10 @@ export default class OncoprintModel {
|
|
|
1272
1487
|
return group ? group.slice() : null;
|
|
1273
1488
|
}
|
|
1274
1489
|
|
|
1275
|
-
private isRuleSetUsed(rule_set_id:RuleSetId) {
|
|
1490
|
+
private isRuleSetUsed(rule_set_id: RuleSetId) {
|
|
1276
1491
|
let used = false;
|
|
1277
1492
|
const tracks = this.getTracks();
|
|
1278
|
-
for (let i=0; i<tracks.length; i++) {
|
|
1493
|
+
for (let i = 0; i < tracks.length; i++) {
|
|
1279
1494
|
if (this.track_rule_set_id[tracks[i]] === rule_set_id) {
|
|
1280
1495
|
used = true;
|
|
1281
1496
|
break;
|
|
@@ -1284,12 +1499,12 @@ export default class OncoprintModel {
|
|
|
1284
1499
|
return used;
|
|
1285
1500
|
}
|
|
1286
1501
|
|
|
1287
|
-
private removeRuleSet(rule_set_id:RuleSetId) {
|
|
1502
|
+
private removeRuleSet(rule_set_id: RuleSetId) {
|
|
1288
1503
|
delete this.rule_sets[rule_set_id];
|
|
1289
1504
|
delete this.rule_set_active_rules[rule_set_id];
|
|
1290
|
-
}
|
|
1505
|
+
}
|
|
1291
1506
|
|
|
1292
|
-
public removeTrack(track_id:TrackId) {
|
|
1507
|
+
public removeTrack(track_id: TrackId) {
|
|
1293
1508
|
const rule_set_id = this.track_rule_set_id[track_id];
|
|
1294
1509
|
|
|
1295
1510
|
// subtract this tracks active rules from usage count,
|
|
@@ -1322,19 +1537,31 @@ export default class OncoprintModel {
|
|
|
1322
1537
|
delete this.track_label_font_weight[track_id];
|
|
1323
1538
|
delete this.track_label_left_padding[track_id];
|
|
1324
1539
|
|
|
1325
|
-
const containing_track_group = this._getMajorTrackGroup(
|
|
1540
|
+
const containing_track_group = this._getMajorTrackGroup(
|
|
1541
|
+
track_id
|
|
1542
|
+
) as TrackGroup;
|
|
1326
1543
|
if (containing_track_group !== null) {
|
|
1327
1544
|
containing_track_group.tracks.splice(
|
|
1328
|
-
containing_track_group.tracks.indexOf(track_id),
|
|
1545
|
+
containing_track_group.tracks.indexOf(track_id),
|
|
1546
|
+
1
|
|
1547
|
+
);
|
|
1329
1548
|
}
|
|
1330
1549
|
// remove listing of the track as an expansion of its parent track
|
|
1331
|
-
const expansion_group = this.track_expansion_tracks[
|
|
1550
|
+
const expansion_group = this.track_expansion_tracks[
|
|
1551
|
+
this.track_expansion_parent[track_id]
|
|
1552
|
+
];
|
|
1332
1553
|
if (expansion_group) {
|
|
1333
1554
|
expansion_group.splice(expansion_group.indexOf(track_id), 1);
|
|
1334
1555
|
}
|
|
1335
1556
|
// remove this track from unclustered order
|
|
1336
|
-
if (
|
|
1337
|
-
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
|
+
);
|
|
1338
1565
|
}
|
|
1339
1566
|
delete this.track_expansion_parent[track_id];
|
|
1340
1567
|
this.track_tops.update();
|
|
@@ -1348,14 +1575,26 @@ export default class OncoprintModel {
|
|
|
1348
1575
|
if (!rule_set_used) {
|
|
1349
1576
|
this.removeRuleSet(rule_set_id);
|
|
1350
1577
|
}
|
|
1351
|
-
}
|
|
1578
|
+
}
|
|
1352
1579
|
|
|
1353
|
-
public getOverlappingCells(
|
|
1580
|
+
public getOverlappingCells(
|
|
1581
|
+
x: number,
|
|
1582
|
+
y: number
|
|
1583
|
+
): TrackOverlappingCells | null {
|
|
1354
1584
|
// First, see if it's in a column
|
|
1355
1585
|
const id_order = this.getIdOrder();
|
|
1356
|
-
const zoomed_column_left = this.getZoomedColumnLeft() as ColumnProp<
|
|
1586
|
+
const zoomed_column_left = this.getZoomedColumnLeft() as ColumnProp<
|
|
1587
|
+
number
|
|
1588
|
+
>;
|
|
1357
1589
|
// this gets the nearest lower index
|
|
1358
|
-
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
|
+
);
|
|
1359
1598
|
if (nearest_id_index === -1) {
|
|
1360
1599
|
return null;
|
|
1361
1600
|
}
|
|
@@ -1363,9 +1602,14 @@ export default class OncoprintModel {
|
|
|
1363
1602
|
// Next, see if it's in a track
|
|
1364
1603
|
const tracks = this.getTracks();
|
|
1365
1604
|
const cell_tops = this.getCellTops() as TrackProp<number>;
|
|
1366
|
-
const nearest_track_index = binarysearch(
|
|
1367
|
-
|
|
1368
|
-
|
|
1605
|
+
const nearest_track_index = binarysearch(
|
|
1606
|
+
tracks,
|
|
1607
|
+
y,
|
|
1608
|
+
function(track) {
|
|
1609
|
+
return cell_tops[track];
|
|
1610
|
+
},
|
|
1611
|
+
true
|
|
1612
|
+
);
|
|
1369
1613
|
if (nearest_track_index === -1) {
|
|
1370
1614
|
return null;
|
|
1371
1615
|
}
|
|
@@ -1383,21 +1627,34 @@ export default class OncoprintModel {
|
|
|
1383
1627
|
if (!this.getTrackHasColumnSpacing(nearest_track)) {
|
|
1384
1628
|
hitzone_width += this.getCellPadding();
|
|
1385
1629
|
}
|
|
1386
|
-
for (let i=nearest_id_index; i<id_order.length; i++) {
|
|
1630
|
+
for (let i = nearest_id_index; i < id_order.length; i++) {
|
|
1387
1631
|
// if hitzone of cell touches the pixel [x,x+1), then include it
|
|
1388
|
-
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
|
+
) {
|
|
1389
1641
|
ids.push(id_order[i]);
|
|
1390
|
-
} else if (zoomed_column_left[id_order[i]] > x+1) {
|
|
1642
|
+
} else if (zoomed_column_left[id_order[i]] > x + 1) {
|
|
1391
1643
|
break;
|
|
1392
1644
|
}
|
|
1393
1645
|
}
|
|
1394
1646
|
if (ids.length > 0) {
|
|
1395
|
-
return {
|
|
1647
|
+
return {
|
|
1648
|
+
ids: ids,
|
|
1649
|
+
track: nearest_track,
|
|
1650
|
+
top: cell_tops[nearest_track],
|
|
1651
|
+
left: zoomed_column_left[ids[0]],
|
|
1652
|
+
};
|
|
1396
1653
|
}
|
|
1397
1654
|
return null;
|
|
1398
|
-
}
|
|
1655
|
+
}
|
|
1399
1656
|
|
|
1400
|
-
public getTrackDatum(track_id:TrackId, id:ColumnId) {
|
|
1657
|
+
public getTrackDatum(track_id: TrackId, id: ColumnId) {
|
|
1401
1658
|
const datumById = this.track_id_to_datum.get()[track_id];
|
|
1402
1659
|
if (!datumById) {
|
|
1403
1660
|
return null;
|
|
@@ -1406,9 +1663,9 @@ export default class OncoprintModel {
|
|
|
1406
1663
|
return datumById[id] || null;
|
|
1407
1664
|
}
|
|
1408
1665
|
|
|
1409
|
-
public getTrackTops():TrackProp<number>;
|
|
1410
|
-
public getTrackTops(desired_track_id:TrackId):number;
|
|
1411
|
-
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) {
|
|
1412
1669
|
if (typeof desired_track_id === 'undefined') {
|
|
1413
1670
|
return copyShallowObject(this.track_tops.get());
|
|
1414
1671
|
} else {
|
|
@@ -1416,9 +1673,9 @@ export default class OncoprintModel {
|
|
|
1416
1673
|
}
|
|
1417
1674
|
}
|
|
1418
1675
|
|
|
1419
|
-
public getZoomedTrackTops():TrackProp<number>;
|
|
1420
|
-
public getZoomedTrackTops(desired_track_id:TrackId):number;
|
|
1421
|
-
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) {
|
|
1422
1679
|
if (typeof desired_track_id === 'undefined') {
|
|
1423
1680
|
return copyShallowObject(this.track_tops_zoomed.get());
|
|
1424
1681
|
} else {
|
|
@@ -1426,9 +1683,9 @@ export default class OncoprintModel {
|
|
|
1426
1683
|
}
|
|
1427
1684
|
}
|
|
1428
1685
|
|
|
1429
|
-
public getZoomedHeaderTops():TrackGroupProp<number>;
|
|
1430
|
-
public getZoomedHeaderTops(track_group_index:TrackGroupIndex):number;
|
|
1431
|
-
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) {
|
|
1432
1689
|
if (typeof track_group_index === 'undefined') {
|
|
1433
1690
|
return copyShallowObject(this.header_tops_zoomed.get());
|
|
1434
1691
|
} else {
|
|
@@ -1436,31 +1693,42 @@ export default class OncoprintModel {
|
|
|
1436
1693
|
}
|
|
1437
1694
|
}
|
|
1438
1695
|
|
|
1439
|
-
public getCellTops(
|
|
1440
|
-
|
|
1441
|
-
|
|
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) {
|
|
1442
1702
|
if (typeof desired_track_id === 'undefined') {
|
|
1443
|
-
return copyShallowObject(
|
|
1703
|
+
return copyShallowObject(
|
|
1704
|
+
(base ? this.cell_tops : this.cell_tops_zoomed).get()
|
|
1705
|
+
);
|
|
1444
1706
|
} else {
|
|
1445
|
-
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
|
+
];
|
|
1446
1710
|
}
|
|
1447
1711
|
}
|
|
1448
1712
|
|
|
1449
|
-
public getLabelTops():TrackProp<number>;
|
|
1450
|
-
public getLabelTops(desired_track_id:TrackId):number;
|
|
1451
|
-
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) {
|
|
1452
1716
|
if (typeof desired_track_id === 'undefined') {
|
|
1453
|
-
return copyShallowObject(
|
|
1717
|
+
return copyShallowObject(
|
|
1718
|
+
(base ? this.label_tops : this.label_tops_zoomed).get()
|
|
1719
|
+
);
|
|
1454
1720
|
} else {
|
|
1455
|
-
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
|
+
];
|
|
1456
1724
|
}
|
|
1457
1725
|
}
|
|
1458
1726
|
|
|
1459
|
-
public getContainingTrackGroup(track_id:TrackId) {
|
|
1727
|
+
public getContainingTrackGroup(track_id: TrackId) {
|
|
1460
1728
|
return this._getEffectiveTrackGroupTracks(track_id);
|
|
1461
1729
|
}
|
|
1462
1730
|
|
|
1463
|
-
public getContainingTrackGroupIndex(track_id:TrackId) {
|
|
1731
|
+
public getContainingTrackGroupIndex(track_id: TrackId) {
|
|
1464
1732
|
return this._getMajorTrackGroup(track_id, true);
|
|
1465
1733
|
}
|
|
1466
1734
|
|
|
@@ -1477,9 +1745,9 @@ export default class OncoprintModel {
|
|
|
1477
1745
|
return ret;
|
|
1478
1746
|
}
|
|
1479
1747
|
|
|
1480
|
-
public getColumnLeft():ColumnProp<number>;
|
|
1481
|
-
public getColumnLeft(id:ColumnId):number;
|
|
1482
|
-
public getColumnLeft(id?:ColumnId) {
|
|
1748
|
+
public getColumnLeft(): ColumnProp<number>;
|
|
1749
|
+
public getColumnLeft(id: ColumnId): number;
|
|
1750
|
+
public getColumnLeft(id?: ColumnId) {
|
|
1483
1751
|
if (typeof id === 'undefined') {
|
|
1484
1752
|
return this.column_left.get();
|
|
1485
1753
|
} else {
|
|
@@ -1487,9 +1755,9 @@ export default class OncoprintModel {
|
|
|
1487
1755
|
}
|
|
1488
1756
|
}
|
|
1489
1757
|
|
|
1490
|
-
public getColumnLeftNoPadding():ColumnProp<number>;
|
|
1491
|
-
public getColumnLeftNoPadding(id:ColumnId):number;
|
|
1492
|
-
public getColumnLeftNoPadding(id?:ColumnId) {
|
|
1758
|
+
public getColumnLeftNoPadding(): ColumnProp<number>;
|
|
1759
|
+
public getColumnLeftNoPadding(id: ColumnId): number;
|
|
1760
|
+
public getColumnLeftNoPadding(id?: ColumnId) {
|
|
1493
1761
|
if (typeof id === 'undefined') {
|
|
1494
1762
|
return this.column_left_no_padding.get();
|
|
1495
1763
|
} else {
|
|
@@ -1497,9 +1765,9 @@ export default class OncoprintModel {
|
|
|
1497
1765
|
}
|
|
1498
1766
|
}
|
|
1499
1767
|
|
|
1500
|
-
public getZoomedColumnLeft():ColumnProp<number>;
|
|
1501
|
-
public getZoomedColumnLeft(id:ColumnId):number;
|
|
1502
|
-
public getZoomedColumnLeft(id?:ColumnId) {
|
|
1768
|
+
public getZoomedColumnLeft(): ColumnProp<number>;
|
|
1769
|
+
public getZoomedColumnLeft(id: ColumnId): number;
|
|
1770
|
+
public getZoomedColumnLeft(id?: ColumnId) {
|
|
1503
1771
|
if (typeof id === 'undefined') {
|
|
1504
1772
|
return this.zoomed_column_left.get();
|
|
1505
1773
|
} else {
|
|
@@ -1507,42 +1775,57 @@ export default class OncoprintModel {
|
|
|
1507
1775
|
}
|
|
1508
1776
|
}
|
|
1509
1777
|
|
|
1510
|
-
|
|
1511
|
-
public getOncoprintHeight(base?:boolean) {
|
|
1778
|
+
public getOncoprintHeight(base?: boolean) {
|
|
1512
1779
|
const tracks = this.getTracks();
|
|
1513
|
-
const last_track = tracks[tracks.length-1];
|
|
1514
|
-
return (
|
|
1515
|
-
|
|
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
|
+
);
|
|
1516
1788
|
}
|
|
1517
1789
|
|
|
1518
|
-
public getOncoprintWidth(base?:boolean) {
|
|
1790
|
+
public getOncoprintWidth(base?: boolean) {
|
|
1519
1791
|
const idOrder = this.getIdOrder();
|
|
1520
|
-
const lastId = idOrder[idOrder.length-1];
|
|
1521
|
-
const lastIdLeft = base
|
|
1522
|
-
|
|
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
|
|
1523
1797
|
}
|
|
1524
1798
|
|
|
1525
1799
|
public getOncoprintWidthNoColumnPaddingNoGaps() {
|
|
1526
|
-
return this.getIdOrder().length*this.getCellWidth(true);
|
|
1800
|
+
return this.getIdOrder().length * this.getCellWidth(true);
|
|
1527
1801
|
}
|
|
1528
1802
|
|
|
1529
1803
|
public getColumnLabels() {
|
|
1530
1804
|
return this.column_labels;
|
|
1531
1805
|
}
|
|
1532
1806
|
|
|
1533
|
-
public setColumnLabels(labels:ColumnProp<ColumnLabel>) {
|
|
1807
|
+
public setColumnLabels(labels: ColumnProp<ColumnLabel>) {
|
|
1534
1808
|
this.column_labels = labels;
|
|
1535
1809
|
}
|
|
1536
1810
|
|
|
1537
|
-
public moveTrack(track_id:TrackId, new_previous_track:TrackId) {
|
|
1538
|
-
|
|
1539
|
-
|
|
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
|
+
) {
|
|
1540
1818
|
const old_start_index = uniqArray.indexOf(first_value),
|
|
1541
1819
|
old_end_index = uniqArray.indexOf(last_value);
|
|
1542
1820
|
const values = uniqArray.slice(old_start_index, old_end_index + 1);
|
|
1543
1821
|
uniqArray.splice(old_start_index, values.length);
|
|
1544
|
-
const new_position =
|
|
1545
|
-
|
|
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);
|
|
1546
1829
|
}
|
|
1547
1830
|
|
|
1548
1831
|
const track_group = this._getMajorTrackGroup(track_id) as TrackGroup,
|
|
@@ -1560,22 +1843,32 @@ export default class OncoprintModel {
|
|
|
1560
1843
|
} else {
|
|
1561
1844
|
flat_previous_track = this.getLastExpansion(new_previous_track);
|
|
1562
1845
|
}
|
|
1563
|
-
moveContiguousValues(
|
|
1846
|
+
moveContiguousValues(
|
|
1847
|
+
track_group.tracks,
|
|
1848
|
+
track_id,
|
|
1849
|
+
this.getLastExpansion(track_id),
|
|
1850
|
+
flat_previous_track
|
|
1851
|
+
);
|
|
1564
1852
|
}
|
|
1565
1853
|
|
|
1566
1854
|
// keep the order of expansion siblings up-to-date as well
|
|
1567
1855
|
if (this.track_expansion_parent[track_id] !== undefined) {
|
|
1568
|
-
moveContiguousValues(
|
|
1856
|
+
moveContiguousValues(
|
|
1857
|
+
this.track_expansion_tracks[expansion_parent],
|
|
1858
|
+
track_id,
|
|
1859
|
+
track_id,
|
|
1860
|
+
new_previous_track
|
|
1861
|
+
);
|
|
1569
1862
|
}
|
|
1570
1863
|
|
|
1571
1864
|
this.track_tops.update();
|
|
1572
|
-
}
|
|
1865
|
+
}
|
|
1573
1866
|
|
|
1574
|
-
public getTrackLabel(track_id:TrackId) {
|
|
1867
|
+
public getTrackLabel(track_id: TrackId) {
|
|
1575
1868
|
return this.track_label[track_id];
|
|
1576
1869
|
}
|
|
1577
1870
|
|
|
1578
|
-
public getTrackSublabel(track_id:TrackId) {
|
|
1871
|
+
public getTrackSublabel(track_id: TrackId) {
|
|
1579
1872
|
return this.track_sublabel[track_id];
|
|
1580
1873
|
}
|
|
1581
1874
|
|
|
@@ -1583,99 +1876,108 @@ export default class OncoprintModel {
|
|
|
1583
1876
|
return this.show_track_sublabels;
|
|
1584
1877
|
}
|
|
1585
1878
|
|
|
1586
|
-
public setShowTrackSublabels(show:boolean) {
|
|
1587
|
-
return this.show_track_sublabels = show;
|
|
1879
|
+
public setShowTrackSublabels(show: boolean) {
|
|
1880
|
+
return (this.show_track_sublabels = show);
|
|
1588
1881
|
}
|
|
1589
1882
|
|
|
1590
|
-
public getTrackLabelColor(track_id:TrackId) {
|
|
1883
|
+
public getTrackLabelColor(track_id: TrackId) {
|
|
1591
1884
|
return this.track_label_color[track_id];
|
|
1592
1885
|
}
|
|
1593
1886
|
|
|
1594
|
-
public getTrackLabelCircleColor(track_id:TrackId) {
|
|
1887
|
+
public getTrackLabelCircleColor(track_id: TrackId) {
|
|
1595
1888
|
return this.track_label_circle_color[track_id];
|
|
1596
1889
|
}
|
|
1597
1890
|
|
|
1598
|
-
public getTrackLabelFontWeight(track_id:TrackId) {
|
|
1891
|
+
public getTrackLabelFontWeight(track_id: TrackId) {
|
|
1599
1892
|
return this.track_label_font_weight[track_id];
|
|
1600
1893
|
}
|
|
1601
1894
|
|
|
1602
|
-
public getTrackLabelLeftPadding(track_id:TrackId) {
|
|
1895
|
+
public getTrackLabelLeftPadding(track_id: TrackId) {
|
|
1603
1896
|
return this.track_label_left_padding[track_id];
|
|
1604
1897
|
}
|
|
1605
1898
|
|
|
1606
|
-
public getOptionalHtmlTrackLabel(track_id:TrackId) {
|
|
1899
|
+
public getOptionalHtmlTrackLabel(track_id: TrackId) {
|
|
1607
1900
|
return this.track_html_label[track_id];
|
|
1608
1901
|
}
|
|
1609
1902
|
|
|
1610
|
-
public getTrackLinkUrl(track_id:TrackId) {
|
|
1903
|
+
public getTrackLinkUrl(track_id: TrackId) {
|
|
1611
1904
|
return this.track_link_url[track_id];
|
|
1612
1905
|
}
|
|
1613
1906
|
|
|
1614
|
-
public getTrackDescription(track_id:TrackId) {
|
|
1907
|
+
public getTrackDescription(track_id: TrackId) {
|
|
1615
1908
|
return this.track_description[track_id];
|
|
1616
1909
|
}
|
|
1617
1910
|
|
|
1618
|
-
public getTrackTooltipFn(track_id:TrackId) {
|
|
1911
|
+
public getTrackTooltipFn(track_id: TrackId) {
|
|
1619
1912
|
return this.track_tooltip_fn[track_id];
|
|
1620
1913
|
}
|
|
1621
|
-
public setTrackTooltipFn(
|
|
1914
|
+
public setTrackTooltipFn(
|
|
1915
|
+
track_id: TrackId,
|
|
1916
|
+
tooltipFn: TrackTooltipFn<Datum>
|
|
1917
|
+
) {
|
|
1622
1918
|
this.track_tooltip_fn[track_id] = tooltipFn;
|
|
1623
1919
|
}
|
|
1624
1920
|
|
|
1625
|
-
public getTrackDataIdKey(track_id:TrackId) {
|
|
1921
|
+
public getTrackDataIdKey(track_id: TrackId) {
|
|
1626
1922
|
return this.track_data_id_key[track_id];
|
|
1627
1923
|
}
|
|
1628
1924
|
|
|
1629
|
-
public getTrackGroupPadding(base?:boolean) {
|
|
1925
|
+
public getTrackGroupPadding(base?: boolean) {
|
|
1630
1926
|
return this.track_group_padding * (base ? 1 : this.vert_zoom);
|
|
1631
1927
|
}
|
|
1632
1928
|
|
|
1633
|
-
public isTrackRemovable(track_id:TrackId) {
|
|
1929
|
+
public isTrackRemovable(track_id: TrackId) {
|
|
1634
1930
|
return this.track_removable[track_id];
|
|
1635
1931
|
}
|
|
1636
1932
|
|
|
1637
|
-
public getTrackRemoveOptionCallback(track_id:TrackId) {
|
|
1933
|
+
public getTrackRemoveOptionCallback(track_id: TrackId) {
|
|
1638
1934
|
return this.track_remove_option_callback[track_id];
|
|
1639
1935
|
}
|
|
1640
1936
|
|
|
1641
|
-
public isTrackSortDirectionChangeable(track_id:TrackId) {
|
|
1937
|
+
public isTrackSortDirectionChangeable(track_id: TrackId) {
|
|
1642
1938
|
return this.track_sort_direction_changeable[track_id];
|
|
1643
1939
|
}
|
|
1644
1940
|
|
|
1645
|
-
public isTrackExpandable(track_id:TrackId) {
|
|
1941
|
+
public isTrackExpandable(track_id: TrackId) {
|
|
1646
1942
|
// return true if the flag is defined and true
|
|
1647
1943
|
return Boolean(this.track_expansion_enabled[track_id]);
|
|
1648
1944
|
}
|
|
1649
1945
|
|
|
1650
|
-
public expandTrack(track_id:TrackId) {
|
|
1946
|
+
public expandTrack(track_id: TrackId) {
|
|
1651
1947
|
return this.track_expand_callback[track_id](track_id);
|
|
1652
1948
|
}
|
|
1653
1949
|
|
|
1654
|
-
public disableTrackExpansion(track_id:TrackId) {
|
|
1950
|
+
public disableTrackExpansion(track_id: TrackId) {
|
|
1655
1951
|
this.track_expansion_enabled[track_id] = false;
|
|
1656
1952
|
}
|
|
1657
1953
|
|
|
1658
|
-
public enableTrackExpansion(track_id:TrackId) {
|
|
1954
|
+
public enableTrackExpansion(track_id: TrackId) {
|
|
1659
1955
|
if (!this.track_expand_callback.hasOwnProperty(track_id)) {
|
|
1660
|
-
throw new Error("Track '" + track_id +"' has no expandCallback");
|
|
1956
|
+
throw new Error("Track '" + track_id + "' has no expandCallback");
|
|
1661
1957
|
}
|
|
1662
1958
|
this.track_expansion_enabled[track_id] = true;
|
|
1663
1959
|
}
|
|
1664
1960
|
|
|
1665
|
-
public isTrackExpanded(track_id:TrackId) {
|
|
1666
|
-
return
|
|
1667
|
-
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
|
+
);
|
|
1668
1966
|
}
|
|
1669
1967
|
|
|
1670
|
-
public getExpandButtonText(track_id:TrackId) {
|
|
1968
|
+
public getExpandButtonText(track_id: TrackId) {
|
|
1671
1969
|
const self = this;
|
|
1672
|
-
const getExpandButtonFunction = function
|
|
1673
|
-
return (
|
|
1674
|
-
|
|
1970
|
+
const getExpandButtonFunction = function(track_id: TrackId) {
|
|
1971
|
+
return (
|
|
1972
|
+
self.track_expand_button_getter[track_id] ||
|
|
1973
|
+
function(is_expanded) {
|
|
1675
1974
|
return is_expanded ? 'Expand more' : 'Expand';
|
|
1676
|
-
}
|
|
1975
|
+
}
|
|
1976
|
+
);
|
|
1677
1977
|
};
|
|
1678
|
-
return getExpandButtonFunction(track_id)(
|
|
1978
|
+
return getExpandButtonFunction(track_id)(
|
|
1979
|
+
this.isTrackExpanded(track_id)
|
|
1980
|
+
);
|
|
1679
1981
|
}
|
|
1680
1982
|
|
|
1681
1983
|
/**
|
|
@@ -1684,9 +1986,13 @@ export default class OncoprintModel {
|
|
|
1684
1986
|
* @param {number} expansion_track_id - the ID of the track to check
|
|
1685
1987
|
* @param {number} set_track_id - the ID of the track it may be an expansion of
|
|
1686
1988
|
*/
|
|
1687
|
-
public isExpansionOf(expansion_track_id:TrackId, set_track_id:TrackId) {
|
|
1688
|
-
return
|
|
1689
|
-
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
|
+
);
|
|
1690
1996
|
}
|
|
1691
1997
|
|
|
1692
1998
|
/**
|
|
@@ -1695,7 +2001,7 @@ export default class OncoprintModel {
|
|
|
1695
2001
|
* @param track_id - the ID of the track to start from
|
|
1696
2002
|
* @returns the ID of its last expansion, or the unchanged param if none
|
|
1697
2003
|
*/
|
|
1698
|
-
public getLastExpansion(track_id:TrackId) {
|
|
2004
|
+
public getLastExpansion(track_id: TrackId) {
|
|
1699
2005
|
let direct_children = this.track_expansion_tracks[track_id];
|
|
1700
2006
|
while (direct_children && direct_children.length) {
|
|
1701
2007
|
track_id = direct_children[direct_children.length - 1];
|
|
@@ -1704,37 +2010,45 @@ export default class OncoprintModel {
|
|
|
1704
2010
|
return track_id;
|
|
1705
2011
|
}
|
|
1706
2012
|
|
|
1707
|
-
public getTrackCustomOptions(track_id:TrackId) {
|
|
2013
|
+
public getTrackCustomOptions(track_id: TrackId) {
|
|
1708
2014
|
return this.track_custom_options[track_id];
|
|
1709
2015
|
}
|
|
1710
2016
|
|
|
1711
|
-
public setTrackCustomOptions(
|
|
2017
|
+
public setTrackCustomOptions(
|
|
2018
|
+
track_id: TrackId,
|
|
2019
|
+
options: CustomTrackOption[] | undefined
|
|
2020
|
+
) {
|
|
1712
2021
|
this.track_custom_options[track_id] = options;
|
|
1713
2022
|
}
|
|
1714
2023
|
|
|
1715
|
-
public setTrackInfoTooltip(
|
|
2024
|
+
public setTrackInfoTooltip(
|
|
2025
|
+
track_id: TrackId,
|
|
2026
|
+
$tooltip_elt: JQuery | undefined
|
|
2027
|
+
) {
|
|
1716
2028
|
this.$track_info_tooltip_elt[track_id] = $tooltip_elt;
|
|
1717
2029
|
}
|
|
1718
2030
|
|
|
1719
|
-
public $getTrackInfoTooltip(track_id:TrackId) {
|
|
2031
|
+
public $getTrackInfoTooltip(track_id: TrackId) {
|
|
1720
2032
|
return this.$track_info_tooltip_elt[track_id];
|
|
1721
2033
|
}
|
|
1722
2034
|
|
|
1723
|
-
public getRuleSet(track_id:TrackId) {
|
|
2035
|
+
public getRuleSet(track_id: TrackId) {
|
|
1724
2036
|
return this.rule_sets[this.track_rule_set_id[track_id]];
|
|
1725
2037
|
}
|
|
1726
2038
|
|
|
1727
|
-
public shareRuleSet(source_track_id:TrackId, target_track_id:TrackId) {
|
|
2039
|
+
public shareRuleSet(source_track_id: TrackId, target_track_id: TrackId) {
|
|
1728
2040
|
this.setTrackActiveRules(target_track_id, {});
|
|
1729
2041
|
|
|
1730
2042
|
const old_rule_set_id = this.track_rule_set_id[target_track_id];
|
|
1731
|
-
this.track_rule_set_id[target_track_id] = this.track_rule_set_id[
|
|
2043
|
+
this.track_rule_set_id[target_track_id] = this.track_rule_set_id[
|
|
2044
|
+
source_track_id
|
|
2045
|
+
];
|
|
1732
2046
|
if (!this.isRuleSetUsed(old_rule_set_id)) {
|
|
1733
2047
|
this.removeRuleSet(old_rule_set_id);
|
|
1734
2048
|
}
|
|
1735
2049
|
}
|
|
1736
2050
|
|
|
1737
|
-
public setRuleSet(track_id:TrackId, rule_set:RuleSet) {
|
|
2051
|
+
public setRuleSet(track_id: TrackId, rule_set: RuleSet) {
|
|
1738
2052
|
this.setTrackActiveRules(track_id, {});
|
|
1739
2053
|
|
|
1740
2054
|
const curr_rule_set_id = this.track_rule_set_id[track_id];
|
|
@@ -1748,40 +2062,47 @@ export default class OncoprintModel {
|
|
|
1748
2062
|
}
|
|
1749
2063
|
}
|
|
1750
2064
|
|
|
1751
|
-
public getTrackSortComparator(track_id:TrackId) {
|
|
2065
|
+
public getTrackSortComparator(track_id: TrackId) {
|
|
1752
2066
|
return this.track_sort_cmp_fn[track_id];
|
|
1753
2067
|
}
|
|
1754
2068
|
|
|
1755
|
-
public setTrackSortComparator(
|
|
2069
|
+
public setTrackSortComparator(
|
|
2070
|
+
track_id: TrackId,
|
|
2071
|
+
sortCmpFn: TrackSortSpecification<Datum>
|
|
2072
|
+
) {
|
|
1756
2073
|
this.track_sort_cmp_fn[track_id] = sortCmpFn;
|
|
1757
2074
|
this.precomputed_comparator.update(this, track_id);
|
|
1758
2075
|
}
|
|
1759
2076
|
|
|
1760
|
-
public getTrackData(track_id:TrackId) {
|
|
2077
|
+
public getTrackData(track_id: TrackId) {
|
|
1761
2078
|
return this.track_data[track_id];
|
|
1762
2079
|
}
|
|
1763
2080
|
|
|
1764
|
-
public clusterTrackGroup(
|
|
2081
|
+
public clusterTrackGroup(
|
|
2082
|
+
track_group_index: TrackGroupIndex,
|
|
2083
|
+
clusterValueFn: (d: Datum) => number
|
|
2084
|
+
): Promise<void | ClusterSortResult> {
|
|
1765
2085
|
const sort_config_at_call = cloneShallow(this.sort_config);
|
|
1766
2086
|
// Prepare input
|
|
1767
2087
|
const self = this;
|
|
1768
2088
|
//@ts-ignore
|
|
1769
2089
|
const def = new $.Deferred();
|
|
1770
|
-
const cluster_input:ColumnProp<TrackProp<number>> = {};
|
|
2090
|
+
const cluster_input: ColumnProp<TrackProp<number>> = {};
|
|
1771
2091
|
|
|
1772
2092
|
// Use data from tracks on the same level of expansion as the first one
|
|
1773
2093
|
// in the track group as input, i.e. the outer level excluding any
|
|
1774
2094
|
// expansions
|
|
1775
2095
|
const track_group = this.getTrackGroups()[track_group_index];
|
|
1776
|
-
let track_ids:TrackId[] = [];
|
|
2096
|
+
let track_ids: TrackId[] = [];
|
|
1777
2097
|
if (track_group !== undefined) {
|
|
1778
|
-
track_ids =
|
|
2098
|
+
track_ids =
|
|
2099
|
+
this._getEffectiveTrackGroupTracks(track_group.tracks[0]) || [];
|
|
1779
2100
|
}
|
|
1780
2101
|
for (let i = 0; i < track_ids.length; i++) {
|
|
1781
2102
|
const track_id = track_ids[i];
|
|
1782
2103
|
const data_id_key = this.getTrackDataIdKey(track_id);
|
|
1783
2104
|
const data = this.getTrackData(track_id);
|
|
1784
|
-
for (let j=0; j<data.length; j++) {
|
|
2105
|
+
for (let j = 0; j < data.length; j++) {
|
|
1785
2106
|
const id = data[j][data_id_key];
|
|
1786
2107
|
const value = clusterValueFn(data[j]);
|
|
1787
2108
|
cluster_input[id] = cluster_input[id] || {};
|
|
@@ -1799,21 +2120,31 @@ export default class OncoprintModel {
|
|
|
1799
2120
|
});*/
|
|
1800
2121
|
|
|
1801
2122
|
//do hierarchical clustering in background:
|
|
1802
|
-
$.when(hclusterColumns(cluster_input), hclusterTracks(cluster_input))
|
|
1803
|
-
function
|
|
2123
|
+
$.when(hclusterColumns(cluster_input), hclusterTracks(cluster_input))
|
|
2124
|
+
.then(function(
|
|
2125
|
+
columnClusterOrder: CaseItem[],
|
|
2126
|
+
trackClusterOrder: EntityItem[]
|
|
2127
|
+
) {
|
|
1804
2128
|
// cancel if sort config is no longer what it was
|
|
1805
2129
|
if (!_.isEqual(self.sort_config, sort_config_at_call)) {
|
|
1806
2130
|
return;
|
|
1807
2131
|
}
|
|
1808
2132
|
// set clustered column order
|
|
1809
|
-
self.setIdOrder(
|
|
2133
|
+
self.setIdOrder(
|
|
2134
|
+
columnClusterOrder.map(function(c) {
|
|
2135
|
+
return c.caseId;
|
|
2136
|
+
})
|
|
2137
|
+
); // TODO
|
|
1810
2138
|
// determine clustered row order
|
|
1811
|
-
const clustered_track_id_order = trackClusterOrder.map(function
|
|
2139
|
+
const clustered_track_id_order = trackClusterOrder.map(function(
|
|
2140
|
+
entity
|
|
2141
|
+
) {
|
|
2142
|
+
// TODO
|
|
1812
2143
|
return parseInt(entity.entityId, 10);
|
|
1813
2144
|
});
|
|
1814
2145
|
// re-insert any expansions below each clustered track
|
|
1815
|
-
const full_track_id_order:TrackId[] = [];
|
|
1816
|
-
clustered_track_id_order.forEach(function
|
|
2146
|
+
const full_track_id_order: TrackId[] = [];
|
|
2147
|
+
clustered_track_id_order.forEach(function(track_id: TrackId) {
|
|
1817
2148
|
full_track_id_order.push(track_id);
|
|
1818
2149
|
Array.prototype.push.apply(
|
|
1819
2150
|
full_track_id_order,
|
|
@@ -1826,11 +2157,12 @@ export default class OncoprintModel {
|
|
|
1826
2157
|
}
|
|
1827
2158
|
def.resolve({
|
|
1828
2159
|
track_group_index: track_group_index,
|
|
1829
|
-
track_id_order: full_track_id_order
|
|
2160
|
+
track_id_order: full_track_id_order,
|
|
1830
2161
|
});
|
|
1831
|
-
})
|
|
1832
|
-
|
|
1833
|
-
|
|
2162
|
+
})
|
|
2163
|
+
.fail(function() {
|
|
2164
|
+
def.reject();
|
|
2165
|
+
});
|
|
1834
2166
|
return def.promise();
|
|
1835
2167
|
}
|
|
1836
2168
|
|
|
@@ -1842,7 +2174,11 @@ export default class OncoprintModel {
|
|
|
1842
2174
|
* @param {string} data_id_key - name of the property of the
|
|
1843
2175
|
* data objects to use as the (column) key
|
|
1844
2176
|
*/
|
|
1845
|
-
public setTrackData(
|
|
2177
|
+
public setTrackData(
|
|
2178
|
+
track_id: TrackId,
|
|
2179
|
+
data: Datum[],
|
|
2180
|
+
data_id_key: string & keyof Datum
|
|
2181
|
+
) {
|
|
1846
2182
|
this.track_data[track_id] = data;
|
|
1847
2183
|
this.track_data_id_key[track_id] = data_id_key;
|
|
1848
2184
|
this.track_id_to_datum.update(this, track_id);
|
|
@@ -1851,7 +2187,7 @@ export default class OncoprintModel {
|
|
|
1851
2187
|
this.precomputed_comparator.update(this, track_id);
|
|
1852
2188
|
}
|
|
1853
2189
|
|
|
1854
|
-
public setTrackGroupLegendOrder(group_order:TrackGroupIndex[]) {
|
|
2190
|
+
public setTrackGroupLegendOrder(group_order: TrackGroupIndex[]) {
|
|
1855
2191
|
this.track_group_legend_order = group_order.slice();
|
|
1856
2192
|
}
|
|
1857
2193
|
|
|
@@ -1859,13 +2195,13 @@ export default class OncoprintModel {
|
|
|
1859
2195
|
return this.track_group_legend_order;
|
|
1860
2196
|
}
|
|
1861
2197
|
|
|
1862
|
-
public setTrackGroupSortPriority(priority:TrackGroupIndex[]) {
|
|
2198
|
+
public setTrackGroupSortPriority(priority: TrackGroupIndex[]) {
|
|
1863
2199
|
this.track_group_sort_priority = priority;
|
|
1864
2200
|
this.sort();
|
|
1865
2201
|
}
|
|
1866
2202
|
private sortAlphabetical() {
|
|
1867
2203
|
const id_order = this.getIdOrder(true).slice();
|
|
1868
|
-
id_order.sort(function(a,b) {
|
|
2204
|
+
id_order.sort(function(a, b) {
|
|
1869
2205
|
return a.localeCompare(b);
|
|
1870
2206
|
});
|
|
1871
2207
|
this.setIdOrder(id_order);
|
|
@@ -1873,26 +2209,33 @@ export default class OncoprintModel {
|
|
|
1873
2209
|
private sortByTracks() {
|
|
1874
2210
|
const track_group_sort_priority = this.track_group_sort_priority;
|
|
1875
2211
|
const track_groups = this.getTrackGroups();
|
|
1876
|
-
let track_groups_in_sort_order:TrackGroup[];
|
|
2212
|
+
let track_groups_in_sort_order: TrackGroup[];
|
|
1877
2213
|
|
|
1878
2214
|
if (track_group_sort_priority.length < track_groups.length) {
|
|
1879
2215
|
track_groups_in_sort_order = track_groups;
|
|
1880
2216
|
} else {
|
|
1881
|
-
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
|
+
) {
|
|
1882
2220
|
return track_groups[x];
|
|
1883
2221
|
});
|
|
1884
2222
|
}
|
|
1885
2223
|
|
|
1886
|
-
const track_sort_priority:TrackId[] = track_groups_in_sort_order.reduce(
|
|
1887
|
-
|
|
1888
|
-
|
|
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
|
+
);
|
|
1889
2230
|
|
|
1890
2231
|
const precomputed_comparator = this.precomputed_comparator.get();
|
|
1891
|
-
function getVector(id:ColumnId) {
|
|
2232
|
+
function getVector(id: ColumnId) {
|
|
1892
2233
|
const mandatory_values = [];
|
|
1893
2234
|
const preferred_values = [];
|
|
1894
|
-
for (let i=0; i<track_sort_priority.length; i++) {
|
|
1895
|
-
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);
|
|
1896
2239
|
mandatory_values.push(sort_value.mandatory);
|
|
1897
2240
|
preferred_values.push(sort_value.preferred);
|
|
1898
2241
|
}
|
|
@@ -1902,25 +2245,39 @@ export default class OncoprintModel {
|
|
|
1902
2245
|
const ids_with_vectors = this.getAllIds().map(function(id) {
|
|
1903
2246
|
return {
|
|
1904
2247
|
id: id,
|
|
1905
|
-
vector: getVector(id)
|
|
2248
|
+
vector: getVector(id),
|
|
1906
2249
|
};
|
|
1907
2250
|
});
|
|
1908
|
-
const order = BucketSort.bucketSort(ids_with_vectors, function(d:
|
|
1909
|
-
|
|
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
|
+
);
|
|
1910
2265
|
}
|
|
1911
|
-
public sort():Promise<void|ClusterSortResult> {
|
|
2266
|
+
public sort(): Promise<void | ClusterSortResult> {
|
|
1912
2267
|
//@ts-ignore
|
|
1913
2268
|
const def = new $.Deferred();
|
|
1914
2269
|
this.sort_config = this.sort_config || {};
|
|
1915
|
-
if (this.sort_config.type ===
|
|
2270
|
+
if (this.sort_config.type === 'alphabetical') {
|
|
1916
2271
|
this.sortAlphabetical();
|
|
1917
2272
|
def.resolve();
|
|
1918
|
-
} else if (this.sort_config.type ===
|
|
2273
|
+
} else if (this.sort_config.type === 'order') {
|
|
1919
2274
|
this.setIdOrder(this.sort_config.order);
|
|
1920
2275
|
def.resolve();
|
|
1921
|
-
} else if (this.sort_config.type ===
|
|
1922
|
-
this.clusterTrackGroup(
|
|
1923
|
-
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) {
|
|
1924
2281
|
def.resolve(x);
|
|
1925
2282
|
});
|
|
1926
2283
|
} else {
|
|
@@ -1930,9 +2287,11 @@ export default class OncoprintModel {
|
|
|
1930
2287
|
return def.promise();
|
|
1931
2288
|
}
|
|
1932
2289
|
|
|
1933
|
-
public setSortConfig(params:SortConfig) {
|
|
1934
|
-
if (
|
|
1935
|
-
|
|
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)
|
|
1936
2295
|
) {
|
|
1937
2296
|
// restore order of currently clustered track group if it will no longer be clustered
|
|
1938
2297
|
this.restoreClusteredTrackGroupOrder();
|
|
@@ -1940,16 +2299,19 @@ export default class OncoprintModel {
|
|
|
1940
2299
|
this.sort_config = params;
|
|
1941
2300
|
}
|
|
1942
2301
|
|
|
1943
|
-
public getTrackMovable(track_id:TrackId) {
|
|
2302
|
+
public getTrackMovable(track_id: TrackId) {
|
|
1944
2303
|
return this.track_movable[track_id];
|
|
1945
2304
|
}
|
|
1946
2305
|
|
|
1947
|
-
public setTrackMovable(track_id:TrackId, movable:boolean) {
|
|
2306
|
+
public setTrackMovable(track_id: TrackId, movable: boolean) {
|
|
1948
2307
|
this.track_movable[track_id] = movable;
|
|
1949
2308
|
}
|
|
1950
2309
|
|
|
1951
|
-
public isTrackInClusteredGroup(track_id:TrackId) {
|
|
1952
|
-
return
|
|
1953
|
-
|
|
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
|
+
);
|
|
1954
2316
|
}
|
|
1955
|
-
}
|
|
2317
|
+
}
|