@massimo-cassandro/minimo 1.18.1 → 1.18.3
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/README.md +2 -1
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/index.js +92 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/hbars.js +356 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/pie.js +245 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/radial-bars.js +177 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/rating-display.js +835 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/costruzione-assi.js +212 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/costruzione-linee.js +101 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/defaults.js +185 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/display-current.js +27 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/grid-areas.js +129 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/parse-opts.js +64 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/paths-setup.js +73 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile.js +126 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/signal-bars.js +290 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/week-utils.js +122 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/hbars-test.js +52 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/mcn-test.js +74 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/pie-test.js +16 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/radial-bars-test.js +48 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/settimanale-mensile-dati-settimanale.js +426 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/settimanale-mensile-test.js +260 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/signal-bars-test.js +64 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/node-test.mjs +86 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/hBars-node-test.mjs +40 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/lines-node-test.mjs +73 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/mcn-node-test.mjs +64 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/pie-node-test.mjs +12 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/radialsBar-node-test.mjs +44 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/settimanale-mensile-node-test.mjs +258 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/signalBars-node-test.mjs +36 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/test-readme.md +24 -0
- package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/textToPath-test.mjs +14 -0
- package/charts/TODO charts/???/InfoBox.js +456 -0
- package/charts/TODO charts/???/README-upg OLD/342/206/222NEW.md" +53 -0
- package/charts/TODO charts/???/README.md +1 -0
- package/charts/TODO charts/???/TODO.md +39 -0
- package/charts/TODO charts/???/base-cfg.js +66 -0
- package/charts/TODO charts/???/rating-displayOLD.js +837 -0
- package/charts/TODO charts/docs/TODO.md +1 -0
- package/charts/TODO charts/docs/costruzione display rating.md +145 -0
- package/charts/TODO charts/test/node-test.mjs +92 -0
- package/charts/TODO charts/test/test-readme.md +23 -0
- package/charts/TODO charts/test/test-src/rating-display-extra-test.js +132 -0
- package/charts/TODO charts/test/test-src/rating-display-test.js +155 -0
- package/charts/TODO charts/test/textToPath-test.mjs +14 -0
- package/charts/TODO.md +1 -1
- package/design-tokens/tokens/{design-tokens/_src → src/components/modal-popup}/modal-popup.minimo.tokens.jsonc +48 -2
- package/design-tokens/utilities/build-tokens-src/config.mjs +5 -2
- package/design-tokens/utilities/build-tokens-src/formats/penpot.mjs +1 -1
- package/design-tokens/utilities/build-tokens-src/platforms.mjs +4 -1
- package/design-tokens/utilities/build-tokens.mjs +5 -3
- package/design-tokens/utilities/check-unresolved-custom-props.mjs +5 -2
- package/dev-tools/starter-kit/webpack.config.mjs +6 -6
- package/package.json +17 -10
- package/snippets/flash-messages.html.twig +34 -0
- package/src/components/modal-alert/modal-alert.js +3 -1
- package/src/components/modal-popup/modal-popup.js +68 -4
- package/{design-tokens/_src → src/components/modal-popup}/modal-popup.minimo.tokens.mjs +51 -2
- package/src/components/modal-popup/modal-popup.module.css +24 -32
- package/src/components/unsplash-page/unsplash-page.js +3 -6
- package/src/components/unsplash-page/unsplash-page.module.css +11 -6
- package/src/custom-properties.css +21 -12
|
@@ -0,0 +1 @@
|
|
|
1
|
+
riscrivere le midalità di calcolo di rating display
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Display rating
|
|
2
|
+
|
|
3
|
+
Il **display rating** raffigura un tachimetro la cui scala è suddivisa in un numero predefinito di porzioni uguali, ognuna corrispondente ad un *range* di valori. L'indicatore indica la porzione corrispondente al range di valori da rappresentare.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
> **Figura 1 - esempio**
|
|
8
|
+
|
|
9
|
+
Dal punto di vista grafico, la scala è generata da tre circonferenze, e si estende su un angolo di 240° rispetto alla circonferenza esterna:
|
|
10
|
+
|
|
11
|
+

|
|
12
|
+
|
|
13
|
+
> **Figura 2 - costruzione grafica con suddivisione in 4 o 5 porzioni**
|
|
14
|
+
|
|
15
|
+
## Costruzione
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
> **Figura 3 - costruzione scala**
|
|
20
|
+
|
|
21
|
+
La scala (l'area in giallo) è costruita dall'unione di 3 circonferenze:
|
|
22
|
+
|
|
23
|
+
* quella esterna, in blu con centro $A$ di coordinate note e raggio noto.
|
|
24
|
+
* Le due circonferenze interne i cui centri $B$ e $C$ sono disposti in modo equidistante lungo un'asse inclinata di $30^\circ$ rispetto all'asse orizzontale che contiene il punto $A$. La lunghezza del segmento $s$ (definito dall'utente) determina l'ampiezza finale della figura.
|
|
25
|
+
|
|
26
|
+
La scala viene quindi suddivisa in un numero dato di porzioni. Nell'esempio di figura 4 è stata suddivisa in 4 porzioni, ma il numero può variare.
|
|
27
|
+
|
|
28
|
+

|
|
29
|
+
|
|
30
|
+
> **Figura 4 - porzione**
|
|
31
|
+
|
|
32
|
+
L'obiettivo è ricavare le coordinate dei punti di ogni porzione ($D$, $E$, $F$ e $G$ nella figura 4), gli archi di cerchio $\overset{\frown}{DE}$ ed $\overset{\frown}{FG}$ e i due segmenti $\overline{EF}$ e $\overline{DG}$. Le rette che contengono i due segmenti passano per il centro $A$.
|
|
33
|
+
|
|
34
|
+
L'angolo $\gamma$ corrisponde al gap tra una porzione e l'altra.
|
|
35
|
+
|
|
36
|
+
Opzionalmente, possono essere costruiti dei *ticks* (vedi figura 2), ovvero dei prolungamenti del segmento iniziale di ogni porzione.
|
|
37
|
+
|
|
38
|
+
## Sviluppo
|
|
39
|
+
|
|
40
|
+
> NB tutti i valori fanno riferimento al sistema di coordinate SVG, in cui l'origine degli assi è collocata sul vertice in alto a sinistra del *viewbox*. Inoltre, a differenza del piano cartesiano standard, la direzione positiva dell'asse delle ordinate è orientata verso il basso.
|
|
41
|
+
|
|
42
|
+
### Parametri iniziali
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
> Il raggio della circonferenza esterna ($r_A$) e le coordinate del centro $A$ sono definite dai valori preimpostati, ovvero le dimensioni del file SVG ($w$ e $h$), l'eventuale padding ($p$) tra l'area del grafico vero e proprio e il *viewbox* del documento e l'eventuale bordo $m$ intorno al display (in grigio in figura 2):
|
|
46
|
+
>
|
|
47
|
+
> $r_A$ = $w / 2 - p - m$
|
|
48
|
+
>
|
|
49
|
+
> $x_A$ = $w / 2$
|
|
50
|
+
>
|
|
51
|
+
> $y_A$ = $h - (r_A \sin(30^\circ)) - 2p - m$ (\*)
|
|
52
|
+
>
|
|
53
|
+
> *(\*) la traccia $m$ non viene rappresentata nella parte inferiore del display, quindi si tiene conto una sola volta del suo spessore. La coordinata $y_A$ del centro è data dall'altezza totale meno traccia e padding meno la parte inferiore del grafico corrispondente a $r_A \sin(30^\circ)$*
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
* $d_B = d_C$: distanza tra i centri delle circonferenze interne $b$ e $c$ dal centro di quella esterna $a$, lungo un'asse inclinata di 30° rispetto all'asse orizzontale che contiene il centro $r_A$. Sono definiti dall'utente
|
|
57
|
+
* $s$: spessore finale del display, impostato dall'utente
|
|
58
|
+
* $T_C$: punto di tangenza tra le circonferenze $a$ e $c$, è posizionato esattamente ad un angolo di $210^\circ$
|
|
59
|
+
* $T_B$: punto di tangenza tra le circonferenze $b$ e $c$, è posizionato ad un angolo di $-30^\circ$ (o $330^\circ$)
|
|
60
|
+
* $a$: circonferenza esterna (blu)
|
|
61
|
+
* centro in $A$ ($x_A$, $y_A$)
|
|
62
|
+
* raggio $r_A$
|
|
63
|
+
* $b$: circonferenza interna a destra (in rosso)
|
|
64
|
+
* centro in $B$
|
|
65
|
+
* $x_B = x_A + d_B \cos(30^\circ)$
|
|
66
|
+
* $y_B = y_A - d_B \sin(30^\circ)$
|
|
67
|
+
* raggio $r_B = r_A - d_B - s$.
|
|
68
|
+
* $c$: circonferenza interna a sinistra (in verde)
|
|
69
|
+
* centro in $C$
|
|
70
|
+
* $x_C = x_A + d_C \cos(30^\circ)$
|
|
71
|
+
* $y_C = y_A - d_C \sin(30^\circ)$
|
|
72
|
+
* raggio $r_C = r_A - d_C$
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
### Verifica dei valori definiti dall'utente
|
|
77
|
+
|
|
78
|
+
Le circonferenze interne $b$ e $c$ non devono mai intersecare quella esterna $a$, l'unico punto di contatto possibile è costituito dal punto di tangenza $T_c$ corrispondente al vertice sinistro della scala.
|
|
79
|
+
|
|
80
|
+
* lo spessore finale $s$ della scala non deve portare il raggio $r_B$ a valori negativi o incoerenti:
|
|
81
|
+
* $d_B + S < r_A$
|
|
82
|
+
* il centro $C$ deve rimanere all'interno della circonferenza $a$ per permettere la tangenza nel punto $T_C$:
|
|
83
|
+
* $d_C < r_A$
|
|
84
|
+
|
|
85
|
+
### Calcolo delle coordinate di una porzione di scala
|
|
86
|
+
|
|
87
|
+
> **Figura 5 - calcolo centri circonferenze interne**
|
|
88
|
+
|
|
89
|
+
L'obiettivo è determinare le coordinate dei punti $D$, $E$, $F$, $G$ per ogni porzione della scala, garantendo che i segmenti laterali siano radiali rispetto al centro $A$ e che la curvatura interna segua l'asimmetria delle circonferenze $b$ e $c$.
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+

|
|
93
|
+
|
|
94
|
+
> **Figura 6 - calcolo coordinate porzione**
|
|
95
|
+
|
|
96
|
+
Ogni porzione è delimitata da due rette $z$ passanti per il centro $A$ con angolo $\theta$. L'angolo è definito in base al numero di porzioni $n$ e al valore dell'angolo $\gamma$ che corrisponde al gap tra una porzione l'altra.
|
|
97
|
+
|
|
98
|
+
I punti che delimitando ogni porzione sono inoltre definiti dalla distanza $\rho$ dal centro $A$.
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
Quindi:
|
|
104
|
+
|
|
105
|
+
* i due punti esterni, $D$ ed $E$ sono definiti dall'angolo $\theta$ e dalla distanza $\rho$ che in questo caso corrisponde al raggio della circonferenza $A$ ($r_A$)
|
|
106
|
+
* per i due punti interni $F$ e $G$ la distanza $\rho$ va calcolata con l'espressione:
|
|
107
|
+
|
|
108
|
+
$$
|
|
109
|
+
\rho(\theta) = d \cdot \cos(\theta - \phi) + \sqrt{r^2 - [d \cdot \sin(\theta - \phi)]^2}
|
|
110
|
+
$$
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
In cui i vari parametri dipendono da quale circonferenza viene utilizzata, in base al valore di $\theta$:
|
|
114
|
+
|
|
115
|
+
* Se $210^\circ \ge \theta \gt 30^\circ$ (parte verde della curva interna, circonferenza $c$):
|
|
116
|
+
* $\phi = \phi_2 = 210^\circ$
|
|
117
|
+
* $d = d_C$
|
|
118
|
+
* $r = r_C = r_A - d_C$
|
|
119
|
+
* Se $330^\circ \le \theta \le 30^\circ$ (parte rossa della curva interna, circonferenza $b$)
|
|
120
|
+
* $\phi = \phi_1 = 330^\circ$
|
|
121
|
+
* $d = d_B$
|
|
122
|
+
* $r = r_B = r_A - d_B - s$
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
Riassumendo, per i punti interni abbiamo un quadro di questo tipo:
|
|
126
|
+
|
|
127
|
+
.svg>)
|
|
128
|
+
|
|
129
|
+
> **Figura 7 - esempio calcolo punto interno (circonferenza verde)**
|
|
130
|
+
|
|
131
|
+
.svg>)
|
|
132
|
+
|
|
133
|
+
> **Figura 8 - esempio calcolo punto interno (circonferenza rossa) nel punto finale della scala. In questo caso gli angoli $\theta$ e $\phi$ sono uguali**
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
in cui:
|
|
137
|
+
|
|
138
|
+
* $\rho = \rho_1 + \rho_2$: distanza dal centro $A$ al punto interno $G$
|
|
139
|
+
* $\rho_1 = \sqrt{{r_C}^2 - [d \cdot \sin(\theta - \phi)]^2}$, corrisponde alla seconda parte dell'espressione precedente, ed è l'applicazione del teorema di Pitagora sul triangolo rettangolo la cui ipotenusa corrisponde al raggio $r_C$ passante per $G$, mentre $\rho_1$ è il cateto maggiore
|
|
140
|
+
* $\rho_2 = d \cdot \cos(\theta - \phi)$, corrisponde alla prima parte dell'espressione e corrisponde al cateto minore del triangolo rettangolo avente per ipotenusa la distanza $d$ tra i centri $A$ e $C$
|
|
141
|
+
* $\delta$: angolo adiacente al cateto $\rho_2$, corrisponde al valore assoluto di $\theta - \phi$
|
|
142
|
+
* $\theta$: angolo della *retta di taglio* definita dall'ampiezza della porzione e dal gap $\gamma$
|
|
143
|
+
* $\phi$: angolo fisso del centro di riferimento della circonferenza interna utilizzata, in questo caso $C$, quindi $210^{\circ}$ ($330^{\circ}$ se utilizziamo $B$)
|
|
144
|
+
* $d$: distanza fissa tra il centro $A$ e il centro interno ($d_C$ o $d_B$)
|
|
145
|
+
* $r$: raggio della circonferenza interna utilizzata ($r_C$ o $r_B$)
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { MinimoCharts } from '../index.js';
|
|
3
|
+
import { createSvgCanvasNode } from '../src/create-svg-canvas-node.mjs';
|
|
4
|
+
import * as fs_promises from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
// https://nodejs.org/api/util.html#utilstyletextformat-text-options
|
|
7
|
+
import { styleText } from 'node:util';
|
|
8
|
+
|
|
9
|
+
import { barsTest } from './src/bars-test.js';
|
|
10
|
+
import { goalTest } from './src/goal-test.js';
|
|
11
|
+
// import { pieNodeTest } from './src/pie-node-test.mjs';
|
|
12
|
+
// import { hBarsNodeTest } from './src/hBars-node-test.mjs';
|
|
13
|
+
// import { signalBarsNodeTest } from './src/signalBars-node-test.mjs';
|
|
14
|
+
// import { ratingDisplayNodeTest } from './src/ratingDisplay-node-test.mjs';
|
|
15
|
+
// import { radialsBarNodeTest } from './src/radialsBar-node-test.mjs';
|
|
16
|
+
// import { settimanaleMensileNodeTest } from './src/settimanale-mensile-node-test.mjs';
|
|
17
|
+
// import { mcnNodeTest } from './src/mcn-node-test.mjs';
|
|
18
|
+
// import { linesNodeTest } from './src/lines-node-test.mjs';
|
|
19
|
+
|
|
20
|
+
const output_path = new URL(import.meta.resolve('./_output')).pathname;
|
|
21
|
+
|
|
22
|
+
// const fontFolder = new URL(import.meta.resolve('../../../ada-brochure-business-analysis/2025/assets/fonts/Roboto_Condensed/static')).pathname;
|
|
23
|
+
const fontFolder = new URL(import.meta.resolve('./fonts/nunito-sans_5.2.7_fontsource/ttf')).pathname;
|
|
24
|
+
|
|
25
|
+
const fontFiles = {
|
|
26
|
+
extrabold: fontFolder + '/nunito-sans-latin-900-normal.ttf',
|
|
27
|
+
bold: fontFolder + '/nunito-sans-latin-700-normal.ttf',
|
|
28
|
+
medium: fontFolder + '/nunito-sans-latin-600-normal.ttf',
|
|
29
|
+
regular: fontFolder + '/nunito-sans-latin-400-normal.ttf',
|
|
30
|
+
italic: fontFolder + '/nunito-sans-latin-400-italic.ttf',
|
|
31
|
+
lightItalic: fontFolder + '/nunito-sans-latin-300-italic.ttf',
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
writeFile = async (svgString, fileName) => {
|
|
35
|
+
try {
|
|
36
|
+
await fs_promises.writeFile(path.join(output_path, fileName), svgString);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
console.error(err);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
// svuota cartella output
|
|
45
|
+
try {
|
|
46
|
+
await fs_promises.rm(output_path, { recursive: true, force: true });
|
|
47
|
+
await fs_promises.mkdir(output_path, { recursive: true });
|
|
48
|
+
} catch (err) {
|
|
49
|
+
console.error('Error clearing output folder:', err);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
const chartInstance = new MinimoCharts({
|
|
54
|
+
createSvgCanvas: createSvgCanvasNode,
|
|
55
|
+
textToPath: true, // converte i font in tracciati
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
console.log( styleText(['green'], '...barsTest' ));
|
|
59
|
+
barsTest(chartInstance, {
|
|
60
|
+
yAxisTitleFontFilePath: fontFiles.medium,
|
|
61
|
+
xAxisTitleFontFilePath: fontFiles.medium,
|
|
62
|
+
labelXFontFilePath: fontFiles.regular,
|
|
63
|
+
labelYFontFilePath: fontFiles.regular,
|
|
64
|
+
width: 800,
|
|
65
|
+
height: 500,
|
|
66
|
+
container: null
|
|
67
|
+
}).then(svgString => writeFile(svgString, 'bars.svg'));
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
console.log( styleText(['green'], '...goalTest' ));
|
|
71
|
+
goalTest(chartInstance, {
|
|
72
|
+
container: null,
|
|
73
|
+
width: 300,
|
|
74
|
+
|
|
75
|
+
currentValueFontFilePath: fontFiles.regular,
|
|
76
|
+
rightLabelFontAttrs: fontFiles.bold,
|
|
77
|
+
}).then(svgString => writeFile(svgString, 'goal.svg'));
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
// await pieNodeTest(cfg);
|
|
82
|
+
// await hBarsNodeTest(cfg);
|
|
83
|
+
// await signalBarsNodeTest(cfg);
|
|
84
|
+
// await ratingDisplayNodeTest(cfg);
|
|
85
|
+
// await radialsBarNodeTest(cfg);
|
|
86
|
+
// await settimanaleMensileNodeTest(cfg);
|
|
87
|
+
// await mcnNodeTest(cfg);
|
|
88
|
+
// await linesNodeTest(cfg);
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
console.log(' DONE ');
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# MinimoCharts test
|
|
2
|
+
|
|
3
|
+
## browser
|
|
4
|
+
|
|
5
|
+
run (dalla root Ada):
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# open -n -a "Google Chrome" --args --profile-directory="Profile 1" # facoltativo, scelta profilo chrome
|
|
9
|
+
NODE_ENV=development npx webpack serve --config ./ada-frontend/ada-charts/test/webpack/webpack-MinimoChartsTest.config.mjs
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
## node
|
|
14
|
+
|
|
15
|
+
Per il test node è necessario scaricare il font indicato nel file di `node-test.mjs`
|
|
16
|
+
|
|
17
|
+
Il percorso dei font va quindi inserito in `./node-test.mjs` (nella variabile `fontFolder`).
|
|
18
|
+
|
|
19
|
+
Per avviare il test:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
node node-test.mjs
|
|
23
|
+
```
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { MinimoCharts, ratingDisplayChart } from '../../index.js';
|
|
2
|
+
|
|
3
|
+
const chartInstance = new MinimoCharts();
|
|
4
|
+
|
|
5
|
+
ratingDisplayChart(chartInstance, {
|
|
6
|
+
debug: true,
|
|
7
|
+
container: '#rd-demo',
|
|
8
|
+
portions: 3,
|
|
9
|
+
|
|
10
|
+
value: 8.99,
|
|
11
|
+
scaleStartValue: 0,
|
|
12
|
+
rodPositionForceCenter: false,
|
|
13
|
+
|
|
14
|
+
displayBackgroundAttrs: {
|
|
15
|
+
fill: '#efefef',
|
|
16
|
+
'stroke-width': 4,
|
|
17
|
+
stroke: '#07914E',
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
displayLabel: [
|
|
21
|
+
{
|
|
22
|
+
label: 'Lorem ipsum',
|
|
23
|
+
font: {
|
|
24
|
+
family: 'Roboto Condensed',
|
|
25
|
+
size: 18,
|
|
26
|
+
// stretch: 'normal',
|
|
27
|
+
// style: 'italic',
|
|
28
|
+
// variant: 'normal',
|
|
29
|
+
weight: 700
|
|
30
|
+
},
|
|
31
|
+
fill: '#000',
|
|
32
|
+
// fontFilePath: path
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: 'dolor sit amet',
|
|
36
|
+
font: {
|
|
37
|
+
family: 'Roboto Condensed',
|
|
38
|
+
size: 12,
|
|
39
|
+
// stretch: 'normal',
|
|
40
|
+
// style: 'italic',
|
|
41
|
+
// variant: 'normal',
|
|
42
|
+
weight: 300
|
|
43
|
+
},
|
|
44
|
+
fill: '#666',
|
|
45
|
+
// fontFilePath: path,
|
|
46
|
+
}
|
|
47
|
+
],
|
|
48
|
+
displayLabelRowGap: 2,
|
|
49
|
+
|
|
50
|
+
miniDisplay: [
|
|
51
|
+
{
|
|
52
|
+
position: 'sx',
|
|
53
|
+
value: 3.1,
|
|
54
|
+
type: 'gauge', // gauge = mini tachimetro, value: mostra il valore indicato in value
|
|
55
|
+
mdLabel: [
|
|
56
|
+
{
|
|
57
|
+
label: 'md#1',
|
|
58
|
+
font: {
|
|
59
|
+
family: 'Roboto Condensed',
|
|
60
|
+
size: 14,
|
|
61
|
+
// stretch: 'normal',
|
|
62
|
+
// style: 'italic',
|
|
63
|
+
// variant: 'normal',
|
|
64
|
+
weight: 400
|
|
65
|
+
},
|
|
66
|
+
fill: '#333',
|
|
67
|
+
// fontFilePath: path,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
label: 'xyz',
|
|
71
|
+
font: {
|
|
72
|
+
family: 'Roboto Condensed',
|
|
73
|
+
size: 12,
|
|
74
|
+
// stretch: 'normal',
|
|
75
|
+
// style: 'italic',
|
|
76
|
+
// variant: 'normal',
|
|
77
|
+
weight: 300
|
|
78
|
+
},
|
|
79
|
+
fill: '#666',
|
|
80
|
+
// fontFilePath: path,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
mdArc: {
|
|
84
|
+
// fill: '#ddd',
|
|
85
|
+
'stroke-width': 1,
|
|
86
|
+
stroke: '#666',
|
|
87
|
+
class: null,
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
position: 'dx',
|
|
92
|
+
value: 4,
|
|
93
|
+
type: 'value', // gauge = mini tachimetro, value: mostra il valore indicato in value
|
|
94
|
+
typeValueFont: {
|
|
95
|
+
label: null,
|
|
96
|
+
font: {
|
|
97
|
+
family: 'Roboto Condensed',
|
|
98
|
+
size: 32,
|
|
99
|
+
// stretch: 'normal',
|
|
100
|
+
// style: 'italic',
|
|
101
|
+
// variant: 'normal',
|
|
102
|
+
weight: 700
|
|
103
|
+
},
|
|
104
|
+
fill: '#036',
|
|
105
|
+
// fontFilePath: path,
|
|
106
|
+
},
|
|
107
|
+
mdLabel: [{
|
|
108
|
+
label: 'md#2',
|
|
109
|
+
font: {
|
|
110
|
+
family: 'Roboto Condensed',
|
|
111
|
+
size: 14,
|
|
112
|
+
// stretch: 'normal',
|
|
113
|
+
// style: 'italic',
|
|
114
|
+
// variant: 'normal',
|
|
115
|
+
weight: 400
|
|
116
|
+
},
|
|
117
|
+
fill: '#333',
|
|
118
|
+
// fontFilePath: path,
|
|
119
|
+
}],
|
|
120
|
+
mdArc: {
|
|
121
|
+
// fill: '#ddd',
|
|
122
|
+
'stroke-width': 2,
|
|
123
|
+
stroke: '#036',
|
|
124
|
+
class: null,
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
miniDisplayTopMargin: 0,
|
|
129
|
+
miniDisplayLabelTopMargin: 0,
|
|
130
|
+
miniDisplayLabelRowGap: -4,
|
|
131
|
+
|
|
132
|
+
});
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
|
|
2
|
+
export function ratingDisplayTest(cfg) {
|
|
3
|
+
|
|
4
|
+
const ratingDisplayOpts = {
|
|
5
|
+
displayValue: 3.2,
|
|
6
|
+
svgAttrs: {class: 'some-class'},
|
|
7
|
+
|
|
8
|
+
displayLabel: [
|
|
9
|
+
{
|
|
10
|
+
label: 'Lorem ipsum',
|
|
11
|
+
font: {
|
|
12
|
+
family: 'Roboto Condensed',
|
|
13
|
+
size: 18,
|
|
14
|
+
// stretch: 'normal',
|
|
15
|
+
// style: 'italic',
|
|
16
|
+
// variant: 'normal',
|
|
17
|
+
weight: 700
|
|
18
|
+
},
|
|
19
|
+
fill: '#000',
|
|
20
|
+
// fontFilePath: path
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
label: 'dolor sit amet',
|
|
24
|
+
font: {
|
|
25
|
+
family: 'Roboto Condensed',
|
|
26
|
+
size: 12,
|
|
27
|
+
// stretch: 'normal',
|
|
28
|
+
// style: 'italic',
|
|
29
|
+
// variant: 'normal',
|
|
30
|
+
weight: 300
|
|
31
|
+
},
|
|
32
|
+
fill: '#666',
|
|
33
|
+
// fontFilePath: path,
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
miniDisplay: [
|
|
37
|
+
{
|
|
38
|
+
position: 'sx',
|
|
39
|
+
value: 3.1,
|
|
40
|
+
type: 'gauge', // gauge = mini tachimetro, value: mostra il valore indicato in value
|
|
41
|
+
mdLabel: [
|
|
42
|
+
{
|
|
43
|
+
label: 'md#1',
|
|
44
|
+
font: {
|
|
45
|
+
family: 'Roboto Condensed',
|
|
46
|
+
size: 14,
|
|
47
|
+
// stretch: 'normal',
|
|
48
|
+
// style: 'italic',
|
|
49
|
+
// variant: 'normal',
|
|
50
|
+
weight: 400
|
|
51
|
+
},
|
|
52
|
+
fill: '#333',
|
|
53
|
+
// fontFilePath: path,
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
label: 'xyz',
|
|
57
|
+
font: {
|
|
58
|
+
family: 'Roboto Condensed',
|
|
59
|
+
size: 12,
|
|
60
|
+
// stretch: 'normal',
|
|
61
|
+
// style: 'italic',
|
|
62
|
+
// variant: 'normal',
|
|
63
|
+
weight: 300
|
|
64
|
+
},
|
|
65
|
+
fill: '#666',
|
|
66
|
+
// fontFilePath: path,
|
|
67
|
+
},
|
|
68
|
+
],
|
|
69
|
+
mdArc: {
|
|
70
|
+
fill: '#ddd',
|
|
71
|
+
'stroke-width': 2,
|
|
72
|
+
stroke: '#036',
|
|
73
|
+
class: null,
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
position: 'dx',
|
|
78
|
+
value: 4,
|
|
79
|
+
type: 'value', // gauge = mini tachimetro, value: mostra il valore indicato in value
|
|
80
|
+
typeValueFont: {
|
|
81
|
+
label: null,
|
|
82
|
+
font: {
|
|
83
|
+
family: 'Roboto Condensed',
|
|
84
|
+
size: 28,
|
|
85
|
+
// stretch: 'normal',
|
|
86
|
+
// style: 'italic',
|
|
87
|
+
// variant: 'normal',
|
|
88
|
+
weight: 700
|
|
89
|
+
},
|
|
90
|
+
fill: '#760592',
|
|
91
|
+
// fontFilePath: path,
|
|
92
|
+
},
|
|
93
|
+
mdLabel: [
|
|
94
|
+
{
|
|
95
|
+
label: 'md#2',
|
|
96
|
+
font: {
|
|
97
|
+
family: 'Roboto Condensed',
|
|
98
|
+
size: 14,
|
|
99
|
+
// stretch: 'normal',
|
|
100
|
+
// style: 'italic',
|
|
101
|
+
// variant: 'normal',
|
|
102
|
+
weight: 400
|
|
103
|
+
},
|
|
104
|
+
fill: '#333',
|
|
105
|
+
// fontFilePath: path,
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
label: '(riga 2)',
|
|
109
|
+
font: {
|
|
110
|
+
family: 'Roboto Condensed',
|
|
111
|
+
size: 12,
|
|
112
|
+
// stretch: 'normal',
|
|
113
|
+
// style: 'italic',
|
|
114
|
+
// variant: 'normal',
|
|
115
|
+
weight: 300
|
|
116
|
+
},
|
|
117
|
+
fill: '#666',
|
|
118
|
+
// fontFilePath: path,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
mdArc: {
|
|
122
|
+
fill: '#ddd',
|
|
123
|
+
'stroke-width': 3,
|
|
124
|
+
stroke: '#036',
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
],
|
|
128
|
+
miniDisplayTopMargin: 5,
|
|
129
|
+
miniDisplayLabelTopMargin: 0,
|
|
130
|
+
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
cfg.charts.ratingDisplay({
|
|
134
|
+
...ratingDisplayOpts,
|
|
135
|
+
container: '#ratingDisplay1',
|
|
136
|
+
scale: 4,
|
|
137
|
+
|
|
138
|
+
displayBackgroundAttrs: {
|
|
139
|
+
fill: '#efefef',
|
|
140
|
+
'stroke-width': 3,
|
|
141
|
+
stroke: '#666',
|
|
142
|
+
class: 'some-class',
|
|
143
|
+
},
|
|
144
|
+
|
|
145
|
+
displayValueForceCenter: false,
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
cfg.charts.ratingDisplay({
|
|
149
|
+
...ratingDisplayOpts,
|
|
150
|
+
debug: true,
|
|
151
|
+
container: '#ratingDisplay2',
|
|
152
|
+
scale: 5,
|
|
153
|
+
displayValueForceCenter: true,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* eslint-disable no-console */
|
|
2
|
+
import { textToSvgPath } from '../src/svg-text-to-path.js';
|
|
3
|
+
|
|
4
|
+
const labelFontFilePath = './Roboto_Condensed/static/RobotoCondensed-Bold.ttf',
|
|
5
|
+
textString = 'Hello World',
|
|
6
|
+
textSize = 24
|
|
7
|
+
;
|
|
8
|
+
|
|
9
|
+
const { pathData, pathElementString } = await textToSvgPath(labelFontFilePath, textString, textSize);
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
console.log(pathData);
|
|
13
|
+
console.log('------');
|
|
14
|
+
console.log(pathElementString);
|
package/charts/TODO.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
completare
|
|
2
|
-
aggionare la documentazione e aggiungere i test a demo (in
|
|
2
|
+
aggionare la documentazione e aggiungere i test a demo (vedi vecchia versione in `TODO charts/test`)
|
|
3
3
|
|
|
4
4
|
implementare tooltip nativo nei file svg, ora viene aggiunto un data-title, ma non è gestito
|
|
5
5
|
|
|
@@ -5,7 +5,37 @@
|
|
|
5
5
|
// Re-generate with: node build-tokens.mjs --config <path/to/config>
|
|
6
6
|
// -----------------------------------------------------------------------
|
|
7
7
|
{
|
|
8
|
-
"
|
|
8
|
+
"mpopup": {
|
|
9
|
+
"width": {
|
|
10
|
+
"$type": "dimension",
|
|
11
|
+
"$value": "max-content"
|
|
12
|
+
},
|
|
13
|
+
"min-width": {
|
|
14
|
+
"$type": "dimension",
|
|
15
|
+
"$value": "400px"
|
|
16
|
+
},
|
|
17
|
+
"max-width": {
|
|
18
|
+
"$type": "dimension",
|
|
19
|
+
"$value": "98dvw"
|
|
20
|
+
},
|
|
21
|
+
"height": {
|
|
22
|
+
"$type": "dimension",
|
|
23
|
+
"$value": "max-content"
|
|
24
|
+
},
|
|
25
|
+
"min-height": {
|
|
26
|
+
"$type": "dimension",
|
|
27
|
+
"$value": "300px"
|
|
28
|
+
},
|
|
29
|
+
"max-height": {
|
|
30
|
+
"$type": "dimension",
|
|
31
|
+
"$value": "90dvh"
|
|
32
|
+
},
|
|
33
|
+
"background": {
|
|
34
|
+
"color": {
|
|
35
|
+
"$type": "color",
|
|
36
|
+
"$value": "{body.background.color}"
|
|
37
|
+
}
|
|
38
|
+
},
|
|
9
39
|
"drop-shadow": {
|
|
10
40
|
"$type": "shadow",
|
|
11
41
|
"$value": [
|
|
@@ -14,7 +44,7 @@
|
|
|
14
44
|
"offsetY": "0",
|
|
15
45
|
"blur": "12px",
|
|
16
46
|
"spread": "2px",
|
|
17
|
-
"color": "
|
|
47
|
+
"color": "rgb(0 0 0 / .25)"
|
|
18
48
|
}
|
|
19
49
|
]
|
|
20
50
|
},
|
|
@@ -34,6 +64,22 @@
|
|
|
34
64
|
"$value": "1.6rem"
|
|
35
65
|
}
|
|
36
66
|
},
|
|
67
|
+
"content": {
|
|
68
|
+
"padding": {
|
|
69
|
+
"$type": "dimension",
|
|
70
|
+
"$value": "{size.base} {size.sm} {size.sm}"
|
|
71
|
+
},
|
|
72
|
+
"scrollbar": {
|
|
73
|
+
"padding": {
|
|
74
|
+
"i": {
|
|
75
|
+
"end": {
|
|
76
|
+
"$type": "dimension",
|
|
77
|
+
"$value": "{size.md}"
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
},
|
|
37
83
|
"header": {
|
|
38
84
|
"padding": {
|
|
39
85
|
"$type": "dimension",
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
// build-tokens-src/config.mjs
|
|
2
3
|
// Reads the --config flag from argv, imports the project config file,
|
|
3
4
|
// resolves all paths and exports them for build-tokens.mjs.
|
|
@@ -8,7 +9,7 @@
|
|
|
8
9
|
/* globals process */
|
|
9
10
|
|
|
10
11
|
import * as path from 'node:path';
|
|
11
|
-
import { pathToFileURL } from 'url';
|
|
12
|
+
import { pathToFileURL } from 'node:url';
|
|
12
13
|
|
|
13
14
|
// ---------------------------------------------------------------------------
|
|
14
15
|
// Read the --config flag
|
|
@@ -31,10 +32,11 @@ export const configDir = path.dirname(configAbsPath);
|
|
|
31
32
|
// ---------------------------------------------------------------------------
|
|
32
33
|
// Import the project config
|
|
33
34
|
// ---------------------------------------------------------------------------
|
|
34
|
-
const buildConfig = (await import(pathToFileURL(configAbsPath))).default;
|
|
35
|
+
const buildConfig = (await import(pathToFileURL(configAbsPath).href)).default;
|
|
35
36
|
|
|
36
37
|
// Helper: resolves a path relative to the config directory.
|
|
37
38
|
// Leaves already-absolute paths untouched.
|
|
39
|
+
/** @param {string} p */
|
|
38
40
|
const resolveFromConfig = (p) => path.resolve(configDir, p);
|
|
39
41
|
|
|
40
42
|
// ---------------------------------------------------------------------------
|
|
@@ -91,6 +93,7 @@ export const penpotExpressions = VALID_EXPR_MODES.includes(buildConfig.penpotExp
|
|
|
91
93
|
// ---------------------------------------------------------------------------
|
|
92
94
|
const GLOB_CHARS = /[*?{[]/;
|
|
93
95
|
|
|
96
|
+
/** @param {string} s */
|
|
94
97
|
const resolveSource = (s) => {
|
|
95
98
|
if (path.isAbsolute(s)) {
|
|
96
99
|
// Already absolute: only normalise separators (needed on Windows)
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
// original expression is kept with a warning.
|
|
33
33
|
|
|
34
34
|
import StyleDictionary from 'style-dictionary';
|
|
35
|
-
import path from 'path';
|
|
35
|
+
import path from 'node:path';
|
|
36
36
|
|
|
37
37
|
// Disclaimer prepended to every generated file when penpotFormat is 'jsonc'
|
|
38
38
|
const DISCLAIMER = [
|