@jackens/nnn 2024.3.5 → 2024.3.31
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/nnn.d.ts +14 -50
- package/nnn.js +9 -155
- package/package.json +1 -4
- package/readme.md +16 -95
package/nnn.d.ts
CHANGED
|
@@ -1,40 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
3
|
-
*
|
|
4
|
-
* Options:
|
|
5
|
-
* - `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
|
|
6
|
-
* - `headerColumn`: flag indicating that `table` has a header column with X axis labels
|
|
7
|
-
* - `xGap`: X axis spacing
|
|
8
|
-
* - `xLabelsMinHeight`: minimal height of X axis labels
|
|
9
|
-
* - `xLabelsRotate`: flag to rotate X axis labels
|
|
10
|
-
* - `xReverse`: flag to reverse all data series
|
|
11
|
-
* - `yGap`: Y axis spacing
|
|
12
|
-
* - `yLabelsLeftMinWidth`: minimal width of Y axis left labels
|
|
13
|
-
* - `yLabelsRightMinWidth`: minimal width of Y axis right labels
|
|
14
|
-
* - `yMax`: number of Y axis lines
|
|
15
|
-
* - `zLabelsMinWidth`: minimal width of data series labels
|
|
16
|
-
* - `zyMappings`: mappings per data series
|
|
17
|
-
*/
|
|
18
|
-
export declare const chartable: ({ table, headerColumn, xGap, xLabelsMinHeight, xLabelsRotate, xReverse, yGap, yLabelsLeftMinWidth, yLabelsRightMinWidth, yMax, zLabelsMinWidth, zyMappings }: {
|
|
19
|
-
table: HTMLTableElement;
|
|
20
|
-
headerColumn?: boolean | undefined;
|
|
21
|
-
xGap?: number | undefined;
|
|
22
|
-
xLabelsMinHeight?: number | undefined;
|
|
23
|
-
xLabelsRotate?: boolean | undefined;
|
|
24
|
-
xReverse?: boolean | undefined;
|
|
25
|
-
yGap?: number | undefined;
|
|
26
|
-
yLabelsLeftMinWidth?: number | undefined;
|
|
27
|
-
yLabelsRightMinWidth?: number | undefined;
|
|
28
|
-
yMax?: number | undefined;
|
|
29
|
-
zLabelsMinWidth?: number | undefined;
|
|
30
|
-
zyMappings?: [(label: string) => number, (value: number) => string][] | undefined;
|
|
31
|
-
}) => SVGSVGElement;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* A helper that checks equality of the given arguments.
|
|
35
|
-
*/
|
|
36
|
-
export declare const eq: (x: any, y: any) => boolean;
|
|
37
|
-
|
|
38
1
|
/**
|
|
39
2
|
* The type of arguments of the `escapeValues` and `escape` helpers.
|
|
40
3
|
*/
|
|
@@ -43,12 +6,12 @@ export type EscapeMap = Map<any, (value?: any) => string>;
|
|
|
43
6
|
/**
|
|
44
7
|
* A generic helper for escaping `values` by given `escapeMap`.
|
|
45
8
|
*/
|
|
46
|
-
export declare const escapeValues: (escapeMap: EscapeMap, values: any
|
|
9
|
+
export declare const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<any>>) => Partial<Array<string>>;
|
|
47
10
|
|
|
48
11
|
/**
|
|
49
12
|
* A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
50
13
|
*/
|
|
51
|
-
export declare const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: any
|
|
14
|
+
export declare const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<any>>) => string;
|
|
52
15
|
|
|
53
16
|
/**
|
|
54
17
|
* A helper that implements typographic corrections specific to Polish typography.
|
|
@@ -81,9 +44,9 @@ export type HArgs = [string | Node, ...HArgs1[]];
|
|
|
81
44
|
* - All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or modified.
|
|
82
45
|
*/
|
|
83
46
|
export declare const h: {
|
|
84
|
-
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1
|
|
85
|
-
<N extends Node>(node: N, ...args1: HArgs1
|
|
86
|
-
(tagOrNode: string | Node, ...args1: HArgs1
|
|
47
|
+
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): HTMLElementTagNameMap[T];
|
|
48
|
+
<N extends Node>(node: N, ...args1: Partial<Array<HArgs1>>): N;
|
|
49
|
+
(tagOrNode: string | Node, ...args1: Partial<Array<HArgs1>>): Node;
|
|
87
50
|
};
|
|
88
51
|
|
|
89
52
|
/**
|
|
@@ -102,15 +65,15 @@ export declare const h: {
|
|
|
102
65
|
* - All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or modified.
|
|
103
66
|
*/
|
|
104
67
|
export declare const s: {
|
|
105
|
-
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: HArgs1
|
|
106
|
-
<N extends Node>(node: N, ...args1: HArgs1
|
|
107
|
-
(tagOrNode: string | Node, ...args1: HArgs1
|
|
68
|
+
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): SVGElementTagNameMap[T];
|
|
69
|
+
<N extends Node>(node: N, ...args1: Partial<Array<HArgs1>>): N;
|
|
70
|
+
(tagOrNode: string | Node, ...args1: Partial<Array<HArgs1>>): Node;
|
|
108
71
|
};
|
|
109
72
|
|
|
110
73
|
/**
|
|
111
74
|
* A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
112
75
|
*/
|
|
113
|
-
export declare const svgUse: (id: string, ...args: HArgs1
|
|
76
|
+
export declare const svgUse: (id: string, ...args: Partial<Array<HArgs1>>) => SVGSVGElement;
|
|
114
77
|
|
|
115
78
|
/**
|
|
116
79
|
* A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
|
|
@@ -121,6 +84,7 @@ export declare const has: (key: any, ref: any) => boolean;
|
|
|
121
84
|
* A helper that checks if the given argument is of a certain type.
|
|
122
85
|
*/
|
|
123
86
|
export declare const is: {
|
|
87
|
+
(type: ArrayConstructor, arg: any): arg is Partial<Array<any>>;
|
|
124
88
|
(type: BigIntConstructor, arg: any): arg is bigint;
|
|
125
89
|
(type: BooleanConstructor, arg: any): arg is boolean;
|
|
126
90
|
(type: NumberConstructor, arg: any): arg is number;
|
|
@@ -128,7 +92,7 @@ export declare const is: {
|
|
|
128
92
|
(type: StringConstructor, arg: any): arg is string;
|
|
129
93
|
(type: SymbolConstructor, arg: any): arg is symbol;
|
|
130
94
|
(type: undefined, arg: any): arg is undefined | null;
|
|
131
|
-
<T extends abstract new (...args: any
|
|
95
|
+
<T extends abstract new (...args: Partial<Array<any>>) => any>(type: T, arg: any): arg is InstanceType<T>;
|
|
132
96
|
};
|
|
133
97
|
|
|
134
98
|
/**
|
|
@@ -191,12 +155,12 @@ export declare const nanolightJs: (code: string) => HArgs1[];
|
|
|
191
155
|
/**
|
|
192
156
|
* A helper that implements TypeScript’s `Pick` utility type.
|
|
193
157
|
*/
|
|
194
|
-
export declare const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: any
|
|
158
|
+
export declare const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Pick<T, K[number]>;
|
|
195
159
|
|
|
196
160
|
/**
|
|
197
161
|
* A helper that implements TypeScript’s `Omit` utility type.
|
|
198
162
|
*/
|
|
199
|
-
export declare const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: any
|
|
163
|
+
export declare const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Omit<T, K[number]>;
|
|
200
164
|
|
|
201
165
|
/**
|
|
202
166
|
* A helper for choosing the correct singular and plural.
|
|
@@ -213,7 +177,7 @@ export declare const pro: (ref: any) => any;
|
|
|
213
177
|
*
|
|
214
178
|
* It returns an array of triples: `[«name», «prototype-name», «array-of-own-property-names»]`.
|
|
215
179
|
*/
|
|
216
|
-
export declare const refsInfo: (...refs: any
|
|
180
|
+
export declare const refsInfo: (...refs: Partial<Array<any>>) => [string, string, (string | undefined)[]][];
|
|
217
181
|
|
|
218
182
|
/**
|
|
219
183
|
* A helper that generates a UUID v1 identifier (with a creation timestamp).
|
package/nnn.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
// src/nnn/escape.ts
|
|
2
|
+
var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? "");
|
|
3
|
+
var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
|
|
4
|
+
|
|
1
5
|
// src/nnn/is.ts
|
|
2
6
|
var is = (type, arg) => arg?.constructor === type;
|
|
3
7
|
|
|
@@ -66,156 +70,6 @@ var h = _h();
|
|
|
66
70
|
var s = _h("http://www.w3.org/2000/svg");
|
|
67
71
|
var svgUse = (id, ...args) => s("svg", ["use", { "xlink:href": "#" + id }], ...args);
|
|
68
72
|
|
|
69
|
-
// src/nnn/chartable.ts
|
|
70
|
-
var COLORS = ["#e22", "#e73", "#fc3", "#ad4", "#4d9", "#3be", "#45d", "#c3e"];
|
|
71
|
-
var PADDING = 15;
|
|
72
|
-
var _svg = s("svg", { viewBox: "0 0 0 0", width: 0, height: 0 });
|
|
73
|
-
h(document.body, ["div", { $style: { width: 0, height: 0 } }, _svg]);
|
|
74
|
-
var toFixed2 = (value) => value.toFixed(2);
|
|
75
|
-
var chartable = ({
|
|
76
|
-
table,
|
|
77
|
-
headerColumn = false,
|
|
78
|
-
xGap = 70,
|
|
79
|
-
xLabelsMinHeight = 0,
|
|
80
|
-
xLabelsRotate = false,
|
|
81
|
-
xReverse = false,
|
|
82
|
-
yGap = 30,
|
|
83
|
-
yLabelsLeftMinWidth = 100,
|
|
84
|
-
yLabelsRightMinWidth = 100,
|
|
85
|
-
yMax = 10,
|
|
86
|
-
zLabelsMinWidth = 0,
|
|
87
|
-
zyMappings = []
|
|
88
|
-
}) => {
|
|
89
|
-
const zxValues = [];
|
|
90
|
-
const xLabels = [];
|
|
91
|
-
const zLabels = [];
|
|
92
|
-
table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col, c) => {
|
|
93
|
-
const x = r - 1;
|
|
94
|
-
const z = c - +headerColumn;
|
|
95
|
-
const value = col.innerText;
|
|
96
|
-
if (x >= 0 && z >= 0) {
|
|
97
|
-
zxValues[z] = zxValues[z] ?? [];
|
|
98
|
-
zxValues[z][x] = (zyMappings?.[z]?.[0] ?? parseFloat)(value);
|
|
99
|
-
} else if (x >= 0 && z < 0) {
|
|
100
|
-
xLabels[x] = value;
|
|
101
|
-
} else if (x < 0 && z >= 0) {
|
|
102
|
-
zLabels[z] = value;
|
|
103
|
-
}
|
|
104
|
-
}));
|
|
105
|
-
if (xReverse) {
|
|
106
|
-
xLabels.reverse();
|
|
107
|
-
zxValues.forEach((xValues) => xValues.reverse());
|
|
108
|
-
}
|
|
109
|
-
const xMax = zxValues[0].length;
|
|
110
|
-
const xPx = Array.from({ length: xMax }, (_, x) => x * xGap);
|
|
111
|
-
const yPx = Array.from({ length: yMax }, (_, y) => y * yGap);
|
|
112
|
-
const width = xGap * (xMax - 1);
|
|
113
|
-
const height = yGap * (yMax - 1);
|
|
114
|
-
const gGraph = s("g", ...yPx.map((px) => ["line", { x1: 0, x2: width, y1: px, y2: px, stroke: "#8888" }]), ...xPx.map((px) => ["line", { x1: px, x2: px, y1: 0, y2: height, stroke: "#8888" }]));
|
|
115
|
-
const gXLabels = s("g");
|
|
116
|
-
const gYLabelsL = zxValues.map((_) => s("g"));
|
|
117
|
-
const gYLabelsR = zxValues.map((_) => s("g"));
|
|
118
|
-
const gZColors = s("g");
|
|
119
|
-
const gZLabels = [];
|
|
120
|
-
const onclick = (z) => {
|
|
121
|
-
gYLabelsL.forEach((g, z2) => s(g, { $style: { display: z2 === z ? "block" : "none" } }));
|
|
122
|
-
gYLabelsR.forEach((g, z2) => s(g, { $style: { display: z2 === z ? "block" : "none" } }));
|
|
123
|
-
gZLabels.forEach((text, z2) => s(text, { $style: { fontWeight: z2 === z ? "bold" : "normal", cursor: "pointer" } }));
|
|
124
|
-
};
|
|
125
|
-
zxValues.forEach((values, z) => {
|
|
126
|
-
const fill = COLORS[z % COLORS.length];
|
|
127
|
-
const minValue = Math.min(...values.filter((value) => !isNaN(value)));
|
|
128
|
-
const maxValue = Math.max(...values.filter((value) => !isNaN(value)));
|
|
129
|
-
yPx.forEach((yp, y) => {
|
|
130
|
-
const value = (zyMappings?.[z]?.[1] ?? toFixed2)(maxValue - (maxValue - minValue) / yMax * (y + 1));
|
|
131
|
-
const textL = s("text", { x: 0, y: yp, "text-anchor": "end", "alignment-baseline": "middle" }, value);
|
|
132
|
-
const textR = s("text", { x: 0, y: yp, "text-anchor": "start", "alignment-baseline": "middle" }, value);
|
|
133
|
-
s(_svg, textL, textR);
|
|
134
|
-
yLabelsLeftMinWidth = Math.max(yLabelsLeftMinWidth, textL.getBBox().width);
|
|
135
|
-
yLabelsRightMinWidth = Math.max(yLabelsRightMinWidth, textR.getBBox().width);
|
|
136
|
-
s(gYLabelsL[z], textL);
|
|
137
|
-
s(gYLabelsR[z], textR);
|
|
138
|
-
});
|
|
139
|
-
const text = s("text", {
|
|
140
|
-
x: 0,
|
|
141
|
-
y: yGap * z,
|
|
142
|
-
"text-anchor": "start",
|
|
143
|
-
"alignment-baseline": "middle",
|
|
144
|
-
$onclick: () => onclick(z),
|
|
145
|
-
$style: { fontWeight: "bold" }
|
|
146
|
-
}, zLabels[z]);
|
|
147
|
-
s(_svg, text);
|
|
148
|
-
zLabelsMinWidth = Math.max(zLabelsMinWidth, text.getBBox().width);
|
|
149
|
-
gZLabels[z] = text;
|
|
150
|
-
s(gZColors, ["circle", { cx: 0, cy: yGap * z, r: 5, fill }]);
|
|
151
|
-
const valuesPx = values.map((value) => isNaN(value) ? value : height * (maxValue - value) / (maxValue - minValue));
|
|
152
|
-
xPx.forEach((px, x) => {
|
|
153
|
-
if (!isNaN(valuesPx[x])) {
|
|
154
|
-
s(gGraph, ["g", ["circle", { cx: px, cy: valuesPx[x], r: 5, fill }]]);
|
|
155
|
-
if (!isNaN(valuesPx[x - 1])) {
|
|
156
|
-
s(gGraph, ["line", { x1: px, x2: xPx[x - 1], y1: valuesPx[x], y2: valuesPx[x - 1], stroke: fill }]);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
if (xLabels.length > 0) {
|
|
162
|
-
xPx.forEach((xp, x) => {
|
|
163
|
-
const text = s("text", xLabelsRotate ? { x: 0, y: -xp, "text-anchor": "start", "alignment-baseline": "middle", transform: "rotate(90)" } : { x: xp, y: PADDING, "text-anchor": "middle", "alignment-baseline": "middle" }, xLabels[x]);
|
|
164
|
-
s(_svg, text);
|
|
165
|
-
xLabelsMinHeight = Math.max(xLabelsMinHeight, xLabelsRotate ? text.getBBox().width : text.getBBox().height);
|
|
166
|
-
s(gXLabels, text);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
const svgW = width + yLabelsLeftMinWidth + yLabelsRightMinWidth + zLabelsMinWidth + 4 * PADDING;
|
|
170
|
-
const svgH = height + xLabelsMinHeight + (xLabels.length > 0 ? 3 : 2) * PADDING;
|
|
171
|
-
s(gGraph, { transform: `translate(${yLabelsLeftMinWidth + PADDING} ${PADDING})` });
|
|
172
|
-
gYLabelsL.forEach((g) => s(g, { transform: `translate(${yLabelsLeftMinWidth} ${PADDING})` }));
|
|
173
|
-
gYLabelsR.forEach((g) => s(g, { transform: `translate(${width + yLabelsLeftMinWidth + 2 * PADDING} ${PADDING})` }));
|
|
174
|
-
s(gZColors, { transform: `translate(${width + yLabelsLeftMinWidth + yLabelsRightMinWidth + 3 * PADDING} ${PADDING})` });
|
|
175
|
-
s(gXLabels, { transform: `translate(${yLabelsLeftMinWidth + PADDING} ${height + 2 * PADDING})` });
|
|
176
|
-
onclick(0);
|
|
177
|
-
return s("svg", { viewBox: `0 0 ${svgW} ${svgH}`, width: `${svgW}px`, height: `${svgH}px`, class: "chartable" }, gGraph, gXLabels, ...gYLabelsL, ...gYLabelsR, gZColors, ["g", { transform: `translate(${width + yLabelsLeftMinWidth + yLabelsRightMinWidth + 4 * PADDING} ${PADDING})` }, ...gZLabels]);
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
// src/nnn/eq.ts
|
|
181
|
-
var eq = (x, y) => {
|
|
182
|
-
if (x === y) {
|
|
183
|
-
return true;
|
|
184
|
-
}
|
|
185
|
-
const xConstructor = x?.constructor;
|
|
186
|
-
if (xConstructor === y?.constructor) {
|
|
187
|
-
if (xConstructor === Number) {
|
|
188
|
-
return isNaN(x) && isNaN(y) || +x === +y;
|
|
189
|
-
}
|
|
190
|
-
if (xConstructor === Date) {
|
|
191
|
-
return +x === +y;
|
|
192
|
-
}
|
|
193
|
-
if (xConstructor === String || xConstructor === RegExp) {
|
|
194
|
-
return "" + x === "" + y;
|
|
195
|
-
}
|
|
196
|
-
if (xConstructor === Array) {
|
|
197
|
-
return x.length === y.length && x.every((item, index) => eq(item, y[index]));
|
|
198
|
-
}
|
|
199
|
-
if (xConstructor === Object) {
|
|
200
|
-
const keysOfX = Object.keys(x);
|
|
201
|
-
return keysOfX.length === Object.keys(y).length && keysOfX.every((key) => eq(x[key], y[key]));
|
|
202
|
-
}
|
|
203
|
-
if (xConstructor === Set || xConstructor === Map) {
|
|
204
|
-
if (x.size !== y.size) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
const xa = [...x];
|
|
208
|
-
const ya = [...y];
|
|
209
|
-
return xa.every((xv) => ya.find((yv) => eq(xv, yv)));
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
return false;
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
// src/nnn/escape.ts
|
|
216
|
-
var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? "");
|
|
217
|
-
var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
|
|
218
|
-
|
|
219
73
|
// src/nnn/fixTypography.ts
|
|
220
74
|
var TAGS_TO_SKIP = ["IFRAME", "NOSCRIPT", "PRE", "SCRIPT", "STYLE", "TEXTAREA"];
|
|
221
75
|
var fixTypography = (node) => {
|
|
@@ -314,8 +168,10 @@ var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
|
314
168
|
}
|
|
315
169
|
isSecondKey = true;
|
|
316
170
|
}
|
|
317
|
-
|
|
318
|
-
|
|
171
|
+
const handler = handlers[key];
|
|
172
|
+
const params = value[key];
|
|
173
|
+
if (is(Function, handler) && is(Array, params)) {
|
|
174
|
+
return handler(...params);
|
|
319
175
|
}
|
|
320
176
|
}
|
|
321
177
|
return value;
|
|
@@ -416,7 +272,5 @@ export {
|
|
|
416
272
|
h,
|
|
417
273
|
fixTypography,
|
|
418
274
|
escapeValues,
|
|
419
|
-
escape
|
|
420
|
-
eq,
|
|
421
|
-
chartable
|
|
275
|
+
escape
|
|
422
276
|
};
|
package/package.json
CHANGED
|
@@ -3,9 +3,6 @@
|
|
|
3
3
|
"description": "Jackens’ JavaScript helpers.",
|
|
4
4
|
"homepage": "https://jackens.github.io/nnn/doc/",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"chart",
|
|
7
|
-
"chartable",
|
|
8
|
-
"charts",
|
|
9
6
|
"CSS-in-JS",
|
|
10
7
|
"deepEqual",
|
|
11
8
|
"DOM",
|
|
@@ -43,5 +40,5 @@
|
|
|
43
40
|
"types": "nnn.d.ts",
|
|
44
41
|
"name": "@jackens/nnn",
|
|
45
42
|
"type": "module",
|
|
46
|
-
"version": "2024.3.
|
|
43
|
+
"version": "2024.3.31"
|
|
47
44
|
}
|
package/readme.md
CHANGED
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
Jackens’ JavaScript helpers.
|
|
4
4
|
|
|
5
|
-
<sub>Version: <code class="version">2024.3.
|
|
5
|
+
<sub>Version: <code class="version">2024.3.31</code></sub>
|
|
6
6
|
|
|
7
7
|
## Examples
|
|
8
8
|
|
|
9
|
-
- [Chartable Demo](https://jackens.github.io/nnn/chartable/)
|
|
10
9
|
- [Chessboard Demo](https://jackens.github.io/nnn/chessboard/)
|
|
11
10
|
- [Documentation](https://jackens.github.io/nnn/doc/)
|
|
12
11
|
- [Gant Chart Demo](https://jackens.github.io/nnn/gantt/)
|
|
@@ -45,8 +44,6 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
45
44
|
- `HArgs1`: The type of arguments of the `h` and `s` helpers.
|
|
46
45
|
- `JcNode`: The type of arguments of the `jc` helper.
|
|
47
46
|
- `JcRoot`: The type of arguments of the `jc` helper.
|
|
48
|
-
- `chartable`: A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
49
|
-
- `eq`: A helper that checks equality of the given arguments.
|
|
50
47
|
- `escape`: A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
51
48
|
- `escapeValues`: A generic helper for escaping `values` by given `escapeMap`.
|
|
52
49
|
- `fixTypography`: A helper that implements typographic corrections specific to Polish typography.
|
|
@@ -109,87 +106,10 @@ type JcRoot = Partial<Record<PropertyKey, JcNode>>;
|
|
|
109
106
|
|
|
110
107
|
The type of arguments of the `jc` helper.
|
|
111
108
|
|
|
112
|
-
### chartable
|
|
113
|
-
|
|
114
|
-
```ts
|
|
115
|
-
const chartable: ({ table, headerColumn, xGap, xLabelsMinHeight, xLabelsRotate, xReverse, yGap, yLabelsLeftMinWidth, yLabelsRightMinWidth, yMax, zLabelsMinWidth, zyMappings }: {
|
|
116
|
-
table: HTMLTableElement;
|
|
117
|
-
headerColumn?: boolean | undefined;
|
|
118
|
-
xGap?: number | undefined;
|
|
119
|
-
xLabelsMinHeight?: number | undefined;
|
|
120
|
-
xLabelsRotate?: boolean | undefined;
|
|
121
|
-
xReverse?: boolean | undefined;
|
|
122
|
-
yGap?: number | undefined;
|
|
123
|
-
yLabelsLeftMinWidth?: number | undefined;
|
|
124
|
-
yLabelsRightMinWidth?: number | undefined;
|
|
125
|
-
yMax?: number | undefined;
|
|
126
|
-
zLabelsMinWidth?: number | undefined;
|
|
127
|
-
zyMappings?: [(label: string) => number, (value: number) => string][] | undefined;
|
|
128
|
-
}) => SVGSVGElement;
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
|
|
132
|
-
|
|
133
|
-
Options:
|
|
134
|
-
- `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
|
|
135
|
-
- `headerColumn`: flag indicating that `table` has a header column with X axis labels
|
|
136
|
-
- `xGap`: X axis spacing
|
|
137
|
-
- `xLabelsMinHeight`: minimal height of X axis labels
|
|
138
|
-
- `xLabelsRotate`: flag to rotate X axis labels
|
|
139
|
-
- `xReverse`: flag to reverse all data series
|
|
140
|
-
- `yGap`: Y axis spacing
|
|
141
|
-
- `yLabelsLeftMinWidth`: minimal width of Y axis left labels
|
|
142
|
-
- `yLabelsRightMinWidth`: minimal width of Y axis right labels
|
|
143
|
-
- `yMax`: number of Y axis lines
|
|
144
|
-
- `zLabelsMinWidth`: minimal width of data series labels
|
|
145
|
-
- `zyMappings`: mappings per data series
|
|
146
|
-
|
|
147
|
-
### eq
|
|
148
|
-
|
|
149
|
-
```ts
|
|
150
|
-
const eq: (x: any, y: any) => boolean;
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
A helper that checks equality of the given arguments.
|
|
154
|
-
|
|
155
|
-
#### Usage Examples
|
|
156
|
-
|
|
157
|
-
```js
|
|
158
|
-
expect(eq(true, true)).toBeTrue()
|
|
159
|
-
expect(eq(NaN, NaN)).toBeTrue()
|
|
160
|
-
expect(eq(null, undefined)).toBeFalse()
|
|
161
|
-
expect(eq(42, 42)).toBeTrue()
|
|
162
|
-
expect(eq(42, new Number(42))).toBeTrue()
|
|
163
|
-
expect(eq(42, Number(42))).toBeTrue()
|
|
164
|
-
expect(eq(new Number(42), Number(42))).toBeTrue()
|
|
165
|
-
expect(eq(42, '42')).toBeFalse()
|
|
166
|
-
expect(eq('42', '42')).toBeTrue()
|
|
167
|
-
expect(eq('42', new String('42'))).toBeTrue()
|
|
168
|
-
expect(eq('42', String('42'))).toBeTrue()
|
|
169
|
-
expect(eq(String('42'), new String('42'))).toBeTrue()
|
|
170
|
-
expect(eq(/42/, /42/)).toBeTrue()
|
|
171
|
-
expect(eq(/42/, /42/g)).toBeFalse()
|
|
172
|
-
expect(eq(new Date(42), new Date(42))).toBeTrue()
|
|
173
|
-
expect(eq(new Date(), new Date(42))).toBeFalse()
|
|
174
|
-
expect(eq({ j: '42', c: 42 }, { c: 42, j: '42' })).toBeTrue()
|
|
175
|
-
expect(eq([42, '42'], [42, '42'])).toBeTrue()
|
|
176
|
-
expect(eq(new Set(['42', 42]), new Set([42, '42']))).toBeTrue()
|
|
177
|
-
expect(eq(new Set(['42', 42]), new Set([42]))).toBeFalse()
|
|
178
|
-
expect(eq(new Set([42, undefined]), new Set([42]))).toBeFalse()
|
|
179
|
-
expect(eq(
|
|
180
|
-
new Map([[{ j: 42 }, { J: '42' }], [{ c: 42 }, { C: '42' }]]),
|
|
181
|
-
new Map([[{ c: 42 }, { C: '42' }], [{ j: 42 }, { J: '42' }]])
|
|
182
|
-
)).toBeTrue()
|
|
183
|
-
expect(eq(
|
|
184
|
-
new Map([[{ j: 42 }, { J: '42' }], [{ c: 42 }, { C: '42' }]]),
|
|
185
|
-
new Map([[{ j: '42' }, { J: 42 }], [{ c: '42' }, { C: 42 }]])
|
|
186
|
-
)).toBeFalse()
|
|
187
|
-
```
|
|
188
|
-
|
|
189
109
|
### escape
|
|
190
110
|
|
|
191
111
|
```ts
|
|
192
|
-
const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: any
|
|
112
|
+
const escape: (escapeMap: EscapeMap, template: TemplateStringsArray, ...values: Partial<Array<any>>) => string;
|
|
193
113
|
```
|
|
194
114
|
|
|
195
115
|
A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
@@ -199,7 +119,7 @@ A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings
|
|
|
199
119
|
```js
|
|
200
120
|
const escapeMap: EscapeMap = new Map([
|
|
201
121
|
[undefined, () => 'NULL'],
|
|
202
|
-
[Array, (values: any
|
|
122
|
+
[Array, (values: Partial<Array<any>>) => escapeValues(escapeMap, values).join(', ')],
|
|
203
123
|
[Boolean, (value: boolean) => `b'${+value}'`],
|
|
204
124
|
[Date, (value: Date) => `'${value.toISOString().replace(/^(.+)T(.+)\..*$/, '$1 $2')}'`],
|
|
205
125
|
[Number, (value: number) => `${value}`],
|
|
@@ -224,7 +144,7 @@ expect(actual).toStrictEqual(expected)
|
|
|
224
144
|
### escapeValues
|
|
225
145
|
|
|
226
146
|
```ts
|
|
227
|
-
const escapeValues: (escapeMap: EscapeMap, values: any
|
|
147
|
+
const escapeValues: (escapeMap: EscapeMap, values: Partial<Array<any>>) => Partial<Array<string>>;
|
|
228
148
|
```
|
|
229
149
|
|
|
230
150
|
A generic helper for escaping `values` by given `escapeMap`.
|
|
@@ -253,9 +173,9 @@ expect(p.innerHTML).toStrictEqual(
|
|
|
253
173
|
|
|
254
174
|
```ts
|
|
255
175
|
const h: {
|
|
256
|
-
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1
|
|
257
|
-
<N extends Node>(node: N, ...args1: HArgs1
|
|
258
|
-
(tagOrNode: string | Node, ...args1: HArgs1
|
|
176
|
+
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): HTMLElementTagNameMap[T];
|
|
177
|
+
<N extends Node>(node: N, ...args1: Partial<Array<HArgs1>>): N;
|
|
178
|
+
(tagOrNode: string | Node, ...args1: Partial<Array<HArgs1>>): Node;
|
|
259
179
|
};
|
|
260
180
|
```
|
|
261
181
|
|
|
@@ -384,6 +304,7 @@ expect(has('key', null)).toBeFalse()
|
|
|
384
304
|
|
|
385
305
|
```ts
|
|
386
306
|
const is: {
|
|
307
|
+
(type: ArrayConstructor, arg: any): arg is Partial<Array<any>>;
|
|
387
308
|
(type: BigIntConstructor, arg: any): arg is bigint;
|
|
388
309
|
(type: BooleanConstructor, arg: any): arg is boolean;
|
|
389
310
|
(type: NumberConstructor, arg: any): arg is number;
|
|
@@ -391,7 +312,7 @@ const is: {
|
|
|
391
312
|
(type: StringConstructor, arg: any): arg is string;
|
|
392
313
|
(type: SymbolConstructor, arg: any): arg is symbol;
|
|
393
314
|
(type: undefined, arg: any): arg is undefined | null;
|
|
394
|
-
<T extends abstract new (...args: any
|
|
315
|
+
<T extends abstract new (...args: Partial<Array<any>>) => any>(type: T, arg: any): arg is InstanceType<T>;
|
|
395
316
|
};
|
|
396
317
|
```
|
|
397
318
|
|
|
@@ -798,7 +719,7 @@ expect(nanolightJs(codeJs)).toStrictEqual([
|
|
|
798
719
|
### omit
|
|
799
720
|
|
|
800
721
|
```ts
|
|
801
|
-
const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: any
|
|
722
|
+
const omit: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Omit<T, K[number]>;
|
|
802
723
|
```
|
|
803
724
|
|
|
804
725
|
A helper that implements TypeScript’s `Omit` utility type.
|
|
@@ -814,7 +735,7 @@ expect(omit(obj, ['c'])).toStrictEqual({ a: 42, b: '42' })
|
|
|
814
735
|
### pick
|
|
815
736
|
|
|
816
737
|
```ts
|
|
817
|
-
const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: any
|
|
738
|
+
const pick: <T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: Partial<Record<PropertyKey, any>>, keys: Partial<Array<any>>) => Pick<T, K[number]>;
|
|
818
739
|
```
|
|
819
740
|
|
|
820
741
|
A helper that implements TypeScript’s `Pick` utility type.
|
|
@@ -894,7 +815,7 @@ expect(ref).toStrictEqual({ one: { two: { three: { four: 1234 } } } })
|
|
|
894
815
|
### refsInfo
|
|
895
816
|
|
|
896
817
|
```ts
|
|
897
|
-
const refsInfo: (...refs: any
|
|
818
|
+
const refsInfo: (...refs: Partial<Array<any>>) => [string, string, (string | undefined)[]][];
|
|
898
819
|
```
|
|
899
820
|
|
|
900
821
|
A helper that provides information about the given `refs`.
|
|
@@ -938,9 +859,9 @@ console.log(browserFingerprint())
|
|
|
938
859
|
|
|
939
860
|
```ts
|
|
940
861
|
const s: {
|
|
941
|
-
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: HArgs1
|
|
942
|
-
<N extends Node>(node: N, ...args1: HArgs1
|
|
943
|
-
(tagOrNode: string | Node, ...args1: HArgs1
|
|
862
|
+
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): SVGElementTagNameMap[T];
|
|
863
|
+
<N extends Node>(node: N, ...args1: Partial<Array<HArgs1>>): N;
|
|
864
|
+
(tagOrNode: string | Node, ...args1: Partial<Array<HArgs1>>): Node;
|
|
944
865
|
};
|
|
945
866
|
```
|
|
946
867
|
|
|
@@ -961,7 +882,7 @@ A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style help
|
|
|
961
882
|
### svgUse
|
|
962
883
|
|
|
963
884
|
```ts
|
|
964
|
-
const svgUse: (id: string, ...args: HArgs1
|
|
885
|
+
const svgUse: (id: string, ...args: Partial<Array<HArgs1>>) => SVGSVGElement;
|
|
965
886
|
```
|
|
966
887
|
|
|
967
888
|
A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|