@massimo-cassandro/minimo 1.18.1 → 1.18.2

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.
Files changed (50) hide show
  1. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/index.js +92 -0
  2. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/hbars.js +356 -0
  3. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/pie.js +245 -0
  4. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/radial-bars.js +177 -0
  5. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/rating-display.js +835 -0
  6. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/costruzione-assi.js +212 -0
  7. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/costruzione-linee.js +101 -0
  8. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/defaults.js +185 -0
  9. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/display-current.js +27 -0
  10. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/grid-areas.js +129 -0
  11. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/parse-opts.js +64 -0
  12. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile-src/paths-setup.js +73 -0
  13. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/settimanale-mensile.js +126 -0
  14. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/charts/signal-bars.js +290 -0
  15. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/src/week-utils.js +122 -0
  16. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/hbars-test.js +52 -0
  17. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/mcn-test.js +74 -0
  18. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/pie-test.js +16 -0
  19. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/radial-bars-test.js +48 -0
  20. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/settimanale-mensile-dati-settimanale.js +426 -0
  21. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/settimanale-mensile-test.js +260 -0
  22. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/browser-test/src/signal-bars-test.js +64 -0
  23. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/node-test.mjs +86 -0
  24. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/hBars-node-test.mjs +40 -0
  25. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/lines-node-test.mjs +73 -0
  26. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/mcn-node-test.mjs +64 -0
  27. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/pie-node-test.mjs +12 -0
  28. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/radialsBar-node-test.mjs +44 -0
  29. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/settimanale-mensile-node-test.mjs +258 -0
  30. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/node-test/src/signalBars-node-test.mjs +36 -0
  31. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/test-readme.md +24 -0
  32. package/charts/TODO charts/1a-vers DA RIFATTORIZZARE/test/textToPath-test.mjs +14 -0
  33. package/charts/TODO charts/???/InfoBox.js +456 -0
  34. package/charts/TODO charts/???/README-upg OLD/342/206/222NEW.md" +53 -0
  35. package/charts/TODO charts/???/README.md +1 -0
  36. package/charts/TODO charts/???/TODO.md +39 -0
  37. package/charts/TODO charts/???/base-cfg.js +66 -0
  38. package/charts/TODO charts/???/rating-displayOLD.js +837 -0
  39. package/charts/TODO charts/docs/TODO.md +1 -0
  40. package/charts/TODO charts/docs/costruzione display rating.md +145 -0
  41. package/charts/TODO charts/test/node-test.mjs +92 -0
  42. package/charts/TODO charts/test/test-readme.md +23 -0
  43. package/charts/TODO charts/test/test-src/rating-display-extra-test.js +132 -0
  44. package/charts/TODO charts/test/test-src/rating-display-test.js +155 -0
  45. package/charts/TODO charts/test/textToPath-test.mjs +14 -0
  46. package/charts/TODO.md +1 -1
  47. package/package.json +1 -1
  48. package/snippets/flash-messages.html.twig +34 -0
  49. package/src/components/unsplash-page/unsplash-page.js +3 -6
  50. package/src/components/unsplash-page/unsplash-page.module.css +11 -6
@@ -0,0 +1,64 @@
1
+ // prima elaborazione e controlli delle impostazioni
2
+
3
+ import { getWeekOfDate } from '../../week-utils.js';
4
+
5
+
6
+ export function parseOpts(cfg) {
7
+
8
+ try {
9
+
10
+ if(+cfg.width < 100 || +cfg.height < 100) {
11
+ throw '`width` e/o `height` mancanti o di dimensioni insufficienti (devono essere maggiori di 99px)';
12
+ }
13
+
14
+ if(!['settimanale', 'mensile'].includes(cfg.modo)) {
15
+ throw `‘modo’ deve essere ‘settimanale’ o ‘mensile’ (valore attuale: ‘${cfg.modo}’)`;
16
+ }
17
+ cfg.isSettimanale = cfg.modo === 'settimanale';
18
+
19
+
20
+ // =>> PARAMETRI calcolati
21
+ //---------------
22
+
23
+ // solo settimanale
24
+ if(cfg.isSettimanale) {
25
+
26
+ // calcolo max_value (tiene conto della eventuale esclusione della settimana zero)
27
+ cfg.max_value = cfg.chartData.filter(row => cfg.skipWeek0? row.w > 0 : true).reduce((prev, curr) => {
28
+ return Math.max(prev, ...Object.values(curr));
29
+ }, 0);
30
+
31
+ // aggiustamento `eti_asseX_cfg.height` per fare spazio alle etichette con il nome dei mesi
32
+ cfg.eti_asseX_height *= 2.2;
33
+ }
34
+
35
+ cfg.currentWeek = getWeekOfDate({year: cfg.anno});
36
+ cfg.currentMonth = new Date().getMonth() + 1; // base 1
37
+
38
+ // primo dell'anno
39
+ cfg.jan1 = new Date(Date.UTC(cfg.anno, 0, 1));
40
+ cfg.jan1DayOfTheWeek = cfg.jan1.getDay();
41
+
42
+ // il numero di settimane dell'anno non include la settimana 0, se presente,
43
+ // che indica il riporto anno precedente.
44
+ // se il 31 dicembre è prima di giovedì, viene considerato nella prima settimana dell'anno successivo
45
+ // e il numero di settimane dell'anno è 52
46
+ cfg.dec31WeekNum = getWeekOfDate({date: new Date(cfg.anno, 11, 31), year: cfg.anno});
47
+ cfg.weeks = cfg.dec31WeekNum === 1? 52 : cfg.dec31WeekNum;
48
+
49
+ cfg.mesi = ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'];
50
+
51
+ // larghezza ogni step dell'asse X (= 1 settimana o mese)
52
+ if(cfg.isSettimanale) {
53
+ cfg.stepX_count = cfg.weeks + (cfg.skipWeek0? 0 : 1);
54
+ } else {
55
+ cfg.stepX_count = 12;
56
+ }
57
+
58
+
59
+ return cfg;
60
+
61
+ } catch(e) {
62
+ console.error( 'AdaCharts → andamentoAnnuale → parseOpts', e ); // eslint-disable-line
63
+ }
64
+ }
@@ -0,0 +1,73 @@
1
+ // elaborazione dati grafico, costruzione coordinate paths e punti
2
+
3
+ export function pathsSetup(cfg) {
4
+
5
+ // coordinate dei punti dei vari set di dati
6
+ // array delle varie serie di punti che saranno poi utilizzate per costruire gli elementi del grafico
7
+ // ogni elemento dell'array contiene le coordinate x,y di ogni punto
8
+ cfg.coords = {
9
+ budget_standard: [],
10
+ budget_positivo: [],
11
+ budget_negativo: [],
12
+ consolidato: [],
13
+ consolidato_forecast: [],
14
+ consolidato_prec: []
15
+ };
16
+
17
+ // step iniziale o 1 se skipWeek0 = true e modo = 'settimanale'
18
+ const firstStep = (cfg.skipWeek0 && cfg.isSettimanale)? 1 : 0
19
+
20
+ // conversione valori in coordinate Y relative al grafico
21
+ ,valueToY = (value) => {
22
+ // la coordinata y è ricavata dalla proporzione con il valore massimo e altezza del grafico
23
+ // arrotondata a 4 cifre decimali
24
+
25
+ // return chart_area.top + chart_area.height - ((value * chart_area.height) / max_value);
26
+ return Math.round(
27
+ (cfg.chart_area.top + cfg.chart_area.height - ((value * cfg.chart_area.height) / cfg.max_value)) * 1e4
28
+ ) / 1e4;
29
+
30
+ }
31
+ ;
32
+
33
+ // valore x iniziale
34
+ let x = cfg.chart_area.left;
35
+
36
+ for (let thisStep = firstStep; thisStep <= cfg.stepX_count; thisStep++) {
37
+
38
+ const dataItem = cfg.chartData.filter(row => row[cfg.isSettimanale? 'w' : 'm'] === thisStep )[0] ?? {};
39
+
40
+ /**
41
+ {
42
+ w: <num>, // numero settimana (se settimanale)
43
+ m: <num>, // numero mese (se mensile)
44
+
45
+ s: <num>, // valore scenario standard
46
+ p: <num>, // valore scenario positivo
47
+ n: <num>, // valore scenario negativo
48
+ c: <num>, // valore consolidato anno corrente (può essere null)
49
+ cp: <num>, // valore consolidato anno precedente
50
+ cf: <num> // valore consolidato forecast (può non essere presente o null)
51
+ }
52
+ */
53
+
54
+ // ['s', 'p', 'n', 'c', 'cp', 'cf'].forEach(k => {
55
+ // if(dataItem[k] != null) {
56
+ // cfg.coords.budget_standard.push([x, valueToY(dataItem[k] ?? 0)]);
57
+ // }
58
+ // });
59
+
60
+ if(dataItem.p != null) cfg.coords.budget_positivo.push([x, valueToY(dataItem.p)]);
61
+ if(dataItem.n != null) cfg.coords.budget_negativo.push([x, valueToY(dataItem.n)]);
62
+ if(dataItem.s != null) cfg.coords.budget_standard.push([x, valueToY(dataItem.s)]);
63
+ if(dataItem.c != null) cfg.coords.consolidato.push([x, valueToY(dataItem.c)]);
64
+ if(dataItem.cf != null) cfg.coords.consolidato_forecast.push([x, valueToY(dataItem.cf)]);
65
+ if(dataItem.cp != null) cfg.coords.consolidato_prec.push([x, valueToY(dataItem.cp)]);
66
+
67
+ x += +cfg.stepX_size;
68
+ x = +x.toFixed(4);
69
+
70
+ } // end for step x
71
+
72
+ return cfg;
73
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ *
3
+ * Grafico andamento economico annuale
4
+ * produce un grafico a linee con l'andamento annuale di un determinato parametro
5
+ * con dettagli settimanali o mensili
6
+ */
7
+
8
+ // vedi test per la definizione delle opzioni
9
+
10
+ // TODO metodo migliore per condivisione variabili
11
+ // TODO parte interattiva
12
+
13
+ import { parseStdAxisOpts } from '../components/parse-std-axis-opts.js';
14
+
15
+ import { costruzioneAssi } from './settimanale-mensile-src/costruzione-assi.js';
16
+ import { default_opts } from './settimanale-mensile-src/defaults.js';
17
+ import { parseOpts } from './settimanale-mensile-src/parse-opts.js';
18
+ import { pathsSetup } from './settimanale-mensile-src/paths-setup.js';
19
+ import { gridAreas } from './settimanale-mensile-src/grid-areas.js';
20
+ import { displayCurrent } from './settimanale-mensile-src/display-current.js';
21
+ import { costruzioneLinee } from './settimanale-mensile-src/costruzione-linee.js';
22
+
23
+
24
+ export async function settimanaleMensile(options) {
25
+
26
+ // =>> parse container
27
+ [options.container, options.width, options.height] = this.utils.parseContainer(options.container, options.width, options.height);
28
+
29
+ let cfg = {...default_opts, ...options};
30
+
31
+ cfg.debug = this.debug? this.debug : (cfg.debug?? false);
32
+
33
+
34
+ // =>> prima elaborazione e controlli delle impostazioni
35
+ cfg = parseOpts(cfg); // elaborazione specifica per questo grafico
36
+
37
+
38
+ if(!cfg.container && (!cfg.width || !cfg.height)) {
39
+ throw '`container` non impostato e almeno uno tra `width` e `height` mancante';
40
+ }
41
+ // valore massimo da rappresentare
42
+ // se `skipWeek0 === true`, i dati della settimana zero non vanno inclusi nel calcolo
43
+
44
+ cfg.max_value = cfg.chartData
45
+ .filter(weekData => cfg.skipWeek0 === true? weekData.w > 0 : true)
46
+ .reduce((prev, curr) => {
47
+ return Math.max(prev, ...Object.values(curr));
48
+ }, 0);
49
+
50
+ const parsed_cfg = parseStdAxisOpts({ // elaborazione standard condivisa con grafici analoghi
51
+ max_value: cfg.max_value,
52
+ values: cfg.chartData.map(item => Object.values(item)).flat(),
53
+ legenda: cfg.legenda,
54
+ padding: cfg.padding,
55
+ width: cfg.width,
56
+ height: cfg.height,
57
+ eti_asseX_height: cfg.eti_asseX_height,
58
+ eti_asseY_width: cfg.eti_asseY_width,
59
+ stepY_count: cfg.stepY_count,
60
+ stepX_count: cfg.stepX_count,
61
+ ticksLength: cfg.ticksLength,
62
+ });
63
+ cfg = {...cfg, ...parsed_cfg};
64
+
65
+
66
+ // =>> svg
67
+ cfg.svgCanvas = this.createSvgCanvas(cfg.container, cfg.debug)
68
+ .size(cfg.width, cfg.height)
69
+ .viewbox(0, 0, cfg.width, cfg.height)
70
+ .attr(cfg.svgAttrs??{});
71
+
72
+
73
+ // =>> elaborazione dati grafico, costruzione coordinate paths e punti
74
+ cfg = pathsSetup(cfg);
75
+
76
+
77
+ // =>> costruzione assi e griglia
78
+ cfg = await costruzioneAssi({
79
+ cfg: cfg,
80
+ adaChartIstance: this,
81
+ xLabels: cfg.isSettimanale? [...Array(cfg.weeks + 1).keys()].slice(cfg.skipWeek0? 1 : 0) : cfg.mesi,
82
+ });
83
+
84
+ // =>> aree colorate per l'evidenziazione dei mesi e seconda riga di etichette
85
+ // solo settimanale
86
+ if(cfg.isSettimanale) {
87
+ cfg = await gridAreas(cfg, this);
88
+ }
89
+
90
+ // =>> costruzione linee
91
+ cfg = costruzioneLinee(cfg);
92
+
93
+ // =>> evidenziazione settimana / mese corrente
94
+ cfg = displayCurrent(cfg);
95
+ cfg.lineeGroup.front();
96
+
97
+ // =>> Legenda
98
+ const legendaEl = await this.legenda(cfg.legenda);
99
+ legendaEl.attr({ 'data-cfg.debug-info': cfg.debug? 'Legenda' : null });
100
+ const legendaBbox = legendaEl.bbox();
101
+
102
+ legendaEl.dmove(
103
+ (cfg.width - legendaBbox.width) / 2,
104
+ cfg.padding
105
+ );
106
+ legendaEl.y(cfg.padding);
107
+
108
+ legendaEl.x((cfg.width - legendaBbox.width) / 2);
109
+
110
+ cfg.svgCanvas.add(legendaEl);
111
+
112
+ if(!cfg.container) {
113
+ return cfg.svgCanvas.svg();
114
+ }
115
+
116
+ if(cfg.debug) {
117
+
118
+ /* eslint-disable no-console */
119
+ console.log('\n****** grafico andamento annuale ******');
120
+ console.log(cfg);
121
+ console.log('************');
122
+ /* eslint-enable no-console */
123
+ }
124
+
125
+ }
126
+
@@ -0,0 +1,290 @@
1
+ /**
2
+ * signal bars (grafico a tacche)
3
+ *
4
+ * Mostra una serie di barre analoghe a quelle del segnale dei cellulari
5
+ * in cui le barre vengono mostrate attive se il valore di riferimento è maggiore o uguale
6
+ * a uno degli indici del range dato e inferiore al successivo.
7
+ * Di conseguenza, se il valore di riferimento è più basso del valore minimo del range
8
+ */
9
+
10
+
11
+ export async function signalBars({
12
+
13
+
14
+ /** container (selettore o elemento DOM), se null viene restituito il codice SVG */
15
+ container = null,
16
+
17
+ /**
18
+ larghezza e altezza del grafico (px),
19
+ Se il container è presente e i parametro `width` e `height` sono `null`,
20
+ vengono utilizzate le dimensioni del container.
21
+ Se uno dei due valori non è impostato o ricavabile, viene generato un errore.
22
+ NB: il padding del container viene considerato nelle dimensioni del grafico,
23
+ è preferibile non impostarlo.
24
+ Il valore 'auto' di height fa sì che l'altezza dell'svg sia calcolata sulla base
25
+ del numero di barre e dei valori `barsGap` e `barsHeight`
26
+ */
27
+ width = null, // null || <value>
28
+ height = 300, // <value> || null
29
+
30
+ /**
31
+ range di valori che corrispondono alle varie tacche,
32
+ un valore inferiore al primo non "accende" nessuna tacca,
33
+ tra il primo (incluso), e il secondo (escluso), una tacca e così via.
34
+ Il numero di elementi determina il numero delle tacche
35
+ */
36
+ ranges = [1,2,3,4],
37
+
38
+ /**
39
+ se fornito, le barre 'accese' non vengono calcolate, ma si uutilizza questo valore
40
+ corrisponde al numero di barre attivate da sinistra verso destra.
41
+ Se presente, `value` può essere omesso ed è comunque ignorato
42
+ */
43
+ activeBars = null,
44
+
45
+ /** Valore da rappresentare */
46
+ value = null,
47
+
48
+ /**
49
+ etichetta da mostrare a destra o sotto le tacche. Se nulla mostra il valore di `value`,
50
+ stringa vuota o false per non avere etichetta
51
+ */
52
+ label = null,
53
+
54
+
55
+ /** posizione dell'etichetta */
56
+ labelPosition = 'right', // right o bottom
57
+
58
+ /**
59
+ Impostazioni font e colori per le etichette
60
+ Impostare solo se non si vogliono usare i colori di default
61
+ se impostato, è un oggetto analogo a quello definito in src/utils/init.js
62
+ */
63
+ labelFont = null,
64
+ labelFill = '#000',
65
+
66
+ /** path del file font per la conversione in tracciati */
67
+ labelFontFilePath = null,
68
+
69
+ /** spazio tra l'etichetta e il grafico */
70
+ textBarsGap = 8,
71
+
72
+ /** spazio tra una barra e la successiva */
73
+ barsGap = 10,
74
+
75
+ /** corner radius */
76
+ barsCornerRadius = 3,
77
+
78
+ /**
79
+ come il precedente, ma relatuvo alla larghezza della barra,
80
+ ad esempio un valore di `.5' crea della barre dalle estremità tonde
81
+ Se presente, il valore di `barsCornerRadius` viene ignorato
82
+ */
83
+ barsRelativeCornerRadius = null,
84
+
85
+ /**
86
+ attributi barre attive e disattive
87
+ ad esclusione di `stroke-width` da gestire separatamente con barsStrokeWidth per esigenze di calcolo
88
+ vedi https://svgjs.dev/docs/3.2/manipulating/#attributes
89
+ */
90
+ barsStrokeWidth = 3,
91
+ barsOnAttr = {
92
+ fill: '#000'
93
+ // ,'fill-opacity': 0.5
94
+ ,stroke: '#000'
95
+ ,'stroke-width': 3
96
+ },
97
+ barsOffAttr = {
98
+ fill: '#000'
99
+ // ,'fill-opacity': 0.5
100
+ ,stroke: '#fff'
101
+ ,'stroke-width': 3
102
+ },
103
+
104
+ /** seimpostato, il valore massimo della larghezz delle barre */
105
+ maxBarWidth = null,
106
+
107
+ /** eventuali classi da aggiungere al grafico */
108
+ svgClassName = null,
109
+ labelClassName = null,
110
+ barOnClassName = null,
111
+ barOffClassName = null,
112
+
113
+
114
+ } = {}) {
115
+
116
+ try {
117
+
118
+
119
+ if(ranges.filter(v => isNaN(v)).length) {
120
+ throw 'There are non-numeric values';
121
+ }
122
+
123
+ if(ranges.length < 2) {
124
+ throw '`ranges`: sono necessari alemno due valori';
125
+ }
126
+
127
+ if(typeof barsStrokeWidth !== 'number') {
128
+ throw '`barsStrokeWidth` deve essere un numero';
129
+ }
130
+
131
+ if((value == null || typeof value !== 'number') && (activeBars == null || typeof activeBars !== 'number')) {
132
+ throw 'Almeno uno tra `value` e `activeBars` deve essere presente e deve essere un numero ' +
133
+ `(value: ${value}, activeBars: ${activeBars})`;
134
+ }
135
+
136
+ if(!['right', 'bottom'].includes(labelPosition)) {
137
+ throw '`labelPosition` deve essere`right` o `bottom`';
138
+ }
139
+
140
+ // container
141
+ [, width, height] = this.utils.parseContainer(container, width, height);
142
+
143
+
144
+ if(barsGap == null) {
145
+ throw '`barsGap` deve essere impostato';
146
+ }
147
+
148
+
149
+ if(!width || !height) {
150
+ throw `width e/o height mancanti: width: ${width}, height: ${height}`;
151
+ }
152
+
153
+ const svgCanvas = this.createSvgCanvas(container).size(width, height);
154
+ svgCanvas.viewbox(0, 0, width, height);
155
+
156
+ if(svgClassName) {
157
+ svgCanvas.addClass(svgClassName);
158
+ }
159
+
160
+ let labelX, labelY, barsAreaWidth, barWidth, barsAreaHeight, labelEl, label_bbox;
161
+ const barsCount = ranges.length;
162
+
163
+ if(label !== '' && label !== false) {
164
+
165
+ if(label == null) {
166
+ label = value.toLocaleString('it-IT', { maximumFractionDigits: 2 });
167
+ }
168
+
169
+ // =>> calcolo dimensioni del testo per ricavare lo spazio utile per le barre
170
+ // in base al posizionamento dell'etichetta
171
+
172
+ // =>> label
173
+ [label_bbox, labelEl] = await this.createTextEl ({
174
+ text: label,
175
+ textFill: labelFill,
176
+ fontAttr: labelFont,
177
+ fontFilePath: labelFontFilePath,
178
+ parentElement: svgCanvas
179
+ });
180
+
181
+
182
+ if(labelPosition === 'right') {
183
+ labelX = width - label_bbox.width;
184
+ labelY = (height - label_bbox.height) / 2;
185
+ barsAreaWidth = width - label_bbox.width - textBarsGap;
186
+ barsAreaHeight = height;
187
+
188
+ } else {
189
+ labelX = (width - label_bbox.width) / 2;
190
+ labelY = height - label_bbox.height;
191
+ barsAreaWidth = width;
192
+ barsAreaHeight = height - label_bbox.height - textBarsGap;
193
+ }
194
+
195
+ // posizionamento etichetta
196
+ labelEl.move(labelX, labelY);
197
+
198
+ if(labelClassName) {
199
+ labelEl.addClass(labelClassName);
200
+ }
201
+
202
+
203
+ } else {
204
+ barsAreaWidth = width;
205
+ barsAreaHeight = height;
206
+ }
207
+
208
+ barWidth = (
209
+ barsAreaWidth -
210
+ (barsGap * (barsCount - 1)) -
211
+ ((barsStrokeWidth?? 0) * barsCount) // lo spessore della traccia è divisa tra interno ed esterno
212
+ ) / barsCount;
213
+ barWidth = Math.min(maxBarWidth?? Infinity, barWidth);
214
+
215
+ const barsMaxHeight = barsAreaHeight - (barsStrokeWidth?? 0),
216
+ barsModuleHeight = barsMaxHeight / barsCount;
217
+
218
+
219
+ // coordinate x e y e altezza della prima barra
220
+ let barX = (
221
+ barsAreaWidth -
222
+ (barWidth * barsCount) -
223
+ (barsGap * (barsCount - 1)) -
224
+ ((barsStrokeWidth?? 0) * barsCount)
225
+ ) / 2 + ((barsStrokeWidth?? 0)/2),
226
+ barHeight = barsModuleHeight,
227
+ barY = barsAreaHeight - barHeight - ((barsStrokeWidth?? 0) / 2);
228
+
229
+
230
+ // indice dell'ultima barra da rappresentare con riempimento attivo
231
+ ranges.sort((a,b) => a - b);
232
+ let lastActiveBarIndex;
233
+
234
+ if(activeBars) {
235
+ lastActiveBarIndex = activeBars - 1;
236
+
237
+ } else {
238
+ const closestRangeValue = ranges.reduce((prev, curr) => {
239
+ return (Math.abs(Math.ceil(curr - value)) < Math.abs(Math.ceil(prev - value)) ? curr : prev);
240
+ });
241
+ lastActiveBarIndex = ranges.indexOf(closestRangeValue);
242
+ }
243
+
244
+ const bar_group = svgCanvas.group();
245
+
246
+ ranges.forEach((val, idx) => {
247
+
248
+ const barIsOn = idx <= lastActiveBarIndex;
249
+
250
+ const bar = bar_group.rect({
251
+ x: barX,
252
+ y: barY,
253
+ width: barWidth,
254
+ height: barHeight,
255
+ ...(barIsOn? barsOnAttr : barsOffAttr),
256
+ });
257
+
258
+ if(barsRelativeCornerRadius != null || barsCornerRadius != null) {
259
+
260
+ barsCornerRadius= barsRelativeCornerRadius != null? barWidth/2 : barsCornerRadius;
261
+
262
+ bar.radius(barsCornerRadius);
263
+ }
264
+
265
+ if( barsStrokeWidth > 0 ) {
266
+ bar.stroke({ width: barsStrokeWidth });
267
+ }
268
+
269
+ if(barOnClassName && barIsOn) {
270
+ bar.addClass(barOnClassName);
271
+ }
272
+ if(barOffClassName && !barIsOn) {
273
+ bar.addClass(barOffClassName);
274
+ }
275
+
276
+ barHeight += barsModuleHeight;
277
+ barX += barWidth + barsStrokeWidth + barsGap;
278
+ barY -= barsModuleHeight;
279
+ });
280
+
281
+ if(!container) {
282
+ return svgCanvas.svg();
283
+ }
284
+
285
+
286
+ } catch(e) {
287
+ console.error( 'AdaCharts → signalBars', e ); // eslint-disable-line
288
+ }
289
+
290
+ }
@@ -0,0 +1,122 @@
1
+
2
+ /**
3
+ * Restituisce il numero della settimana corrente
4
+ * se la prima settimana ha meno di 4 gg e viene quindi assegnata all'ultima dell'anno precedente
5
+ * i giorni relativi vengono aggiunti alla prima settimana (che così ha più di 7 giorni)
6
+ * discorso analogo per l'ultima settimana
7
+ *
8
+ * @param {date} date
9
+ * @param {number} year
10
+ * @returns Number
11
+ */
12
+
13
+
14
+ export function getWeekOfDate({date = new Date(), year = null}) {
15
+
16
+ // se year è null, si considera quello della data indicata
17
+ if(year == null) {
18
+ year = date.getFullYear();
19
+ }
20
+
21
+ // se la data non è nell'anno indicato, viene restituito null
22
+ if(date.getFullYear() !== year) {
23
+ return null;
24
+ }
25
+
26
+ const dateMonth = date.getMonth(); // necessario congelarlo, date viene modificata più volte
27
+
28
+ date.setHours(0, 0, 0, 0);
29
+
30
+ // Thursday in current week decides the year.
31
+ date.setDate(date.getDate() + 3 - (date.getDay() + 6) % 7);
32
+ // January 4 is always in week 1.
33
+ let week1 = new Date(date.getFullYear(), 0, 4);
34
+ // Adjust to Thursday in week 1 and count number of weeks from date to week1.
35
+ let currentWeek = 1 + Math.round(
36
+ ((date.getTime() - week1.getTime()) / 86400e3 - 3 + (week1.getDay() + 6) % 7) / 7
37
+ );
38
+
39
+ // prima settimana con meno di 4 giorni, normalmente sarebbe calcolata nell'anno precedente
40
+ // ma in questo caso i giorni relativi vengono aggiunti alla prima settimana del nuovo anno
41
+ if(currentWeek >= 52 && dateMonth === 0) {
42
+ currentWeek = 1;
43
+ }
44
+
45
+ return currentWeek;
46
+
47
+ }
48
+
49
+
50
+ /**
51
+ * Restituisce le date di inizio e fine della settimana dell'anno dati
52
+ *
53
+ * @param {number} week
54
+ * @param {number} year
55
+ * @returns Array
56
+ */
57
+ export function getDatesOfWeek(week, year) {
58
+ if(week) {
59
+
60
+ let startDay, endDay;
61
+
62
+ const jan1 = new Date(Date.UTC(year, 0, 1, 0, 0, 0))
63
+ , jan1DayOfTheWeek = jan1.getDay()
64
+ // primo lunedì dell'anno
65
+ , daysToFirstMonday = jan1DayOfTheWeek === 1? 0 : jan1DayOfTheWeek === 0? 1 : 8 - jan1DayOfTheWeek
66
+ , firstMonday = daysToFirstMonday === 0 ? jan1 : new Date(+jan1 + daysToFirstMonday * 86400e3)
67
+ , dec31 = new Date(Date.UTC(year, 11, 31))
68
+ , lastDayOfThisWeek = new Date(+firstMonday + ((week - 1) * 7 * 86400e3) + (86400e3 * 6) )
69
+ , __weeks = 52 // ricavato dalla 'array dati, qui è usato un valore fittizio
70
+ ;
71
+
72
+ // console.log('jan1', jan1.toUTCString());
73
+ // console.log('jan1DayOfTheWeek', jan1DayOfTheWeek);
74
+ // console.log('daysToFirstMonday', daysToFirstMonday);
75
+ // console.log('firstMonday', firstMonday.toUTCString());
76
+ // console.log('dec31', dec31.toUTCString());
77
+ // console.log('lastDayOfThisWeek', lastDayOfThisWeek.toUTCString());
78
+
79
+
80
+ // forza il primo giorno della prima settimana al 1 gennaio anche se non è lunedì
81
+ if(week === 1) {
82
+ startDay = jan1;
83
+ } else {
84
+ startDay = new Date(firstMonday.valueOf());
85
+ startDay = new Date(startDay.setDate(startDay.getDate() + 7 * (week - 2)));
86
+ }
87
+
88
+ // prima settimana con più di 4 gg, viene considerata a se stante
89
+ endDay = new Date(startDay.valueOf());
90
+ if(week === 1 && jan1DayOfTheWeek < 5) {
91
+ endDay = new Date(endDay.setDate(endDay.getDate() + 7 - jan1DayOfTheWeek));
92
+ } else {
93
+ endDay = new Date(endDay.setDate(endDay.getDate() + 6));
94
+ }
95
+
96
+ // forza l'ultmo giorno dell'ultima settimana al 31 dic anche se non è domenica
97
+ if(endDay.getFullYear() > year || week === __weeks) {
98
+ endDay = dec31;
99
+ }
100
+
101
+
102
+
103
+ // nel caso in cui la settimana sia la prima o l'ultima,viene restituito un terzo elemento
104
+ // a indicare, rispettivamente, se 1 gennaio corrisponde all'inizione reale della 1a settimana
105
+ // o se 31 dic corrisponde all'ultimo giorno dell'ultima settimana
106
+
107
+ if(week === 1) {
108
+ return [startDay, endDay, +firstMonday === +jan1];
109
+
110
+ } else if (week === __weeks) {
111
+ return [startDay, endDay, +dec31 === +lastDayOfThisWeek];
112
+
113
+ } else {
114
+ return [startDay, endDay];
115
+ }
116
+
117
+ } else {
118
+ return null;
119
+ }
120
+
121
+
122
+ }