@jbrowse/wiggle-core 5.0.0-beta.8 → 5.0.0-beta.9

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 (47) hide show
  1. package/README.md +49 -83
  2. package/esm/ScoreAxisMixin.d.ts +99 -0
  3. package/esm/ScoreAxisMixin.js +150 -0
  4. package/esm/ScoreFieldConfigMixin.d.ts +60 -0
  5. package/esm/ScoreFieldConfigMixin.js +25 -0
  6. package/esm/ScorePlotChrome.d.ts +45 -0
  7. package/esm/ScorePlotChrome.js +47 -0
  8. package/esm/ScorePlotSvgFrame.d.ts +27 -0
  9. package/esm/ScorePlotSvgFrame.js +23 -0
  10. package/esm/ScoreScaleMixin.d.ts +65 -99
  11. package/esm/ScoreScaleMixin.js +78 -141
  12. package/esm/SetScoreRulesDialog.d.ts +14 -0
  13. package/esm/SetScoreRulesDialog.js +45 -0
  14. package/esm/WiggleScoreConfigMixin.d.ts +89 -0
  15. package/esm/WiggleScoreConfigMixin.js +69 -0
  16. package/esm/autoscale.d.ts +45 -5
  17. package/esm/autoscale.js +99 -67
  18. package/esm/chrome.d.ts +4 -0
  19. package/esm/chrome.js +7 -0
  20. package/esm/computeYTicks.d.ts +1 -1
  21. package/esm/computeYTicks.js +4 -2
  22. package/esm/dataTypes.d.ts +2 -6
  23. package/esm/gapBreak.d.ts +2 -3
  24. package/esm/gapBreak.js +2 -3
  25. package/esm/index.d.ts +20 -16
  26. package/esm/index.js +17 -13
  27. package/esm/normalize.d.ts +1 -26
  28. package/esm/normalize.js +1 -86
  29. package/esm/pointSizeMenu.d.ts +13 -0
  30. package/esm/pointSizeMenu.js +21 -3
  31. package/esm/renderingBackendTypes.d.ts +12 -3
  32. package/esm/renderingBackendTypes.js +4 -1
  33. package/esm/scale.d.ts +1 -1
  34. package/esm/scoreFieldConfigSchemaFields.d.ts +10 -0
  35. package/esm/scoreFieldConfigSchemaFields.js +11 -0
  36. package/esm/scoreMenuItems.d.ts +19 -7
  37. package/esm/scoreMenuItems.js +64 -29
  38. package/esm/scoreRuleMarks.d.ts +13 -37
  39. package/esm/scoreRuleMarks.js +12 -45
  40. package/esm/transferables.js +3 -8
  41. package/esm/valueScaleConfigSchema.d.ts +211 -0
  42. package/esm/valueScaleConfigSchema.js +240 -0
  43. package/esm/wiggleRenderModes.generated.d.ts +1 -2
  44. package/esm/wiggleRenderModes.generated.js +1 -2
  45. package/package.json +12 -8
  46. package/esm/scoreAxisConfigSchemaFields.d.ts +0 -44
  47. package/esm/scoreAxisConfigSchemaFields.js +0 -54
@@ -1,20 +1,4 @@
1
- import type { ScoreRuleMark } from '@jbrowse/display-ui';
2
- /**
3
- * #api
4
- * One horizontal rule across a score plot, at a score the user chose.
5
- *
6
- * `label` is free text and carries no meaning this package assigns. That is
7
- * deliberate: the obvious use is reading a coverage or CNV track against copy
8
- * number, and there is no ploidy JBrowse could assume on the user's behalf. A
9
- * whole-genome triplication is not diploid, plenty of genomes are not diploid to
10
- * begin with, and a cancer sample can be neither — so "2 copies" is a claim only
11
- * the person looking at the track can make.
12
- */
13
- export interface ScoreRule {
14
- value: number;
15
- label?: string;
16
- color?: string;
17
- }
1
+ import type { ScoreRuleMark, ValueScaleRule } from '@jbrowse/display-ui';
18
2
  export type { ScoreRuleMark } from '@jbrowse/display-ui';
19
3
  /**
20
4
  * #api
@@ -33,12 +17,12 @@ export type { ScoreRuleMark } from '@jbrowse/display-ui';
33
17
  * to be read against is not.
34
18
  *
35
19
  * `box` is likewise the caller's own — hand it the same `{yTop, yBottom}` the
36
- * display's ticks were built with (a `YScaleTicks` satisfies it). Recomputing a
37
- * box here would silently disagree with any band that lays its axis out
38
- * 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.
39
23
  */
40
24
  export declare function scoreRuleMarks({ rules, domain, box, normalize, }: {
41
- rules: readonly ScoreRule[];
25
+ rules: readonly ValueScaleRule[];
42
26
  domain: [number, number] | undefined;
43
27
  box: {
44
28
  yTop: number;
@@ -46,27 +30,19 @@ export declare function scoreRuleMarks({ rules, domain, box, normalize, }: {
46
30
  };
47
31
  normalize: (score: number) => number;
48
32
  }): ScoreRuleMark[];
49
- /**
50
- * #api
51
- * Normalizes whatever a `scoreRules` config slot holds into `ScoreRule`s,
52
- * dropping entries that are not usable. Config is user-authored JSON, so a bare
53
- * number, a missing value or a non-numeric one all have to survive being read.
54
- */
55
- export declare function parseScoreRules(value: unknown): ScoreRule[];
56
33
  /**
57
34
  * #api
58
35
  * Widens an autoscaled range so every configured rule stays on the axis.
59
36
  *
60
- * Without this a rule silently disappears in exactly the window that makes it
61
- * worth having. Autoscale follows the visible data, so over a homozygous
62
- * deletion a coverage domain collapses to about `[0, 1]` and a rule at the
63
- * diploid depth falls outside it — and "2 copies would be up there" is the most
64
- * informative thing that view can say. The reader has no menu to check either:
65
- * `scoreRules` is set by whoever wrote the config, so a rule that vanishes
66
- * 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.
67
43
  *
68
- * Applied to the raw range, before `getNiceDomain` takes the `minScore` /
69
- * `maxScore` bounds. Those still win: a rule outside an explicitly bounded axis
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
70
46
  * is one the config asked not to be shown, and it drops as before.
71
47
  */
72
48
  export declare function widenRangeToRules(range: [number, number], ruleValues: readonly number[]): [number, number];
@@ -1,4 +1,4 @@
1
- import { clampStrokeInsideAxis, scoreToAxisY } from '@jbrowse/display-ui';
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 '@jbrowse/display-ui';
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). Recomputing a
20
- * box here would silently disagree with any band that lays its axis out
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 silently disappears in exactly the window that makes it
78
- * worth having. Autoscale follows the visible data, so over a homozygous
79
- * deletion a coverage domain collapses to about `[0, 1]` and a rule at the
80
- * diploid depth falls outside it — and "2 copies would be up there" is the most
81
- * informative thing that view can say. The reader has no menu to check either:
82
- * `scoreRules` is set by whoever wrote the config, so a rule that vanishes
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 `minScore` /
86
- * `maxScore` bounds. Those still win: a rule outside an explicitly bounded axis
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) {
@@ -1,12 +1,11 @@
1
- // Walks every result's sources once and returns each source's eight per-feature
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 fields onto one buffer whenever a copy would be identical (no summary
8
- // data → min/max are the scores; an all-one-sided window → the pos or neg
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.
@@ -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];
@@ -0,0 +1,211 @@
1
+ import type { Instance } from '@jbrowse/mobx-state-tree';
2
+ /** The autoscale modes a display offers, and the one it starts on. */
3
+ export interface ValueScaleAutoscale {
4
+ modes: readonly string[];
5
+ default: string;
6
+ }
7
+ export interface ValueScaleOptions {
8
+ /** the scale types this display's renderer places, `linear` first */
9
+ types: readonly string[];
10
+ /** omitted where the display's domain consults no mode */
11
+ autoscale?: ValueScaleAutoscale;
12
+ /** `symlogConstant`'s default, where `types` holds `symlog` */
13
+ symlogConstant?: number;
14
+ /** the display draws `rules` and widens its domain to them */
15
+ rules?: boolean;
16
+ /** the display captions its axis with `title` */
17
+ title?: boolean;
18
+ }
19
+ declare function valueScaleRuleSchema(): import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
20
+ readonly value: {
21
+ type: "number";
22
+ } & {
23
+ defaultValue: number;
24
+ };
25
+ readonly color: {
26
+ type: "maybeColor";
27
+ };
28
+ readonly label: {
29
+ type: "string";
30
+ } & {
31
+ defaultValue: string;
32
+ };
33
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>;
34
+ export type ValueScaleRuleConfig = Instance<ReturnType<typeof valueScaleRuleSchema>>;
35
+ /**
36
+ * #config ValueScale
37
+ * #category display
38
+ * The value scale of a quantitative display, written as `scales.y`: the
39
+ * wiggle and multi-wiggle plots, the Manhattan plot, the alignments coverage
40
+ * band and the mark display each carry one. Which members it has follows what
41
+ * the display draws: Manhattan places a linear axis and consults no autoscale
42
+ * mode, so it has neither `type` alternatives nor `autoscale`.
43
+ *
44
+ * Vega-Lite's spelling: a pinned end is `domainMin` or `domainMax`, and an end
45
+ * left unset autoscales over the loaded regions.
46
+ *
47
+ * Two defaults come from the display rather than from the scale. `autoscale`
48
+ * starts at `localpercentile` on the wiggle and multi-wiggle plots and at
49
+ * `local` on the coverage band and the mark display. `symlogConstant` starts
50
+ * at `0` on the wiggle family and at `1` on the coverage band.
51
+ *
52
+ * The wiggle family, the Manhattan plot and the mark display also carry
53
+ * `rules`, reference lines at chosen values; the mark display adds `title`,
54
+ * the caption beside the axis. A rule naming no `color` draws in the one
55
+ * colour the chrome rules every plot in, so a red line is a claim its author
56
+ * makes rather than a meaning a display assigns.
57
+ *
58
+ * #example
59
+ * A log axis floored at 1:
60
+ * ```js
61
+ * {
62
+ * type: 'LinearWiggleDisplay',
63
+ * scales: { y: { type: 'log', domainMin: 1 } },
64
+ * }
65
+ * ```
66
+ *
67
+ * #example
68
+ * The whole visible range, rather than the 99th percentile the wiggle
69
+ * displays start on:
70
+ * ```js
71
+ * {
72
+ * type: 'LinearWiggleDisplay',
73
+ * scales: { y: { autoscale: 'local' } },
74
+ * }
75
+ * ```
76
+ *
77
+ * #example
78
+ * A titled axis with a labelled genome-wide threshold over a plain
79
+ * suggestive one:
80
+ * ```js
81
+ * {
82
+ * type: 'LinearMarkDisplay',
83
+ * scales: {
84
+ * y: {
85
+ * title: '-log10 p',
86
+ * rules: [{ value: 7.3, color: 'red', label: 'p = 5e-8' }, 5],
87
+ * },
88
+ * },
89
+ * }
90
+ * ```
91
+ */
92
+ export declare function valueScaleSchema({ types: scaleTypes, autoscale, symlogConstant, rules, title, }: ValueScaleOptions): import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
93
+ readonly type: {
94
+ type: "stringEnum";
95
+ } & {
96
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
97
+ } & {
98
+ defaultValue: string;
99
+ };
100
+ readonly domainMin: {
101
+ type: "maybeNumber";
102
+ };
103
+ readonly domainMax: {
104
+ type: "maybeNumber";
105
+ };
106
+ readonly symlogConstant?: ({
107
+ type: "number";
108
+ } & {
109
+ defaultValue: number;
110
+ }) | undefined;
111
+ readonly autoscale?: ({
112
+ type: "stringEnum";
113
+ } & {
114
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
115
+ } & {
116
+ defaultValue: string;
117
+ }) | undefined;
118
+ readonly numStdDev?: ({
119
+ type: "number";
120
+ } & {
121
+ defaultValue: number;
122
+ }) | undefined;
123
+ readonly numQuantile?: ({
124
+ type: "number";
125
+ } & {
126
+ defaultValue: number;
127
+ }) | undefined;
128
+ readonly title?: {
129
+ type: "maybeString";
130
+ } | undefined;
131
+ readonly rules?: import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
132
+ readonly value: {
133
+ type: "number";
134
+ } & {
135
+ defaultValue: number;
136
+ };
137
+ readonly color: {
138
+ type: "maybeColor";
139
+ };
140
+ readonly label: {
141
+ type: "string";
142
+ } & {
143
+ defaultValue: string;
144
+ };
145
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>> | undefined;
146
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>;
147
+ export type ValueScaleConfigSchema = ReturnType<typeof valueScaleSchema>;
148
+ /**
149
+ * The `scales` object a display declares, one member per aesthetic the
150
+ * grammar gives a scale. `y` is the only one so far, and every mark, bar or
151
+ * bin the display draws is placed through it.
152
+ */
153
+ export declare function scalesSchema(y: ValueScaleConfigSchema): import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
154
+ readonly y: import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
155
+ readonly type: {
156
+ type: "stringEnum";
157
+ } & {
158
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
159
+ } & {
160
+ defaultValue: string;
161
+ };
162
+ readonly domainMin: {
163
+ type: "maybeNumber";
164
+ };
165
+ readonly domainMax: {
166
+ type: "maybeNumber";
167
+ };
168
+ readonly symlogConstant?: ({
169
+ type: "number";
170
+ } & {
171
+ defaultValue: number;
172
+ }) | undefined;
173
+ readonly autoscale?: ({
174
+ type: "stringEnum";
175
+ } & {
176
+ model: import("@jbrowse/mobx-state-tree").ISimpleType<string>;
177
+ } & {
178
+ defaultValue: string;
179
+ }) | undefined;
180
+ readonly numStdDev?: ({
181
+ type: "number";
182
+ } & {
183
+ defaultValue: number;
184
+ }) | undefined;
185
+ readonly numQuantile?: ({
186
+ type: "number";
187
+ } & {
188
+ defaultValue: number;
189
+ }) | undefined;
190
+ readonly title?: {
191
+ type: "maybeString";
192
+ } | undefined;
193
+ readonly rules?: import("@jbrowse/mobx-state-tree").IArrayType<import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaType<{
194
+ readonly value: {
195
+ type: "number";
196
+ } & {
197
+ defaultValue: number;
198
+ };
199
+ readonly color: {
200
+ type: "maybeColor";
201
+ };
202
+ readonly label: {
203
+ type: "string";
204
+ } & {
205
+ defaultValue: string;
206
+ };
207
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>> | undefined;
208
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>;
209
+ }, import("@jbrowse/core/configuration/configurationSchema").ConfigurationSchemaOptions<undefined, undefined, undefined, import("@jbrowse/core/configuration").ConfigurationSchemaRequirement<Partial<Record<string, string[]>>, string>>>;
210
+ export type ScalesConfigSchema = ReturnType<typeof scalesSchema>;
211
+ export {};
@@ -0,0 +1,240 @@
1
+ import { ConfigurationSchema } from '@jbrowse/core/configuration';
2
+ import { types } from '@jbrowse/mobx-state-tree';
3
+ function valueScaleRuleSchema() {
4
+ return ConfigurationSchema('ValueScaleRule', {
5
+ /**
6
+ * #slot scales.y.rules.value
7
+ * Where the rule sits on the axis, in the units the axis plots: a
8
+ * `-log10(p)` over a Manhattan plot, a depth over coverage.
9
+ */
10
+ value: {
11
+ type: 'number',
12
+ defaultValue: 0,
13
+ description: 'the value the rule is drawn at',
14
+ },
15
+ /**
16
+ * #slot scales.y.rules.color
17
+ * The line's colour, and its label's. Unset draws every rule in the one
18
+ * colour the chrome rules plots in, so a threshold that means something
19
+ * particular — genome-wide significance, a diploid depth — is one an
20
+ * author paints, on the plot where it means it.
21
+ */
22
+ color: {
23
+ type: 'maybeColor',
24
+ description: 'line and label colour; unset is the chrome’s own',
25
+ },
26
+ /**
27
+ * #slot scales.y.rules.label
28
+ * Free text drawn at the rule's right-hand end. JBrowse assigns it no
29
+ * meaning: "2 copies" over a coverage plot is a claim only the author
30
+ * can make, since no ploidy can be assumed.
31
+ */
32
+ label: {
33
+ type: 'string',
34
+ defaultValue: '',
35
+ description: "text at the rule's right-hand end",
36
+ },
37
+ }, { shorthand: 'value', closed: true });
38
+ }
39
+ /**
40
+ * #config ValueScale
41
+ * #category display
42
+ * The value scale of a quantitative display, written as `scales.y`: the
43
+ * wiggle and multi-wiggle plots, the Manhattan plot, the alignments coverage
44
+ * band and the mark display each carry one. Which members it has follows what
45
+ * the display draws: Manhattan places a linear axis and consults no autoscale
46
+ * mode, so it has neither `type` alternatives nor `autoscale`.
47
+ *
48
+ * Vega-Lite's spelling: a pinned end is `domainMin` or `domainMax`, and an end
49
+ * left unset autoscales over the loaded regions.
50
+ *
51
+ * Two defaults come from the display rather than from the scale. `autoscale`
52
+ * starts at `localpercentile` on the wiggle and multi-wiggle plots and at
53
+ * `local` on the coverage band and the mark display. `symlogConstant` starts
54
+ * at `0` on the wiggle family and at `1` on the coverage band.
55
+ *
56
+ * The wiggle family, the Manhattan plot and the mark display also carry
57
+ * `rules`, reference lines at chosen values; the mark display adds `title`,
58
+ * the caption beside the axis. A rule naming no `color` draws in the one
59
+ * colour the chrome rules every plot in, so a red line is a claim its author
60
+ * makes rather than a meaning a display assigns.
61
+ *
62
+ * #example
63
+ * A log axis floored at 1:
64
+ * ```js
65
+ * {
66
+ * type: 'LinearWiggleDisplay',
67
+ * scales: { y: { type: 'log', domainMin: 1 } },
68
+ * }
69
+ * ```
70
+ *
71
+ * #example
72
+ * The whole visible range, rather than the 99th percentile the wiggle
73
+ * displays start on:
74
+ * ```js
75
+ * {
76
+ * type: 'LinearWiggleDisplay',
77
+ * scales: { y: { autoscale: 'local' } },
78
+ * }
79
+ * ```
80
+ *
81
+ * #example
82
+ * A titled axis with a labelled genome-wide threshold over a plain
83
+ * suggestive one:
84
+ * ```js
85
+ * {
86
+ * type: 'LinearMarkDisplay',
87
+ * scales: {
88
+ * y: {
89
+ * title: '-log10 p',
90
+ * rules: [{ value: 7.3, color: 'red', label: 'p = 5e-8' }, 5],
91
+ * },
92
+ * },
93
+ * }
94
+ * ```
95
+ */
96
+ export function valueScaleSchema({ types: scaleTypes, autoscale, symlogConstant = 0, rules, title = false, }) {
97
+ return ConfigurationSchema('ValueScale', {
98
+ /**
99
+ * #slot scales.y.type
100
+ * How the axis reads its domain — the ticks, the cross-hatches and the
101
+ * renderer's placement all come from it. `log` cannot represent 0 or
102
+ * negative values and floors the domain above them; `symlog` is log-like
103
+ * away from zero and linear through it, so a track whose values touch or
104
+ * cross 0 keeps them. Which of the three a display offers is which of
105
+ * them its renderer places.
106
+ */
107
+ // #region stringEnumSlot
108
+ type: {
109
+ type: 'stringEnum',
110
+ model: types.enumeration('ValueScaleType', [...scaleTypes]),
111
+ defaultValue: 'linear',
112
+ description: scaleTypes.join(' or '),
113
+ },
114
+ // #endregion
115
+ /**
116
+ * #slot scales.y.domainMin
117
+ * The bottom of the axis, pinning what would otherwise autoscale to the
118
+ * loaded regions. Unset autoscales that end. The score menu's "Set
119
+ * min/max" writes here.
120
+ */
121
+ domainMin: {
122
+ type: 'maybeNumber',
123
+ description: 'pinned bottom of the axis; unset autoscales',
124
+ },
125
+ /**
126
+ * #slot scales.y.domainMax
127
+ * The top of the axis. Unset autoscales that end.
128
+ */
129
+ domainMax: {
130
+ type: 'maybeNumber',
131
+ description: 'pinned top of the axis; unset autoscales',
132
+ },
133
+ ...(scaleTypes.includes('symlog')
134
+ ? {
135
+ /**
136
+ * #slot scales.y.symlogConstant
137
+ * Width of symlog's linear region around zero. `0` derives it from
138
+ * the domain, a thousandth of its largest magnitude — right for a
139
+ * wiggle track, whose units are its own. The coverage band starts
140
+ * at `1` instead, which makes symlog exactly `log(depth+1)` and
141
+ * puts the knee at one read.
142
+ */
143
+ symlogConstant: {
144
+ type: 'number',
145
+ defaultValue: symlogConstant,
146
+ description: "width of symlog's linear region around zero",
147
+ advanced: true,
148
+ },
149
+ }
150
+ : {}),
151
+ ...(autoscale
152
+ ? {
153
+ /**
154
+ * #slot scales.y.autoscale
155
+ * What an unpinned end scales to: `local` takes the extremes of
156
+ * the visible region, `localsd` the mean ± `numStdDev` standard
157
+ * deviations, `localpercentile` the `numQuantile`-th percentile of
158
+ * each sign, which is robust to a peaky distribution.
159
+ */
160
+ autoscale: {
161
+ type: 'stringEnum',
162
+ model: types.enumeration('ValueScaleAutoscale', [
163
+ ...autoscale.modes,
164
+ ]),
165
+ defaultValue: autoscale.default,
166
+ description: autoscale.modes.join(' or '),
167
+ },
168
+ }
169
+ : {}),
170
+ ...(autoscale?.modes.includes('localsd')
171
+ ? {
172
+ /**
173
+ * #slot scales.y.numStdDev
174
+ * Standard deviations either side of the mean the `localsd`
175
+ * autoscale reaches.
176
+ */
177
+ numStdDev: {
178
+ type: 'number',
179
+ defaultValue: 3,
180
+ description: 'standard deviations for the localsd autoscale',
181
+ advanced: true,
182
+ },
183
+ }
184
+ : {}),
185
+ ...(autoscale?.modes.includes('localpercentile')
186
+ ? {
187
+ /**
188
+ * #slot scales.y.numQuantile
189
+ * The percentile `localpercentile` clips outliers at — 0.99 drops
190
+ * the outermost 1% of each sign. The two signs are measured
191
+ * independently and anchored at 0, so a sparse minority tail
192
+ * stays visible and all-positive data pins its bottom at 0.
193
+ */
194
+ numQuantile: {
195
+ type: 'number',
196
+ defaultValue: 0.99,
197
+ description: 'percentile the localpercentile autoscale clips at',
198
+ advanced: true,
199
+ },
200
+ }
201
+ : {}),
202
+ ...(title
203
+ ? {
204
+ /**
205
+ * #slot scales.y.title
206
+ * The caption beside the axis, naming what it measures, drawn
207
+ * once however many bands the scale rules and at every zoom.
208
+ * Optional, as JBrowse's other captions are: unset, `""` or
209
+ * `null`, the axis has none; some text is that text.
210
+ */
211
+ title: {
212
+ type: 'maybeString',
213
+ description: 'axis caption; unset draws none',
214
+ },
215
+ }
216
+ : {}),
217
+ ...(rules
218
+ ? {
219
+ /**
220
+ * #slot scales.y.rules
221
+ * Horizontal reference lines at chosen values, across every band
222
+ * the scale rules: a significance threshold, a zero line, an
223
+ * allele-frequency cut. Each is `{ value, color, label }`, or a
224
+ * bare number for a plain line. An autoscaled end widens to keep
225
+ * every rule on the axis; a pinned `domainMin` or `domainMax`
226
+ * that excludes a rule drops it.
227
+ */
228
+ rules: types.array(valueScaleRuleSchema()),
229
+ }
230
+ : {}),
231
+ }, { closed: true });
232
+ }
233
+ /**
234
+ * The `scales` object a display declares, one member per aesthetic the
235
+ * grammar gives a scale. `y` is the only one so far, and every mark, bar or
236
+ * bin the display draws is placed through it.
237
+ */
238
+ export function scalesSchema(y) {
239
+ return ConfigurationSchema('Scales', { y }, { closed: true });
240
+ }
@@ -3,7 +3,6 @@ export declare const RENDERING_TYPE_DENSITY = 1;
3
3
  export declare const RENDERING_TYPE_LINE = 2;
4
4
  export declare const RENDERING_TYPE_SCATTER = 3;
5
5
  export declare const RENDERING_TYPE_LINE_CENTER = 4;
6
- export declare const SCALE_TYPE_LOG = 1;
7
- export declare const SCALE_TYPE_SYMLOG = 2;
8
6
  export declare const NO_PREV_START = 4294967295;
9
7
  export declare const MIN_FILL_WIDTH_PX = 1.5;
8
+ export declare const MAX_WIGGLE_CUTS = 8;
@@ -5,7 +5,6 @@ export const RENDERING_TYPE_DENSITY = 1;
5
5
  export const RENDERING_TYPE_LINE = 2;
6
6
  export const RENDERING_TYPE_SCATTER = 3;
7
7
  export const RENDERING_TYPE_LINE_CENTER = 4;
8
- export const SCALE_TYPE_LOG = 1;
9
- export const SCALE_TYPE_SYMLOG = 2;
10
8
  export const NO_PREV_START = 4294967295;
11
9
  export const MIN_FILL_WIDTH_PX = 1.5;
10
+ export const MAX_WIGGLE_CUTS = 8;