@jbrowse/wiggle-core 5.0.0-beta.10 → 5.0.0-beta.13

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 (53) hide show
  1. package/README.md +21 -7
  2. package/esm/ResolutionStepper.d.ts +1 -0
  3. package/esm/ResolutionStepper.js +5 -2
  4. package/esm/ScoreAxisWidget/RangeFields.d.ts +5 -0
  5. package/esm/ScoreAxisWidget/RangeFields.js +70 -0
  6. package/esm/ScoreAxisWidget/ReferenceLines.d.ts +10 -0
  7. package/esm/ScoreAxisWidget/ReferenceLines.js +53 -0
  8. package/esm/ScoreAxisWidget/ResetAxisButton.d.ts +6 -0
  9. package/esm/ScoreAxisWidget/ResetAxisButton.js +20 -0
  10. package/esm/ScoreAxisWidget/ScoreAxisHeading.d.ts +5 -0
  11. package/esm/ScoreAxisWidget/ScoreAxisHeading.js +9 -0
  12. package/esm/ScoreAxisWidget/ScoreAxisWidget.d.ts +5 -0
  13. package/esm/ScoreAxisWidget/ScoreAxisWidget.js +69 -0
  14. package/esm/ScoreAxisWidget/Section.d.ts +5 -0
  15. package/esm/ScoreAxisWidget/Section.js +13 -0
  16. package/esm/ScoreAxisWidget/ShareAxisWith.d.ts +5 -0
  17. package/esm/ScoreAxisWidget/ShareAxisWith.js +32 -0
  18. package/esm/ScoreAxisWidget/constants.d.ts +1 -0
  19. package/esm/ScoreAxisWidget/constants.js +1 -0
  20. package/esm/ScoreAxisWidget/index.d.ts +8 -0
  21. package/esm/ScoreAxisWidget/index.js +22 -0
  22. package/esm/ScoreAxisWidget/stateModel.d.ts +30 -0
  23. package/esm/ScoreAxisWidget/stateModel.js +30 -0
  24. package/esm/ScoreAxisWidget/types.d.ts +10 -0
  25. package/esm/ScoreAxisWidget/types.js +1 -0
  26. package/esm/ScoreAxisWidget/writeThrough.d.ts +2 -0
  27. package/esm/ScoreAxisWidget/writeThrough.js +7 -0
  28. package/esm/ScorePlotChrome.d.ts +1 -0
  29. package/esm/ScorePlotChrome.js +3 -3
  30. package/esm/ScorePlotSvgFrame.d.ts +7 -12
  31. package/esm/ScorePlotSvgFrame.js +6 -14
  32. package/esm/ScoreScaleMixin.d.ts +5 -5
  33. package/esm/ScoreScaleMixin.js +5 -5
  34. package/esm/autoscale.d.ts +12 -8
  35. package/esm/autoscale.js +18 -11
  36. package/esm/chrome.d.ts +0 -1
  37. package/esm/chrome.js +0 -1
  38. package/esm/dataTypes.d.ts +0 -1
  39. package/esm/index.d.ts +2 -2
  40. package/esm/index.js +1 -1
  41. package/esm/scale.js +1 -1
  42. package/esm/scoreMenuItems.d.ts +14 -28
  43. package/esm/scoreMenuItems.js +35 -130
  44. package/esm/valueScaleConfigSchema.d.ts +4 -5
  45. package/esm/valueScaleConfigSchema.js +21 -19
  46. package/esm/visibleStatsDomain.d.ts +0 -1
  47. package/package.json +11 -8
  48. package/esm/AutoscaleGroupDialog.d.ts +0 -7
  49. package/esm/AutoscaleGroupDialog.js +0 -26
  50. package/esm/SetMinMaxDialog.d.ts +0 -12
  51. package/esm/SetMinMaxDialog.js +0 -32
  52. package/esm/SetScoreRulesDialog.d.ts +0 -14
  53. package/esm/SetScoreRulesDialog.js +0 -45
@@ -1,23 +1,15 @@
1
1
  import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { PaintLayer } from '@jbrowse/core/util/paintLayer';
2
+ import MarkSvgLayer from '@jbrowse/display-kit/MarkSvgLayer';
3
3
  import { axisPlotBox } from '@jbrowse/display-ui';
4
- import { paintMarkBlocks } from '@jbrowse/render-core/marks';
5
4
  /**
6
5
  * The SVG-export body of a display with a score axis, mounted through
7
6
  * `renderDisplaySvg`, which draws the axis and cross-hatches. Paints `marks`
8
- * over `regions` inside the plot box, at the export's width and the box's
9
- * height — the two fields of `renderState` the on-screen canvas sizes
10
- * differently. `plotGeometry` defaults to the single-plot box `ScorePlotChrome`
11
- * draws in; multi-wiggle stacks its rows over the full height instead.
12
- * `children` draw over the plot, in the same untranslated space as the axis.
7
+ * over `regions` inside the plot box. `plotGeometry` defaults to the
8
+ * single-plot box `ScorePlotChrome` draws in; multi-wiggle stacks its rows over
9
+ * the full height instead. `children` draw over the plot, in the same
10
+ * untranslated space as the axis.
13
11
  */
14
12
  export function ScorePlotSvgFrame({ height, canvasWidth, renderBlocks, opts, plotGeometry = axisPlotBox(height), marks, regions, renderState, children, }) {
15
13
  const { yTop, plotHeight } = plotGeometry;
16
- return (_jsxs(_Fragment, { children: [_jsx("g", { transform: `translate(0,${yTop})`, children: _jsx(PaintLayer, { width: canvasWidth, height: plotHeight, opts: opts, paint: ctx => {
17
- paintMarkBlocks(ctx, marks, regions, renderBlocks, {
18
- ...renderState,
19
- canvasWidth,
20
- canvasHeight: plotHeight,
21
- });
22
- } }) }), children] }));
14
+ return (_jsxs(_Fragment, { children: [_jsx("g", { transform: `translate(0,${yTop})`, children: _jsx(MarkSvgLayer, { marks: marks, regions: regions, blocks: renderBlocks, state: renderState, width: canvasWidth, height: plotHeight, opts: opts }) }), children] }));
23
15
  }
@@ -15,15 +15,15 @@ export interface ScoreScaleHost {
15
15
  /**
16
16
  * #stateModel ScoreScaleMixin
17
17
  * #category display
18
- * #crossCuttingMixin Value scale, written in `scales.y`. `valueScaleSchema` / `scalesSchema`. Brings `ScoreAxisMixin` plus `scaleType` / `scaleZero` / `domainQuantile` / `clipQuantile` / `symlogConstant` / `manual*` and their setters, i.e. the whole `ScoreScaleModel` interface the shared score menu and `SetMinMaxDialog` consume
18
+ * #crossCuttingMixin Value scale, written in `scales.y`. `valueScaleSchema` / `scalesSchema`. Brings `ScoreAxisMixin` plus `scaleType` / `scaleZero` / `domainQuantile` / `clipQuantile` / `symlogConstant` / `manual*` and their setters, i.e. the whole `ScoreScaleModel` interface the Y axis row and its drawer widget consume
19
19
  *
20
20
  * The value scale of every quantitative display: wiggle, the alignments
21
21
  * coverage band and the mark display, Manhattan among them, each declare
22
22
  * `scales.y` through {@link valueScaleSchema} and compose this. It backs
23
23
  * {@link ScoreAxisMixin}'s three overridable members off that object and adds
24
24
  * the setters that write it, so composing this is how a display satisfies
25
- * {@link ScoreScaleModel} in `scoreMenuItems.ts` — the interface the shared
26
- * Score menu, the scale and autoscale submenus and `SetMinMaxDialog` consume.
25
+ * {@link ScoreScaleModel} in `scoreMenuItems.ts` — the interface the Y axis
26
+ * row and its drawer widget consume.
27
27
  *
28
28
  * Deliberately just the scale and the guides it owns. Colors, `resolution`
29
29
  * and the autoscale *computation* stay in `WiggleScoreConfigMixin` /
@@ -68,7 +68,7 @@ export declare function ScoreScaleMixin(): import("@jbrowse/mobx-state-tree").IM
68
68
  readonly domainQuantile: number;
69
69
  /**
70
70
  * #getter
71
- * The quantile "Clip outliers" clips at: the one an untick this session
71
+ * The quantile "Clip extreme outliers" fences at: the one an untick this session
72
72
  * wrote over, else the scale's own default where that is below 1, else
73
73
  * 0.99.
74
74
  */
@@ -119,7 +119,7 @@ export declare function ScoreScaleMixin(): import("@jbrowse/mobx-state-tree").IM
119
119
  /**
120
120
  * #getter
121
121
  * Whether this display draws `scales.y.rules`, which is whether the
122
- * score menu offers the reference lines: a scale it places y through
122
+ * Y axis panel offers Include 0 and the reference lines: a scale it places y through
123
123
  * rules a band for them to cross, which a density plot's colour-mapped
124
124
  * rows and a colour ramp do not.
125
125
  */
@@ -11,15 +11,15 @@ const confNode = (self) => self;
11
11
  /**
12
12
  * #stateModel ScoreScaleMixin
13
13
  * #category display
14
- * #crossCuttingMixin Value scale, written in `scales.y`. `valueScaleSchema` / `scalesSchema`. Brings `ScoreAxisMixin` plus `scaleType` / `scaleZero` / `domainQuantile` / `clipQuantile` / `symlogConstant` / `manual*` and their setters, i.e. the whole `ScoreScaleModel` interface the shared score menu and `SetMinMaxDialog` consume
14
+ * #crossCuttingMixin Value scale, written in `scales.y`. `valueScaleSchema` / `scalesSchema`. Brings `ScoreAxisMixin` plus `scaleType` / `scaleZero` / `domainQuantile` / `clipQuantile` / `symlogConstant` / `manual*` and their setters, i.e. the whole `ScoreScaleModel` interface the Y axis row and its drawer widget consume
15
15
  *
16
16
  * The value scale of every quantitative display: wiggle, the alignments
17
17
  * coverage band and the mark display, Manhattan among them, each declare
18
18
  * `scales.y` through {@link valueScaleSchema} and compose this. It backs
19
19
  * {@link ScoreAxisMixin}'s three overridable members off that object and adds
20
20
  * the setters that write it, so composing this is how a display satisfies
21
- * {@link ScoreScaleModel} in `scoreMenuItems.ts` — the interface the shared
22
- * Score menu, the scale and autoscale submenus and `SetMinMaxDialog` consume.
21
+ * {@link ScoreScaleModel} in `scoreMenuItems.ts` — the interface the Y axis
22
+ * row and its drawer widget consume.
23
23
  *
24
24
  * Deliberately just the scale and the guides it owns. Colors, `resolution`
25
25
  * and the autoscale *computation* stay in `WiggleScoreConfigMixin` /
@@ -56,7 +56,7 @@ export function ScoreScaleMixin() {
56
56
  },
57
57
  /**
58
58
  * #getter
59
- * The quantile "Clip outliers" clips at: the one an untick this session
59
+ * The quantile "Clip extreme outliers" fences at: the one an untick this session
60
60
  * wrote over, else the scale's own default where that is below 1, else
61
61
  * 0.99.
62
62
  */
@@ -131,7 +131,7 @@ export function ScoreScaleMixin() {
131
131
  /**
132
132
  * #getter
133
133
  * Whether this display draws `scales.y.rules`, which is whether the
134
- * score menu offers the reference lines: a scale it places y through
134
+ * Y axis panel offers Include 0 and the reference lines: a scale it places y through
135
135
  * rules a band for them to cross, which a density plot's colour-mapped
136
136
  * rows and a colour ramp do not.
137
137
  */
@@ -66,30 +66,34 @@ export declare function computeScoreStats(summaryScoreMode: string, datasets: Da
66
66
  /**
67
67
  * #api
68
68
  * The domain the visible instances autoscale to: at a `quantile` of 1 their
69
- * extremes, `stats`; below it `quantileExtent`'s ends, the bottom read off
70
- * the `low`s and the top off the `high`s less the zeros where any is
71
- * positive, so whiskers open to their spread, a sparse window's empty bins
72
- * lower no top, and a window of nothing above 0 keeps the top it has.
69
+ * extremes, `stats`; below it those extremes fenced by `quantileExtent`'s
70
+ * ends (`fenceOutliers`), the bottom read off the `low`s and the top off the
71
+ * `high`s less the zeros where any is positive, so whiskers open to their
72
+ * spread, a sparse window's empty bins lower no top, and a window of nothing
73
+ * above 0 keeps the top it has.
73
74
  */
74
- export declare function autoscaleDomainFromSpans({ stats, quantile, spans, }: {
75
+ export declare function autoscaleDomainFromSpans({ stats, quantile, zero, spans, }: {
75
76
  stats: ScoreStats;
76
77
  quantile: number;
78
+ zero: boolean;
77
79
  spans: ScoreSpan[];
78
80
  }): [number, number];
79
81
  /** `autoscaleDomainFromSpans` over the wiggle packer's datasets. */
80
- export declare function autoscaleDomainFromStats({ stats, quantile, summaryScoreMode, visibleEntries, }: {
82
+ export declare function autoscaleDomainFromStats({ stats, quantile, zero, summaryScoreMode, visibleEntries, }: {
81
83
  stats: ScoreStats;
82
84
  quantile: number;
85
+ zero: boolean;
83
86
  summaryScoreMode: string;
84
87
  visibleEntries: Dataset[];
85
88
  }): [number, number];
86
89
  /**
87
90
  * #api
88
91
  * The score domain of the visible feature arrays, following `quantile` as
89
- * `scales.y.domainQuantile` says.
92
+ * `scales.y.domainQuantile` says, its outliers fenced for an axis that
93
+ * reaches 0 under `zero`.
90
94
  */
91
95
  export declare function computeAutoscaleDomain(quantile: number, summaryScoreMode: string, visibleEntries: {
92
96
  data: FeatureArrays;
93
97
  visStart: number;
94
98
  visEnd: number;
95
- }[]): [number, number] | undefined;
99
+ }[], zero: boolean): [number, number] | undefined;
package/esm/autoscale.js CHANGED
@@ -1,4 +1,4 @@
1
- import { quantileExtent } from '@jbrowse/core/util/quantileExtent';
1
+ import { fenceOutliers, quantileExtent, } from '@jbrowse/core/util/quantileExtent';
2
2
  /** The wiggle packer's arrays as a span, under a summary mode. */
3
3
  export function datasetSpan({ data, visStart, visEnd }, summaryScoreMode) {
4
4
  const { low, high } = boundArrays(summaryScoreMode);
@@ -128,12 +128,13 @@ export function computeScoreStats(summaryScoreMode, datasets) {
128
128
  /**
129
129
  * #api
130
130
  * The domain the visible instances autoscale to: at a `quantile` of 1 their
131
- * extremes, `stats`; below it `quantileExtent`'s ends, the bottom read off
132
- * the `low`s and the top off the `high`s less the zeros where any is
133
- * positive, so whiskers open to their spread, a sparse window's empty bins
134
- * lower no top, and a window of nothing above 0 keeps the top it has.
131
+ * extremes, `stats`; below it those extremes fenced by `quantileExtent`'s
132
+ * ends (`fenceOutliers`), the bottom read off the `low`s and the top off the
133
+ * `high`s less the zeros where any is positive, so whiskers open to their
134
+ * spread, a sparse window's empty bins lower no top, and a window of nothing
135
+ * above 0 keeps the top it has.
135
136
  */
136
- export function autoscaleDomainFromSpans({ stats, quantile, spans, }) {
137
+ export function autoscaleDomainFromSpans({ stats, quantile, zero, spans, }) {
137
138
  if (quantile >= 1) {
138
139
  return [stats.scoreMin, stats.scoreMax];
139
140
  }
@@ -153,25 +154,31 @@ export function autoscaleDomainFromSpans({ stats, quantile, spans, }) {
153
154
  const tops = highs.some(v => v > 0) ? highs.filter(v => v !== 0) : highs;
154
155
  const min = quantileExtent(lows, lows.length, quantile)[0];
155
156
  const max = quantileExtent(tops, tops.length, quantile)[1];
156
- return [Number.isFinite(min) ? min : 0, Number.isFinite(max) ? max : 0];
157
+ return fenceOutliers({
158
+ extremes: [stats.scoreMin, stats.scoreMax],
159
+ quantiles: [Number.isFinite(min) ? min : 0, Number.isFinite(max) ? max : 0],
160
+ zero,
161
+ });
157
162
  }
158
163
  /** `autoscaleDomainFromSpans` over the wiggle packer's datasets. */
159
- export function autoscaleDomainFromStats({ stats, quantile, summaryScoreMode, visibleEntries, }) {
164
+ export function autoscaleDomainFromStats({ stats, quantile, zero, summaryScoreMode, visibleEntries, }) {
160
165
  return autoscaleDomainFromSpans({
161
166
  stats,
162
167
  quantile,
168
+ zero,
163
169
  spans: visibleEntries.map(d => datasetSpan(d, summaryScoreMode)),
164
170
  });
165
171
  }
166
172
  /**
167
173
  * #api
168
174
  * The score domain of the visible feature arrays, following `quantile` as
169
- * `scales.y.domainQuantile` says.
175
+ * `scales.y.domainQuantile` says, its outliers fenced for an axis that
176
+ * reaches 0 under `zero`.
170
177
  */
171
- export function computeAutoscaleDomain(quantile, summaryScoreMode, visibleEntries) {
178
+ export function computeAutoscaleDomain(quantile, summaryScoreMode, visibleEntries, zero) {
172
179
  const spans = visibleEntries.map(d => datasetSpan(d, summaryScoreMode));
173
180
  const stats = computeSpanStats(spans);
174
181
  return stats
175
- ? autoscaleDomainFromSpans({ stats, quantile, spans })
182
+ ? autoscaleDomainFromSpans({ stats, quantile, zero, spans })
176
183
  : undefined;
177
184
  }
package/esm/chrome.d.ts CHANGED
@@ -2,4 +2,3 @@ export { AxisGutter, CrossHatchLines, CrossHatches, ScoreDomainCaption, ScoreRul
2
2
  export { makeResolutionSubMenuItem } from './ResolutionStepper.tsx';
3
3
  export { makePointSizeSubMenu, pointSizeAccess } from './pointSizeMenu.tsx';
4
4
  export type { PointSizeAccess } from './pointSizeMenu.tsx';
5
- export { default as SetMinMaxDialog } from './SetMinMaxDialog.tsx';
package/esm/chrome.js CHANGED
@@ -4,4 +4,3 @@
4
4
  export { AxisGutter, CrossHatchLines, CrossHatches, ScoreDomainCaption, ScoreRuleLines, ScoreRules, YScaleBar, YScaleBarOverlay, } from '@jbrowse/display-ui';
5
5
  export { makeResolutionSubMenuItem } from './ResolutionStepper.js';
6
6
  export { makePointSizeSubMenu, pointSizeAccess } from './pointSizeMenu.js';
7
- export { default as SetMinMaxDialog } from './SetMinMaxDialog.js';
@@ -2,7 +2,6 @@ import type { ZoomRange } from '@jbrowse/core/data_adapters/BaseAdapter/zoomRang
2
2
  export interface SourceInfo {
3
3
  name: string;
4
4
  color?: string;
5
- labelColor?: string;
6
5
  label?: string;
7
6
  group?: string;
8
7
  baseUri?: string;
package/esm/index.d.ts CHANGED
@@ -18,8 +18,8 @@ export type { SettledBlocksView, VisibleEntry, VisibleStatsDomainSpec, VisibleSt
18
18
  export { scoreRuleMarks, widenRangeToRules } from './scoreRuleMarks.ts';
19
19
  export type { ScoreRuleMark } from './scoreRuleMarks.ts';
20
20
  export { DEFAULT_POINT_DIAMETER_PX, SMALL_POINT_MAX_DIAMETER_PX, appendPointMarker, } from './pointMarker.ts';
21
- export { makeClipOutliersItem, AXIS_ZERO_LABEL, makeAxisZeroItem, makeCrossHatchItem, makeScaleTypeSubMenu, makeScoreSubMenu, makeSetMinMaxScoreItem, } from './scoreMenuItems.ts';
22
- export type { ScoreScaleModel, ScoreSubMenuOptions } from './scoreMenuItems.ts';
21
+ export { COVERAGE_AXIS_LABEL, SCORE_RANGE_LABEL, Y_AXIS_LABEL, makeScoreAxisMenuItem, } from './scoreMenuItems.ts';
22
+ export type { ScoreAxisMenuItemOptions, ScoreRulesModel, ScoreScaleModel, } from './scoreMenuItems.ts';
23
23
  export { ScoreAxisMixin } from './ScoreAxisMixin.ts';
24
24
  export { ScoreScaleMixin } from './ScoreScaleMixin.ts';
25
25
  export type { ScoreScaleHost } from './ScoreScaleMixin.ts';
package/esm/index.js CHANGED
@@ -16,7 +16,7 @@ export { resolveRenderState } from './resolveRenderState.js';
16
16
  export { visibleStatsDomain, visibleStatsRange } from './visibleStatsDomain.js';
17
17
  export { scoreRuleMarks, widenRangeToRules } from './scoreRuleMarks.js';
18
18
  export { DEFAULT_POINT_DIAMETER_PX, SMALL_POINT_MAX_DIAMETER_PX, appendPointMarker, } from './pointMarker.js';
19
- export { makeClipOutliersItem, AXIS_ZERO_LABEL, makeAxisZeroItem, makeCrossHatchItem, makeScaleTypeSubMenu, makeScoreSubMenu, makeSetMinMaxScoreItem, } from './scoreMenuItems.js';
19
+ export { COVERAGE_AXIS_LABEL, SCORE_RANGE_LABEL, Y_AXIS_LABEL, makeScoreAxisMenuItem, } from './scoreMenuItems.js';
20
20
  export { ScoreAxisMixin } from './ScoreAxisMixin.js';
21
21
  export { ScoreScaleMixin } from './ScoreScaleMixin.js';
22
22
  export { WiggleScoreConfigMixin, wiggleScoreConfigExtraSlots, } from './WiggleScoreConfigMixin.js';
package/esm/scale.js CHANGED
@@ -147,7 +147,7 @@ export function getNiceDomain({ scaleType, domain, bounds, zero, }) {
147
147
  }
148
148
  }
149
149
  // Rounding is for an autoscaled end, whose only meaning is "roughly the
150
- // data's extent". A bound the user typed into Set min/max score means itself,
150
+ // data's extent". A bound the user typed into the Y axis panel means itself,
151
151
  // and the menu row goes on displaying it, so it is taken as given.
152
152
  //
153
153
  // `min`/`max` rather than `minScore`/`maxScore`: the log guards above may
@@ -1,5 +1,4 @@
1
- import type { AutoscalePeer } from './autoscaleGroup.ts';
2
- import type { CheckboxMenuItem, MenuItem } from '@jbrowse/core/ui';
1
+ import type { NormalMenuItem } from '@jbrowse/core/ui';
3
2
  import type { ValueScaleRule } from '@jbrowse/display-ui';
4
3
  import type { IStateTreeNode } from '@jbrowse/mobx-state-tree';
5
4
  export interface ScoreScaleModel extends IStateTreeNode {
@@ -12,6 +11,7 @@ export interface ScoreScaleModel extends IStateTreeNode {
12
11
  minScoreBound: number | undefined;
13
12
  maxScoreBound: number | undefined;
14
13
  hasManualScoreBounds: boolean;
14
+ autoscaleRange: [number, number] | undefined;
15
15
  autoscaledDomain: [number, number] | undefined;
16
16
  setScaleType: (v: string) => void;
17
17
  setScaleZero: (zero: boolean) => void;
@@ -24,33 +24,19 @@ export interface ScoreRulesModel {
24
24
  scoreRules: ValueScaleRule[];
25
25
  setScoreRules: (rules: ValueScaleRule[]) => void;
26
26
  }
27
- export declare function makeScaleTypeSubMenu(self: {
28
- scaleType: string;
29
- setScaleType: (v: string) => void;
30
- }): MenuItem;
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;
42
- export declare function makeSetMinMaxScoreItem(self: ScoreScaleModel): MenuItem;
43
- export declare function makeCrossHatchItem(self: {
44
- grid: boolean;
45
- setGrid: (grid: boolean) => void;
46
- }): MenuItem;
47
- export interface ScoreSubMenuOptions {
27
+ export declare const Y_AXIS_LABEL = "Y axis";
28
+ export declare const COVERAGE_AXIS_LABEL = "Coverage axis";
29
+ export declare const SCORE_RANGE_LABEL = "Score range";
30
+ export interface ScoreAxisMenuItemOptions {
48
31
  label?: string;
49
- leadingItems?: MenuItem[];
50
- trailingItems?: MenuItem[];
51
32
  disabled?: boolean;
52
33
  disabledHelpText?: string;
53
34
  }
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;
35
+ /**
36
+ * The one track-menu row for a value scale. It opens the drawer widget that
37
+ * edits `scales.y` live — scale type, range, 0, outlier clipping, the axis a
38
+ * group shares, grid and reference lines — so the track redraws beside it.
39
+ */
40
+ export declare function makeScoreAxisMenuItem(self: ScoreScaleModel & {
41
+ id: string;
42
+ }, opts?: ScoreAxisMenuItemOptions): NormalMenuItem;
@@ -1,137 +1,42 @@
1
- import { lazy } from 'react';
2
- import { checkboxItem, radioItems, toggleItem, } from '@jbrowse/core/ui/menuItems';
3
- import { getDialogHost } from '@jbrowse/core/util';
1
+ import { getSession, isSessionModelWithWidgets } from '@jbrowse/core/util';
4
2
  import EqualizerIcon from '@mui/icons-material/Equalizer';
5
- import { autoscaleGroupMembers, autoscalePeers } from './autoscaleGroup.js';
6
- import { VALUE_SCALE_TYPES } from './valueScaleConfigSchema.js';
7
- const AutoscaleGroupDialog = lazy(() => import('./AutoscaleGroupDialog.js'));
8
- const SetMinMaxDialog = lazy(() => import('./SetMinMaxDialog.js'));
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
- };
15
- export function makeScaleTypeSubMenu(self) {
3
+ import { SCORE_AXIS_WIDGET } from './ScoreAxisWidget/constants.js';
4
+ // Quoted by the docs' click paths, so literal strings.
5
+ export const Y_AXIS_LABEL = 'Y axis';
6
+ export const COVERAGE_AXIS_LABEL = 'Coverage axis';
7
+ export const SCORE_RANGE_LABEL = 'Score range';
8
+ // The caption carries only what the plot cannot show: a pinned end, `auto`
9
+ // for the other, and a scale that isn't linear. The resolved pair would
10
+ // caption every GC content track "(0 – 1)" off its default domain.
11
+ function caption(self) {
12
+ const parts = [
13
+ ...(self.hasManualScoreBounds
14
+ ? [`${self.manualMinScore ?? 'auto'} – ${self.manualMaxScore ?? 'auto'}`]
15
+ : []),
16
+ ...(self.scaleType === 'linear' ? [] : [self.scaleType]),
17
+ ];
18
+ return parts.length ? ` (${parts.join(', ')})` : '';
19
+ }
20
+ /**
21
+ * The one track-menu row for a value scale. It opens the drawer widget that
22
+ * edits `scales.y` live — scale type, range, 0, outlier clipping, the axis a
23
+ * group shares, grid and reference lines — so the track redraws beside it.
24
+ */
25
+ export function makeScoreAxisMenuItem(self, opts = {}) {
26
+ const { label = Y_AXIS_LABEL, disabled, disabledHelpText } = opts;
16
27
  return {
17
- label: 'Scale type',
18
- subMenu: radioItems(VALUE_SCALE_TYPES.map(value => ({
19
- value,
20
- label: SCALE_TYPE_LABELS[value],
21
- })), self.scaleType, v => {
22
- self.setScaleType(v);
23
- }),
24
- };
25
- }
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
- });
38
- }
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
- });
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.
52
- export function makeSetMinMaxScoreItem(self) {
53
- const { manualMinScore, manualMaxScore, autoscaledDomain: domain } = self;
54
- return {
55
- label: self.hasManualScoreBounds
56
- ? `Set min/max score (${manualMinScore ?? 'auto'} – ${manualMaxScore ?? 'auto'})...`
57
- : 'Set min/max score...',
58
- onClick: () => {
59
- getDialogHost(self).queueDialog(handleClose => [
60
- SetMinMaxDialog,
61
- { model: self, domain, handleClose },
62
- ]);
63
- },
64
- };
65
- }
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;
79
- return {
80
- label: others > 0
81
- ? `Autoscale with other tracks (${others})...`
82
- : 'Autoscale with other tracks...',
83
- onClick: () => {
84
- getDialogHost(self).queueDialog(handleClose => [
85
- AutoscaleGroupDialog,
86
- { model: self, handleClose },
87
- ]);
88
- },
89
- };
90
- }
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
- };
118
- }
119
- export function makeScoreSubMenu(self, opts = {}) {
120
- const { label = 'Score', leadingItems = [], trailingItems = [], disabled, disabledHelpText, } = opts;
121
- return {
122
- label,
28
+ label: `${label}${caption(self)}...`,
123
29
  icon: EqualizerIcon,
124
30
  disabled,
125
31
  disabledHelpText,
126
- subMenu: [
127
- ...leadingItems,
128
- makeScaleTypeSubMenu(self),
129
- makeClipOutliersItem(self),
130
- ...(rulesABand(self) ? [makeAxisZeroItem(self)] : []),
131
- makeSetMinMaxScoreItem(self),
132
- ...(autoscalesInGroups(self) ? [makeAutoscaleGroupItem(self)] : []),
133
- ...(drawsScoreRules(self) ? [makeSetScoreRulesItem(self)] : []),
134
- ...trailingItems,
135
- ],
32
+ onClick: () => {
33
+ const session = getSession(self);
34
+ if (isSessionModelWithWidgets(session)) {
35
+ session.openWidget(SCORE_AXIS_WIDGET, 'scoreAxis', {
36
+ display: self.id,
37
+ label,
38
+ });
39
+ }
40
+ },
136
41
  };
137
42
  }
@@ -1,7 +1,7 @@
1
1
  import type { Instance } from '@jbrowse/mobx-state-tree';
2
2
  export declare const VALUE_SCALE_TYPES: readonly ['linear', 'log', 'symlog'];
3
3
  export interface ValueScaleOptions {
4
- /** `domainQuantile`'s default: 1 follows the extremes, 0.99 clips the outermost 1% */
4
+ /** `domainQuantile`'s default: 1 follows the extremes, 0.99 fences a spike */
5
5
  domainQuantile?: number;
6
6
  /** `symlogConstant`'s default */
7
7
  symlogConstant?: number;
@@ -35,9 +35,8 @@ export type ValueScaleRuleConfig = Instance<ReturnType<typeof valueScaleRuleSche
35
35
  * autoscaled linear or symlog axis reaches 0 whatever those regions hold.
36
36
  *
37
37
  * Two defaults come from the display rather than from the scale.
38
- * `domainQuantile` starts at `0.99` on the wiggle plot, clipping the outermost
39
- * 1% of each sign, and at `1`, the extremes, on the coverage band and the mark
40
- * display. `symlogConstant` starts at `0` on the wiggle family and the mark
38
+ * `domainQuantile` starts at `0.99` on the wiggle plot, fencing a spike, and
39
+ * at `1`, the extremes, on the coverage band and the mark display. `symlogConstant` starts at `0` on the wiggle family and the mark
41
40
  * display and at `1` on the coverage band.
42
41
  *
43
42
  * Every scale carries the same guides: `rules`, reference lines at chosen
@@ -65,7 +64,7 @@ export type ValueScaleRuleConfig = Instance<ReturnType<typeof valueScaleRuleSche
65
64
  * ```
66
65
  *
67
66
  * #example
68
- * The whole visible range, rather than the 99th percentile the wiggle
67
+ * The whole visible range, spikes included, rather than the fence the wiggle
69
68
  * displays start on:
70
69
  * ```js
71
70
  * {
@@ -50,9 +50,8 @@ function valueScaleRuleSchema() {
50
50
  * autoscaled linear or symlog axis reaches 0 whatever those regions hold.
51
51
  *
52
52
  * Two defaults come from the display rather than from the scale.
53
- * `domainQuantile` starts at `0.99` on the wiggle plot, clipping the outermost
54
- * 1% of each sign, and at `1`, the extremes, on the coverage band and the mark
55
- * display. `symlogConstant` starts at `0` on the wiggle family and the mark
53
+ * `domainQuantile` starts at `0.99` on the wiggle plot, fencing a spike, and
54
+ * at `1`, the extremes, on the coverage band and the mark display. `symlogConstant` starts at `0` on the wiggle family and the mark
56
55
  * display and at `1` on the coverage band.
57
56
  *
58
57
  * Every scale carries the same guides: `rules`, reference lines at chosen
@@ -80,7 +79,7 @@ function valueScaleRuleSchema() {
80
79
  * ```
81
80
  *
82
81
  * #example
83
- * The whole visible range, rather than the 99th percentile the wiggle
82
+ * The whole visible range, spikes included, rather than the fence the wiggle
84
83
  * displays start on:
85
84
  * ```js
86
85
  * {
@@ -135,8 +134,8 @@ export function valueScaleSchema({ domainQuantile = 1, symlogConstant = 0, } = {
135
134
  /**
136
135
  * #slot scales.y.domainMin
137
136
  * The bottom of the axis, pinning what would otherwise autoscale to the
138
- * loaded regions. Unset autoscales that end. The score menu's "Set
139
- * min/max" writes here.
137
+ * loaded regions. Unset autoscales that end. The Y axis panel's Min
138
+ * field writes here.
140
139
  */
141
140
  domainMin: {
142
141
  type: 'maybeNumber',
@@ -158,7 +157,7 @@ export function valueScaleSchema({ domainQuantile = 1, symlogConstant = 0, } = {
158
157
  * Off, the axis spans the values alone. A pinned end is unmoved either
159
158
  * way, a log axis has no 0, and a density plot, which maps score to
160
159
  * colour and has no axis, spans its values whatever this says.
161
- * The score menu's "Start axis at 0" toggles it.
160
+ * The Y axis panel's "Include 0" toggles it.
162
161
  */
163
162
  zero: {
164
163
  type: 'boolean',
@@ -170,8 +169,8 @@ export function valueScaleSchema({ domainQuantile = 1, symlogConstant = 0, } = {
170
169
  * A name shared by the tracks whose axes autoscale together: each
171
170
  * unpinned end spans the data of every track in the view naming the
172
171
  * same group, so three coverage lanes stay comparable as the view
173
- * moves. A pinned end stays this track's own. The score menu's
174
- * "Autoscale with other tracks" writes it.
172
+ * moves. A pinned end stays this track's own. The Y axis panel's
173
+ * "Share axis with" writes it.
175
174
  */
176
175
  autoscaleGroup: {
177
176
  type: 'maybeString',
@@ -193,24 +192,27 @@ export function valueScaleSchema({ domainQuantile = 1, symlogConstant = 0, } = {
193
192
  },
194
193
  /**
195
194
  * #slot scales.y.domainQuantile
196
- * What an unpinned end follows over the loaded values: `1` their
197
- * extremes, and below it that quantile of the values on its side of 0,
198
- * so `0.99` drops the outermost 1% at each end and one spike no longer
199
- * flattens the rest. Where both signs appear each end is measured on its
200
- * own sign, so a sparse minority tail stays visible; whether the axis
201
- * then reaches 0 is `zero`'s. The score menu's "Clip outliers" toggles
202
- * it.
195
+ * Where an unpinned end's outliers are fenced. An end follows the
196
+ * loaded values' extreme; below `1`, an extreme that would stretch the
197
+ * axis past twice the span this quantile of the values draws stops at
198
+ * that fence, and the bars past it wear the red clip strip. So `0.99`
199
+ * leaves a plot with no spike whole and keeps one spike from flattening
200
+ * the rest. Each end's quantile is measured among the values on its side
201
+ * of 0, so a sparse minority tail stays visible, and the span includes 0
202
+ * where `zero` reaches it. A colour ramp's `domainQuantile` clips at the
203
+ * quantile itself, since a saturated colour hides nothing its key does
204
+ * not say. The Y axis panel's "Clip extreme outliers" toggles it.
203
205
  */
204
206
  domainQuantile: {
205
207
  type: 'number',
206
208
  defaultValue: domainQuantile,
207
- description: 'the quantile an unpinned end follows: 1 the extremes, 0.99 drops the outermost 1% at each end, each sign measured on its own',
209
+ description: 'fences outliers: 1 follows the extremes; below it an extreme past twice the span this quantile draws is cut there',
208
210
  },
209
211
  /**
210
212
  * #slot scales.y.grid
211
213
  * Rule the plot across at every tick, ggplot2's panel grid and
212
- * Vega-Lite's `axis.grid`. The score menu's "Show cross hatches"
213
- * toggles it.
214
+ * Vega-Lite's `axis.grid`. The Y axis panel's "Grid lines" toggles
215
+ * it.
214
216
  */
215
217
  grid: {
216
218
  type: 'boolean',
@@ -17,7 +17,6 @@ export interface VisibleEntry<T> {
17
17
  * `coarseDynamicBlocks`: over the empty initial coarse list every walker below
18
18
  * yields no entries, and no entries is not a stale domain but the caller's
19
19
  * `[0, 1]` fallback — a bigwig line track drew blank and a density track solid.
20
- * reference/FETCH_SKELETON.md, "Every fetch autorun runs on the leading edge".
21
20
  */
22
21
  export interface SettledBlocksView {
23
22
  initialized: boolean;