oncoprintjs 5.0.3 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +34 -0
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.es.js +14746 -0
  4. package/dist/index.es.js.map +1 -0
  5. package/dist/index.js +14760 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/js/CachedProperty.d.ts +10 -10
  8. package/dist/js/binarysearch.d.ts +1 -1
  9. package/dist/js/bucketsort.d.ts +16 -16
  10. package/dist/js/clustering.d.ts +14 -14
  11. package/dist/js/extractrgba.d.ts +4 -4
  12. package/dist/js/haselementsininterval.d.ts +1 -1
  13. package/dist/js/heatmapcolors.d.ts +5 -4
  14. package/dist/js/makesvgelement.d.ts +1 -1
  15. package/dist/js/modelutils.d.ts +7 -7
  16. package/dist/js/oncoprint.d.ts +168 -170
  17. package/dist/js/oncoprintheaderview.d.ts +23 -22
  18. package/dist/js/oncoprintlabelview.d.ts +79 -78
  19. package/dist/js/oncoprintlegendrenderer.d.ts +32 -31
  20. package/dist/js/oncoprintminimapview.d.ts +69 -68
  21. package/dist/js/oncoprintmodel.d.ts +403 -398
  22. package/dist/js/oncoprintruleset.d.ts +176 -177
  23. package/dist/js/oncoprintshape.d.ts +67 -67
  24. package/dist/js/oncoprintshapetosvg.d.ts +2 -2
  25. package/dist/js/oncoprintshapetovertexes.d.ts +5 -5
  26. package/dist/js/oncoprinttooltip.d.ts +23 -22
  27. package/dist/js/oncoprinttrackinfoview.d.ts +40 -39
  28. package/dist/js/oncoprinttrackoptionsview.d.ts +58 -57
  29. package/dist/js/oncoprintwebglcellview.d.ts +168 -167
  30. package/dist/js/oncoprintzoomslider.d.ts +28 -27
  31. package/dist/js/polyfill.d.ts +4 -4
  32. package/dist/js/precomputedcomparator.d.ts +13 -13
  33. package/dist/js/shaders.d.ts +2 -2
  34. package/dist/js/svgfactory.d.ts +24 -23
  35. package/dist/js/utils.d.ts +16 -16
  36. package/dist/js/workers/clustering-worker.d.ts +19 -20
  37. package/dist/test/gradientCategoricalRuleset.spec.d.ts +1 -1
  38. package/dist/test/monolith.spec.d.ts +1 -1
  39. package/jest.config.ts +2 -0
  40. package/package.json +20 -26
  41. package/rollup.config.ts +14 -0
  42. package/rules/geneticrules.ts +344 -305
  43. package/server.js +11 -0
  44. package/src/img/menudots.svg +9 -9
  45. package/src/img/zoomtofit.svg +12 -12
  46. package/src/index.tsx +13 -0
  47. package/src/js/CachedProperty.ts +6 -7
  48. package/src/js/binarysearch.ts +8 -3
  49. package/src/js/bucketsort.ts +89 -47
  50. package/src/js/clustering.ts +22 -10
  51. package/src/js/extractrgba.ts +16 -12
  52. package/src/js/haselementsininterval.ts +8 -4
  53. package/src/js/heatmapcolors.ts +515 -515
  54. package/src/js/main.js +1 -1
  55. package/src/js/makesvgelement.ts +2 -2
  56. package/src/js/modelutils.ts +11 -8
  57. package/src/js/oncoprint.ts +706 -385
  58. package/src/js/oncoprintheaderview.ts +165 -125
  59. package/src/js/oncoprintlabelview.ts +388 -170
  60. package/src/js/oncoprintlegendrenderer.ts +203 -72
  61. package/src/js/oncoprintminimapview.ts +965 -423
  62. package/src/js/oncoprintmodel.ts +905 -532
  63. package/src/js/oncoprintruleset.ts +694 -379
  64. package/src/js/oncoprintshape.ts +240 -97
  65. package/src/js/oncoprintshapetosvg.ts +77 -26
  66. package/src/js/oncoprintshapetovertexes.ts +153 -48
  67. package/src/js/oncoprinttooltip.ts +58 -27
  68. package/src/js/oncoprinttrackinfoview.ts +115 -59
  69. package/src/js/oncoprinttrackoptionsview.ts +354 -187
  70. package/src/js/oncoprintwebglcellview.ts +951 -415
  71. package/src/js/oncoprintzoomslider.ts +172 -107
  72. package/src/js/polyfill.ts +7 -3
  73. package/src/js/precomputedcomparator.ts +133 -50
  74. package/src/js/shaders.ts +2 -4
  75. package/src/js/svgfactory.ts +128 -73
  76. package/src/js/utils.ts +51 -31
  77. package/src/js/workers/clustering-worker.ts +50 -42
  78. package/src/test/gradientCategoricalRuleset.spec.ts +55 -38
  79. package/src/test/monolith.spec.ts +718 -285
  80. package/test/generate_data.py +108 -0
  81. package/test/glyphmap-data.js +1041 -0
  82. package/test/heatmap-data.js +1027 -0
  83. package/test/index.html +21 -0
  84. package/test/oncoprint-glyphmap.js +79 -0
  85. package/test/oncoprint-heatmap.js +123 -0
  86. package/tsconfig.json +4 -10
  87. package/tsconfig.test.json +11 -0
  88. package/.idea/misc.xml +0 -6
  89. package/.idea/modules.xml +0 -8
  90. package/.idea/oncoprintjs.iml +0 -12
  91. package/.idea/vcs.xml +0 -6
  92. package/.idea/workspace.xml +0 -105
  93. package/dist/.gitkeep +0 -0
  94. package/dist/js/minimaputils.d.ts +0 -0
  95. package/dist/oncoprint.bundle.js +0 -44313
  96. package/jest.config.js +0 -12
  97. package/src/js/minimaputils.ts +0 -0
  98. package/typings/custom.d.ts +0 -7
  99. package/typings/missing.d.ts +0 -7
  100. package/webpack.config.js +0 -43
@@ -1,61 +1,78 @@
1
1
  /* Rule:
2
- *
2
+ *
3
3
  * condition: function from datum to boolean
4
4
  * shapes - a list of Shapes
5
5
  * legend_label
6
6
  * exclude_from_legend
7
- *
7
+ *
8
8
  * Shape:
9
9
  * type
10
10
  * x
11
11
  * y
12
12
  * ... shape-specific attrs ...
13
- *
13
+ *
14
14
  * Attrs by shape:
15
- *
15
+ *
16
16
  * rectangle: x, y, width, height, stroke, stroke-width, fill
17
17
  * triangle: x1, y1, x2, y2, x3, y3, stroke, stroke-width, fill
18
18
  * ellipse: x, y, width, height, stroke, stroke-width, fill
19
19
  * line: x1, y1, x2, y2, stroke, stroke-width
20
20
  */
21
21
 
22
- import {ComputedShapeParams, Ellipse, Line, Rectangle, Shape, ShapeParams, Triangle} from "./oncoprintshape";
23
- import heatmapColors from "./heatmapcolors";
24
- import binarysearch from "./binarysearch";
25
- import {Omit, cloneShallow, ifndef, objectValues, shallowExtend, z_comparator} from "./utils";
26
- import {ActiveRules, ColumnProp, Datum, RuleSetId} from "./oncoprintmodel";
27
- import _ from "lodash";
28
- import extractrgba, {hexToRGBA, rgbaToHex} from "./extractrgba";
29
-
30
- export type RuleSetParams = ILinearInterpRuleSetParams | ICategoricalRuleSetParams |
31
- IGradientRuleSetParams |
32
- IBarRuleSetParams |
33
- IStackedBarRuleSetParams |
34
- IGradientAndCategoricalRuleSetParams |
35
- IGeneticAlterationRuleSetParams;
22
+ import {
23
+ ComputedShapeParams,
24
+ Ellipse,
25
+ Line,
26
+ Rectangle,
27
+ Shape,
28
+ ShapeParams,
29
+ Triangle,
30
+ } from './oncoprintshape';
31
+ import heatmapColors from './heatmapcolors';
32
+ import binarysearch from './binarysearch';
33
+ import {
34
+ Omit,
35
+ cloneShallow,
36
+ ifndef,
37
+ objectValues,
38
+ shallowExtend,
39
+ z_comparator,
40
+ } from './utils';
41
+ import { ActiveRules, ColumnProp, Datum, RuleSetId } from './oncoprintmodel';
42
+ import _ from 'lodash';
43
+ import extractrgba, { hexToRGBA, rgbaToHex } from './extractrgba';
44
+
45
+ export type RuleSetParams =
46
+ | ILinearInterpRuleSetParams
47
+ | ICategoricalRuleSetParams
48
+ | IGradientRuleSetParams
49
+ | IBarRuleSetParams
50
+ | IStackedBarRuleSetParams
51
+ | IGradientAndCategoricalRuleSetParams
52
+ | IGeneticAlterationRuleSetParams;
36
53
 
37
54
  interface IGeneralRuleSetParams {
38
- type?:RuleSetType;
55
+ type?: RuleSetType;
39
56
  legend_label?: string;
40
57
  legend_base_color?: RGBAColor;
41
58
  exclude_from_legend?: boolean;
42
- na_z?:number; // z index of na shapes (defaults to 1)
43
- na_legend_label?:string; // legend label associated to NA (defaults to 'No data')
44
- na_shapes?:ShapeParams[]; // defaults to single strikethrough line
59
+ na_z?: number; // z index of na shapes (defaults to 1)
60
+ na_legend_label?: string; // legend label associated to NA (defaults to 'No data')
61
+ na_shapes?: ShapeParams[]; // defaults to single strikethrough line
45
62
  }
46
63
 
47
64
  interface ILinearInterpRuleSetParams extends IGeneralRuleSetParams {
48
- log_scale?:boolean;
49
- value_key:string;
50
- value_range:[number, number];
65
+ log_scale?: boolean;
66
+ value_key: string;
67
+ value_range: [number, number];
51
68
  }
52
69
 
53
70
  // all colors are hex, rgb, or rgba
54
71
  export interface ICategoricalRuleSetParams extends IGeneralRuleSetParams {
55
72
  type: RuleSetType.CATEGORICAL;
56
73
  category_key: string; // key into data which gives category
57
- category_to_color?: {[category:string]:RGBAColor};
58
- universal_rule_categories?: {[category:string]:any};
74
+ category_to_color?: { [category: string]: RGBAColor };
75
+ universal_rule_categories?: { [category: string]: any };
59
76
  }
60
77
 
61
78
  export interface IGradientRuleSetParams extends ILinearInterpRuleSetParams {
@@ -65,13 +82,14 @@ export interface IGradientRuleSetParams extends ILinearInterpRuleSetParams {
65
82
  colormap_name?: string; // name of a colormap found in src/js/heatmapcolors.js
66
83
  value_stop_points: number[];
67
84
  null_color?: RGBAColor;
68
- null_legend_label?:string;
85
+ null_legend_label?: string;
69
86
  }
70
87
 
71
88
  // TODO: it would be more elegant to create multiple inheritance (if possible) since
72
89
  // IGradientAndCategoricalRuleSetParams is a IGradientRuleSetParams and
73
90
  // ICategoricalRuleSetParams with a different `type` field.
74
- export interface IGradientAndCategoricalRuleSetParams extends IGeneralRuleSetParams {
91
+ export interface IGradientAndCategoricalRuleSetParams
92
+ extends IGeneralRuleSetParams {
75
93
  type: RuleSetType.GRADIENT_AND_CATEGORICAL;
76
94
  // either `colormap_name` or `colors` needs to be present
77
95
  colors?: RGBAColor[];
@@ -79,12 +97,12 @@ export interface IGradientAndCategoricalRuleSetParams extends IGeneralRuleSetPar
79
97
  value_stop_points: number[];
80
98
  null_color?: RGBAColor;
81
99
 
82
- log_scale?:boolean;
100
+ log_scale?: boolean;
83
101
  value_key: string;
84
102
  value_range: [number, number];
85
103
 
86
104
  category_key: string; // key into data which gives category
87
- category_to_color?: {[category:string]:RGBAColor};
105
+ category_to_color?: { [category: string]: RGBAColor };
88
106
  }
89
107
 
90
108
  export interface IBarRuleSetParams extends ILinearInterpRuleSetParams {
@@ -108,97 +126,119 @@ export interface IGeneticAlterationRuleSetParams extends IGeneralRuleSetParams {
108
126
  type GeneticAlterationSingleRuleParams = {
109
127
  shapes: ShapeParams[];
110
128
  legend_label: string;
111
- exclude_from_legend?:boolean;
112
- legend_order?:number;
129
+ exclude_from_legend?: boolean;
130
+ legend_order?: number;
113
131
  };
114
132
 
115
133
  export type GeneticAlterationRuleParams = {
116
- always?:GeneticAlterationSingleRuleParams,
117
- conditional:{
118
- [datumKey:string]:{
119
- [commaSeparatedDatumValues:string]: GeneticAlterationSingleRuleParams
120
- }
121
- }
134
+ always?: GeneticAlterationSingleRuleParams;
135
+ conditional: {
136
+ [datumKey: string]: {
137
+ [commaSeparatedDatumValues: string]: GeneticAlterationSingleRuleParams;
138
+ };
139
+ };
122
140
  };
123
141
 
124
-
125
- export type RGBAColor = [number,number,number,number]; //[0,255] x [0,255] x [0,255] x [0,1]
142
+ export type RGBAColor = [number, number, number, number]; //[0,255] x [0,255] x [0,255] x [0,1]
126
143
 
127
144
  type RuleParams = {
128
- shapes:ShapeParams[];
129
- legend_label?:string;
130
- exclude_from_legend?:boolean;
131
- legend_config?:RuleLegendConfig;
132
- legend_order?:number;
133
- legend_base_color?:RGBAColor;
145
+ shapes: ShapeParams[];
146
+ legend_label?: string;
147
+ exclude_from_legend?: boolean;
148
+ legend_config?: RuleLegendConfig;
149
+ legend_order?: number;
150
+ legend_base_color?: RGBAColor;
134
151
  };
135
152
 
136
153
  type RuleLegendConfig =
137
- { type: "rule", target:any } |
138
- {
139
- type: "number",
140
- range:[number, number],
141
- range_type:LinearInterpRangeType,
142
- positive_color:RGBAColor,
143
- negative_color:RGBAColor,
144
- interpFn:(val:number)=>number
145
- } | // range: [lower, upper]
146
- {
147
- type: "gradient",
148
- range:[number,number],
149
- colorFn:(val:number)=>RGBAColor
150
- };
151
-
154
+ | { type: 'rule'; target: any }
155
+ | {
156
+ type: 'number';
157
+ range: [number, number];
158
+ range_type: LinearInterpRangeType;
159
+ positive_color: RGBAColor;
160
+ negative_color: RGBAColor;
161
+ interpFn: (val: number) => number;
162
+ } // range: [lower, upper]
163
+ | {
164
+ type: 'gradient';
165
+ range: [number, number];
166
+ colorFn: (val: number) => RGBAColor;
167
+ };
152
168
 
153
169
  export enum RuleSetType {
154
- CATEGORICAL = "categorical",
155
- GRADIENT = "gradient",
156
- GRADIENT_AND_CATEGORICAL = "gradient+categorical",
157
- BAR = "bar",
158
- STACKED_BAR = "stacked_bar",
159
- GENE = "gene"
170
+ CATEGORICAL = 'categorical',
171
+ GRADIENT = 'gradient',
172
+ GRADIENT_AND_CATEGORICAL = 'gradient+categorical',
173
+ BAR = 'bar',
174
+ STACKED_BAR = 'stacked_bar',
175
+ GENE = 'gene',
160
176
  }
161
177
 
162
178
  export type RuleId = number;
163
179
 
164
180
  export type RuleWithId = {
165
- id:RuleId;
166
- rule:Rule;
181
+ id: RuleId;
182
+ rule: Rule;
167
183
  };
168
184
 
169
185
  function makeIdCounter() {
170
186
  let id = 0;
171
- return function () {
187
+ return function() {
172
188
  id += 1;
173
189
  return id;
174
190
  };
175
191
  }
176
192
 
177
- function intRange(length:number) {
193
+ function intRange(length: number) {
178
194
  const ret = [];
179
- for (let i=0; i<length; i++) {
195
+ for (let i = 0; i < length; i++) {
180
196
  ret.push(i);
181
197
  }
182
198
  return ret;
183
199
  }
184
200
 
185
-
186
- function makeUniqueColorGetter(init_used_colors:string[]) {
201
+ function makeUniqueColorGetter(init_used_colors: string[]) {
187
202
  init_used_colors = init_used_colors || [];
188
- const colors = ["#3366cc", "#dc3912", "#ff9900", "#109618",
189
- "#990099", "#0099c6", "#dd4477", "#66aa00",
190
- "#b82e2e", "#316395", "#994499", "#22aa99",
191
- "#aaaa11", "#6633cc", "#e67300", "#8b0707",
192
- "#651067", "#329262", "#5574a6", "#3b3eac",
193
- "#b77322", "#16d620", "#b91383", "#f4359e",
194
- "#9c5935", "#a9c413", "#2a778d", "#668d1c",
195
- "#bea413", "#0c5922", "#743411"];; // Source: D3
203
+ const colors = [
204
+ '#3366cc',
205
+ '#dc3912',
206
+ '#ff9900',
207
+ '#109618',
208
+ '#990099',
209
+ '#0099c6',
210
+ '#dd4477',
211
+ '#66aa00',
212
+ '#b82e2e',
213
+ '#316395',
214
+ '#994499',
215
+ '#22aa99',
216
+ '#aaaa11',
217
+ '#6633cc',
218
+ '#e67300',
219
+ '#8b0707',
220
+ '#651067',
221
+ '#329262',
222
+ '#5574a6',
223
+ '#3b3eac',
224
+ '#b77322',
225
+ '#16d620',
226
+ '#b91383',
227
+ '#f4359e',
228
+ '#9c5935',
229
+ '#a9c413',
230
+ '#2a778d',
231
+ '#668d1c',
232
+ '#bea413',
233
+ '#0c5922',
234
+ '#743411',
235
+ ]; // Source: D3
196
236
  let index = 0;
197
- const used_colors:{[color:string]:boolean} = {};
198
- for (let i=0; i<init_used_colors.length; i++) {
237
+ const used_colors: { [color: string]: boolean } = {};
238
+ for (let i = 0; i < init_used_colors.length; i++) {
199
239
  used_colors[init_used_colors[i]] = true;
200
240
  }
201
- return function(color?:string) {
241
+ return function(color?: string) {
202
242
  if (color) {
203
243
  // calling with an argument adds it to the used colors record
204
244
  used_colors[color] = true;
@@ -217,35 +257,40 @@ function makeUniqueColorGetter(init_used_colors:string[]) {
217
257
 
218
258
  return hexToRGBA(next_color);
219
259
  }
260
+
261
+ return undefined;
220
262
  };
221
263
  }
222
264
 
223
- function makeNAShapes(z:number):ShapeParams[] {
265
+ function makeNAShapes(z: number): ShapeParams[] {
224
266
  return [
225
267
  {
226
- 'type': 'rectangle',
227
- 'fill': [255,255,255,1],
228
- 'z':z
229
- }, {
230
- 'type': 'line',
231
- 'stroke': [190,190,190,1],
268
+ type: 'rectangle',
269
+ fill: [255, 255, 255, 1],
270
+ z: z,
271
+ },
272
+ {
273
+ type: 'line',
274
+ stroke: [190, 190, 190, 1],
232
275
  'stroke-width': 1,
233
- 'x1': 0,
234
- 'x2': 100,
235
- 'y1':50,
236
- 'y2':50,
237
- 'z':z
238
- }
276
+ x1: 0,
277
+ x2: 100,
278
+ y1: 50,
279
+ y2: 50,
280
+ z: z,
281
+ },
239
282
  ];
240
283
  }
241
- const NA_STRING = "na";
242
- const NA_LABEL = "No data";
284
+ const NA_STRING = 'na';
285
+ const NA_LABEL = 'No data';
243
286
 
244
- function colorToHex(color:string) {
287
+ function colorToHex(color: string) {
245
288
  let r;
246
289
  let g;
247
290
  let b;
248
- const rgba_match = color.match(/^[\s]*rgba\([\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*,[\s]*([0-9.]+)[\s]*\)[\s]*$/);
291
+ const rgba_match = color.match(
292
+ /^[\s]*rgba\([\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*,[\s]*([0-9.]+)[\s]*\)[\s]*$/
293
+ );
249
294
  if (rgba_match && rgba_match.length === 5) {
250
295
  r = parseInt(rgba_match[1]).toString(16);
251
296
  g = parseInt(rgba_match[2]).toString(16);
@@ -262,7 +307,9 @@ function colorToHex(color:string) {
262
307
  return '#' + r + g + b;
263
308
  }
264
309
 
265
- const rgb_match = color.match(/^[\s]*rgb\([\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*\)[\s]*$/);
310
+ const rgb_match = color.match(
311
+ /^[\s]*rgb\([\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*,[\s]*([0-9]+)[\s]*\)[\s]*$/
312
+ );
266
313
  if (rgb_match && rgb_match.length === 4) {
267
314
  r = parseInt(rgb_match[1]).toString(16);
268
315
  g = parseInt(rgb_match[2]).toString(16);
@@ -282,7 +329,7 @@ function colorToHex(color:string) {
282
329
  return color;
283
330
  }
284
331
 
285
- function darkenHexChannel(c:string) {
332
+ function darkenHexChannel(c: string) {
286
333
  let numC = parseInt(c, 16);
287
334
  numC *= 0.95;
288
335
  numC = Math.round(numC);
@@ -293,7 +340,7 @@ function darkenHexChannel(c:string) {
293
340
  return c;
294
341
  }
295
342
 
296
- function darkenHexColor(color:string) {
343
+ function darkenHexColor(color: string) {
297
344
  let r = color[1] + color[2];
298
345
  let g = color[3] + color[4];
299
346
  let b = color[5] + color[6];
@@ -307,15 +354,15 @@ export class RuleSet {
307
354
  static getRuleSetId = makeIdCounter();
308
355
  static getRuleId = makeIdCounter();
309
356
 
310
- public rule_set_id:RuleSetId;
311
- public legend_label?:string;
312
- protected legend_base_color?:RGBAColor;
313
- public exclude_from_legend?:boolean;
314
- protected active_rule_ids:ActiveRules;
315
- protected rules_with_id:RuleWithId[];
316
- protected universal_rule?:RuleWithId;
357
+ public rule_set_id: RuleSetId;
358
+ public legend_label?: string;
359
+ protected legend_base_color?: RGBAColor;
360
+ public exclude_from_legend?: boolean;
361
+ protected active_rule_ids: ActiveRules;
362
+ protected rules_with_id: RuleWithId[];
363
+ protected universal_rule?: RuleWithId;
317
364
 
318
- constructor(params:Omit<RuleSetParams, "type">) {
365
+ constructor(params: Omit<RuleSetParams, 'type'>) {
319
366
  /* params:
320
367
  * - legend_label
321
368
  * - exclude_from_legend
@@ -336,26 +383,26 @@ export class RuleSet {
336
383
  return this.rule_set_id;
337
384
  }
338
385
 
339
- public addRules(list_of_params:RuleParams[]) {
386
+ public addRules(list_of_params: RuleParams[]) {
340
387
  const self = this;
341
- return list_of_params.map(function (params) {
388
+ return list_of_params.map(function(params) {
342
389
  return self._addRule(params);
343
390
  });
344
391
  }
345
392
 
346
- public _addRule(params:RuleParams, rule_id?:RuleId) {
347
- if (typeof rule_id === "undefined") {
393
+ public _addRule(params: RuleParams, rule_id?: RuleId) {
394
+ if (typeof rule_id === 'undefined') {
348
395
  rule_id = RuleSet.getRuleId();
349
396
  }
350
- this.rules_with_id.push({id: rule_id, rule: new Rule(params)});
397
+ this.rules_with_id.push({ id: rule_id, rule: new Rule(params) });
351
398
  return rule_id;
352
399
  }
353
400
 
354
- public setUniversalRule(r:RuleWithId) {
401
+ public setUniversalRule(r: RuleWithId) {
355
402
  this.universal_rule = r;
356
403
  }
357
404
 
358
- public removeRule(rule_id:RuleId) {
405
+ public removeRule(rule_id: RuleId) {
359
406
  var index = -1;
360
407
  for (let i = 0; i < this.rules_with_id.length; i++) {
361
408
  if (this.rules_with_id[i].id === rule_id) {
@@ -369,7 +416,7 @@ export class RuleSet {
369
416
  delete this.active_rule_ids[rule_id];
370
417
  }
371
418
 
372
- public getRuleWithId(rule_id:RuleId) {
419
+ public getRuleWithId(rule_id: RuleId) {
373
420
  let ret = null;
374
421
  for (let i = 0; i < this.rules_with_id.length; i++) {
375
422
  if (this.rules_with_id[i].id === rule_id) {
@@ -384,36 +431,42 @@ export class RuleSet {
384
431
  return this.exclude_from_legend;
385
432
  }
386
433
 
387
- public getRule(rule_id:RuleId):Rule {
434
+ public getRule(rule_id: RuleId): Rule {
388
435
  return this.getRuleWithId(rule_id).rule;
389
436
  }
390
437
 
391
438
  public getRecentlyUsedRules() {
392
439
  const self = this;
393
- return Object.keys(this.active_rule_ids).map(
394
- function (rule_id) {
395
- return self.getRule(parseInt(rule_id, 10));
396
- });
440
+ return Object.keys(this.active_rule_ids).map(function(rule_id) {
441
+ return self.getRule(parseInt(rule_id, 10));
442
+ });
397
443
  }
398
444
 
399
- public applyRulesToDatum(rules_with_id:RuleWithId[], datum:Datum, cell_width:number, cell_height:number) {
400
- let shapes:ComputedShapeParams[] = [];
445
+ public applyRulesToDatum(
446
+ rules_with_id: RuleWithId[],
447
+ datum: Datum,
448
+ cell_width: number,
449
+ cell_height: number
450
+ ) {
451
+ let shapes: ComputedShapeParams[] = [];
401
452
  const rules_len = rules_with_id.length;
402
453
  for (let j = 0; j < rules_len; j++) {
403
- shapes = shapes.concat(rules_with_id[j].rule.apply(datum, cell_width, cell_height));
454
+ shapes = shapes.concat(
455
+ rules_with_id[j].rule.apply(datum, cell_width, cell_height)
456
+ );
404
457
  }
405
458
  return shapes;
406
459
  }
407
460
 
408
- public getSpecificRulesForDatum(datum?:Datum):RuleWithId[] {
409
- throw "Not implemented on base class";
461
+ public getSpecificRulesForDatum(datum?: Datum): RuleWithId[] {
462
+ throw 'Not implemented on base class';
410
463
  }
411
464
 
412
465
  public getUniversalRule() {
413
466
  return this.universal_rule;
414
467
  }
415
468
 
416
- public getUniversalShapes(cell_width:number, cell_height:number) {
469
+ public getUniversalShapes(cell_width: number, cell_height: number) {
417
470
  if (this.getUniversalRule()) {
418
471
  const shapes = this.getUniversalRule().rule.apply(
419
472
  {}, // a universal rule does not rely on anything specific to the data
@@ -427,26 +480,42 @@ export class RuleSet {
427
480
  }
428
481
  }
429
482
 
430
- public getSpecificShapesForDatum(data:Datum[], cell_width:number, cell_height:number, out_active_rules?:ActiveRules|undefined, data_id_key?:string&keyof Datum, important_ids?:ColumnProp<boolean>) {
483
+ public getSpecificShapesForDatum(
484
+ data: Datum[],
485
+ cell_width: number,
486
+ cell_height: number,
487
+ out_active_rules?: ActiveRules | undefined,
488
+ data_id_key?: string & keyof Datum,
489
+ important_ids?: ColumnProp<boolean>
490
+ ) {
431
491
  // Returns a list of lists of concrete shapes, in the same order as data
432
492
  // optional parameter important_ids determines which ids count towards active rules (optional parameter data_id_key
433
493
  // is used for this too)
434
494
  const ret = [];
435
495
  for (var i = 0; i < data.length; i++) {
436
496
  const datum = data[i];
437
- const should_mark_active = !important_ids || !!important_ids[datum[data_id_key!]];
497
+ const should_mark_active =
498
+ !important_ids || !!important_ids[datum[data_id_key!]];
438
499
  const rules = this.getSpecificRulesForDatum(datum);
439
500
  if (typeof out_active_rules !== 'undefined' && should_mark_active) {
440
501
  for (let j = 0; j < rules.length; j++) {
441
502
  out_active_rules[rules[j].id] = true;
442
503
  }
443
504
  }
444
- const shapes = this.applyRulesToDatum(rules, data[i], cell_width, cell_height);
505
+ const shapes = this.applyRulesToDatum(
506
+ rules,
507
+ data[i],
508
+ cell_width,
509
+ cell_height
510
+ );
445
511
  shapes.sort(z_comparator);
446
512
  ret.push(shapes);
447
513
  }
448
514
  // mark universal rule as active
449
- if (this.getUniversalRule() && typeof out_active_rules !== 'undefined') {
515
+ if (
516
+ this.getUniversalRule() &&
517
+ typeof out_active_rules !== 'undefined'
518
+ ) {
450
519
  out_active_rules[this.getUniversalRule().id] = true;
451
520
  }
452
521
  return ret;
@@ -454,22 +523,29 @@ export class RuleSet {
454
523
  }
455
524
 
456
525
  class LookupRuleSet extends RuleSet {
457
- private lookup_map_by_key_and_value:{[key:string]:{[value:string]:RuleWithId}} = {};
458
- private lookup_map_by_key:{[key:string]:RuleWithId} = {};
459
- private rule_id_to_conditions:{[ruleId:number]:{ key:string, value:string }[] } = {};
460
-
461
- public getSpecificRulesForDatum(datum?:Datum) {
526
+ private lookup_map_by_key_and_value: {
527
+ [key: string]: { [value: string]: RuleWithId };
528
+ } = {};
529
+ private lookup_map_by_key: { [key: string]: RuleWithId } = {};
530
+ private rule_id_to_conditions: {
531
+ [ruleId: number]: { key: string; value: string }[];
532
+ } = {};
533
+
534
+ public getSpecificRulesForDatum(datum?: Datum) {
462
535
  if (typeof datum === 'undefined') {
463
536
  return this.rules_with_id;
464
537
  }
465
- let ret:RuleWithId[] = [];
538
+ let ret: RuleWithId[] = [];
466
539
  for (var key in datum) {
467
- if ((key in datum) && typeof datum[key] !== 'undefined') {
540
+ if (key in datum && typeof datum[key] !== 'undefined') {
468
541
  var key_rule = this.lookup_map_by_key[key];
469
542
  if (typeof key_rule !== 'undefined') {
470
543
  ret.push(key_rule);
471
544
  }
472
- var key_and_value_rule = (this.lookup_map_by_key_and_value[key] && this.lookup_map_by_key_and_value[key][datum[key]]) || undefined;
545
+ var key_and_value_rule =
546
+ (this.lookup_map_by_key_and_value[key] &&
547
+ this.lookup_map_by_key_and_value[key][datum[key]]) ||
548
+ undefined;
473
549
  if (typeof key_and_value_rule !== 'undefined') {
474
550
  ret.push(key_and_value_rule);
475
551
  }
@@ -478,34 +554,61 @@ class LookupRuleSet extends RuleSet {
478
554
  return ret;
479
555
  }
480
556
 
481
- private indexRuleForLookup(condition_key:string, condition_value:string, rule_with_id:RuleWithId) {
557
+ private indexRuleForLookup(
558
+ condition_key: string,
559
+ condition_value: string,
560
+ rule_with_id: RuleWithId
561
+ ) {
482
562
  if (condition_key === null) {
483
563
  this.setUniversalRule(rule_with_id);
484
564
  } else {
485
565
  if (condition_value === null) {
486
566
  this.lookup_map_by_key[condition_key] = rule_with_id;
487
567
  } else {
488
- this.lookup_map_by_key_and_value[condition_key] = this.lookup_map_by_key_and_value[condition_key] || {};
489
- this.lookup_map_by_key_and_value[condition_key][condition_value] = rule_with_id;
568
+ this.lookup_map_by_key_and_value[condition_key] =
569
+ this.lookup_map_by_key_and_value[condition_key] || {};
570
+ this.lookup_map_by_key_and_value[condition_key][
571
+ condition_value
572
+ ] = rule_with_id;
490
573
  }
491
574
  }
492
- this.rule_id_to_conditions[rule_with_id.id] = this.rule_id_to_conditions[rule_with_id.id] || [];
493
- this.rule_id_to_conditions[rule_with_id.id].push({key: condition_key, value: condition_value});
494
- };
575
+ this.rule_id_to_conditions[rule_with_id.id] =
576
+ this.rule_id_to_conditions[rule_with_id.id] || [];
577
+ this.rule_id_to_conditions[rule_with_id.id].push({
578
+ key: condition_key,
579
+ value: condition_value,
580
+ });
581
+ }
495
582
 
496
- public addRule(condition_key:string, condition_value:any, params:RuleParams) {
583
+ public addRule(
584
+ condition_key: string,
585
+ condition_value: any,
586
+ params: RuleParams
587
+ ) {
497
588
  const rule_id = this._addRule(params);
498
589
 
499
- this.indexRuleForLookup(condition_key, condition_value, this.getRuleWithId(rule_id));
590
+ this.indexRuleForLookup(
591
+ condition_key,
592
+ condition_value,
593
+ this.getRuleWithId(rule_id)
594
+ );
500
595
 
501
596
  return rule_id;
502
597
  }
503
598
 
504
- public linkExistingRule(condition_key:string, condition_value:string, existing_rule_id:RuleId) {
505
- this.indexRuleForLookup(condition_key, condition_value, this.getRuleWithId(existing_rule_id));
599
+ public linkExistingRule(
600
+ condition_key: string,
601
+ condition_value: string,
602
+ existing_rule_id: RuleId
603
+ ) {
604
+ this.indexRuleForLookup(
605
+ condition_key,
606
+ condition_value,
607
+ this.getRuleWithId(existing_rule_id)
608
+ );
506
609
  }
507
610
 
508
- public removeRule(rule_id:RuleId) {
611
+ public removeRule(rule_id: RuleId) {
509
612
  super.removeRule(rule_id);
510
613
 
511
614
  while (this.rule_id_to_conditions[rule_id].length > 0) {
@@ -517,7 +620,9 @@ class LookupRuleSet extends RuleSet {
517
620
  if (condition.value === null) {
518
621
  delete this.lookup_map_by_key[condition.key];
519
622
  } else {
520
- delete this.lookup_map_by_key_and_value[condition.key][condition.value];
623
+ delete this.lookup_map_by_key_and_value[condition.key][
624
+ condition.value
625
+ ];
521
626
  }
522
627
  }
523
628
  }
@@ -525,28 +630,33 @@ class LookupRuleSet extends RuleSet {
525
630
  }
526
631
  }
527
632
 
528
- type ConditionRuleSetCondition = (d:Datum)=>boolean;
633
+ type ConditionRuleSetCondition = (d: Datum) => boolean;
529
634
  class ConditionRuleSet extends RuleSet {
530
- private rule_id_to_condition:{[ruleId:number]:ConditionRuleSetCondition} = {};
635
+ private rule_id_to_condition: {
636
+ [ruleId: number]: ConditionRuleSetCondition;
637
+ } = {};
531
638
 
532
- constructor(params:RuleSetParams, omitNArule?:boolean) {
639
+ constructor(params: RuleSetParams, omitNArule?: boolean) {
533
640
  super(params);
534
641
 
535
642
  if (!omitNArule) {
536
- this.addRule(function (d) {
643
+ this.addRule(
644
+ function(d) {
537
645
  return d[NA_STRING] === true;
538
646
  },
539
647
  {
540
- shapes: params.na_shapes || makeNAShapes(params.na_z || 1000),
648
+ shapes:
649
+ params.na_shapes || makeNAShapes(params.na_z || 1000),
541
650
  legend_label: params.na_legend_label || NA_LABEL,
542
651
  exclude_from_legend: false,
543
- legend_config: {'type': 'rule', 'target': {'na': true}},
544
- legend_order: Number.POSITIVE_INFINITY
545
- });
652
+ legend_config: { type: 'rule', target: { na: true } },
653
+ legend_order: Number.POSITIVE_INFINITY,
654
+ }
655
+ );
546
656
  }
547
657
  }
548
658
 
549
- public getSpecificRulesForDatum(datum?:Datum) {
659
+ public getSpecificRulesForDatum(datum?: Datum) {
550
660
  if (typeof datum === 'undefined') {
551
661
  return this.rules_with_id;
552
662
  }
@@ -559,39 +669,50 @@ class ConditionRuleSet extends RuleSet {
559
669
  return ret;
560
670
  }
561
671
 
562
- public addRule(condition:ConditionRuleSetCondition, params:RuleParams, rule_id?:RuleId) {
672
+ public addRule(
673
+ condition: ConditionRuleSetCondition,
674
+ params: RuleParams,
675
+ rule_id?: RuleId
676
+ ) {
563
677
  rule_id = this._addRule(params, rule_id);
564
678
  this.rule_id_to_condition[rule_id] = condition;
565
679
  return rule_id;
566
680
  }
567
681
 
568
- public removeRule(rule_id:RuleId) {
682
+ public removeRule(rule_id: RuleId) {
569
683
  super.removeRule(rule_id);
570
684
  delete this.rule_id_to_condition[rule_id];
571
685
  }
572
686
  }
573
687
 
574
688
  class CategoricalRuleSet extends LookupRuleSet {
575
- public readonly category_key:string;
576
- private readonly category_to_color:{[category:string]:RGBAColor};
577
- private readonly getUnusedColor:(color?:string)=>RGBAColor;
578
- private readonly universal_rule_categories?:{[category:string]:any};
579
- constructor(params:Omit<ICategoricalRuleSetParams, "type">, omitNArule?:boolean) {
689
+ public readonly category_key: string;
690
+ private readonly category_to_color: { [category: string]: RGBAColor };
691
+ private readonly getUnusedColor: (color?: string) => RGBAColor;
692
+ private readonly universal_rule_categories?: { [category: string]: any };
693
+ constructor(
694
+ params: Omit<ICategoricalRuleSetParams, 'type'>,
695
+ omitNArule?: boolean
696
+ ) {
580
697
  super(params);
581
698
  if (!omitNArule) {
582
699
  this.addRule(NA_STRING, true, {
583
700
  shapes: params.na_shapes || makeNAShapes(params.na_z || 1000),
584
701
  legend_label: params.na_legend_label || NA_LABEL,
585
702
  exclude_from_legend: false,
586
- legend_config: {'type': 'rule', 'target': {'na': true}},
587
- legend_order: Number.POSITIVE_INFINITY
703
+ legend_config: { type: 'rule', target: { na: true } },
704
+ legend_order: Number.POSITIVE_INFINITY,
588
705
  });
589
706
  }
590
707
 
591
708
  this.category_key = params.category_key;
592
709
  this.universal_rule_categories = params.universal_rule_categories;
593
- this.category_to_color = cloneShallow(ifndef(params.category_to_color, {}));
594
- this.getUnusedColor = makeUniqueColorGetter(objectValues(this.category_to_color).map(rgbaToHex));
710
+ this.category_to_color = cloneShallow(
711
+ ifndef(params.category_to_color, {})
712
+ );
713
+ this.getUnusedColor = makeUniqueColorGetter(
714
+ objectValues(this.category_to_color).map(rgbaToHex)
715
+ );
595
716
  for (const category of Object.keys(this.category_to_color)) {
596
717
  const color = this.category_to_color[category];
597
718
  this.addCategoryRule(category, color);
@@ -599,19 +720,24 @@ class CategoricalRuleSet extends LookupRuleSet {
599
720
  }
600
721
  }
601
722
 
602
- private addCategoryRule(category:string, color:RGBAColor) {
603
- const legend_rule_target:any = {};
723
+ private addCategoryRule(category: string, color: RGBAColor) {
724
+ const legend_rule_target: any = {};
604
725
  legend_rule_target[this.category_key] = category;
605
- const rule_params:RuleParams = {
606
- shapes: [{
607
- type: 'rectangle',
608
- fill: color,
609
- }],
726
+ const rule_params: RuleParams = {
727
+ shapes: [
728
+ {
729
+ type: 'rectangle',
730
+ fill: color,
731
+ },
732
+ ],
610
733
  legend_label: category,
611
734
  exclude_from_legend: false,
612
- legend_config: {'type': 'rule', 'target': legend_rule_target}
735
+ legend_config: { type: 'rule', target: legend_rule_target },
613
736
  };
614
- if (this.universal_rule_categories && this.universal_rule_categories.hasOwnProperty(category)) {
737
+ if (
738
+ this.universal_rule_categories &&
739
+ this.universal_rule_categories.hasOwnProperty(category)
740
+ ) {
615
741
  // add universal rule
616
742
  this.addRule(null, category, rule_params);
617
743
  } else {
@@ -619,7 +745,14 @@ class CategoricalRuleSet extends LookupRuleSet {
619
745
  }
620
746
  }
621
747
 
622
- public getSpecificShapesForDatum(data:Datum, cell_width:number, cell_height:number, out_active_rules:ActiveRules|undefined, data_id_key:string&keyof Datum, important_ids?:ColumnProp<boolean>) {
748
+ public getSpecificShapesForDatum(
749
+ data: Datum,
750
+ cell_width: number,
751
+ cell_height: number,
752
+ out_active_rules: ActiveRules | undefined,
753
+ data_id_key: string & keyof Datum,
754
+ important_ids?: ColumnProp<boolean>
755
+ ) {
623
756
  // First ensure there is a color for all categories
624
757
  for (let i = 0, data_len = data.length; i < data_len; i++) {
625
758
  if (data[i][NA_STRING]) {
@@ -634,45 +767,56 @@ class CategoricalRuleSet extends LookupRuleSet {
634
767
  }
635
768
  }
636
769
  // Then propagate the call up
637
- return super.getSpecificShapesForDatum(data, cell_width, cell_height, out_active_rules, data_id_key, important_ids);
770
+ return super.getSpecificShapesForDatum(
771
+ data,
772
+ cell_width,
773
+ cell_height,
774
+ out_active_rules,
775
+ data_id_key,
776
+ important_ids
777
+ );
638
778
  }
639
779
  }
640
780
 
641
781
  export enum LinearInterpRangeType {
642
- ALL = 'ALL', // all values positive, negative and zero
782
+ ALL = 'ALL', // all values positive, negative and zero
643
783
  NON_NEGATIVE = 'NON_NEGATIVE', // value range all positive values inclusive zero (0)
644
- NON_POSITIVE = 'NON_POSITIVE' // value range all negative values inclusive zero (0)
784
+ NON_POSITIVE = 'NON_POSITIVE', // value range all negative values inclusive zero (0)
645
785
  }
646
786
 
647
787
  class LinearInterpRuleSet extends ConditionRuleSet {
648
-
649
- protected value_key:string;
650
- protected value_range:[number, number];
651
- protected log_scale?:boolean;
652
- protected type:string;
653
- protected makeInterpFn:()=>((valToConvert:number)=>number);
654
- protected inferred_value_range:[number, number];
655
-
656
- constructor(params:ILinearInterpRuleSetParams) {
788
+ protected value_key: string;
789
+ protected value_range: [number, number];
790
+ protected log_scale?: boolean;
791
+ protected type: string;
792
+ protected makeInterpFn: () => (valToConvert: number) => number;
793
+ protected inferred_value_range: [number, number];
794
+
795
+ constructor(params: ILinearInterpRuleSetParams) {
657
796
  super(params);
658
797
  this.value_key = params.value_key;
659
798
  this.value_range = params.value_range;
660
799
  this.log_scale = params.log_scale; // boolean
661
800
  this.type = params.type;
662
801
 
663
- this.makeInterpFn = function () {
802
+ this.makeInterpFn = function() {
664
803
  const range = this.getEffectiveValueRange();
665
804
  const rangeType = this.getValueRangeType();
666
805
  const plotType = this.type;
667
806
  if (this.log_scale) {
668
807
  var shift_to_make_pos = Math.abs(range[0]) + 1;
669
- var log_range = Math.log(range[1] + shift_to_make_pos) - Math.log(range[0] + shift_to_make_pos);
808
+ var log_range =
809
+ Math.log(range[1] + shift_to_make_pos) -
810
+ Math.log(range[0] + shift_to_make_pos);
670
811
  var log_range_lower = Math.log(range[0] + shift_to_make_pos);
671
- return function (val:number) {
672
- return (Math.log(val + shift_to_make_pos) - log_range_lower) / log_range;
812
+ return function(val: number) {
813
+ return (
814
+ (Math.log(val + shift_to_make_pos) - log_range_lower) /
815
+ log_range
816
+ );
673
817
  };
674
818
  } else {
675
- return function (val) {
819
+ return function(val) {
676
820
  var range_spread = range[1] - range[0],
677
821
  range_lower = range[0],
678
822
  range_higher = range[1];
@@ -680,27 +824,36 @@ class LinearInterpRuleSet extends ConditionRuleSet {
680
824
  if (rangeType === LinearInterpRangeType.NON_POSITIVE) {
681
825
  // when data only contains non positive values
682
826
  return (val - range_higher) / range_spread;
683
- } else if (rangeType === LinearInterpRangeType.NON_NEGATIVE) {
827
+ } else if (
828
+ rangeType === LinearInterpRangeType.NON_NEGATIVE
829
+ ) {
684
830
  // when data only contains non negative values
685
831
  return (val - range_lower) / range_spread;
686
832
  } else if (rangeType === LinearInterpRangeType.ALL) {
687
- range_spread = Math.abs(range[0]) > range[1] ? Math.abs(range[0]) : range[1];
833
+ range_spread =
834
+ Math.abs(range[0]) > range[1]
835
+ ? Math.abs(range[0])
836
+ : range[1];
688
837
  return val / range_spread;
689
838
  }
690
839
  } else {
691
840
  return (val - range_lower) / range_spread;
692
841
  }
842
+ return undefined;
693
843
  };
694
844
  }
695
845
  };
696
846
  }
697
847
 
698
- protected getEffectiveValueRange():[number,number] {
699
- const ret = (this.value_range && this.value_range.slice()) || [undefined, undefined];
700
- if (typeof ret[0] === "undefined") {
848
+ protected getEffectiveValueRange(): [number, number] {
849
+ const ret = (this.value_range && this.value_range.slice()) || [
850
+ undefined,
851
+ undefined,
852
+ ];
853
+ if (typeof ret[0] === 'undefined') {
701
854
  ret[0] = this.inferred_value_range[0];
702
855
  }
703
- if (typeof ret[1] === "undefined") {
856
+ if (typeof ret[1] === 'undefined') {
704
857
  ret[1] = this.inferred_value_range[1];
705
858
  }
706
859
  if (ret[0] === ret[1]) {
@@ -708,11 +861,11 @@ class LinearInterpRuleSet extends ConditionRuleSet {
708
861
  ret[0] -= ret[0] / 2;
709
862
  ret[1] += ret[1] / 2;
710
863
  }
711
- return ret as [number,number];
864
+ return ret as [number, number];
712
865
  }
713
866
  protected getValueRangeType() {
714
867
  var range = this.getEffectiveValueRange();
715
- if (range[0] < 0 && range[1] <=0) {
868
+ if (range[0] < 0 && range[1] <= 0) {
716
869
  return LinearInterpRangeType.NON_POSITIVE;
717
870
  } else if (range[0] >= 0 && range[1] > 0) {
718
871
  return LinearInterpRangeType.NON_NEGATIVE;
@@ -721,7 +874,14 @@ class LinearInterpRuleSet extends ConditionRuleSet {
721
874
  }
722
875
  }
723
876
 
724
- public getSpecificShapesForDatum(data:Datum, cell_width:number, cell_height:number, out_active_rules:ActiveRules|undefined, data_id_key:string&keyof Datum, important_ids?:ColumnProp<boolean>) {
877
+ public getSpecificShapesForDatum(
878
+ data: Datum,
879
+ cell_width: number,
880
+ cell_height: number,
881
+ out_active_rules: ActiveRules | undefined,
882
+ data_id_key: string & keyof Datum,
883
+ important_ids?: ColumnProp<boolean>
884
+ ) {
725
885
  // First find value range
726
886
  let value_min = Number.POSITIVE_INFINITY;
727
887
  let value_max = Number.NEGATIVE_INFINITY;
@@ -743,21 +903,28 @@ class LinearInterpRuleSet extends ConditionRuleSet {
743
903
  this.updateLinearRules();
744
904
 
745
905
  // Then propagate the call up
746
- return super.getSpecificShapesForDatum(data, cell_width, cell_height, out_active_rules, data_id_key, important_ids);
906
+ return super.getSpecificShapesForDatum(
907
+ data,
908
+ cell_width,
909
+ cell_height,
910
+ out_active_rules,
911
+ data_id_key,
912
+ important_ids
913
+ );
747
914
  }
748
915
 
749
916
  protected updateLinearRules() {
750
- throw "Not implemented in abstract class";
917
+ throw 'Not implemented in abstract class';
751
918
  }
752
919
  }
753
920
 
754
921
  class GradientRuleSet extends LinearInterpRuleSet {
755
- private colors:RGBAColor[] = [];
922
+ private colors: RGBAColor[] = [];
756
923
  private value_stop_points: number[];
757
- private null_color?:RGBAColor;
758
- private gradient_rule:RuleId;
924
+ private null_color?: RGBAColor;
925
+ private gradient_rule: RuleId;
759
926
 
760
- constructor(params:Omit<IGradientRuleSetParams, "type">) {
927
+ constructor(params: Omit<IGradientRuleSetParams, 'type'>) {
761
928
  super(params);
762
929
  if (params.colors) {
763
930
  this.colors = params.colors || [];
@@ -765,68 +932,98 @@ class GradientRuleSet extends LinearInterpRuleSet {
765
932
  this.colors = heatmapColors[params.colormap_name] || [];
766
933
  }
767
934
  if (this.colors.length === 0) {
768
- this.colors.push([0,0,0,1],[255,0,0,1]);
935
+ this.colors.push([0, 0, 0, 1], [255, 0, 0, 1]);
769
936
  }
770
937
 
771
938
  this.value_stop_points = params.value_stop_points;
772
- this.null_color = params.null_color || [211,211,211,1];
939
+ this.null_color = params.null_color || [211, 211, 211, 1];
773
940
 
774
941
  var self = this;
775
942
  var value_key = this.value_key;
776
- this.addRule(function(d) {
777
- return d[NA_STRING] !== true && d[value_key] === null;
778
- }, {
779
- shapes: [{
780
- type: 'rectangle',
781
- fill: self.null_color
782
- }],
783
- legend_label: params.null_legend_label || "Not a number",
784
- exclude_from_legend:false,
785
- legend_config: {'type':'rule', 'target':{ [value_key]:null } }
786
- });
943
+ this.addRule(
944
+ function(d) {
945
+ return d[NA_STRING] !== true && d[value_key] === null;
946
+ },
947
+ {
948
+ shapes: [
949
+ {
950
+ type: 'rectangle',
951
+ fill: self.null_color,
952
+ },
953
+ ],
954
+ legend_label: params.null_legend_label || 'Not a number',
955
+ exclude_from_legend: false,
956
+ legend_config: { type: 'rule', target: { [value_key]: null } },
957
+ }
958
+ );
787
959
  }
788
960
 
789
- static linInterpColors(t:number, begin_color:RGBAColor, end_color:RGBAColor):RGBAColor {
961
+ static linInterpColors(
962
+ t: number,
963
+ begin_color: RGBAColor,
964
+ end_color: RGBAColor
965
+ ): RGBAColor {
790
966
  // 0 <= t <= 1
791
967
  return [
792
- Math.round(begin_color[0]*(1-t) + end_color[0]*t),
793
- Math.round(begin_color[1]*(1-t) + end_color[1]*t),
794
- Math.round(begin_color[2]*(1-t) + end_color[2]*t),
795
- begin_color[3]*(1-t) + end_color[3]*t
968
+ Math.round(begin_color[0] * (1 - t) + end_color[0] * t),
969
+ Math.round(begin_color[1] * (1 - t) + end_color[1] * t),
970
+ Math.round(begin_color[2] * (1 - t) + end_color[2] * t),
971
+ begin_color[3] * (1 - t) + end_color[3] * t,
796
972
  ];
797
973
  }
798
974
 
799
- private makeColorFn(colors:RGBAColor[], interpFn:(valToConvert:number)=>number) {
975
+ private makeColorFn(
976
+ colors: RGBAColor[],
977
+ interpFn: (valToConvert: number) => number
978
+ ) {
800
979
  const value_stop_points = this.value_stop_points;
801
- let stop_points:number[];
980
+ let stop_points: number[];
802
981
  if (value_stop_points) {
803
982
  stop_points = value_stop_points.map(interpFn);
804
983
  } else {
805
- stop_points = intRange(colors.length).map(function(x) { return x/(colors.length -1); });
984
+ stop_points = intRange(colors.length).map(function(x) {
985
+ return x / (colors.length - 1);
986
+ });
806
987
  }
807
- return function(t:number):RGBAColor {
988
+ return function(t: number): RGBAColor {
808
989
  // 0 <= t <= 1
809
- var begin_interval_index = binarysearch(stop_points, t, function(x) { return x; }, true);
990
+ var begin_interval_index = binarysearch(
991
+ stop_points,
992
+ t,
993
+ function(x) {
994
+ return x;
995
+ },
996
+ true
997
+ );
810
998
  if (begin_interval_index === -1) {
811
- return [0,0,0,1];
999
+ return [0, 0, 0, 1];
812
1000
  }
813
- var end_interval_index = Math.min(colors.length - 1, begin_interval_index + 1);
814
- var spread = stop_points[end_interval_index] - stop_points[begin_interval_index];
1001
+ var end_interval_index = Math.min(
1002
+ colors.length - 1,
1003
+ begin_interval_index + 1
1004
+ );
1005
+ var spread =
1006
+ stop_points[end_interval_index] -
1007
+ stop_points[begin_interval_index];
815
1008
  if (spread === 0) {
816
1009
  return colors[end_interval_index];
817
1010
  } else {
818
- var interval_t = (t - stop_points[begin_interval_index]) / spread;
1011
+ var interval_t =
1012
+ (t - stop_points[begin_interval_index]) / spread;
819
1013
  var begin_color = colors[begin_interval_index];
820
1014
  var end_color = colors[end_interval_index];
821
- return GradientRuleSet.linInterpColors(interval_t, begin_color, end_color);
1015
+ return GradientRuleSet.linInterpColors(
1016
+ interval_t,
1017
+ begin_color,
1018
+ end_color
1019
+ );
822
1020
  }
823
-
824
1021
  };
825
1022
  }
826
1023
 
827
1024
  protected updateLinearRules() {
828
1025
  let rule_id;
829
- if (typeof this.gradient_rule !== "undefined") {
1026
+ if (typeof this.gradient_rule !== 'undefined') {
830
1027
  rule_id = this.gradient_rule;
831
1028
  this.removeRule(this.gradient_rule);
832
1029
  }
@@ -835,37 +1032,46 @@ class GradientRuleSet extends LinearInterpRuleSet {
835
1032
  const value_key = this.value_key;
836
1033
  const null_color = this.null_color;
837
1034
 
838
- this.gradient_rule = this.addRule(function (d) {
1035
+ this.gradient_rule = this.addRule(
1036
+ function(d) {
839
1037
  return d[NA_STRING] !== true && d[value_key] !== null;
840
1038
  },
841
- {shapes: [{
842
- type: 'rectangle',
843
- fill: function(d) {
844
- var t = interpFn(d[value_key]);
845
- return colorFn(t) as RGBAColor;
846
- }
847
- }],
1039
+ {
1040
+ shapes: [
1041
+ {
1042
+ type: 'rectangle',
1043
+ fill: function(d) {
1044
+ var t = interpFn(d[value_key]);
1045
+ return colorFn(t) as RGBAColor;
1046
+ },
1047
+ },
1048
+ ],
848
1049
  exclude_from_legend: false,
849
- legend_config: {'type': "gradient" as "gradient", 'range': this.getEffectiveValueRange(), 'colorFn':colorFn}
1050
+ legend_config: {
1051
+ type: 'gradient' as 'gradient',
1052
+ range: this.getEffectiveValueRange(),
1053
+ colorFn: colorFn,
1054
+ },
850
1055
  },
851
- rule_id);
1056
+ rule_id
1057
+ );
852
1058
  }
853
1059
  }
854
1060
 
855
1061
  class BarRuleSet extends LinearInterpRuleSet {
856
- private fill:RGBAColor;
857
- private negative_fill:RGBAColor;
858
- private bar_rule?:RuleId;
1062
+ private fill: RGBAColor;
1063
+ private negative_fill: RGBAColor;
1064
+ private bar_rule?: RuleId;
859
1065
 
860
- constructor(params:IBarRuleSetParams) {
1066
+ constructor(params: IBarRuleSetParams) {
861
1067
  super(params);
862
- this.fill = params.fill || [0,128,0,1]; // green
863
- this.negative_fill = params.negative_fill || [255,0,0,1]; //red
1068
+ this.fill = params.fill || [0, 128, 0, 1]; // green
1069
+ this.negative_fill = params.negative_fill || [255, 0, 0, 1]; //red
864
1070
  }
865
1071
 
866
1072
  protected updateLinearRules() {
867
1073
  let rule_id;
868
- if (typeof this.bar_rule !== "undefined") {
1074
+ if (typeof this.bar_rule !== 'undefined') {
869
1075
  rule_id = this.bar_rule;
870
1076
  this.removeRule(this.bar_rule);
871
1077
  }
@@ -875,47 +1081,60 @@ class BarRuleSet extends LinearInterpRuleSet {
875
1081
  const negative_color = this.negative_fill;
876
1082
  const yPosFn = this.getYPosPercentagesFn();
877
1083
  const cellHeightFn = this.getCellHeightPercentagesFn();
878
- this.bar_rule = this.addRule(function (d) {
1084
+ this.bar_rule = this.addRule(
1085
+ function(d) {
879
1086
  return d[NA_STRING] !== true;
880
1087
  },
881
- {shapes: [{
882
- type: 'rectangle',
883
- y: function (d) {
884
- var t = interpFn(d[value_key]);
885
- return yPosFn(t);
886
- },
887
- height: function (d) {
888
- var t = interpFn(d[value_key]);
889
- return cellHeightFn(t);
1088
+ {
1089
+ shapes: [
1090
+ {
1091
+ type: 'rectangle',
1092
+ y: function(d) {
1093
+ var t = interpFn(d[value_key]);
1094
+ return yPosFn(t);
1095
+ },
1096
+ height: function(d) {
1097
+ var t = interpFn(d[value_key]);
1098
+ return cellHeightFn(t);
1099
+ },
1100
+ fill: function(d) {
1101
+ return d[value_key] < 0
1102
+ ? negative_color
1103
+ : positive_color;
1104
+ },
890
1105
  },
891
- fill: function (d) {
892
- return d[value_key] < 0 ? negative_color : positive_color;
893
- }
894
- }],
1106
+ ],
895
1107
  exclude_from_legend: false,
896
1108
  legend_config: {
897
- 'type': 'number' as 'number',
898
- 'range': this.getEffectiveValueRange(),
899
- 'range_type': this.getValueRangeType(),
900
- 'positive_color': positive_color,
901
- 'negative_color': negative_color,
902
- 'interpFn': interpFn
903
- }
1109
+ type: 'number' as 'number',
1110
+ range: this.getEffectiveValueRange(),
1111
+ range_type: this.getValueRangeType(),
1112
+ positive_color: positive_color,
1113
+ negative_color: negative_color,
1114
+ interpFn: interpFn,
1115
+ },
904
1116
  },
905
- rule_id);
1117
+ rule_id
1118
+ );
906
1119
  }
907
1120
 
908
1121
  public getYPosPercentagesFn() {
909
1122
  let ret;
910
1123
  switch (this.getValueRangeType()) {
911
1124
  case LinearInterpRangeType.NON_POSITIVE:
912
- ret = (function(t:number) { return 0; });
1125
+ ret = function(t: number) {
1126
+ return 0;
1127
+ };
913
1128
  break;
914
1129
  case LinearInterpRangeType.NON_NEGATIVE:
915
- ret = (function(t:number) { return (1 - t) * 100; });
1130
+ ret = function(t: number) {
1131
+ return (1 - t) * 100;
1132
+ };
916
1133
  break;
917
1134
  case LinearInterpRangeType.ALL:
918
- ret = (function(t:number) { return Math.min(1-t, 1)*50; });
1135
+ ret = function(t: number) {
1136
+ return Math.min(1 - t, 1) * 50;
1137
+ };
919
1138
  break;
920
1139
  }
921
1140
  return ret;
@@ -925,13 +1144,19 @@ class BarRuleSet extends LinearInterpRuleSet {
925
1144
  let ret;
926
1145
  switch (this.getValueRangeType()) {
927
1146
  case LinearInterpRangeType.NON_POSITIVE:
928
- ret = (function(t:number) { return -t * 100; });
1147
+ ret = function(t: number) {
1148
+ return -t * 100;
1149
+ };
929
1150
  break;
930
1151
  case LinearInterpRangeType.NON_NEGATIVE:
931
- ret = (function(t:number) { return t * 100; });
1152
+ ret = function(t: number) {
1153
+ return t * 100;
1154
+ };
932
1155
  break;
933
1156
  case LinearInterpRangeType.ALL:
934
- ret = (function(t:number) { return Math.abs(t) * 50; });
1157
+ ret = function(t: number) {
1158
+ return Math.abs(t) * 50;
1159
+ };
935
1160
  break;
936
1161
  }
937
1162
  return ret;
@@ -939,7 +1164,7 @@ class BarRuleSet extends LinearInterpRuleSet {
939
1164
  }
940
1165
 
941
1166
  class StackedBarRuleSet extends ConditionRuleSet {
942
- constructor(params:IStackedBarRuleSetParams) {
1167
+ constructor(params: IStackedBarRuleSetParams) {
943
1168
  super(params);
944
1169
  const value_key = params.value_key;
945
1170
  const fills = params.fills || [];
@@ -952,91 +1177,143 @@ class StackedBarRuleSet extends ConditionRuleSet {
952
1177
  }
953
1178
 
954
1179
  const self = this;
955
- for (let i=0; i < categories.length; i++) {
1180
+ for (let i = 0; i < categories.length; i++) {
956
1181
  (function(I) {
957
- const legend_target:any = {};
1182
+ const legend_target: any = {};
958
1183
  legend_target[value_key] = {};
959
- for (let j=0; j<categories.length; j++) {
1184
+ for (let j = 0; j < categories.length; j++) {
960
1185
  legend_target[value_key][categories[j]] = 0;
961
1186
  }
962
1187
  legend_target[value_key][categories[I]] = 1;
963
- self.addRule(function(d) {
1188
+ self.addRule(
1189
+ function(d) {
964
1190
  return d[NA_STRING] !== true;
965
1191
  },
966
- {shapes: [{
967
- type: 'rectangle',
968
- fill: fills[I],
969
- width: 100,
970
- height: function(d) {
971
- var total = 0;
972
- for (var j=0; j<categories.length; j++) {
973
- total += parseFloat(d[value_key][categories[j]]);
974
- }
975
- return parseFloat(d[value_key][categories[I]])*100/total;
976
- },
977
- y: function(d) {
978
- var total = 0;
979
- var prev_vals_sum = 0;
980
- for (var j=0; j<categories.length; j++) {
981
- var new_val = parseFloat(d[value_key][categories[j]]);
982
- if (j < I) {
983
- prev_vals_sum += new_val;
1192
+ {
1193
+ shapes: [
1194
+ {
1195
+ type: 'rectangle',
1196
+ fill: fills[I],
1197
+ width: 100,
1198
+ height: function(d) {
1199
+ var total = 0;
1200
+ for (
1201
+ var j = 0;
1202
+ j < categories.length;
1203
+ j++
1204
+ ) {
1205
+ total += parseFloat(
1206
+ d[value_key][categories[j]]
1207
+ );
984
1208
  }
985
- total += new_val;
986
- }
987
- return prev_vals_sum*100/total;
988
- }
989
- }],
1209
+ return (
1210
+ (parseFloat(
1211
+ d[value_key][categories[I]]
1212
+ ) *
1213
+ 100) /
1214
+ total
1215
+ );
1216
+ },
1217
+ y: function(d) {
1218
+ var total = 0;
1219
+ var prev_vals_sum = 0;
1220
+ for (
1221
+ var j = 0;
1222
+ j < categories.length;
1223
+ j++
1224
+ ) {
1225
+ var new_val = parseFloat(
1226
+ d[value_key][categories[j]]
1227
+ );
1228
+ if (j < I) {
1229
+ prev_vals_sum += new_val;
1230
+ }
1231
+ total += new_val;
1232
+ }
1233
+ return (prev_vals_sum * 100) / total;
1234
+ },
1235
+ },
1236
+ ],
990
1237
  exclude_from_legend: false,
991
- legend_config: {'type': 'rule', 'target': legend_target},
992
- legend_label: categories[I]});
1238
+ legend_config: { type: 'rule', target: legend_target },
1239
+ legend_label: categories[I],
1240
+ }
1241
+ );
993
1242
  })(i);
994
1243
  }
995
1244
  }
996
1245
  }
997
1246
 
998
1247
  export class GeneticAlterationRuleSet extends LookupRuleSet {
999
- constructor(params:IGeneticAlterationRuleSetParams) {
1248
+ constructor(params: IGeneticAlterationRuleSetParams) {
1000
1249
  super(params);
1001
1250
  this.addRulesFromParams(params);
1002
1251
  this.addRule(NA_STRING, true, {
1003
1252
  shapes: params.na_shapes || makeNAShapes(params.na_z || 1),
1004
1253
  legend_label: params.na_legend_label || NA_LABEL,
1005
1254
  exclude_from_legend: false,
1006
- legend_config: {'type': 'rule', 'target': {'na': true}},
1007
- legend_order: Number.POSITIVE_INFINITY
1255
+ legend_config: { type: 'rule', target: { na: true } },
1256
+ legend_order: Number.POSITIVE_INFINITY,
1008
1257
  });
1009
1258
  }
1010
1259
 
1011
- private addRulesFromParams(params:IGeneticAlterationRuleSetParams) {
1260
+ private addRulesFromParams(params: IGeneticAlterationRuleSetParams) {
1012
1261
  const rule_params = params.rule_params;
1013
- _.forEach(rule_params.conditional, (datumValuesToRuleParams:GeneticAlterationRuleParams["conditional"]["datumKey"], datumKey:string)=>{
1014
- _.forEach(datumValuesToRuleParams, (ruleParams:GeneticAlterationSingleRuleParams, commaSeparatedDatumValues:string)=>{
1015
- const equiv_values = commaSeparatedDatumValues.split(",");
1016
- const legend_rule_target:any = {};
1017
- legend_rule_target[equiv_values[0]] = commaSeparatedDatumValues;
1018
- const rule_id = this.addRule(
1019
- datumKey,
1020
- (equiv_values[0] === '*' ? null : equiv_values[0]),
1021
- shallowExtend(ruleParams,
1022
- {
1023
- shapes: ruleParams.shapes,
1024
- legend_config: {'type': 'rule' as 'rule', 'target': legend_rule_target},
1025
- legend_base_color: ifndef(this.legend_base_color, [255,255,255,1])
1262
+ _.forEach(
1263
+ rule_params.conditional,
1264
+ (
1265
+ datumValuesToRuleParams: GeneticAlterationRuleParams['conditional']['datumKey'],
1266
+ datumKey: string
1267
+ ) => {
1268
+ _.forEach(
1269
+ datumValuesToRuleParams,
1270
+ (
1271
+ ruleParams: GeneticAlterationSingleRuleParams,
1272
+ commaSeparatedDatumValues: string
1273
+ ) => {
1274
+ const equiv_values = commaSeparatedDatumValues.split(
1275
+ ','
1276
+ );
1277
+ const legend_rule_target: any = {};
1278
+ legend_rule_target[
1279
+ equiv_values[0]
1280
+ ] = commaSeparatedDatumValues;
1281
+ const rule_id = this.addRule(
1282
+ datumKey,
1283
+ equiv_values[0] === '*' ? null : equiv_values[0],
1284
+ shallowExtend(ruleParams, {
1285
+ shapes: ruleParams.shapes,
1286
+ legend_config: {
1287
+ type: 'rule' as 'rule',
1288
+ target: legend_rule_target,
1289
+ },
1290
+ legend_base_color: ifndef(
1291
+ this.legend_base_color,
1292
+ [255, 255, 255, 1]
1293
+ ) as [number, number, number, number],
1294
+ })
1295
+ );
1296
+ for (let i = 1; i < equiv_values.length; i++) {
1297
+ this.linkExistingRule(
1298
+ datumKey,
1299
+ equiv_values[i] === '*'
1300
+ ? null
1301
+ : equiv_values[i],
1302
+ rule_id
1303
+ );
1026
1304
  }
1027
- )
1305
+ }
1028
1306
  );
1029
- for (let i = 1; i < equiv_values.length; i++) {
1030
- this.linkExistingRule(datumKey, (equiv_values[i] === '*' ? null : equiv_values[i]), rule_id);
1031
- }
1032
- });
1033
- });
1307
+ }
1308
+ );
1034
1309
 
1035
1310
  if (rule_params.always) {
1036
- this.addRule(null, null,
1311
+ this.addRule(
1312
+ null,
1313
+ null,
1037
1314
  shallowExtend(rule_params.always, {
1038
- shapes:rule_params.always.shapes,
1039
- legend_config: {'type': 'rule' as 'rule', 'target': {}}
1315
+ shapes: rule_params.always.shapes,
1316
+ legend_config: { type: 'rule' as 'rule', target: {} },
1040
1317
  })
1041
1318
  );
1042
1319
  }
@@ -1044,15 +1321,15 @@ export class GeneticAlterationRuleSet extends LookupRuleSet {
1044
1321
  }
1045
1322
 
1046
1323
  export class Rule {
1047
- private shapes:Shape[];
1048
- public legend_label:string;
1049
- public legend_base_color?:RGBAColor;
1050
- public exclude_from_legend?:boolean;
1051
- private legend_config?:RuleLegendConfig;
1052
- public legend_order?:number;
1053
-
1054
- constructor(params:RuleParams) {
1055
- this.shapes = params.shapes.map(function (shape) {
1324
+ private shapes: Shape[];
1325
+ public legend_label: string;
1326
+ public legend_base_color?: RGBAColor;
1327
+ public exclude_from_legend?: boolean;
1328
+ private legend_config?: RuleLegendConfig;
1329
+ public legend_order?: number;
1330
+
1331
+ constructor(params: RuleParams) {
1332
+ this.shapes = params.shapes.map(function(shape) {
1056
1333
  if (shape.type === 'rectangle') {
1057
1334
  return new Rectangle(shape);
1058
1335
  } else if (shape.type === 'triangle') {
@@ -1062,8 +1339,12 @@ export class Rule {
1062
1339
  } else if (shape.type === 'line') {
1063
1340
  return new Line(shape);
1064
1341
  }
1342
+ return undefined;
1065
1343
  });
1066
- this.legend_label = typeof params.legend_label === "undefined" ? "" : params.legend_label;
1344
+ this.legend_label =
1345
+ typeof params.legend_label === 'undefined'
1346
+ ? ''
1347
+ : params.legend_label;
1067
1348
  this.legend_base_color = params.legend_base_color;
1068
1349
  this.exclude_from_legend = params.exclude_from_legend;
1069
1350
  this.legend_config = params.legend_config;
@@ -1073,12 +1354,14 @@ export class Rule {
1073
1354
  return this.legend_config;
1074
1355
  }
1075
1356
 
1076
- public apply(d:Datum, cell_width:number, cell_height:number) {
1357
+ public apply(d: Datum, cell_width: number, cell_height: number) {
1077
1358
  // Gets concrete shapes (i.e. computed
1078
1359
  // real values from percentages)
1079
1360
  const concrete_shapes = [];
1080
1361
  for (let i = 0, shapes_len = this.shapes.length; i < shapes_len; i++) {
1081
- concrete_shapes.push(this.shapes[i].getComputedParams(d, cell_width, cell_height));
1362
+ concrete_shapes.push(
1363
+ this.shapes[i].getComputedParams(d, cell_width, cell_height)
1364
+ );
1082
1365
  }
1083
1366
  return concrete_shapes;
1084
1367
  }
@@ -1089,9 +1372,9 @@ export class Rule {
1089
1372
  }
1090
1373
 
1091
1374
  class GradientCategoricalRuleSet extends RuleSet {
1092
- private gradientRuleSet:GradientRuleSet;
1093
- private categoricalRuleSet:CategoricalRuleSet;
1094
- constructor(params:IGradientAndCategoricalRuleSetParams) {
1375
+ private gradientRuleSet: GradientRuleSet;
1376
+ private categoricalRuleSet: CategoricalRuleSet;
1377
+ constructor(params: IGradientAndCategoricalRuleSetParams) {
1095
1378
  super(params);
1096
1379
  // For the GradientCategoricalRuleSet a datum must always have a
1097
1380
  // value and may have a category attribute. A datum is 'NA'
@@ -1103,40 +1386,68 @@ class GradientCategoricalRuleSet extends RuleSet {
1103
1386
  }
1104
1387
 
1105
1388
  // RuleSet API
1106
- public getSpecificShapesForDatum(data:Datum, cell_width:number, cell_height:number, out_active_rules:ActiveRules|undefined, data_id_key:string&keyof Datum, important_ids?:ColumnProp<boolean>) {
1107
-
1389
+ public getSpecificShapesForDatum(
1390
+ data: Datum,
1391
+ cell_width: number,
1392
+ cell_height: number,
1393
+ out_active_rules: ActiveRules | undefined,
1394
+ data_id_key: string & keyof Datum,
1395
+ important_ids?: ColumnProp<boolean>
1396
+ ) {
1108
1397
  const shapes = [];
1109
1398
  // check the type of datum (categorical or continuous) and delegate
1110
1399
  // fetching of shapes to the appropriate RuleSet class
1111
1400
  for (let i = 0; i < data.length; i++) {
1112
1401
  const datum = data[i];
1113
- if ( this.isCategorical(datum) ) {
1114
- shapes.push( this.categoricalRuleSet.getSpecificShapesForDatum([datum], cell_width, cell_height, out_active_rules, data_id_key, important_ids)[0] );
1402
+ if (this.isCategorical(datum)) {
1403
+ shapes.push(
1404
+ this.categoricalRuleSet.getSpecificShapesForDatum(
1405
+ [datum],
1406
+ cell_width,
1407
+ cell_height,
1408
+ out_active_rules,
1409
+ data_id_key,
1410
+ important_ids
1411
+ )[0]
1412
+ );
1115
1413
  } else {
1116
- shapes.push( this.gradientRuleSet.getSpecificShapesForDatum([datum], cell_width, cell_height, out_active_rules, data_id_key, important_ids)[0] );
1414
+ shapes.push(
1415
+ this.gradientRuleSet.getSpecificShapesForDatum(
1416
+ [datum],
1417
+ cell_width,
1418
+ cell_height,
1419
+ out_active_rules,
1420
+ data_id_key,
1421
+ important_ids
1422
+ )[0]
1423
+ );
1117
1424
  }
1118
1425
  }
1119
1426
  return shapes;
1120
1427
  }
1121
1428
 
1122
1429
  // RuleSet API
1123
- public getSpecificRulesForDatum(datum?:Datum) {
1124
- const categoricalRules = this.categoricalRuleSet.getSpecificRulesForDatum(datum);
1125
- const gradientRules = this.gradientRuleSet.getSpecificRulesForDatum(datum);
1430
+ public getSpecificRulesForDatum(datum?: Datum) {
1431
+ const categoricalRules = this.categoricalRuleSet.getSpecificRulesForDatum(
1432
+ datum
1433
+ );
1434
+ const gradientRules = this.gradientRuleSet.getSpecificRulesForDatum(
1435
+ datum
1436
+ );
1126
1437
  const rules = categoricalRules.concat(gradientRules);
1127
1438
  return rules;
1128
1439
  }
1129
1440
 
1130
1441
  // helper function
1131
- public isCategorical(datum:Datum) {
1442
+ public isCategorical(datum: Datum) {
1132
1443
  // A categorical value is recognized by presence of a category attribute.
1133
1444
  // Note: a categorical datum still requires a continuous value (used for clustering).
1134
1445
  return datum[this.categoricalRuleSet.category_key] !== undefined;
1135
1446
  }
1136
1447
  }
1137
1448
 
1138
- export default function (params:RuleSetParams) {
1139
- let ret:RuleSet;
1449
+ export default function(params: RuleSetParams) {
1450
+ let ret: RuleSet;
1140
1451
  switch (params.type) {
1141
1452
  case RuleSetType.CATEGORICAL:
1142
1453
  ret = new CategoricalRuleSet(params as ICategoricalRuleSetParams);
@@ -1145,7 +1456,9 @@ export default function (params:RuleSetParams) {
1145
1456
  ret = new GradientRuleSet(params as IGradientRuleSetParams);
1146
1457
  break;
1147
1458
  case RuleSetType.GRADIENT_AND_CATEGORICAL:
1148
- ret = new GradientCategoricalRuleSet(params as IGradientAndCategoricalRuleSetParams);
1459
+ ret = new GradientCategoricalRuleSet(
1460
+ params as IGradientAndCategoricalRuleSetParams
1461
+ );
1149
1462
  break;
1150
1463
  case RuleSetType.BAR:
1151
1464
  ret = new BarRuleSet(params as IBarRuleSetParams);
@@ -1155,8 +1468,10 @@ export default function (params:RuleSetParams) {
1155
1468
  break;
1156
1469
  case RuleSetType.GENE:
1157
1470
  default:
1158
- ret = new GeneticAlterationRuleSet(params as IGeneticAlterationRuleSetParams);
1471
+ ret = new GeneticAlterationRuleSet(
1472
+ params as IGeneticAlterationRuleSetParams
1473
+ );
1159
1474
  break;
1160
1475
  }
1161
1476
  return ret;
1162
- };
1477
+ }