@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
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
// Conditional-format icon sets drawn as small vector icons on the canvas.
|
|
2
|
+
//
|
|
3
|
+
// Excel's 20 icon sets (https://support.microsoft.com/office/
|
|
4
|
+
// use-data-bars-color-scales-and-icon-sets-to-highlight-data-
|
|
5
|
+
// f118d0b6-f19e-4ca2-8c9d-e4eac0b3b0f1, "Icon sets"). Each set lists its
|
|
6
|
+
// icons in OOXML `iconId` order — index 0 is the icon for the LOWEST bucket —
|
|
7
|
+
// so `iconId` matches what `<iconFilter>` / `<x14:cfIcon>` store. Each icon
|
|
8
|
+
// is described once in a 16 × 16 design box and painted with plain canvas
|
|
9
|
+
// paths, so it scales with zoom and needs no font or image asset.
|
|
10
|
+
const RED = "#E5383B";
|
|
11
|
+
const YELLOW = "#F2C12E";
|
|
12
|
+
const GREEN = "#2BA84A";
|
|
13
|
+
const GRAY = "#7F7F7F";
|
|
14
|
+
const BLACK = "#262626";
|
|
15
|
+
const PINK = "#F4A6A6";
|
|
16
|
+
const DARK_GRAY = "#8C8C8C";
|
|
17
|
+
const GOLD = "#F5B800";
|
|
18
|
+
const BLUE = "#2F6EBA";
|
|
19
|
+
const EMPTY = "#D9D9D9";
|
|
20
|
+
const UP = 0;
|
|
21
|
+
const UP_RIGHT = 45;
|
|
22
|
+
const RIGHT = 90;
|
|
23
|
+
const DOWN_RIGHT = 135;
|
|
24
|
+
const DOWN = 180;
|
|
25
|
+
const arrow = (angle, color) => ({
|
|
26
|
+
kind: "arrow",
|
|
27
|
+
angle,
|
|
28
|
+
color,
|
|
29
|
+
});
|
|
30
|
+
const circle = (color) => ({ kind: "circle", color });
|
|
31
|
+
/** Every icon set, lowest bucket first (OOXML `iconId` order). */
|
|
32
|
+
export const CF_ICON_SETS = {
|
|
33
|
+
"3Arrows": [arrow(DOWN, RED), arrow(RIGHT, YELLOW), arrow(UP, GREEN)],
|
|
34
|
+
"3ArrowsGray": [arrow(DOWN, GRAY), arrow(RIGHT, GRAY), arrow(UP, GRAY)],
|
|
35
|
+
"3Flags": [
|
|
36
|
+
{ kind: "flag", color: RED },
|
|
37
|
+
{ kind: "flag", color: YELLOW },
|
|
38
|
+
{ kind: "flag", color: GREEN },
|
|
39
|
+
],
|
|
40
|
+
"3TrafficLights1": [circle(RED), circle(YELLOW), circle(GREEN)],
|
|
41
|
+
"3TrafficLights2": [
|
|
42
|
+
{ kind: "rimmedCircle", color: RED },
|
|
43
|
+
{ kind: "rimmedCircle", color: YELLOW },
|
|
44
|
+
{ kind: "rimmedCircle", color: GREEN },
|
|
45
|
+
],
|
|
46
|
+
"3Signs": [
|
|
47
|
+
{ kind: "diamond", color: RED },
|
|
48
|
+
{ kind: "triangleUp", color: YELLOW },
|
|
49
|
+
circle(GREEN),
|
|
50
|
+
],
|
|
51
|
+
"3Symbols": [
|
|
52
|
+
{ kind: "symbol", glyph: "cross", color: RED },
|
|
53
|
+
{ kind: "symbol", glyph: "exclamation", color: YELLOW },
|
|
54
|
+
{ kind: "symbol", glyph: "check", color: GREEN },
|
|
55
|
+
],
|
|
56
|
+
"3Symbols2": [
|
|
57
|
+
{ kind: "symbolPlain", glyph: "cross", color: RED },
|
|
58
|
+
{ kind: "symbolPlain", glyph: "exclamation", color: YELLOW },
|
|
59
|
+
{ kind: "symbolPlain", glyph: "check", color: GREEN },
|
|
60
|
+
],
|
|
61
|
+
"3Stars": [
|
|
62
|
+
{ kind: "star", fill: 0 },
|
|
63
|
+
{ kind: "star", fill: 0.5 },
|
|
64
|
+
{ kind: "star", fill: 1 },
|
|
65
|
+
],
|
|
66
|
+
"3Triangles": [
|
|
67
|
+
{ kind: "triangleDown", color: RED },
|
|
68
|
+
{ kind: "dash", color: YELLOW },
|
|
69
|
+
{ kind: "triangleUp", color: GREEN },
|
|
70
|
+
],
|
|
71
|
+
"4Arrows": [
|
|
72
|
+
arrow(DOWN, RED),
|
|
73
|
+
arrow(DOWN_RIGHT, YELLOW),
|
|
74
|
+
arrow(UP_RIGHT, YELLOW),
|
|
75
|
+
arrow(UP, GREEN),
|
|
76
|
+
],
|
|
77
|
+
"4ArrowsGray": [
|
|
78
|
+
arrow(DOWN, GRAY),
|
|
79
|
+
arrow(DOWN_RIGHT, GRAY),
|
|
80
|
+
arrow(UP_RIGHT, GRAY),
|
|
81
|
+
arrow(UP, GRAY),
|
|
82
|
+
],
|
|
83
|
+
"4RedToBlack": [circle(BLACK), circle(DARK_GRAY), circle(PINK), circle(RED)],
|
|
84
|
+
"4Rating": [1, 2, 3, 4].map((filled) => ({ kind: "rating", filled })),
|
|
85
|
+
"4TrafficLights": [circle(BLACK), circle(RED), circle(YELLOW), circle(GREEN)],
|
|
86
|
+
"5Arrows": [
|
|
87
|
+
arrow(DOWN, RED),
|
|
88
|
+
arrow(DOWN_RIGHT, YELLOW),
|
|
89
|
+
arrow(RIGHT, YELLOW),
|
|
90
|
+
arrow(UP_RIGHT, YELLOW),
|
|
91
|
+
arrow(UP, GREEN),
|
|
92
|
+
],
|
|
93
|
+
"5ArrowsGray": [
|
|
94
|
+
arrow(DOWN, GRAY),
|
|
95
|
+
arrow(DOWN_RIGHT, GRAY),
|
|
96
|
+
arrow(RIGHT, GRAY),
|
|
97
|
+
arrow(UP_RIGHT, GRAY),
|
|
98
|
+
arrow(UP, GRAY),
|
|
99
|
+
],
|
|
100
|
+
"5Rating": [0, 1, 2, 3, 4].map((filled) => ({ kind: "rating", filled })),
|
|
101
|
+
"5Quarters": [0, 1, 2, 3, 4].map((filled) => ({ kind: "quarters", filled })),
|
|
102
|
+
"5Boxes": [0, 1, 2, 3, 4].map((filled) => ({ kind: "boxes", filled })),
|
|
103
|
+
};
|
|
104
|
+
/** Families Excel only stores in the x14 extension (no Excel 2007 equivalent). */
|
|
105
|
+
export const X14_ONLY_ICON_SETS = new Set([
|
|
106
|
+
"3Stars",
|
|
107
|
+
"3Triangles",
|
|
108
|
+
"5Boxes",
|
|
109
|
+
]);
|
|
110
|
+
export const getCfIcon = (iconSet, iconId) => iconSet && iconId != null
|
|
111
|
+
? CF_ICON_SETS[iconSet]?.[iconId]
|
|
112
|
+
: undefined;
|
|
113
|
+
const ARROW_POINTS = [
|
|
114
|
+
[8, 1],
|
|
115
|
+
[15, 8],
|
|
116
|
+
[11, 8],
|
|
117
|
+
[11, 15],
|
|
118
|
+
[5, 15],
|
|
119
|
+
[5, 8],
|
|
120
|
+
[1, 8],
|
|
121
|
+
];
|
|
122
|
+
const STAR_POINTS = Array.from({ length: 10 }, (_, i) => {
|
|
123
|
+
const radius = i % 2 === 0 ? 7.5 : 3.2;
|
|
124
|
+
const angle = -Math.PI / 2 + (i * Math.PI) / 5;
|
|
125
|
+
return [8 + radius * Math.cos(angle), 8.6 + radius * Math.sin(angle)];
|
|
126
|
+
});
|
|
127
|
+
/**
|
|
128
|
+
* Paint `icon` into the square at (`x`, `y`) with side `size` (local canvas
|
|
129
|
+
* coordinates).
|
|
130
|
+
*/
|
|
131
|
+
export const paintCfIcon = (ctx, icon, x, y, size) => {
|
|
132
|
+
const k = size / 16;
|
|
133
|
+
const px = (u) => x + u * k;
|
|
134
|
+
const py = (v) => y + v * k;
|
|
135
|
+
const polygon = (points) => {
|
|
136
|
+
ctx.beginPath();
|
|
137
|
+
points.forEach(([u, v], i) => i === 0 ? ctx.moveTo(px(u), py(v)) : ctx.lineTo(px(u), py(v)));
|
|
138
|
+
ctx.closePath();
|
|
139
|
+
};
|
|
140
|
+
const fillWith = (color) => {
|
|
141
|
+
ctx.setAttr("fillStyle", color);
|
|
142
|
+
ctx.fill();
|
|
143
|
+
};
|
|
144
|
+
const strokeWith = (color, width) => {
|
|
145
|
+
ctx.setAttr("strokeStyle", color);
|
|
146
|
+
ctx.setAttr("lineWidth", width * k);
|
|
147
|
+
ctx.setAttr("lineCap", "round");
|
|
148
|
+
ctx.setAttr("lineJoin", "round");
|
|
149
|
+
ctx.stroke();
|
|
150
|
+
};
|
|
151
|
+
const disc = (radius) => {
|
|
152
|
+
ctx.beginPath();
|
|
153
|
+
ctx.arc(px(8), py(8), radius * k, 0, Math.PI * 2);
|
|
154
|
+
ctx.closePath();
|
|
155
|
+
};
|
|
156
|
+
const glyph = (kind, color, width) => {
|
|
157
|
+
ctx.beginPath();
|
|
158
|
+
if (kind === "check") {
|
|
159
|
+
ctx.moveTo(px(4.5), py(8.5));
|
|
160
|
+
ctx.lineTo(px(7), py(11));
|
|
161
|
+
ctx.lineTo(px(11.5), py(5));
|
|
162
|
+
}
|
|
163
|
+
else if (kind === "cross") {
|
|
164
|
+
ctx.moveTo(px(5), py(5));
|
|
165
|
+
ctx.lineTo(px(11), py(11));
|
|
166
|
+
ctx.moveTo(px(11), py(5));
|
|
167
|
+
ctx.lineTo(px(5), py(11));
|
|
168
|
+
}
|
|
169
|
+
else {
|
|
170
|
+
ctx.moveTo(px(8), py(3.5));
|
|
171
|
+
ctx.lineTo(px(8), py(9));
|
|
172
|
+
ctx.moveTo(px(8), py(12));
|
|
173
|
+
ctx.lineTo(px(8), py(12.2));
|
|
174
|
+
}
|
|
175
|
+
strokeWith(color, width);
|
|
176
|
+
};
|
|
177
|
+
switch (icon.kind) {
|
|
178
|
+
case "arrow": {
|
|
179
|
+
const rad = (icon.angle * Math.PI) / 180;
|
|
180
|
+
const cos = Math.cos(rad);
|
|
181
|
+
const sin = Math.sin(rad);
|
|
182
|
+
polygon(ARROW_POINTS.map(([u, v]) => [
|
|
183
|
+
8 + (u - 8) * cos - (v - 8) * sin,
|
|
184
|
+
8 + (u - 8) * sin + (v - 8) * cos,
|
|
185
|
+
]));
|
|
186
|
+
fillWith(icon.color);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
case "circle":
|
|
190
|
+
disc(7);
|
|
191
|
+
fillWith(icon.color);
|
|
192
|
+
return;
|
|
193
|
+
case "rimmedCircle":
|
|
194
|
+
ctx.beginPath();
|
|
195
|
+
ctx.rect(px(0.5), py(0.5), 15 * k, 15 * k);
|
|
196
|
+
ctx.closePath();
|
|
197
|
+
fillWith(BLACK);
|
|
198
|
+
disc(5.5);
|
|
199
|
+
fillWith(icon.color);
|
|
200
|
+
return;
|
|
201
|
+
case "flag":
|
|
202
|
+
ctx.beginPath();
|
|
203
|
+
ctx.rect(px(3), py(1), 1.5 * k, 14 * k);
|
|
204
|
+
ctx.closePath();
|
|
205
|
+
fillWith(BLACK);
|
|
206
|
+
polygon([
|
|
207
|
+
[4.5, 1.5],
|
|
208
|
+
[14, 5.25],
|
|
209
|
+
[4.5, 9],
|
|
210
|
+
]);
|
|
211
|
+
fillWith(icon.color);
|
|
212
|
+
return;
|
|
213
|
+
case "diamond":
|
|
214
|
+
polygon([
|
|
215
|
+
[8, 1],
|
|
216
|
+
[15, 8],
|
|
217
|
+
[8, 15],
|
|
218
|
+
[1, 8],
|
|
219
|
+
]);
|
|
220
|
+
fillWith(icon.color);
|
|
221
|
+
return;
|
|
222
|
+
case "triangleUp":
|
|
223
|
+
polygon([
|
|
224
|
+
[8, 2],
|
|
225
|
+
[15, 14],
|
|
226
|
+
[1, 14],
|
|
227
|
+
]);
|
|
228
|
+
fillWith(icon.color);
|
|
229
|
+
return;
|
|
230
|
+
case "triangleDown":
|
|
231
|
+
polygon([
|
|
232
|
+
[1, 2],
|
|
233
|
+
[15, 2],
|
|
234
|
+
[8, 14],
|
|
235
|
+
]);
|
|
236
|
+
fillWith(icon.color);
|
|
237
|
+
return;
|
|
238
|
+
case "dash":
|
|
239
|
+
ctx.beginPath();
|
|
240
|
+
ctx.rect(px(2), py(6), 12 * k, 4 * k);
|
|
241
|
+
ctx.closePath();
|
|
242
|
+
fillWith(icon.color);
|
|
243
|
+
return;
|
|
244
|
+
case "symbol":
|
|
245
|
+
disc(7.5);
|
|
246
|
+
fillWith(icon.color);
|
|
247
|
+
glyph(icon.glyph, "#FFFFFF", 2);
|
|
248
|
+
return;
|
|
249
|
+
case "symbolPlain":
|
|
250
|
+
glyph(icon.glyph, icon.color, 2.6);
|
|
251
|
+
return;
|
|
252
|
+
case "star":
|
|
253
|
+
if (icon.fill > 0) {
|
|
254
|
+
ctx.save();
|
|
255
|
+
if (icon.fill < 1) {
|
|
256
|
+
ctx.beginPath();
|
|
257
|
+
ctx.rect(px(0), py(0), 8 * k, 16 * k);
|
|
258
|
+
ctx.clip();
|
|
259
|
+
}
|
|
260
|
+
polygon(STAR_POINTS);
|
|
261
|
+
fillWith(GOLD);
|
|
262
|
+
ctx.restore();
|
|
263
|
+
}
|
|
264
|
+
polygon(STAR_POINTS);
|
|
265
|
+
strokeWith(GOLD, 1);
|
|
266
|
+
return;
|
|
267
|
+
case "rating":
|
|
268
|
+
for (let bar = 0; bar < 4; bar++) {
|
|
269
|
+
const height = 4 + bar * 3.5;
|
|
270
|
+
ctx.beginPath();
|
|
271
|
+
ctx.rect(px(1 + bar * 3.75), py(15 - height), 2.75 * k, height * k);
|
|
272
|
+
ctx.closePath();
|
|
273
|
+
fillWith(bar < icon.filled ? BLUE : EMPTY);
|
|
274
|
+
}
|
|
275
|
+
return;
|
|
276
|
+
case "quarters":
|
|
277
|
+
disc(7);
|
|
278
|
+
fillWith("#FFFFFF");
|
|
279
|
+
if (icon.filled > 0) {
|
|
280
|
+
ctx.beginPath();
|
|
281
|
+
ctx.moveTo(px(8), py(8));
|
|
282
|
+
ctx.arc(px(8), py(8), 7 * k, -Math.PI / 2, -Math.PI / 2 + (icon.filled / 4) * Math.PI * 2);
|
|
283
|
+
ctx.closePath();
|
|
284
|
+
fillWith(BLACK);
|
|
285
|
+
}
|
|
286
|
+
disc(7);
|
|
287
|
+
strokeWith(BLACK, 1);
|
|
288
|
+
return;
|
|
289
|
+
case "boxes": {
|
|
290
|
+
// Quadrants fill clockwise from the top-left.
|
|
291
|
+
const cells = [
|
|
292
|
+
[1.5, 1.5],
|
|
293
|
+
[8.5, 1.5],
|
|
294
|
+
[8.5, 8.5],
|
|
295
|
+
[1.5, 8.5],
|
|
296
|
+
];
|
|
297
|
+
cells.forEach(([u, v], i) => {
|
|
298
|
+
ctx.beginPath();
|
|
299
|
+
ctx.rect(px(u), py(v), 6 * k, 6 * k);
|
|
300
|
+
ctx.closePath();
|
|
301
|
+
fillWith(i < icon.filled ? BLUE : EMPTY);
|
|
302
|
+
});
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
};
|
|
@@ -1,7 +1,93 @@
|
|
|
1
|
-
import type { CfThreshold, IconSetFamily } from "../types";
|
|
1
|
+
import type { CellFormat, CfThreshold, ConditionalFormatRule, IconSetFamily } from "../types";
|
|
2
2
|
export declare const ICON_SET_GLYPHS: Record<IconSetFamily, string[]>;
|
|
3
|
+
/** The colour each icon is painted in — what text stand-ins use. */
|
|
3
4
|
export declare const ICON_SET_COLORS: Record<IconSetFamily, string[]>;
|
|
4
|
-
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Numeric statistics of a rule's covered cells — what cfvo thresholds
|
|
7
|
+
* resolve against. `sorted` (ascending) backs PERCENTILE thresholds; it may
|
|
8
|
+
* be omitted when the caller already knows the rule needs no percentile.
|
|
9
|
+
*/
|
|
10
|
+
export type CfRangeStats = {
|
|
11
|
+
count: number;
|
|
12
|
+
min: number;
|
|
13
|
+
max: number;
|
|
14
|
+
sorted?: number[];
|
|
15
|
+
/**
|
|
16
|
+
* Engine-backed stand-ins for `sorted` on windowed hosts: PERCENTILE.INC
|
|
17
|
+
* at `p` (0..100), the k-th largest / smallest value (`k` a percent of the
|
|
18
|
+
* count when `percent`), the mean and the sample standard deviation.
|
|
19
|
+
*/
|
|
20
|
+
percentile?: (p: number) => number;
|
|
21
|
+
rankValue?: (k: number, top: boolean, percent?: boolean) => number;
|
|
22
|
+
mean?: number;
|
|
23
|
+
stdDev?: number;
|
|
24
|
+
};
|
|
25
|
+
/** What a rule needs from its full-range statistics (the engine request). */
|
|
26
|
+
export type CfRuleStatsRequest = {
|
|
27
|
+
percentiles: number[];
|
|
28
|
+
ranks: Array<{
|
|
29
|
+
k: number;
|
|
30
|
+
top: boolean;
|
|
31
|
+
percent?: boolean;
|
|
32
|
+
}>;
|
|
33
|
+
};
|
|
34
|
+
/** The engine's reply to a {@link CfRuleStatsRequest} (`conditionalFormatRuleStats`). */
|
|
35
|
+
export type CfRuleStatsResponse = {
|
|
36
|
+
count: number;
|
|
37
|
+
min: number | null;
|
|
38
|
+
max: number | null;
|
|
39
|
+
mean: number | null;
|
|
40
|
+
stdDev: number | null;
|
|
41
|
+
percentiles: Array<number | null>;
|
|
42
|
+
ranks: Array<number | null>;
|
|
43
|
+
};
|
|
44
|
+
/** The percentiles / ranks a rule's thresholds resolve with. */
|
|
45
|
+
export declare const buildCfRuleStatsRequest: (rule: ConditionalFormatRule) => CfRuleStatsRequest;
|
|
46
|
+
/**
|
|
47
|
+
* Turn the engine's reply into {@link CfRangeStats} for the CF hook — what a
|
|
48
|
+
* windowed host returns from `getConditionalFormatRuleStats`.
|
|
49
|
+
*/
|
|
50
|
+
export declare const toCfRangeStats: (request: CfRuleStatsRequest, response: CfRuleStatsResponse | null | undefined) => CfRangeStats | undefined;
|
|
51
|
+
export declare const buildCfRangeStats: (values: number[]) => CfRangeStats;
|
|
52
|
+
/** Excel's PERCENTILE.INC over ascending values (`p` in 0..100). */
|
|
53
|
+
export declare const percentileInc: (sorted: number[], p: number) => number;
|
|
54
|
+
/**
|
|
55
|
+
* Resolves a FORMULA threshold's text (e.g. `=$B$1`, `=10`) to a number,
|
|
56
|
+
* or `undefined` when it can't be evaluated.
|
|
57
|
+
*/
|
|
58
|
+
export type CfFormulaResolver = (formula: string) => number | undefined;
|
|
59
|
+
/**
|
|
60
|
+
* Resolve a cfvo threshold against the rule's range statistics (OOXML cfvo
|
|
61
|
+
* semantics). `role` picks the AUTOMATIC bound (data bars only): the lower
|
|
62
|
+
* bound is `min(0, lowest)`, the upper `max(0, highest)`. Returns NaN when
|
|
63
|
+
* the threshold can't be resolved.
|
|
64
|
+
*/
|
|
65
|
+
export declare const resolveCfThreshold: (threshold: CfThreshold, stats: CfRangeStats, options?: {
|
|
66
|
+
role?: "min" | "max";
|
|
67
|
+
resolveFormula?: CfFormulaResolver;
|
|
68
|
+
}) => number;
|
|
69
|
+
export declare const resolveThreshold: (threshold: CfThreshold, rangeMin: number, rangeMax: number, sorted?: number[]) => number;
|
|
70
|
+
export declare const pickIconBucket: (value: number, thresholds: number[], strict?: boolean[]) => number;
|
|
6
71
|
export declare const computeDataBarFill: (value: number, min: number, max: number) => number;
|
|
72
|
+
/**
|
|
73
|
+
* Whether a cell counts as a number for data bars, colour scales, icon sets
|
|
74
|
+
* and the other numeric rules: its computed value is a number (Excel's rule —
|
|
75
|
+
* a typed `1` or a spilled `=SEQUENCE(3)` value qualifies without any number
|
|
76
|
+
* format), or it carries a number format (the legacy store's signal).
|
|
77
|
+
*/
|
|
78
|
+
export declare const isConditionalFormatNumberCell: (effectiveValue: Record<string, any> | null | undefined, cellFormat: CellFormat | null | undefined) => boolean;
|
|
79
|
+
/**
|
|
80
|
+
* The comparison bound of an above / below average rule: the mean, moved
|
|
81
|
+
* `stdDev` sample standard deviations (Excel's STDEV) above or below it for
|
|
82
|
+
* the "1/2/3 std dev above / below" options. Mirrors the engine's
|
|
83
|
+
* `average_bound` (rnc-store `derive.rs`).
|
|
84
|
+
*/
|
|
85
|
+
export declare const averageBound: (values: number[], above: boolean, stdDev?: number | null) => number;
|
|
86
|
+
/**
|
|
87
|
+
* Whether a CSS colour (`#rrggbb` / `rgb()`) is dark — relative luminance
|
|
88
|
+
* under 0.5. Unparseable colours count as light.
|
|
89
|
+
*/
|
|
90
|
+
export declare const isDarkCssColor: (color: string | null | undefined) => boolean;
|
|
91
|
+
/** {@link averageBound} from full-range statistics (sorted values or the engine's mean / std dev). */
|
|
92
|
+
export declare const averageBoundFromStats: (stats: CfRangeStats, above: boolean, stdDev?: number | null) => number | undefined;
|
|
7
93
|
//# sourceMappingURL=cf-overlays.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cf-overlays.d.ts","sourceRoot":"","sources":["../../../api/cf-overlays.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cf-overlays.d.ts","sourceRoot":"","sources":["../../../api/cf-overlays.ts"],"names":[],"mappings":"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"}
|