@rowsncolumns/spreadsheet 10.5.17 → 10.6.4
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/dist/cjs/api/cf-data-bar.d.ts +73 -0
- package/dist/cjs/api/cf-data-bar.d.ts.map +1 -0
- package/dist/cjs/api/cf-data-bar.js +182 -0
- package/dist/cjs/api/cf-icons.d.ts +73 -0
- package/dist/cjs/api/cf-icons.d.ts.map +1 -0
- package/dist/cjs/api/cf-icons.js +322 -0
- package/dist/cjs/api/cf-overlays.d.ts +89 -3
- package/dist/cjs/api/cf-overlays.d.ts.map +1 -1
- package/dist/cjs/api/cf-overlays.js +256 -80
- package/dist/cjs/api/cf-priority.d.ts +34 -0
- package/dist/cjs/api/cf-priority.d.ts.map +1 -0
- package/dist/cjs/api/cf-priority.js +94 -0
- package/dist/cjs/api/heatmap.d.ts +7 -1
- package/dist/cjs/api/heatmap.d.ts.map +1 -1
- package/dist/cjs/api/heatmap.js +27 -11
- package/dist/cjs/api/selections.d.ts +2 -2
- package/dist/cjs/api/validation.d.ts +6 -0
- package/dist/cjs/api/validation.d.ts.map +1 -1
- package/dist/cjs/api/validation.js +10 -1
- package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts +8 -3
- package/dist/cjs/atoms/goal-seek-dialog.atom.d.ts.map +1 -1
- package/dist/cjs/atoms/index.d.ts +4 -0
- package/dist/cjs/atoms/index.d.ts.map +1 -1
- package/dist/cjs/atoms/index.js +4 -0
- package/dist/cjs/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/cjs/components/canvas-grid/index.js +194 -51
- package/dist/cjs/components/canvas-grid/overflow.d.ts +37 -0
- package/dist/cjs/components/canvas-grid/overflow.d.ts.map +1 -0
- package/dist/cjs/components/canvas-grid/overflow.js +49 -0
- package/dist/cjs/components/canvas-grid/page-breaks.d.ts +15 -0
- package/dist/cjs/components/canvas-grid/page-breaks.d.ts.map +1 -0
- package/dist/cjs/components/canvas-grid/page-breaks.js +77 -0
- package/dist/cjs/components/canvas-grid/typings.d.ts +32 -3
- package/dist/cjs/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.d.ts +58 -1
- package/dist/cjs/components/cell/alignment.d.ts.map +1 -1
- package/dist/cjs/components/cell/alignment.js +144 -1
- package/dist/cjs/components/cell/cell-background.d.ts +2 -0
- package/dist/cjs/components/cell/cell-background.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-background.js +5 -6
- package/dist/cjs/components/cell/cell-backgrounds.d.ts.map +1 -1
- package/dist/cjs/components/cell/cell-backgrounds.js +5 -1
- package/dist/cjs/components/cell/cell-text-runs.js +1 -1
- package/dist/cjs/components/cell/index.d.ts.map +1 -1
- package/dist/cjs/components/cell/index.js +378 -37
- package/dist/cjs/components/cell/number-format-layout.d.ts +35 -0
- package/dist/cjs/components/cell/number-format-layout.d.ts.map +1 -0
- package/dist/cjs/components/cell/number-format-layout.js +106 -0
- package/dist/cjs/components/cell/typings.d.ts +22 -0
- package/dist/cjs/components/cell/typings.d.ts.map +1 -1
- package/dist/cjs/components/cell-editor/index.js +2 -2
- package/dist/cjs/components/cell-filter/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-filter/index.js +3 -3
- package/dist/cjs/components/cell-overlay/index.d.ts +20 -0
- package/dist/cjs/components/cell-overlay/index.d.ts.map +1 -1
- package/dist/cjs/components/cell-overlay/index.js +155 -28
- package/dist/cjs/components/cf-icon-preview/index.d.ts +16 -0
- package/dist/cjs/components/cf-icon-preview/index.d.ts.map +1 -0
- package/dist/cjs/components/cf-icon-preview/index.js +48 -0
- package/dist/cjs/components/context-menu/index.d.ts.map +1 -1
- package/dist/cjs/components/context-menu/index.js +11 -3
- package/dist/cjs/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/cjs/components/embeds/embed-component.js +3 -2
- package/dist/cjs/components/goal-seek-dialog/index.d.ts +15 -5
- package/dist/cjs/components/goal-seek-dialog/index.d.ts.map +1 -1
- package/dist/cjs/components/goal-seek-dialog/index.js +145 -42
- package/dist/cjs/components/hidden-markers/index.d.ts.map +1 -1
- package/dist/cjs/components/hidden-markers/index.js +8 -7
- package/dist/cjs/components/hidden-markers/style.d.ts +7 -0
- package/dist/cjs/components/hidden-markers/style.d.ts.map +1 -1
- package/dist/cjs/components/hidden-markers/style.js +13 -2
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts +67 -0
- package/dist/cjs/components/protect-sheet-dialog/index.d.ts.map +1 -0
- package/dist/cjs/components/protect-sheet-dialog/index.js +196 -0
- package/dist/cjs/components/toolbar/types.d.ts +1 -1
- package/dist/cjs/components/toolbar/types.d.ts.map +1 -1
- package/dist/cjs/config.d.ts +13 -1
- package/dist/cjs/config.d.ts.map +1 -1
- package/dist/cjs/config.js +15 -3
- package/dist/cjs/helpers.d.ts +10 -5
- package/dist/cjs/helpers.d.ts.map +1 -1
- package/dist/cjs/helpers.js +43 -31
- package/dist/cjs/hooks/use-border-styles.d.ts.map +1 -1
- package/dist/cjs/hooks/use-border-styles.js +5 -28
- package/dist/cjs/hooks/use-cell-renderer.d.ts +35 -3
- package/dist/cjs/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/cjs/hooks/use-cell-renderer.js +85 -47
- package/dist/cjs/hooks/use-conditional-formatting.d.ts +13 -1
- package/dist/cjs/hooks/use-conditional-formatting.d.ts.map +1 -1
- package/dist/cjs/hooks/use-conditional-formatting.js +281 -230
- package/dist/cjs/index.d.ts +7 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +13 -1
- package/dist/cjs/release-date.js +1 -1
- package/dist/cjs/themes.d.ts +8 -0
- package/dist/cjs/themes.d.ts.map +1 -1
- package/dist/cjs/themes.js +21 -3
- package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -1
- package/dist/cjs/types.d.ts +115 -5
- package/dist/cjs/types.d.ts.map +1 -1
- package/dist/esm/api/cf-data-bar.d.ts +73 -0
- package/dist/esm/api/cf-data-bar.d.ts.map +1 -0
- package/dist/esm/api/cf-data-bar.js +178 -0
- package/dist/esm/api/cf-icons.d.ts +73 -0
- package/dist/esm/api/cf-icons.d.ts.map +1 -0
- package/dist/esm/api/cf-icons.js +306 -0
- package/dist/esm/api/cf-overlays.d.ts +89 -3
- package/dist/esm/api/cf-overlays.d.ts.map +1 -1
- package/dist/esm/api/cf-overlays.js +223 -67
- package/dist/esm/api/cf-priority.d.ts +34 -0
- package/dist/esm/api/cf-priority.d.ts.map +1 -0
- package/dist/esm/api/cf-priority.js +61 -0
- package/dist/esm/api/heatmap.d.ts +7 -1
- package/dist/esm/api/heatmap.d.ts.map +1 -1
- package/dist/esm/api/heatmap.js +24 -9
- package/dist/esm/api/selections.d.ts +2 -2
- package/dist/esm/api/validation.d.ts +6 -0
- package/dist/esm/api/validation.d.ts.map +1 -1
- package/dist/esm/api/validation.js +6 -0
- package/dist/esm/atoms/goal-seek-dialog.atom.d.ts +8 -3
- package/dist/esm/atoms/goal-seek-dialog.atom.d.ts.map +1 -1
- package/dist/esm/atoms/index.d.ts +4 -0
- package/dist/esm/atoms/index.d.ts.map +1 -1
- package/dist/esm/atoms/index.js +4 -0
- package/dist/esm/components/canvas-grid/index.d.ts.map +1 -1
- package/dist/esm/components/canvas-grid/index.js +163 -47
- package/dist/esm/components/canvas-grid/overflow.d.ts +37 -0
- package/dist/esm/components/canvas-grid/overflow.d.ts.map +1 -0
- package/dist/esm/components/canvas-grid/overflow.js +39 -0
- package/dist/esm/components/canvas-grid/page-breaks.d.ts +15 -0
- package/dist/esm/components/canvas-grid/page-breaks.d.ts.map +1 -0
- package/dist/esm/components/canvas-grid/page-breaks.js +50 -0
- package/dist/esm/components/canvas-grid/typings.d.ts +32 -3
- package/dist/esm/components/canvas-grid/typings.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.d.ts +58 -1
- package/dist/esm/components/cell/alignment.d.ts.map +1 -1
- package/dist/esm/components/cell/alignment.js +110 -1
- package/dist/esm/components/cell/cell-background.d.ts +2 -0
- package/dist/esm/components/cell/cell-background.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-background.js +4 -5
- package/dist/esm/components/cell/cell-backgrounds.d.ts.map +1 -1
- package/dist/esm/components/cell/cell-backgrounds.js +5 -1
- package/dist/esm/components/cell/cell-text-runs.js +2 -2
- package/dist/esm/components/cell/index.d.ts.map +1 -1
- package/dist/esm/components/cell/index.js +339 -39
- package/dist/esm/components/cell/number-format-layout.d.ts +35 -0
- package/dist/esm/components/cell/number-format-layout.d.ts.map +1 -0
- package/dist/esm/components/cell/number-format-layout.js +99 -0
- package/dist/esm/components/cell/typings.d.ts +22 -0
- package/dist/esm/components/cell/typings.d.ts.map +1 -1
- package/dist/esm/components/cell-editor/index.js +2 -2
- package/dist/esm/components/cell-filter/index.d.ts.map +1 -1
- package/dist/esm/components/cell-filter/index.js +4 -4
- package/dist/esm/components/cell-overlay/index.d.ts +20 -0
- package/dist/esm/components/cell-overlay/index.d.ts.map +1 -1
- package/dist/esm/components/cell-overlay/index.js +111 -25
- package/dist/esm/components/cf-icon-preview/index.d.ts +16 -0
- package/dist/esm/components/cf-icon-preview/index.d.ts.map +1 -0
- package/dist/esm/components/cf-icon-preview/index.js +41 -0
- package/dist/esm/components/context-menu/index.d.ts.map +1 -1
- package/dist/esm/components/context-menu/index.js +11 -3
- package/dist/esm/components/embeds/embed-component.d.ts.map +1 -1
- package/dist/esm/components/embeds/embed-component.js +4 -3
- package/dist/esm/components/goal-seek-dialog/index.d.ts +15 -5
- package/dist/esm/components/goal-seek-dialog/index.d.ts.map +1 -1
- package/dist/esm/components/goal-seek-dialog/index.js +126 -29
- package/dist/esm/components/hidden-markers/index.d.ts.map +1 -1
- package/dist/esm/components/hidden-markers/index.js +9 -8
- package/dist/esm/components/hidden-markers/style.d.ts +7 -0
- package/dist/esm/components/hidden-markers/style.d.ts.map +1 -1
- package/dist/esm/components/hidden-markers/style.js +8 -1
- package/dist/esm/components/protect-sheet-dialog/index.d.ts +67 -0
- package/dist/esm/components/protect-sheet-dialog/index.d.ts.map +1 -0
- package/dist/esm/components/protect-sheet-dialog/index.js +154 -0
- package/dist/esm/components/toolbar/types.d.ts +1 -1
- package/dist/esm/components/toolbar/types.d.ts.map +1 -1
- package/dist/esm/config.d.ts +13 -1
- package/dist/esm/config.d.ts.map +1 -1
- package/dist/esm/config.js +13 -1
- package/dist/esm/helpers.d.ts +10 -5
- package/dist/esm/helpers.d.ts.map +1 -1
- package/dist/esm/helpers.js +40 -28
- package/dist/esm/hooks/use-border-styles.d.ts.map +1 -1
- package/dist/esm/hooks/use-border-styles.js +5 -26
- package/dist/esm/hooks/use-cell-renderer.d.ts +35 -3
- package/dist/esm/hooks/use-cell-renderer.d.ts.map +1 -1
- package/dist/esm/hooks/use-cell-renderer.js +83 -42
- package/dist/esm/hooks/use-conditional-formatting.d.ts +13 -1
- package/dist/esm/hooks/use-conditional-formatting.d.ts.map +1 -1
- package/dist/esm/hooks/use-conditional-formatting.js +215 -120
- package/dist/esm/index.d.ts +7 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +7 -0
- package/dist/esm/release-date.js +1 -1
- package/dist/esm/themes.d.ts +8 -0
- package/dist/esm/themes.d.ts.map +1 -1
- package/dist/esm/themes.js +20 -3
- package/dist/esm/tsconfig.esm.tsbuildinfo +1 -1
- package/dist/esm/types.d.ts +115 -5
- package/dist/esm/types.d.ts.map +1 -1
- package/dist/spreadsheet.min.css +1 -1
- package/package.json +4 -4
|
@@ -1,106 +1,203 @@
|
|
|
1
1
|
// Helpers for IconSetRule and DataBarRule evaluation.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Icon sets are painted as vector icons (`cf-icons.ts`); the glyphs below
|
|
4
|
+
// are the plain-text stand-ins menus (filter by icon, rule lists) show. Every
|
|
5
|
+
// family lists its icons in OOXML `iconId` order — index 0 is the icon of the
|
|
6
|
+
// LOWEST bucket; `reverse` on the rule flips the order. The number of icons
|
|
7
|
+
// encodes the family's bucket count (3, 4, or 5).
|
|
7
8
|
//
|
|
8
|
-
// Bucket selection:
|
|
9
|
-
//
|
|
10
|
-
//
|
|
11
|
-
//
|
|
12
|
-
//
|
|
9
|
+
// Bucket selection (Excel): thresholds are checked from the top bucket down;
|
|
10
|
+
// a value lands in the first bucket whose threshold it meets (`>=`, or `>`
|
|
11
|
+
// when the threshold's `gte` is false), else in bucket 0. Threshold types
|
|
12
|
+
// follow OOXML cfvo semantics: NUMBER is absolute, PERCENT is relative to
|
|
13
|
+
// the range's min..max, PERCENTILE is PERCENTILE.INC over the range values.
|
|
14
|
+
import { getExtendedValueNumber } from "@rowsncolumns/utils";
|
|
15
|
+
import { CF_ICON_SETS } from "./cf-icons";
|
|
13
16
|
export const ICON_SET_GLYPHS = {
|
|
14
|
-
// 3-icon families (
|
|
17
|
+
// 3-icon families (lowest → highest)
|
|
15
18
|
"3Arrows": ["▼", "▶", "▲"],
|
|
16
19
|
"3ArrowsGray": ["▽", "▷", "△"],
|
|
17
|
-
"3Flags": ["⚑", "
|
|
20
|
+
"3Flags": ["⚑", "⚑", "⚑"],
|
|
18
21
|
"3TrafficLights1": ["●", "●", "●"],
|
|
19
|
-
"3TrafficLights2": ["
|
|
22
|
+
"3TrafficLights2": ["●", "●", "●"],
|
|
20
23
|
"3Signs": ["◆", "▲", "●"],
|
|
21
|
-
"3Symbols": ["✖", "
|
|
24
|
+
"3Symbols": ["✖", "!", "✔"],
|
|
22
25
|
"3Symbols2": ["✗", "!", "✓"],
|
|
26
|
+
"3Stars": ["☆", "⯪", "★"],
|
|
27
|
+
"3Triangles": ["▼", "▬", "▲"],
|
|
23
28
|
// 4-icon families
|
|
24
29
|
"4Arrows": ["▼", "↘", "↗", "▲"],
|
|
25
30
|
"4ArrowsGray": ["▽", "↘", "↗", "△"],
|
|
26
31
|
"4RedToBlack": ["●", "●", "●", "●"],
|
|
27
|
-
"4Rating": ["
|
|
28
|
-
"4TrafficLights": ["
|
|
32
|
+
"4Rating": ["▂", "▃", "▅", "▇"],
|
|
33
|
+
"4TrafficLights": ["●", "●", "●", "●"],
|
|
29
34
|
// 5-icon families
|
|
30
35
|
"5Arrows": ["▼", "↘", "→", "↗", "▲"],
|
|
31
36
|
"5ArrowsGray": ["▽", "↘", "→", "↗", "△"],
|
|
32
37
|
"5Rating": ["▁", "▂", "▄", "▆", "▇"],
|
|
33
38
|
"5Quarters": ["○", "◔", "◑", "◕", "●"],
|
|
39
|
+
"5Boxes": ["□", "◰", "◧", "◩", "■"],
|
|
34
40
|
};
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"4ArrowsGray": ["#6b7280", "#6b7280", "#6b7280", "#6b7280"],
|
|
48
|
-
"4RedToBlack": ["#dc2626", "#f97316", "#525252", "#000000"],
|
|
49
|
-
"4Rating": ["#6b7280", "#6b7280", "#6b7280", "#6b7280"],
|
|
50
|
-
"4TrafficLights": ["#dc2626", "#f59e0b", "#84cc16", "#16a34a"],
|
|
51
|
-
"5Arrows": ["#dc2626", "#f59e0b", "#eab308", "#84cc16", "#16a34a"],
|
|
52
|
-
"5ArrowsGray": ["#6b7280", "#6b7280", "#6b7280", "#6b7280", "#6b7280"],
|
|
53
|
-
"5Rating": ["#6b7280", "#6b7280", "#6b7280", "#6b7280", "#6b7280"],
|
|
54
|
-
"5Quarters": ["#6b7280", "#6b7280", "#6b7280", "#6b7280", "#6b7280"],
|
|
41
|
+
const shapeColor = (shape) => {
|
|
42
|
+
switch (shape.kind) {
|
|
43
|
+
case "star":
|
|
44
|
+
return "#F5B800";
|
|
45
|
+
case "rating":
|
|
46
|
+
case "boxes":
|
|
47
|
+
return "#2F6EBA";
|
|
48
|
+
case "quarters":
|
|
49
|
+
return "#262626";
|
|
50
|
+
default:
|
|
51
|
+
return shape.color;
|
|
52
|
+
}
|
|
55
53
|
};
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
54
|
+
/** The colour each icon is painted in — what text stand-ins use. */
|
|
55
|
+
export const ICON_SET_COLORS = Object.fromEntries(Object.entries(CF_ICON_SETS).map(([family, shapes]) => [
|
|
56
|
+
family,
|
|
57
|
+
shapes.map(shapeColor),
|
|
58
|
+
]));
|
|
59
|
+
/** The percentiles / ranks a rule's thresholds resolve with. */
|
|
60
|
+
export const buildCfRuleStatsRequest = (rule) => {
|
|
61
|
+
const percentiles = new Set();
|
|
62
|
+
const addPoint = (point) => {
|
|
63
|
+
if (point?.type !== "PERCENTILE")
|
|
64
|
+
return;
|
|
65
|
+
const p = Number(point.value);
|
|
66
|
+
if (!Number.isFinite(p))
|
|
67
|
+
return;
|
|
68
|
+
percentiles.add(p);
|
|
69
|
+
// Colour scales read a 0..1 percentile as a fraction.
|
|
70
|
+
if (p <= 1)
|
|
71
|
+
percentiles.add(p * 100);
|
|
72
|
+
};
|
|
73
|
+
addPoint(rule.dataBarRule?.minpoint);
|
|
74
|
+
addPoint(rule.dataBarRule?.maxpoint);
|
|
75
|
+
rule.iconSetRule?.thresholds.forEach(addPoint);
|
|
76
|
+
addPoint(rule.gradientRule?.minpoint);
|
|
77
|
+
addPoint(rule.gradientRule?.midpoint);
|
|
78
|
+
addPoint(rule.gradientRule?.maxpoint);
|
|
79
|
+
const ranks = [];
|
|
80
|
+
if (rule.topBottomRule) {
|
|
81
|
+
ranks.push({
|
|
82
|
+
k: rule.topBottomRule.rank,
|
|
83
|
+
top: rule.topBottomRule.type === "TOP",
|
|
84
|
+
percent: !!rule.topBottomRule.isPercent,
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
return { percentiles: [...percentiles], ranks };
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Turn the engine's reply into {@link CfRangeStats} for the CF hook — what a
|
|
91
|
+
* windowed host returns from `getConditionalFormatRuleStats`.
|
|
92
|
+
*/
|
|
93
|
+
export const toCfRangeStats = (request, response) => {
|
|
94
|
+
if (!response)
|
|
95
|
+
return undefined;
|
|
96
|
+
const at = (list, i) => i >= 0 && list[i] != null ? list[i] : NaN;
|
|
97
|
+
return {
|
|
98
|
+
count: response.count,
|
|
99
|
+
min: response.min ?? NaN,
|
|
100
|
+
max: response.max ?? NaN,
|
|
101
|
+
mean: response.mean ?? undefined,
|
|
102
|
+
stdDev: response.stdDev ?? undefined,
|
|
103
|
+
percentile: (p) => at(response.percentiles, request.percentiles.indexOf(p)),
|
|
104
|
+
rankValue: (k, top, percent) => at(response.ranks, request.ranks.findIndex((r) => r.k === k && r.top === top && !!r.percent === !!percent)),
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
export const buildCfRangeStats = (values) => {
|
|
108
|
+
const sorted = values.slice().sort((a, b) => a - b);
|
|
109
|
+
return {
|
|
110
|
+
count: sorted.length,
|
|
111
|
+
min: sorted.length ? sorted[0] : NaN,
|
|
112
|
+
max: sorted.length ? sorted[sorted.length - 1] : NaN,
|
|
113
|
+
sorted,
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
/** Excel's PERCENTILE.INC over ascending values (`p` in 0..100). */
|
|
117
|
+
export const percentileInc = (sorted, p) => {
|
|
118
|
+
if (!sorted.length || !Number.isFinite(p))
|
|
119
|
+
return NaN;
|
|
120
|
+
const k = (Math.max(0, Math.min(100, p)) / 100) * (sorted.length - 1);
|
|
121
|
+
const lower = Math.floor(k);
|
|
122
|
+
const upper = Math.ceil(k);
|
|
123
|
+
if (lower === upper)
|
|
124
|
+
return sorted[lower];
|
|
125
|
+
return sorted[lower] + (sorted[upper] - sorted[lower]) * (k - lower);
|
|
126
|
+
};
|
|
127
|
+
const numericValue = (raw) => typeof raw === "number" ? raw : raw == null || raw === "" ? NaN : Number(raw);
|
|
128
|
+
/**
|
|
129
|
+
* Resolve a cfvo threshold against the rule's range statistics (OOXML cfvo
|
|
130
|
+
* semantics). `role` picks the AUTOMATIC bound (data bars only): the lower
|
|
131
|
+
* bound is `min(0, lowest)`, the upper `max(0, highest)`. Returns NaN when
|
|
132
|
+
* the threshold can't be resolved.
|
|
133
|
+
*/
|
|
134
|
+
export const resolveCfThreshold = (threshold, stats, options = {}) => {
|
|
135
|
+
const num = numericValue(threshold.value);
|
|
62
136
|
switch (threshold.type) {
|
|
63
137
|
case "MIN":
|
|
64
|
-
return
|
|
138
|
+
return stats.min;
|
|
65
139
|
case "MAX":
|
|
66
|
-
return
|
|
140
|
+
return stats.max;
|
|
141
|
+
case "AUTOMATIC":
|
|
142
|
+
return options.role === "max"
|
|
143
|
+
? Math.max(0, stats.max)
|
|
144
|
+
: Math.min(0, stats.min);
|
|
67
145
|
case "NUMBER":
|
|
68
146
|
return Number.isFinite(num) ? num : NaN;
|
|
69
|
-
case "PERCENT":
|
|
147
|
+
case "PERCENT":
|
|
70
148
|
if (!Number.isFinite(num))
|
|
71
149
|
return NaN;
|
|
72
|
-
|
|
73
|
-
return rangeMin + (span * num) / 100;
|
|
74
|
-
}
|
|
150
|
+
return stats.min + ((stats.max - stats.min) * num) / 100;
|
|
75
151
|
case "PERCENTILE":
|
|
76
|
-
// Approximate percentile by linear interpolation of min/max — the
|
|
77
|
-
// engine doesn't have access to the sorted value list here. For tight
|
|
78
|
-
// OOXML conformance the caller can pass a true percentile separately.
|
|
79
152
|
if (!Number.isFinite(num))
|
|
80
153
|
return NaN;
|
|
81
|
-
return
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
154
|
+
return stats.sorted
|
|
155
|
+
? percentileInc(stats.sorted, num)
|
|
156
|
+
: stats.percentile
|
|
157
|
+
? stats.percentile(num)
|
|
158
|
+
: stats.min + (stats.max - stats.min) * (num / 100);
|
|
159
|
+
case "FORMULA": {
|
|
160
|
+
if (Number.isFinite(num))
|
|
161
|
+
return num;
|
|
162
|
+
const text = String(threshold.value ?? "").trim();
|
|
163
|
+
if (!text)
|
|
164
|
+
return NaN;
|
|
165
|
+
const literal = Number(text.replace(/^=/, ""));
|
|
166
|
+
if (text.replace(/^=/, "") !== "" && Number.isFinite(literal)) {
|
|
167
|
+
return literal;
|
|
168
|
+
}
|
|
169
|
+
const resolved = options.resolveFormula?.(text);
|
|
170
|
+
return typeof resolved === "number" && Number.isFinite(resolved)
|
|
171
|
+
? resolved
|
|
172
|
+
: NaN;
|
|
173
|
+
}
|
|
87
174
|
default:
|
|
88
175
|
return NaN;
|
|
89
176
|
}
|
|
90
177
|
};
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
178
|
+
// Resolve a cfvo threshold value against a range's min/max numeric values.
|
|
179
|
+
// Returns NaN when the threshold can't be resolved (e.g. PERCENT against
|
|
180
|
+
// an empty range), which downstream callers should skip. Pass `sorted`
|
|
181
|
+
// values for an exact PERCENTILE.
|
|
182
|
+
export const resolveThreshold = (threshold, rangeMin, rangeMax, sorted) => resolveCfThreshold(threshold, {
|
|
183
|
+
count: sorted?.length ?? 0,
|
|
184
|
+
min: rangeMin,
|
|
185
|
+
max: rangeMax,
|
|
186
|
+
sorted,
|
|
187
|
+
});
|
|
188
|
+
// Pick the icon bucket index for a value. `thresholds[i]` is the lower bound
|
|
189
|
+
// of bucket `i + 1` (length = iconCount - 1); `strict[i]` makes it a `>`
|
|
190
|
+
// comparison. Checked from the top bucket down, like Excel; non-finite
|
|
191
|
+
// thresholds never match.
|
|
192
|
+
export const pickIconBucket = (value, thresholds, strict) => {
|
|
193
|
+
for (let i = thresholds.length - 1; i >= 0; i--) {
|
|
194
|
+
const t = thresholds[i];
|
|
96
195
|
if (!Number.isFinite(t))
|
|
97
|
-
|
|
98
|
-
if (value >= t)
|
|
99
|
-
|
|
100
|
-
else
|
|
101
|
-
break;
|
|
196
|
+
continue;
|
|
197
|
+
if (strict?.[i] ? value > t : value >= t)
|
|
198
|
+
return i + 1;
|
|
102
199
|
}
|
|
103
|
-
return
|
|
200
|
+
return 0;
|
|
104
201
|
};
|
|
105
202
|
// Compute a 0..1 fill fraction for a data-bar cell value.
|
|
106
203
|
// When `min >= max`, all cells in the range share the same value; return 1
|
|
@@ -116,3 +213,62 @@ export const computeDataBarFill = (value, min, max) => {
|
|
|
116
213
|
const clamped = Math.max(min, Math.min(max, value));
|
|
117
214
|
return (clamped - min) / (max - min);
|
|
118
215
|
};
|
|
216
|
+
/**
|
|
217
|
+
* Whether a cell counts as a number for data bars, colour scales, icon sets
|
|
218
|
+
* and the other numeric rules: its computed value is a number (Excel's rule —
|
|
219
|
+
* a typed `1` or a spilled `=SEQUENCE(3)` value qualifies without any number
|
|
220
|
+
* format), or it carries a number format (the legacy store's signal).
|
|
221
|
+
*/
|
|
222
|
+
export const isConditionalFormatNumberCell = (effectiveValue, cellFormat) => getExtendedValueNumber(effectiveValue) != null ||
|
|
223
|
+
!!cellFormat?.numberFormat?.type;
|
|
224
|
+
/**
|
|
225
|
+
* The comparison bound of an above / below average rule: the mean, moved
|
|
226
|
+
* `stdDev` sample standard deviations (Excel's STDEV) above or below it for
|
|
227
|
+
* the "1/2/3 std dev above / below" options. Mirrors the engine's
|
|
228
|
+
* `average_bound` (rnc-store `derive.rs`).
|
|
229
|
+
*/
|
|
230
|
+
export const averageBound = (values, above, stdDev) => {
|
|
231
|
+
const mean = values.reduce((sum, v) => sum + v, 0) / values.length;
|
|
232
|
+
if (!stdDev || stdDev <= 0 || values.length < 2)
|
|
233
|
+
return mean;
|
|
234
|
+
const variance = values.reduce((sum, v) => sum + (v - mean) ** 2, 0) / (values.length - 1);
|
|
235
|
+
const offset = stdDev * Math.sqrt(variance);
|
|
236
|
+
return above ? mean + offset : mean - offset;
|
|
237
|
+
};
|
|
238
|
+
/**
|
|
239
|
+
* Whether a CSS colour (`#rrggbb` / `rgb()`) is dark — relative luminance
|
|
240
|
+
* under 0.5. Unparseable colours count as light.
|
|
241
|
+
*/
|
|
242
|
+
export const isDarkCssColor = (color) => {
|
|
243
|
+
if (!color)
|
|
244
|
+
return false;
|
|
245
|
+
const hex = /^#?([0-9a-f]{6})/i.exec(color.trim());
|
|
246
|
+
const rgb = /^rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)/i.exec(color.trim());
|
|
247
|
+
let channels;
|
|
248
|
+
if (hex) {
|
|
249
|
+
const n = parseInt(hex[1], 16);
|
|
250
|
+
channels = [(n >> 16) & 255, (n >> 8) & 255, n & 255];
|
|
251
|
+
}
|
|
252
|
+
else if (rgb) {
|
|
253
|
+
channels = [Number(rgb[1]), Number(rgb[2]), Number(rgb[3])];
|
|
254
|
+
}
|
|
255
|
+
if (!channels)
|
|
256
|
+
return false;
|
|
257
|
+
const [r, g, b] = channels.map((c) => {
|
|
258
|
+
const v = c / 255;
|
|
259
|
+
return v <= 0.03928 ? v / 12.92 : ((v + 0.055) / 1.055) ** 2.4;
|
|
260
|
+
});
|
|
261
|
+
return 0.2126 * r + 0.7152 * g + 0.0722 * b < 0.5;
|
|
262
|
+
};
|
|
263
|
+
/** {@link averageBound} from full-range statistics (sorted values or the engine's mean / std dev). */
|
|
264
|
+
export const averageBoundFromStats = (stats, above, stdDev) => {
|
|
265
|
+
if (stats.sorted) {
|
|
266
|
+
return stats.sorted.length
|
|
267
|
+
? averageBound(stats.sorted, above, stdDev)
|
|
268
|
+
: undefined;
|
|
269
|
+
}
|
|
270
|
+
if (stats.mean == null || !stats.count)
|
|
271
|
+
return undefined;
|
|
272
|
+
const offset = stdDev && stdDev > 0 ? stdDev * (stats.stdDev ?? 0) : 0;
|
|
273
|
+
return above ? stats.mean + offset : stats.mean - offset;
|
|
274
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { ConditionalFormatRule } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Conditional-format precedence, as Excel defines it ("Manage conditional formatting rule
|
|
4
|
+
* precedence", support.microsoft.com): the rule listed FIRST has the highest precedence and wins a
|
|
5
|
+
* conflicting format; new rules go to the top of the list.
|
|
6
|
+
*
|
|
7
|
+
* `priority` carries that order (lower = higher precedence, as in xlsx `<cfRule priority>`). A rule
|
|
8
|
+
* without one ranks below every rule that has one; ties keep the stored order. The grid paints, the
|
|
9
|
+
* Rules Manager lists and the exporters number rules with this one ordering.
|
|
10
|
+
*/
|
|
11
|
+
export declare const sortConditionalFormatRules: <T extends Pick<ConditionalFormatRule, "priority">>(rules: ReadonlyArray<T>) => T[];
|
|
12
|
+
/**
|
|
13
|
+
* The `priority` that puts a new rule above every existing one (Excel adds new rules at the top of
|
|
14
|
+
* the list). Priorities may go to zero or below; exporters renumber from 1.
|
|
15
|
+
*/
|
|
16
|
+
export declare const getTopConditionalFormatPriority: (rules: ReadonlyArray<Pick<ConditionalFormatRule, "priority">>) => number;
|
|
17
|
+
/** A new rule with its `priority` set to the top of `rules`, unless it already carries one. */
|
|
18
|
+
export declare const withTopConditionalFormatPriority: <T extends Pick<ConditionalFormatRule, "priority">>(rule: T, rules: ReadonlyArray<Pick<ConditionalFormatRule, "priority">>) => T;
|
|
19
|
+
/**
|
|
20
|
+
* Move one rule up (`-1`) or down (`+1`) among `scope` (the rules the Rules Manager is showing —
|
|
21
|
+
* "Show formatting rules for" may hide some), returning the `priority` updates that realise the new
|
|
22
|
+
* order: every rule of the workbook renumbered 1..N in its new precedence order, keeping only the
|
|
23
|
+
* rules whose priority changes. Empty when the move is a no-op (first rule up, last rule down).
|
|
24
|
+
*/
|
|
25
|
+
export declare const planConditionalFormatMove: <T extends Pick<ConditionalFormatRule, "id" | "priority">>(rules: ReadonlyArray<T>, ruleId: T["id"], direction: -1 | 1, scope?: ReadonlyArray<Pick<T, "id">>) => Array<{
|
|
26
|
+
rule: T;
|
|
27
|
+
priority: number;
|
|
28
|
+
}>;
|
|
29
|
+
/** `priority` updates that make `ordered` the precedence order (1..N), changed rules only. */
|
|
30
|
+
export declare const planConditionalFormatOrder: <T extends Pick<ConditionalFormatRule, "priority">>(ordered: ReadonlyArray<T>) => Array<{
|
|
31
|
+
rule: T;
|
|
32
|
+
priority: number;
|
|
33
|
+
}>;
|
|
34
|
+
//# sourceMappingURL=cf-priority.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cf-priority.d.ts","sourceRoot":"","sources":["../../../api/cf-priority.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEtD;;;;;;;;GAQG;AACH,eAAO,MAAM,0BAA0B,GACrC,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAEjD,OAAO,aAAa,CAAC,CAAC,CAAC,KACtB,CAAC,EAWwB,CAAC;AAE7B;;;GAGG;AACH,eAAO,MAAM,+BAA+B,GAC1C,OAAO,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC,KAC5D,MAQF,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,gCAAgC,GAC3C,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAEjD,MAAM,CAAC,EACP,OAAO,aAAa,CAAC,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,CAAC,KAC5D,CAGgE,CAAC;AAEpE;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB,GACpC,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,IAAI,GAAG,UAAU,CAAC,EAExD,OAAO,aAAa,CAAC,CAAC,CAAC,EACvB,QAAQ,CAAC,CAAC,IAAI,CAAC,EACf,WAAW,CAAC,CAAC,GAAG,CAAC,EACjB,QAAO,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAS,KAC1C,KAAK,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAerC,CAAC;AAEF,8FAA8F;AAC9F,eAAO,MAAM,0BAA0B,GACrC,CAAC,SAAS,IAAI,CAAC,qBAAqB,EAAE,UAAU,CAAC,EAEjD,SAAS,aAAa,CAAC,CAAC,CAAC,KACxB,KAAK,CAAC;IAAE,IAAI,EAAE,CAAC,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAGnC,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conditional-format precedence, as Excel defines it ("Manage conditional formatting rule
|
|
3
|
+
* precedence", support.microsoft.com): the rule listed FIRST has the highest precedence and wins a
|
|
4
|
+
* conflicting format; new rules go to the top of the list.
|
|
5
|
+
*
|
|
6
|
+
* `priority` carries that order (lower = higher precedence, as in xlsx `<cfRule priority>`). A rule
|
|
7
|
+
* without one ranks below every rule that has one; ties keep the stored order. The grid paints, the
|
|
8
|
+
* Rules Manager lists and the exporters number rules with this one ordering.
|
|
9
|
+
*/
|
|
10
|
+
export const sortConditionalFormatRules = (rules) => rules
|
|
11
|
+
.map((rule, index) => ({ rule, index }))
|
|
12
|
+
.sort((left, right) => {
|
|
13
|
+
const leftPriority = left.rule.priority ?? Number.POSITIVE_INFINITY;
|
|
14
|
+
const rightPriority = right.rule.priority ?? Number.POSITIVE_INFINITY;
|
|
15
|
+
if (leftPriority === rightPriority) {
|
|
16
|
+
return left.index - right.index;
|
|
17
|
+
}
|
|
18
|
+
return leftPriority - rightPriority;
|
|
19
|
+
})
|
|
20
|
+
.map(({ rule }) => rule);
|
|
21
|
+
/**
|
|
22
|
+
* The `priority` that puts a new rule above every existing one (Excel adds new rules at the top of
|
|
23
|
+
* the list). Priorities may go to zero or below; exporters renumber from 1.
|
|
24
|
+
*/
|
|
25
|
+
export const getTopConditionalFormatPriority = (rules) => {
|
|
26
|
+
let top = 1;
|
|
27
|
+
for (const rule of rules) {
|
|
28
|
+
if (typeof rule.priority === "number" && Number.isFinite(rule.priority)) {
|
|
29
|
+
top = Math.min(top, rule.priority);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return top - 1;
|
|
33
|
+
};
|
|
34
|
+
/** A new rule with its `priority` set to the top of `rules`, unless it already carries one. */
|
|
35
|
+
export const withTopConditionalFormatPriority = (rule, rules) => typeof rule.priority === "number"
|
|
36
|
+
? rule
|
|
37
|
+
: { ...rule, priority: getTopConditionalFormatPriority(rules) };
|
|
38
|
+
/**
|
|
39
|
+
* Move one rule up (`-1`) or down (`+1`) among `scope` (the rules the Rules Manager is showing —
|
|
40
|
+
* "Show formatting rules for" may hide some), returning the `priority` updates that realise the new
|
|
41
|
+
* order: every rule of the workbook renumbered 1..N in its new precedence order, keeping only the
|
|
42
|
+
* rules whose priority changes. Empty when the move is a no-op (first rule up, last rule down).
|
|
43
|
+
*/
|
|
44
|
+
export const planConditionalFormatMove = (rules, ruleId, direction, scope = rules) => {
|
|
45
|
+
const ordered = sortConditionalFormatRules(rules);
|
|
46
|
+
const scopeIds = new Set(scope.map((rule) => rule.id));
|
|
47
|
+
const visible = ordered.filter((rule) => scopeIds.has(rule.id));
|
|
48
|
+
const at = visible.findIndex((rule) => rule.id === ruleId);
|
|
49
|
+
const neighbour = visible[at + direction];
|
|
50
|
+
if (at === -1 || !neighbour) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
const from = ordered.indexOf(visible[at]);
|
|
54
|
+
const to = ordered.indexOf(neighbour);
|
|
55
|
+
const next = [...ordered];
|
|
56
|
+
next[from] = neighbour;
|
|
57
|
+
next[to] = visible[at];
|
|
58
|
+
return planConditionalFormatOrder(next);
|
|
59
|
+
};
|
|
60
|
+
/** `priority` updates that make `ordered` the precedence order (1..N), changed rules only. */
|
|
61
|
+
export const planConditionalFormatOrder = (ordered) => ordered.flatMap((rule, index) => rule.priority === index + 1 ? [] : [{ rule, priority: index + 1 }]);
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { SpreadsheetTheme } from "../components/canvas-grid/typings";
|
|
2
2
|
import type { GradientRule } from "../types";
|
|
3
|
-
|
|
3
|
+
import type { CfRangeStats } from "./cf-overlays";
|
|
4
|
+
/**
|
|
5
|
+
* `population` — the rule's full-range statistics when `values` is only the
|
|
6
|
+
* visible slice of a windowed rule; min / mid / max resolve over it instead
|
|
7
|
+
* of the slice.
|
|
8
|
+
*/
|
|
9
|
+
export declare const getGradientColors: (values: (number | undefined)[][][], gradientRule: GradientRule, theme: SpreadsheetTheme, population?: CfRangeStats) => (string | undefined)[][][];
|
|
4
10
|
//# sourceMappingURL=heatmap.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../../../api/heatmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"heatmap.d.ts","sourceRoot":"","sources":["../../../api/heatmap.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAC5B,QAAQ,CAAC,MAAM,GAAG,SAAS,CAAC,EAAE,EAAE,EAAE,EAClC,cAAc,YAAY,EAC1B,OAAO,gBAAgB,EACvB,aAAa,YAAY,+BAoE1B,CAAC"}
|
package/dist/esm/api/heatmap.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { hexToRgb, isNil, rgbToHex } from "@rowsncolumns/utils";
|
|
2
2
|
import { getStringifiedColor } from "../themes";
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* `population` — the rule's full-range statistics when `values` is only the
|
|
5
|
+
* visible slice of a windowed rule; min / mid / max resolve over it instead
|
|
6
|
+
* of the slice.
|
|
7
|
+
*/
|
|
8
|
+
export const getGradientColors = (values, gradientRule, theme, population) => {
|
|
4
9
|
const colors = [];
|
|
5
10
|
const { minpoint, midpoint, maxpoint } = gradientRule;
|
|
6
|
-
const [minValue, midValue, maxValue] = getMinMidMax(values, gradientRule);
|
|
11
|
+
const [minValue, midValue, maxValue] = getMinMidMax(population?.sorted ? [[population.sorted]] : values, gradientRule, population?.sorted ? undefined : population);
|
|
7
12
|
const range = maxValue - minValue || 1;
|
|
8
13
|
const minColor = getStringifiedColor(minpoint?.color, theme);
|
|
9
14
|
const midColor = getStringifiedColor(midpoint?.color, theme);
|
|
@@ -67,16 +72,20 @@ const interpolateColor = (color1, color2, ratio) => {
|
|
|
67
72
|
const interpolate = (value1, value2, ratio) => {
|
|
68
73
|
return value1 + (value2 - value1) * ratio;
|
|
69
74
|
};
|
|
70
|
-
const getMinMidMax = (values, { minpoint, midpoint, maxpoint }
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
const getMinMidMax = (values, { minpoint, midpoint, maxpoint },
|
|
76
|
+
// Engine statistics without the sorted values (windowed hosts).
|
|
77
|
+
stats) => {
|
|
78
|
+
const flattenedValues = stats
|
|
79
|
+
? []
|
|
80
|
+
: values
|
|
81
|
+
.flat(2)
|
|
82
|
+
.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
83
|
+
if (stats ? !stats.count : flattenedValues.length === 0) {
|
|
75
84
|
return [0, 0, 0];
|
|
76
85
|
}
|
|
77
86
|
const sortedValues = [...flattenedValues].sort((a, b) => a - b);
|
|
78
|
-
const dataMin = sortedValues[0];
|
|
79
|
-
const dataMax = sortedValues[sortedValues.length - 1];
|
|
87
|
+
const dataMin = stats ? stats.min : sortedValues[0];
|
|
88
|
+
const dataMax = stats ? stats.max : sortedValues[sortedValues.length - 1];
|
|
80
89
|
const parseNumericInput = (value) => {
|
|
81
90
|
if (typeof value === "number") {
|
|
82
91
|
return Number.isFinite(value) ? value : undefined;
|
|
@@ -93,6 +102,12 @@ const getMinMidMax = (values, { minpoint, midpoint, maxpoint }) => {
|
|
|
93
102
|
return undefined;
|
|
94
103
|
};
|
|
95
104
|
const getPercentileValue = (percent) => {
|
|
105
|
+
if (stats) {
|
|
106
|
+
const value = stats.percentile?.(percent);
|
|
107
|
+
return value !== undefined && Number.isFinite(value)
|
|
108
|
+
? value
|
|
109
|
+
: dataMin + ((dataMax - dataMin) * percent) / 100;
|
|
110
|
+
}
|
|
96
111
|
if (!sortedValues.length) {
|
|
97
112
|
return dataMin;
|
|
98
113
|
}
|
|
@@ -8,7 +8,7 @@ import type { SheetRange, TableView } from "../types";
|
|
|
8
8
|
* @param isActiveCell
|
|
9
9
|
* @param isSelection
|
|
10
10
|
*/
|
|
11
|
-
export declare const getSelectionStrokeStyle: (formulaMode: boolean, isFill: boolean, isActiveCell: boolean, emptySelections: boolean) => "
|
|
11
|
+
export declare const getSelectionStrokeStyle: (formulaMode: boolean, isFill: boolean, isActiveCell: boolean, emptySelections: boolean) => "dashed" | "solid";
|
|
12
12
|
export type SelectionStrokeOptions = {
|
|
13
13
|
/** Border width of a range selection outside formula mode. Default `1`. */
|
|
14
14
|
selectionStrokeWidth?: number;
|
|
@@ -37,7 +37,7 @@ export declare const getSelectionStrokeWidth: (formulaMode: boolean, isFill: boo
|
|
|
37
37
|
* @param isFill
|
|
38
38
|
* @returns
|
|
39
39
|
*/
|
|
40
|
-
export declare const getSelectionFillOpacity: (formulaMode: boolean, isFill: boolean) =>
|
|
40
|
+
export declare const getSelectionFillOpacity: (formulaMode: boolean, isFill: boolean) => 1 | 0 | 0.2;
|
|
41
41
|
/**
|
|
42
42
|
* Get background color of selection
|
|
43
43
|
* @param formulaMode
|
|
@@ -86,6 +86,12 @@ export declare const isActionBlockedBySheetProtection: (sheetProtection: Maybe<S
|
|
|
86
86
|
* protection is inactive.
|
|
87
87
|
*/
|
|
88
88
|
export declare const isCellLockedUnderProtection: (sheetProtection: Maybe<SheetProtection> | undefined, cellProtection: Maybe<Pick<NonNullable<CellData["protection"]>, "locked">>) => boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Whether a cell's contents are hidden from the formula bar: Excel's Format
|
|
91
|
+
* Cells ▸ Protection ▸ Hidden takes effect only while the sheet is protected.
|
|
92
|
+
* Cells are NOT hidden by default.
|
|
93
|
+
*/
|
|
94
|
+
export declare const isCellFormulaHiddenUnderProtection: (sheetProtection: Maybe<SheetProtection> | undefined, cellProtection: Maybe<Pick<NonNullable<CellData["protection"]>, "hidden">>) => boolean;
|
|
89
95
|
/**
|
|
90
96
|
* Check if a range is protected
|
|
91
97
|
* @param sheetId
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../api/validation.ts"],"names":[],"mappings":"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"}
|
|
@@ -530,6 +530,12 @@ export const isActionBlockedBySheetProtection = (sheetProtection, action) => {
|
|
|
530
530
|
* protection is inactive.
|
|
531
531
|
*/
|
|
532
532
|
export const isCellLockedUnderProtection = (sheetProtection, cellProtection) => isSheetProtectionActive(sheetProtection) && cellProtection?.locked !== false;
|
|
533
|
+
/**
|
|
534
|
+
* Whether a cell's contents are hidden from the formula bar: Excel's Format
|
|
535
|
+
* Cells ▸ Protection ▸ Hidden takes effect only while the sheet is protected.
|
|
536
|
+
* Cells are NOT hidden by default.
|
|
537
|
+
*/
|
|
538
|
+
export const isCellFormulaHiddenUnderProtection = (sheetProtection, cellProtection) => isSheetProtectionActive(sheetProtection) && cellProtection?.hidden === true;
|
|
533
539
|
/**
|
|
534
540
|
* Check if a range is protected
|
|
535
541
|
* @param sheetId
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GoalSeekResult } from "../types";
|
|
1
|
+
import type { GoalSeekResult, GoalSeekTargetOptions } from "../types";
|
|
2
2
|
/**
|
|
3
3
|
* Open-state + payload for the Goal Seek dialog (Excel's Data → What-If
|
|
4
4
|
* Analysis → Goal Seek). The context menu opens it with the active cell as
|
|
@@ -9,8 +9,13 @@ import type { GoalSeekResult } from "../types";
|
|
|
9
9
|
export type GoalSeekDialogRequest = {
|
|
10
10
|
/** A1 reference of the active cell — the default "Set cell". */
|
|
11
11
|
setCell: string;
|
|
12
|
-
/**
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* Runs the search; resolves to the result, or `undefined` when the engine reports none. With
|
|
14
|
+
* `options` (a one-sided target or a round answer) it only proposes `candidates`.
|
|
15
|
+
*/
|
|
16
|
+
onApply: (setCell: string, targetValue: number, changingCell: string, options?: GoalSeekTargetOptions) => Promise<GoalSeekResult | undefined>;
|
|
17
|
+
/** Writes the candidate the user picked into the changing cell (an ordinary edit). */
|
|
18
|
+
onCommit?: (changingCell: string, value: number) => void;
|
|
14
19
|
};
|
|
15
20
|
export declare const goalSeekDialogAtom: import("jotai").PrimitiveAtom<GoalSeekDialogRequest | null> & {
|
|
16
21
|
init: GoalSeekDialogRequest | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"goal-seek-dialog.atom.d.ts","sourceRoot":"","sources":["../../../atoms/goal-seek-dialog.atom.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"goal-seek-dialog.atom.d.ts","sourceRoot":"","sources":["../../../atoms/goal-seek-dialog.atom.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAEtE;;;;;;GAMG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,CACP,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,qBAAqB,KAC5B,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACzC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CAC1D,CAAC;AAEF,eAAO,MAAM,kBAAkB;;CAA2C,CAAC;AAE3E,eAAO,MAAM,sBAAsB,+JAAoC,CAAC;AAExE,yFAAyF;AACzF,eAAO,MAAM,2BAA2B;;CAAU,CAAC;AAEnD,8DAA8D;AAC9D,eAAO,MAAM,0BAA0B,eACQ,CAAC;AAEhD,yEAAyE;AACzE,eAAO,MAAM,6BAA6B,YAMzC,CAAC;AAEF,uEAAuE;AACvE,eAAO,MAAM,qBAAqB,kBAGpB,qBAAqB,SAGlC,CAAC"}
|
|
@@ -23,6 +23,10 @@ export * from "./go-to-dialog.atom";
|
|
|
23
23
|
export * from "./move-overwrite-confirm.atom";
|
|
24
24
|
export * from "./evaluate-formula-dialog.atom";
|
|
25
25
|
export * from "./remove-duplicates-dialog.atom";
|
|
26
|
+
export * from "./text-to-columns-dialog.atom";
|
|
27
|
+
export * from "./subtotal-dialog.atom";
|
|
28
|
+
export * from "./goal-seek-dialog.atom";
|
|
29
|
+
export * from "./advanced-filter-dialog.atom";
|
|
26
30
|
export * from "./watch-window.atom";
|
|
27
31
|
export * from "./insert-cells-dialog.atom";
|
|
28
32
|
export * from "./insert-options.atom";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../atoms/index.ts"],"names":[],"mappings":"AAAA,cAAc,sBAAsB,CAAC;AACrC,cAAc,qBAAqB,CAAC;AACpC,cAAc,iCAAiC,CAAC;AAChD,cAAc,qBAAqB,CAAC;AACpC,cAAc,gCAAgC,CAAC;AAC/C,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,cAAc,6BAA6B,CAAC;AAC5C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,gBAAgB,CAAC;AAC/B,cAAc,mBAAmB,CAAC;AAClC,cAAc,qBAAqB,CAAC;AACpC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,yBAAyB,CAAC;AACxC,cAAc,yBAAyB,CAAC;AACxC,cAAc,oBAAoB,CAAC;AACnC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,qBAAqB,CAAC;AACpC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,uBAAuB,CAAC;AACtC,cAAc,sBAAsB,CAAC;AACrC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,yBAAyB,CAAC"}
|