@jackens/nnn 2024.2.19 → 2024.2.20

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/chartable.d.ts CHANGED
@@ -5,27 +5,29 @@
5
5
  * - `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
6
6
  * - `headerColumn`: flag indicating that `table` has a header column with X axis labels
7
7
  * - `xGap`: X axis spacing
8
- * - `xLabelsPx`:
8
+ * - `xLabelsMinHeight`: minimal height of X axis labels
9
9
  * - `xLabelsRotate`: flag to rotate X axis labels
10
10
  * - `xReverse`: flag to reverse all data series
11
11
  * - `yGap`: Y axis spacing
12
- * - `yLabelsLeftPx`:
13
- * - `yLabelsRightPx`:
12
+ * - `yLabelsLeftMinWidth`: minimal width of Y axis left labels
13
+ * - `yLabelsRightMinWidth`: minimal width of Y axis right labels
14
14
  * - `yMax`: number of Y axis lines
15
- * - `zLabelsPx`:
15
+ * - `zLabelsMinWidth`: minimal width of data series labels
16
+ * - `zyMappings`: mappings per data series
16
17
  */
17
- export function chartable({ table, headerColumn, xGap, xLabelsPx, xLabelsRotate, xReverse, yGap, yLabelsLeftPx, yLabelsRightPx, yMax, zLabelsPx }: {
18
+ export function chartable({ table, headerColumn, xGap, xLabelsMinHeight, xLabelsRotate, xReverse, yGap, yLabelsLeftMinWidth, yLabelsRightMinWidth, yMax, zLabelsMinWidth, zyMappings }: {
18
19
  table: HTMLTableElement;
19
- headerColumn?: boolean;
20
- xGap?: number;
21
- xLabelsPx?: number;
22
- xLabelsRotate?: boolean;
23
- xReverse?: boolean;
24
- yGap?: number;
25
- yLabelsLeftPx?: number;
26
- yLabelsRightPx?: number;
27
- yMax?: number;
28
- zLabelsPx?: number;
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;
29
31
  }): SVGSVGElement;
30
32
 
31
33
  export const tests: {};
package/chartable.js CHANGED
@@ -7,6 +7,8 @@ const _svg = s('svg', { viewBox: '0 0 0 0', width: 0, height: 0 })
7
7
 
8
8
  h(document.body, ['div', { $style: { width: 0, height: 0 } }, _svg])
9
9
 
10
+ const toFixed2 = (/** @type {number} */ value) => value.toFixed(2)
11
+
10
12
  /**
11
13
  * A helper for creating a chart based on a table (conf. <https://jackens.github.io/nnn/chartable/>).
12
14
  *
@@ -14,41 +16,44 @@ h(document.body, ['div', { $style: { width: 0, height: 0 } }, _svg])
14
16
  * - `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
15
17
  * - `headerColumn`: flag indicating that `table` has a header column with X axis labels
16
18
  * - `xGap`: X axis spacing
17
- * - `xLabelsPx`:
19
+ * - `xLabelsMinHeight`: minimal height of X axis labels
18
20
  * - `xLabelsRotate`: flag to rotate X axis labels
19
21
  * - `xReverse`: flag to reverse all data series
20
22
  * - `yGap`: Y axis spacing
21
- * - `yLabelsLeftPx`:
22
- * - `yLabelsRightPx`:
23
+ * - `yLabelsLeftMinWidth`: minimal width of Y axis left labels
24
+ * - `yLabelsRightMinWidth`: minimal width of Y axis right labels
23
25
  * - `yMax`: number of Y axis lines
24
- * - `zLabelsPx`:
26
+ * - `zLabelsMinWidth`: minimal width of data series labels
27
+ * - `zyMappings`: mappings per data series
25
28
  *
26
29
  * @param {{
27
30
  * table: HTMLTableElement;
28
31
  * headerColumn?: boolean;
29
32
  * xGap?: number;
30
- * xLabelsPx?: number;
33
+ * xLabelsMinHeight?: number;
31
34
  * xLabelsRotate?: boolean;
32
35
  * xReverse?: boolean;
33
36
  * yGap?: number;
34
- * yLabelsLeftPx?: number;
35
- * yLabelsRightPx?: number;
37
+ * yLabelsLeftMinWidth?: number;
38
+ * yLabelsRightMinWidth?: number;
36
39
  * yMax?: number;
37
- * zLabelsPx?: number;
40
+ * zLabelsMinWidth?: number;
41
+ * zyMappings?: [(label: string) => number, (value: number) => string][];
38
42
  * }} options
39
43
  */
40
44
  export const chartable = ({
41
45
  table,
42
46
  headerColumn = false,
43
47
  xGap = 70,
44
- xLabelsPx = 0,
48
+ xLabelsMinHeight = 0,
45
49
  xLabelsRotate = false,
46
50
  xReverse = false,
47
51
  yGap = 30,
48
- yLabelsLeftPx = 100,
49
- yLabelsRightPx = 100,
52
+ yLabelsLeftMinWidth = 100,
53
+ yLabelsRightMinWidth = 100,
50
54
  yMax = 10,
51
- zLabelsPx = 0
55
+ zLabelsMinWidth = 0,
56
+ zyMappings = []
52
57
  }) => {
53
58
  const /** @type {number[][]} */ zxValues = []
54
59
  const /** @type {string[]} */ xLabels = []
@@ -63,7 +68,7 @@ export const chartable = ({
63
68
 
64
69
  if (x >= 0 && z >= 0) {
65
70
  zxValues[z] = zxValues[z] ?? []
66
- zxValues[z][x] = parseFloat(value)
71
+ zxValues[z][x] = (zyMappings?.[z]?.[0] ?? parseFloat)(value)
67
72
  } else if (x >= 0 && z < 0) {
68
73
  xLabels[x] = value
69
74
  } else if (x < 0 && z >= 0) {
@@ -104,17 +109,14 @@ export const chartable = ({
104
109
  const maxValue = Math.max(...values.filter(value => !isNaN(value)))
105
110
 
106
111
  yPx.forEach((yp, y) => {
107
- const textL = s('text',
108
- { x: 0, y: yp, 'text-anchor': 'end', 'alignment-baseline': 'middle' },
109
- (maxValue - (maxValue - minValue) / yMax * (y + 1)).toFixed(2))
110
- const textR = s('text',
111
- { x: 0, y: yp, 'text-anchor': 'start', 'alignment-baseline': 'middle' },
112
- (maxValue - (maxValue - minValue) / yMax * (y + 1)).toFixed(2))
112
+ const value = (zyMappings?.[z]?.[1] ?? toFixed2)(maxValue - (maxValue - minValue) / yMax * (y + 1))
113
+ const textL = s('text', { x: 0, y: yp, 'text-anchor': 'end', 'alignment-baseline': 'middle' }, value)
114
+ const textR = s('text', { x: 0, y: yp, 'text-anchor': 'start', 'alignment-baseline': 'middle' }, value)
113
115
 
114
116
  s(_svg, textL, textR)
115
117
 
116
- yLabelsLeftPx = Math.max(yLabelsLeftPx, textL.getBBox().width)
117
- yLabelsRightPx = Math.max(yLabelsRightPx, textL.getBBox().width)
118
+ yLabelsLeftMinWidth = Math.max(yLabelsLeftMinWidth, textL.getBBox().width)
119
+ yLabelsRightMinWidth = Math.max(yLabelsRightMinWidth, textR.getBBox().width)
118
120
 
119
121
  s(gYLabelsL[z], textL)
120
122
  s(gYLabelsR[z], textR)
@@ -132,7 +134,7 @@ export const chartable = ({
132
134
 
133
135
  s(_svg, text)
134
136
 
135
- zLabelsPx = Math.max(zLabelsPx, text.getBBox().width)
137
+ zLabelsMinWidth = Math.max(zLabelsMinWidth, text.getBBox().width)
136
138
 
137
139
  gZLabels[z] = text
138
140
 
@@ -161,22 +163,22 @@ export const chartable = ({
161
163
 
162
164
  s(_svg, text)
163
165
 
164
- xLabelsPx = Math.max(xLabelsPx, xLabelsRotate ? text.getBBox().width : text.getBBox().height)
166
+ xLabelsMinHeight = Math.max(xLabelsMinHeight, xLabelsRotate ? text.getBBox().width : text.getBBox().height)
165
167
 
166
168
  s(gXLabels, text)
167
169
  })
168
170
  }
169
171
 
170
- const svgW = width + yLabelsLeftPx + yLabelsRightPx + zLabelsPx + 4 * PADDING
171
- const svgH = height + xLabelsPx + (xLabels.length > 0 ? 3 : 2) * PADDING
172
+ const svgW = width + yLabelsLeftMinWidth + yLabelsRightMinWidth + zLabelsMinWidth + 4 * PADDING
173
+ const svgH = height + xLabelsMinHeight + (xLabels.length > 0 ? 3 : 2) * PADDING
172
174
 
173
- s(gGraph, { transform: `translate(${yLabelsLeftPx + PADDING} ${PADDING})` })
175
+ s(gGraph, { transform: `translate(${yLabelsLeftMinWidth + PADDING} ${PADDING})` })
174
176
 
175
- gYLabelsL.forEach(g => s(g, { transform: `translate(${yLabelsLeftPx} ${PADDING})` }))
176
- gYLabelsR.forEach(g => s(g, { transform: `translate(${width + yLabelsLeftPx + 2 * PADDING} ${PADDING})` }))
177
+ gYLabelsL.forEach(g => s(g, { transform: `translate(${yLabelsLeftMinWidth} ${PADDING})` }))
178
+ gYLabelsR.forEach(g => s(g, { transform: `translate(${width + yLabelsLeftMinWidth + 2 * PADDING} ${PADDING})` }))
177
179
 
178
- s(gZColors, { transform: `translate(${width + yLabelsLeftPx + yLabelsRightPx + 3 * PADDING} ${PADDING})` })
179
- s(gXLabels, { transform: `translate(${yLabelsLeftPx + PADDING} ${height + 2 * PADDING})` })
180
+ s(gZColors, { transform: `translate(${width + yLabelsLeftMinWidth + yLabelsRightMinWidth + 3 * PADDING} ${PADDING})` })
181
+ s(gXLabels, { transform: `translate(${yLabelsLeftMinWidth + PADDING} ${height + 2 * PADDING})` })
180
182
 
181
183
  onclick(0)
182
184
 
@@ -187,7 +189,7 @@ export const chartable = ({
187
189
  ...gYLabelsL,
188
190
  ...gYLabelsR,
189
191
  gZColors,
190
- ['g', { transform: `translate(${width + yLabelsLeftPx + yLabelsRightPx + 4 * PADDING} ${PADDING})` }, ...gZLabels])
192
+ ['g', { transform: `translate(${width + yLabelsLeftMinWidth + yLabelsRightMinWidth + 4 * PADDING} ${PADDING})` }, ...gZLabels])
191
193
  }
192
194
 
193
195
  export const tests = {}
package/package.json CHANGED
@@ -27,6 +27,8 @@
27
27
  "localization",
28
28
  "nanolight",
29
29
  "nnn",
30
+ "omit",
31
+ "pick",
30
32
  "RWD",
31
33
  "SVG",
32
34
  "translation",
@@ -40,5 +42,5 @@
40
42
  "types": "nnn.d.ts",
41
43
  "name": "@jackens/nnn",
42
44
  "type": "module",
43
- "version": "2024.2.19"
45
+ "version": "2024.2.20"
44
46
  }
package/readme.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Jackens’ JavaScript helpers.
4
4
 
5
- <sub>Version: <code class="version">2024.2.19</code></sub>
5
+ <sub>Version: <code class="version">2024.2.20</code></sub>
6
6
 
7
7
  ## Installation
8
8
 
@@ -103,18 +103,19 @@ The type of arguments of the `jcss` helper.
103
103
  ### chartable
104
104
 
105
105
  ```ts
106
- export function chartable({ table, headerColumn, xGap, xLabelsPx, xLabelsRotate, xReverse, yGap, yLabelsLeftPx, yLabelsRightPx, yMax, zLabelsPx }: {
106
+ export function chartable({ table, headerColumn, xGap, xLabelsMinHeight, xLabelsRotate, xReverse, yGap, yLabelsLeftMinWidth, yLabelsRightMinWidth, yMax, zLabelsMinWidth, zyMappings }: {
107
107
  table: HTMLTableElement;
108
- headerColumn?: boolean;
109
- xGap?: number;
110
- xLabelsPx?: number;
111
- xLabelsRotate?: boolean;
112
- xReverse?: boolean;
113
- yGap?: number;
114
- yLabelsLeftPx?: number;
115
- yLabelsRightPx?: number;
116
- yMax?: number;
117
- zLabelsPx?: number;
108
+ headerColumn?: boolean | undefined;
109
+ xGap?: number | undefined;
110
+ xLabelsMinHeight?: number | undefined;
111
+ xLabelsRotate?: boolean | undefined;
112
+ xReverse?: boolean | undefined;
113
+ yGap?: number | undefined;
114
+ yLabelsLeftMinWidth?: number | undefined;
115
+ yLabelsRightMinWidth?: number | undefined;
116
+ yMax?: number | undefined;
117
+ zLabelsMinWidth?: number | undefined;
118
+ zyMappings?: [(label: string) => number, (value: number) => string][] | undefined;
118
119
  }): SVGSVGElement;
119
120
  ```
120
121
 
@@ -124,14 +125,15 @@ Options:
124
125
  - `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
125
126
  - `headerColumn`: flag indicating that `table` has a header column with X axis labels
126
127
  - `xGap`: X axis spacing
127
- - `xLabelsPx`:
128
+ - `xLabelsMinHeight`: minimal height of X axis labels
128
129
  - `xLabelsRotate`: flag to rotate X axis labels
129
130
  - `xReverse`: flag to reverse all data series
130
131
  - `yGap`: Y axis spacing
131
- - `yLabelsLeftPx`:
132
- - `yLabelsRightPx`:
132
+ - `yLabelsLeftMinWidth`: minimal width of Y axis left labels
133
+ - `yLabelsRightMinWidth`: minimal width of Y axis right labels
133
134
  - `yMax`: number of Y axis lines
134
- - `zLabelsPx`:
135
+ - `zLabelsMinWidth`: minimal width of data series labels
136
+ - `zyMappings`: mappings per data series
135
137
 
136
138
  ### eq
137
139