@jbrowse/wiggle-core 5.0.0-beta.1 → 5.0.0-beta.11
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 +76 -107
- package/esm/AutoscaleGroupDialog.d.ts +7 -0
- package/esm/AutoscaleGroupDialog.js +26 -0
- package/esm/ScoreAxisMixin.d.ts +134 -0
- package/esm/ScoreAxisMixin.js +213 -0
- package/esm/ScoreFieldConfigMixin.d.ts +72 -0
- package/esm/ScoreFieldConfigMixin.js +25 -0
- package/esm/ScorePlotChrome.d.ts +45 -0
- package/esm/ScorePlotChrome.js +47 -0
- package/esm/ScorePlotSvgFrame.d.ts +27 -0
- package/esm/ScorePlotSvgFrame.js +23 -0
- package/esm/ScoreScaleMixin.d.ts +113 -50
- package/esm/ScoreScaleMixin.js +148 -70
- package/esm/SetMinMaxDialog.d.ts +3 -2
- package/esm/SetMinMaxDialog.js +20 -6
- package/esm/SetScoreRulesDialog.d.ts +14 -0
- package/esm/SetScoreRulesDialog.js +45 -0
- package/esm/WiggleScoreConfigMixin.d.ts +89 -0
- package/esm/WiggleScoreConfigMixin.js +54 -0
- package/esm/autoscale.d.ts +54 -14
- package/esm/autoscale.js +105 -180
- package/esm/autoscaleGroup.d.ts +30 -0
- package/esm/autoscaleGroup.js +97 -0
- package/esm/chrome.d.ts +5 -0
- package/esm/chrome.js +7 -0
- package/esm/computeYTicks.d.ts +1 -1
- package/esm/computeYTicks.js +4 -3
- package/esm/constants.d.ts +1 -2
- package/esm/constants.js +1 -10
- package/esm/dataTypes.d.ts +4 -6
- package/esm/displayModel.d.ts +1 -2
- package/esm/gapBreak.d.ts +2 -3
- package/esm/gapBreak.js +2 -3
- package/esm/index.d.ts +24 -25
- package/esm/index.js +20 -18
- package/esm/normalize.d.ts +1 -26
- package/esm/normalize.js +1 -86
- package/esm/pointMarker.d.ts +7 -2
- package/esm/pointMarker.js +14 -18
- package/esm/pointSizeMenu.d.ts +30 -11
- package/esm/pointSizeMenu.js +42 -19
- package/esm/renderingBackendTypes.d.ts +13 -4
- package/esm/renderingBackendTypes.js +4 -1
- package/esm/rowLabelOffset.d.ts +8 -0
- package/esm/rowLabelOffset.js +16 -0
- package/esm/scale.d.ts +12 -8
- package/esm/scale.js +27 -14
- package/esm/scoreFieldConfigSchemaFields.d.ts +10 -0
- package/esm/scoreFieldConfigSchemaFields.js +8 -0
- package/esm/scoreMenuItems.d.ts +35 -16
- package/esm/scoreMenuItems.js +95 -62
- package/esm/scoreRuleMarks.d.ts +14 -39
- package/esm/scoreRuleMarks.js +12 -45
- package/esm/transferables.js +4 -9
- package/esm/valueScaleConfigSchema.d.ts +253 -0
- package/esm/valueScaleConfigSchema.js +270 -0
- package/esm/visibleStatsDomain.d.ts +19 -8
- package/esm/visibleStatsDomain.js +32 -27
- package/esm/wiggleRenderModes.generated.d.ts +1 -2
- package/esm/wiggleRenderModes.generated.js +1 -2
- package/package.json +17 -10
- package/esm/CrossHatches.d.ts +0 -11
- package/esm/CrossHatches.js +0 -32
- package/esm/ScoreRules.d.ts +0 -11
- package/esm/ScoreRules.js +0 -37
- package/esm/YScaleBar.d.ts +0 -6
- package/esm/YScaleBar.js +0 -46
- package/esm/YScaleBarOverlay.d.ts +0 -6
- package/esm/YScaleBarOverlay.js +0 -24
- package/esm/scoreAxisConfigSchemaFields.d.ts +0 -44
- package/esm/scoreAxisConfigSchemaFields.js +0 -54
- package/esm/yScaleTicks.d.ts +0 -59
- package/esm/yScaleTicks.js +0 -59
package/esm/scoreMenuItems.d.ts
CHANGED
|
@@ -1,37 +1,56 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { AutoscalePeer } from './autoscaleGroup.ts';
|
|
2
|
+
import type { CheckboxMenuItem, MenuItem } from '@jbrowse/core/ui';
|
|
3
|
+
import type { ValueScaleRule } from '@jbrowse/display-ui';
|
|
2
4
|
import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
3
5
|
export interface ScoreScaleModel extends IStateTreeNode {
|
|
4
6
|
scaleType: string;
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
scaleZero: boolean;
|
|
8
|
+
domainQuantile: number;
|
|
9
|
+
clipQuantile: number;
|
|
10
|
+
manualMinScore: number | undefined;
|
|
11
|
+
manualMaxScore: number | undefined;
|
|
8
12
|
minScoreBound: number | undefined;
|
|
9
13
|
maxScoreBound: number | undefined;
|
|
14
|
+
hasManualScoreBounds: boolean;
|
|
15
|
+
autoscaledDomain: [number, number] | undefined;
|
|
10
16
|
setScaleType: (v: string) => void;
|
|
11
|
-
|
|
17
|
+
setScaleZero: (zero: boolean) => void;
|
|
12
18
|
setMinScore: (n?: number) => void;
|
|
13
19
|
setMaxScore: (n?: number) => void;
|
|
20
|
+
setDomainQuantile: (quantile: number) => void;
|
|
21
|
+
}
|
|
22
|
+
export interface ScoreRulesModel {
|
|
23
|
+
scoreRulesDrawn: boolean;
|
|
24
|
+
scoreRules: ValueScaleRule[];
|
|
25
|
+
setScoreRules: (rules: ValueScaleRule[]) => void;
|
|
14
26
|
}
|
|
15
27
|
export declare function makeScaleTypeSubMenu(self: {
|
|
16
28
|
scaleType: string;
|
|
17
29
|
setScaleType: (v: string) => void;
|
|
18
30
|
}): MenuItem;
|
|
19
|
-
export declare
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
31
|
+
export declare const CLIP_OUTLIERS_LABEL = "Clip outliers";
|
|
32
|
+
export declare function makeClipOutliersItem(self: {
|
|
33
|
+
domainQuantile: number;
|
|
34
|
+
clipQuantile: number;
|
|
35
|
+
setDomainQuantile: (quantile: number) => void;
|
|
36
|
+
}): CheckboxMenuItem;
|
|
37
|
+
export declare const AXIS_ZERO_LABEL = "Start axis at 0";
|
|
38
|
+
export declare function makeAxisZeroItem(self: {
|
|
39
|
+
scaleZero: boolean;
|
|
40
|
+
setScaleZero: (zero: boolean) => void;
|
|
41
|
+
}): CheckboxMenuItem;
|
|
23
42
|
export declare function makeSetMinMaxScoreItem(self: ScoreScaleModel): MenuItem;
|
|
24
43
|
export declare function makeCrossHatchItem(self: {
|
|
25
|
-
|
|
26
|
-
|
|
44
|
+
grid: boolean;
|
|
45
|
+
setGrid: (grid: boolean) => void;
|
|
27
46
|
}): MenuItem;
|
|
28
|
-
export
|
|
47
|
+
export interface ScoreSubMenuOptions {
|
|
29
48
|
label?: string;
|
|
30
|
-
scaleType?: boolean;
|
|
31
|
-
autoscale?: boolean;
|
|
32
|
-
autoscaleOptions?: [string, string][];
|
|
33
49
|
leadingItems?: MenuItem[];
|
|
34
50
|
trailingItems?: MenuItem[];
|
|
35
51
|
disabled?: boolean;
|
|
36
52
|
disabledHelpText?: string;
|
|
37
|
-
}
|
|
53
|
+
}
|
|
54
|
+
export declare function makeAutoscaleGroupItem(self: IStateTreeNode & AutoscalePeer): MenuItem;
|
|
55
|
+
export declare function makeSetScoreRulesItem(self: IStateTreeNode & ScoreRulesModel): MenuItem;
|
|
56
|
+
export declare function makeScoreSubMenu(self: ScoreScaleModel & Partial<ScoreRulesModel> & Partial<AutoscalePeer>, opts?: ScoreSubMenuOptions): MenuItem;
|
package/esm/scoreMenuItems.js
CHANGED
|
@@ -1,90 +1,123 @@
|
|
|
1
1
|
import { lazy } from 'react';
|
|
2
|
-
import { checkboxItem, radioItems } from '@jbrowse/core/ui/menuItems';
|
|
2
|
+
import { checkboxItem, radioItems, toggleItem, } from '@jbrowse/core/ui/menuItems';
|
|
3
3
|
import { getDialogHost } from '@jbrowse/core/util';
|
|
4
4
|
import EqualizerIcon from '@mui/icons-material/Equalizer';
|
|
5
|
-
import {
|
|
5
|
+
import { autoscaleGroupMembers, autoscalePeers } from './autoscaleGroup.js';
|
|
6
|
+
import { VALUE_SCALE_TYPES } from './valueScaleConfigSchema.js';
|
|
7
|
+
const AutoscaleGroupDialog = lazy(() => import('./AutoscaleGroupDialog.js'));
|
|
6
8
|
const SetMinMaxDialog = lazy(() => import('./SetMinMaxDialog.js'));
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
const SetScoreRulesDialog = lazy(() => import('./SetScoreRulesDialog.js'));
|
|
10
|
+
const SCALE_TYPE_LABELS = {
|
|
11
|
+
linear: 'Linear scale',
|
|
12
|
+
log: 'Log scale',
|
|
13
|
+
symlog: 'Symlog scale (allows zero)',
|
|
14
|
+
};
|
|
12
15
|
export function makeScaleTypeSubMenu(self) {
|
|
13
16
|
return {
|
|
14
17
|
label: 'Scale type',
|
|
15
|
-
subMenu: radioItems(
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
], self.scaleType, v => {
|
|
18
|
+
subMenu: radioItems(VALUE_SCALE_TYPES.map(value => ({
|
|
19
|
+
value,
|
|
20
|
+
label: SCALE_TYPE_LABELS[value],
|
|
21
|
+
})), self.scaleType, v => {
|
|
20
22
|
self.setScaleType(v);
|
|
21
23
|
}),
|
|
22
24
|
};
|
|
23
25
|
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
// Quoted by the docs' click paths, so one literal string.
|
|
27
|
+
export const CLIP_OUTLIERS_LABEL = 'Clip outliers';
|
|
28
|
+
// One checkbox rather than a radio over modes: what a reader decides is whether
|
|
29
|
+
// a spike may take the axis, and the quantile it clips at is the config's.
|
|
30
|
+
export function makeClipOutliersItem(self) {
|
|
31
|
+
const clipsAt = self.domainQuantile < 1 ? self.domainQuantile : self.clipQuantile;
|
|
32
|
+
const percent = Math.round(clipsAt * 100);
|
|
33
|
+
return toggleItem(CLIP_OUTLIERS_LABEL, self.domainQuantile < 1, on => {
|
|
34
|
+
self.setDomainQuantile(on ? self.clipQuantile : 1);
|
|
35
|
+
}, {
|
|
36
|
+
helpText: `An unpinned end follows the ${percent}th percentile of each sign rather than the extremes, so one spike no longer flattens the rest.`,
|
|
37
|
+
});
|
|
31
38
|
}
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
return { min, max, hasManual: min !== undefined || max !== undefined };
|
|
39
|
+
// Quoted by the docs' click paths, so one literal string.
|
|
40
|
+
export const AXIS_ZERO_LABEL = 'Start axis at 0';
|
|
41
|
+
export function makeAxisZeroItem(self) {
|
|
42
|
+
return toggleItem(AXIS_ZERO_LABEL, self.scaleZero, zero => {
|
|
43
|
+
self.setScaleZero(zero);
|
|
44
|
+
}, {
|
|
45
|
+
helpText: 'A linear or symlog axis reaches 0 whatever the values in view span. Off, it spans those values alone.',
|
|
46
|
+
});
|
|
41
47
|
}
|
|
48
|
+
// The label shows the PINNED pair, `auto` for an end nobody pinned: the
|
|
49
|
+
// resolved pair captioned every GC content track "(0 – 1)" off its default
|
|
50
|
+
// domain. "Use current range" copies `autoscaledDomain`, undefined while the
|
|
51
|
+
// alignments density tier's features per bin stand in for depth.
|
|
42
52
|
export function makeSetMinMaxScoreItem(self) {
|
|
43
|
-
const {
|
|
53
|
+
const { manualMinScore, manualMaxScore, autoscaledDomain: domain } = self;
|
|
44
54
|
return {
|
|
45
|
-
label:
|
|
46
|
-
? `Set min/max score (${
|
|
55
|
+
label: self.hasManualScoreBounds
|
|
56
|
+
? `Set min/max score (${manualMinScore ?? 'auto'} – ${manualMaxScore ?? 'auto'})...`
|
|
47
57
|
: 'Set min/max score...',
|
|
48
58
|
onClick: () => {
|
|
49
59
|
getDialogHost(self).queueDialog(handleClose => [
|
|
50
60
|
SetMinMaxDialog,
|
|
51
|
-
{ model: self, handleClose },
|
|
61
|
+
{ model: self, domain, handleClose },
|
|
52
62
|
]);
|
|
53
63
|
},
|
|
54
64
|
};
|
|
55
65
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
export function makeCrossHatchItem(self) {
|
|
67
|
+
return checkboxItem('Show cross hatches', self.grid, () => {
|
|
68
|
+
self.setGrid(!self.grid);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
// The count of the other tracks in the group is in the label, as the min/max
|
|
72
|
+
// row carries its bounds: an axis that moves when another track pans is
|
|
73
|
+
// something the reader has to be able to find the cause of.
|
|
74
|
+
export function makeAutoscaleGroupItem(self) {
|
|
75
|
+
const { autoscaleGroup } = self;
|
|
76
|
+
const others = autoscaleGroup === undefined
|
|
77
|
+
? 0
|
|
78
|
+
: autoscaleGroupMembers(self, autoscaleGroup).length - 1;
|
|
59
79
|
return {
|
|
60
|
-
label:
|
|
80
|
+
label: others > 0
|
|
81
|
+
? `Autoscale with other tracks (${others})...`
|
|
82
|
+
: 'Autoscale with other tracks...',
|
|
61
83
|
onClick: () => {
|
|
62
|
-
self.
|
|
63
|
-
|
|
84
|
+
getDialogHost(self).queueDialog(handleClose => [
|
|
85
|
+
AutoscaleGroupDialog,
|
|
86
|
+
{ model: self, handleClose },
|
|
87
|
+
]);
|
|
64
88
|
},
|
|
65
89
|
};
|
|
66
90
|
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
91
|
+
// Offered once the view holds another track with a value axis to share.
|
|
92
|
+
function autoscalesInGroups(self) {
|
|
93
|
+
return self.setAutoscaleGroup !== undefined && autoscalePeers(self).length > 0;
|
|
94
|
+
}
|
|
95
|
+
function drawsScoreRules(self) {
|
|
96
|
+
return (self.scoreRulesDrawn === true &&
|
|
97
|
+
self.scoreRules !== undefined &&
|
|
98
|
+
self.setScoreRules !== undefined);
|
|
99
|
+
}
|
|
100
|
+
// A density plot maps its score to colour and rules no band, so its domain
|
|
101
|
+
// spans the values whatever `zero` says; the row is offered with the axis.
|
|
102
|
+
function rulesABand(self) {
|
|
103
|
+
return self.scoreRulesDrawn === true;
|
|
104
|
+
}
|
|
105
|
+
// The count is in the label, as the min/max row carries its bounds: a dashed
|
|
106
|
+
// line across a plot means nothing until the reader knows it was put there.
|
|
107
|
+
export function makeSetScoreRulesItem(self) {
|
|
108
|
+
const count = self.scoreRules.length;
|
|
109
|
+
return {
|
|
110
|
+
label: count > 0 ? `Reference lines (${count})...` : 'Reference lines...',
|
|
111
|
+
onClick: () => {
|
|
112
|
+
getDialogHost(self).queueDialog(handleClose => [
|
|
113
|
+
SetScoreRulesDialog,
|
|
114
|
+
{ model: self, handleClose },
|
|
115
|
+
]);
|
|
116
|
+
},
|
|
117
|
+
};
|
|
71
118
|
}
|
|
72
|
-
// The single Score submenu used by every wiggle-family display. Composition is
|
|
73
|
-
// capability-driven: `leadingItems` lets wiggle prepend its Resolution/Summary
|
|
74
|
-
// submenus, `trailingItems` appends what belongs after the range controls rather
|
|
75
|
-
// than before them (the alignments band's allele-fraction floor); `scaleType` is
|
|
76
|
-
// dropped by manhattan (linear-only); `autoscaleOptions` is overridden by
|
|
77
|
-
// coverage's reduced + dynamic-σ list.
|
|
78
|
-
//
|
|
79
|
-
// `autoscale` is the same kind of opt-out as `scaleType`, and exists for the
|
|
80
|
-
// same reason: a display whose domain doesn't consult `autoscaleType` must not
|
|
81
|
-
// offer radios for it. Manhattan takes plain min/max over the loaded regions and
|
|
82
|
-
// applies only the manual bounds, so its Autoscale-type radios wrote the config
|
|
83
|
-
// slot and changed nothing on screen — a control that lies is worse than a
|
|
84
|
-
// missing one. Opt-out rather than opt-in so a display that grows a domain
|
|
85
|
-
// without wiring autoscale keeps the menu it already had.
|
|
86
119
|
export function makeScoreSubMenu(self, opts = {}) {
|
|
87
|
-
const { label = 'Score',
|
|
120
|
+
const { label = 'Score', leadingItems = [], trailingItems = [], disabled, disabledHelpText, } = opts;
|
|
88
121
|
return {
|
|
89
122
|
label,
|
|
90
123
|
icon: EqualizerIcon,
|
|
@@ -92,12 +125,12 @@ export function makeScoreSubMenu(self, opts = {}) {
|
|
|
92
125
|
disabledHelpText,
|
|
93
126
|
subMenu: [
|
|
94
127
|
...leadingItems,
|
|
95
|
-
|
|
96
|
-
|
|
128
|
+
makeScaleTypeSubMenu(self),
|
|
129
|
+
makeClipOutliersItem(self),
|
|
130
|
+
...(rulesABand(self) ? [makeAxisZeroItem(self)] : []),
|
|
97
131
|
makeSetMinMaxScoreItem(self),
|
|
98
|
-
...(
|
|
99
|
-
|
|
100
|
-
: []),
|
|
132
|
+
...(autoscalesInGroups(self) ? [makeAutoscaleGroupItem(self)] : []),
|
|
133
|
+
...(drawsScoreRules(self) ? [makeSetScoreRulesItem(self)] : []),
|
|
101
134
|
...trailingItems,
|
|
102
135
|
],
|
|
103
136
|
};
|
package/esm/scoreRuleMarks.d.ts
CHANGED
|
@@ -1,22 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* One horizontal rule across a score plot, at a score the user chose.
|
|
4
|
-
*
|
|
5
|
-
* `label` is free text and carries no meaning this package assigns. That is
|
|
6
|
-
* deliberate: the obvious use is reading a coverage or CNV track against copy
|
|
7
|
-
* number, and there is no ploidy JBrowse could assume on the user's behalf. A
|
|
8
|
-
* whole-genome triplication is not diploid, plenty of genomes are not diploid to
|
|
9
|
-
* begin with, and a cancer sample can be neither — so "2 copies" is a claim only
|
|
10
|
-
* the person looking at the track can make.
|
|
11
|
-
*/
|
|
12
|
-
export interface ScoreRule {
|
|
13
|
-
value: number;
|
|
14
|
-
label?: string;
|
|
15
|
-
color?: string;
|
|
16
|
-
}
|
|
17
|
-
export interface ScoreRuleMark extends ScoreRule {
|
|
18
|
-
y: number;
|
|
19
|
-
}
|
|
1
|
+
import type { ScoreRuleMark, ValueScaleRule } from '@jbrowse/display-ui';
|
|
2
|
+
export type { ScoreRuleMark } from '@jbrowse/display-ui';
|
|
20
3
|
/**
|
|
21
4
|
* #api
|
|
22
5
|
* Screen y for each rule that falls inside the plotted domain, dropping the
|
|
@@ -34,12 +17,12 @@ export interface ScoreRuleMark extends ScoreRule {
|
|
|
34
17
|
* to be read against is not.
|
|
35
18
|
*
|
|
36
19
|
* `box` is likewise the caller's own — hand it the same `{yTop, yBottom}` the
|
|
37
|
-
* display's ticks were built with (a `YScaleTicks` satisfies it).
|
|
38
|
-
*
|
|
39
|
-
* differently, and the alignments coverage band does.
|
|
20
|
+
* display's ticks were built with (a `YScaleTicks` satisfies it). A box
|
|
21
|
+
* recomputed here would place rules off the ticks of any band that lays its
|
|
22
|
+
* axis out differently, and the alignments coverage band does.
|
|
40
23
|
*/
|
|
41
24
|
export declare function scoreRuleMarks({ rules, domain, box, normalize, }: {
|
|
42
|
-
rules: readonly
|
|
25
|
+
rules: readonly ValueScaleRule[];
|
|
43
26
|
domain: [number, number] | undefined;
|
|
44
27
|
box: {
|
|
45
28
|
yTop: number;
|
|
@@ -47,27 +30,19 @@ export declare function scoreRuleMarks({ rules, domain, box, normalize, }: {
|
|
|
47
30
|
};
|
|
48
31
|
normalize: (score: number) => number;
|
|
49
32
|
}): ScoreRuleMark[];
|
|
50
|
-
/**
|
|
51
|
-
* #api
|
|
52
|
-
* Normalizes whatever a `scoreRules` config slot holds into `ScoreRule`s,
|
|
53
|
-
* dropping entries that are not usable. Config is user-authored JSON, so a bare
|
|
54
|
-
* number, a missing value or a non-numeric one all have to survive being read.
|
|
55
|
-
*/
|
|
56
|
-
export declare function parseScoreRules(value: unknown): ScoreRule[];
|
|
57
33
|
/**
|
|
58
34
|
* #api
|
|
59
35
|
* Widens an autoscaled range so every configured rule stays on the axis.
|
|
60
36
|
*
|
|
61
|
-
* Without this a rule
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* informative
|
|
66
|
-
*
|
|
67
|
-
* leaves nothing behind to notice.
|
|
37
|
+
* Without this a rule is dropped from the plot in the views where it is most
|
|
38
|
+
* useful. Autoscale follows the visible data, so over a homozygous deletion a
|
|
39
|
+
* coverage domain collapses to about `[0, 1]` and a rule at the diploid depth
|
|
40
|
+
* falls outside it, though the rule's position above the data is the most
|
|
41
|
+
* informative mark in that view, and a rule that vanishes leaves nothing
|
|
42
|
+
* behind to notice.
|
|
68
43
|
*
|
|
69
|
-
* Applied to the raw range, before `getNiceDomain` takes the `
|
|
70
|
-
*
|
|
44
|
+
* Applied to the raw range, before `getNiceDomain` takes the `scales.y`
|
|
45
|
+
* domain bounds. Those still win: a rule outside an explicitly bounded axis
|
|
71
46
|
* is one the config asked not to be shown, and it drops as before.
|
|
72
47
|
*/
|
|
73
48
|
export declare function widenRangeToRules(range: [number, number], ruleValues: readonly number[]): [number, number];
|
package/esm/scoreRuleMarks.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { clampStrokeInsideAxis, scoreToAxisY } from '
|
|
1
|
+
import { clampStrokeInsideAxis, scoreToAxisY, } from '@jbrowse/display-ui/yScaleTicks';
|
|
2
2
|
/**
|
|
3
3
|
* #api
|
|
4
4
|
* Screen y for each rule that falls inside the plotted domain, dropping the
|
|
@@ -16,9 +16,9 @@ import { clampStrokeInsideAxis, scoreToAxisY } from './yScaleTicks.js';
|
|
|
16
16
|
* to be read against is not.
|
|
17
17
|
*
|
|
18
18
|
* `box` is likewise the caller's own — hand it the same `{yTop, yBottom}` the
|
|
19
|
-
* display's ticks were built with (a `YScaleTicks` satisfies it).
|
|
20
|
-
*
|
|
21
|
-
* differently, and the alignments coverage band does.
|
|
19
|
+
* display's ticks were built with (a `YScaleTicks` satisfies it). A box
|
|
20
|
+
* recomputed here would place rules off the ticks of any band that lays its
|
|
21
|
+
* axis out differently, and the alignments coverage band does.
|
|
22
22
|
*/
|
|
23
23
|
export function scoreRuleMarks({ rules, domain, box, normalize, }) {
|
|
24
24
|
if (!domain) {
|
|
@@ -38,52 +38,19 @@ export function scoreRuleMarks({ rules, domain, box, normalize, }) {
|
|
|
38
38
|
}), box.yBottom),
|
|
39
39
|
}));
|
|
40
40
|
}
|
|
41
|
-
/**
|
|
42
|
-
* #api
|
|
43
|
-
* Normalizes whatever a `scoreRules` config slot holds into `ScoreRule`s,
|
|
44
|
-
* dropping entries that are not usable. Config is user-authored JSON, so a bare
|
|
45
|
-
* number, a missing value or a non-numeric one all have to survive being read.
|
|
46
|
-
*/
|
|
47
|
-
export function parseScoreRules(value) {
|
|
48
|
-
if (!Array.isArray(value)) {
|
|
49
|
-
return [];
|
|
50
|
-
}
|
|
51
|
-
const out = [];
|
|
52
|
-
for (const entry of value) {
|
|
53
|
-
if (typeof entry === 'number') {
|
|
54
|
-
if (Number.isFinite(entry)) {
|
|
55
|
-
out.push({ value: entry });
|
|
56
|
-
}
|
|
57
|
-
continue;
|
|
58
|
-
}
|
|
59
|
-
if (entry && typeof entry === 'object') {
|
|
60
|
-
const { value: v, label, color } = entry;
|
|
61
|
-
const n = typeof v === 'string' ? Number(v) : v;
|
|
62
|
-
if (typeof n === 'number' && Number.isFinite(n)) {
|
|
63
|
-
out.push({
|
|
64
|
-
value: n,
|
|
65
|
-
...(typeof label === 'string' && label ? { label } : {}),
|
|
66
|
-
...(typeof color === 'string' && color ? { color } : {}),
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
return out;
|
|
72
|
-
}
|
|
73
41
|
/**
|
|
74
42
|
* #api
|
|
75
43
|
* Widens an autoscaled range so every configured rule stays on the axis.
|
|
76
44
|
*
|
|
77
|
-
* Without this a rule
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
* informative
|
|
82
|
-
*
|
|
83
|
-
* leaves nothing behind to notice.
|
|
45
|
+
* Without this a rule is dropped from the plot in the views where it is most
|
|
46
|
+
* useful. Autoscale follows the visible data, so over a homozygous deletion a
|
|
47
|
+
* coverage domain collapses to about `[0, 1]` and a rule at the diploid depth
|
|
48
|
+
* falls outside it, though the rule's position above the data is the most
|
|
49
|
+
* informative mark in that view, and a rule that vanishes leaves nothing
|
|
50
|
+
* behind to notice.
|
|
84
51
|
*
|
|
85
|
-
* Applied to the raw range, before `getNiceDomain` takes the `
|
|
86
|
-
*
|
|
52
|
+
* Applied to the raw range, before `getNiceDomain` takes the `scales.y`
|
|
53
|
+
* domain bounds. Those still win: a rule outside an explicitly bounded axis
|
|
87
54
|
* is one the config asked not to be shown, and it drops as before.
|
|
88
55
|
*/
|
|
89
56
|
export function widenRangeToRules(range, ruleValues) {
|
package/esm/transferables.js
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
// Walks every result's sources once and returns each source's
|
|
1
|
+
// Walks every result's sources once and returns each source's four per-feature
|
|
2
2
|
// TypedArray buffers as one flat list for postMessage transfer. Field set
|
|
3
3
|
// matches WiggleFeatureArrays — when fields change there, update here so the
|
|
4
4
|
// buffers actually transfer instead of being structured-cloned.
|
|
5
5
|
//
|
|
6
6
|
// The Set dedupe is load-bearing, not insurance: processFeaturesFromArrays
|
|
7
|
-
// aliases
|
|
8
|
-
//
|
|
9
|
-
// arrays are the full arrays). postMessage throws on a repeated transferable.
|
|
7
|
+
// aliases min/max onto the scores where no feature is a summary, and
|
|
8
|
+
// postMessage throws on a repeated transferable.
|
|
10
9
|
//
|
|
11
10
|
// Takes ALL the results rather than one, so the dedupe spans regions too — a
|
|
12
11
|
// per-result Set would list a shared buffer twice.
|
|
13
12
|
//
|
|
14
13
|
// Aliasing the adapter's own arrays here as well, rather than copying them, is
|
|
15
|
-
// costed and declined in agent-docs/
|
|
14
|
+
// costed and declined in agent-docs/architecture-decision-records/: it retains 20
|
|
16
15
|
// bytes a feature on the main thread where copying retains 12.
|
|
17
16
|
export function collectWiggleTransferables(results) {
|
|
18
17
|
const buffers = new Set();
|
|
@@ -22,10 +21,6 @@ export function collectWiggleTransferables(results) {
|
|
|
22
21
|
buffers.add(s.featureScores.buffer);
|
|
23
22
|
buffers.add(s.featureMinScores.buffer);
|
|
24
23
|
buffers.add(s.featureMaxScores.buffer);
|
|
25
|
-
buffers.add(s.posFeaturePositions.buffer);
|
|
26
|
-
buffers.add(s.posFeatureScores.buffer);
|
|
27
|
-
buffers.add(s.negFeaturePositions.buffer);
|
|
28
|
-
buffers.add(s.negFeatureScores.buffer);
|
|
29
24
|
}
|
|
30
25
|
}
|
|
31
26
|
return [...buffers];
|