@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,456 @@
1
+ import classnames from 'classnames';
2
+ import { useState, useEffect, useRef, Fragment } from 'react';
3
+ import PropTypes from 'prop-types';
4
+ // import styles from '../charts-base.module.scss';
5
+ import { nanoid } from 'nanoid';
6
+
7
+
8
+ /*
9
+ InfoBox versione su grafico linee
10
+
11
+
12
+
13
+ function InfoBox({
14
+ year = new Date().getFullYear(),
15
+ infoBoxItems = [],
16
+ infoBoxPositionRefs = [],
17
+ cfg = {},
18
+ mode = 'week',
19
+ data,
20
+ week,
21
+ month,
22
+ dataGroupEl,
23
+ skipWeek0
24
+ }) {
25
+ const [content, setContent] = useState(null),
26
+ infoBoxWrapperRef = useRef();
27
+
28
+
29
+ const weekMode = useMemo(() => {
30
+ return mode === 'week';
31
+ }, [mode]),
32
+ infoBoxWidth = useMemo(() => {
33
+ return weekMode? 300 : 240;
34
+ }, [weekMode]);
35
+
36
+ useEffect(() => {
37
+
38
+ // =>> getDatesOfWeek
39
+ const getDatesOfWeek = week => {
40
+ if(week) {
41
+
42
+ let startDay, endDay;
43
+ const daysToFirstMonday = cfg.jan1DayOfTheWeek === 1? 0 : cfg.jan1DayOfTheWeek === 0? 1 : 8 - cfg.jan1DayOfTheWeek;
44
+ // primo lunedì dell'anno
45
+ const firstMonday = daysToFirstMonday === 0 ? cfg.jan1 : new Date(+cfg.jan1 + daysToFirstMonday * 86400e3);
46
+
47
+ const dec31 = new Date(year, 11, 31),
48
+ lastDayOfLastWeek = new Date(+firstMonday + ((week - 1) * 7 * 86400e3) + (86400e3 * 6) );
49
+
50
+ // forza il primo giorno della prima settimana al 1 gennaio anche se non è lunedì
51
+ if(week === 1) {
52
+ startDay = cfg.jan1;
53
+ } else {
54
+ startDay = new Date(firstMonday.valueOf());
55
+ startDay = new Date(startDay.setDate(startDay.getDate() + 7 * (week - 2)));
56
+ }
57
+
58
+ // prima settimana con più di 4 gg, viene considerata a se stante
59
+ endDay = new Date(startDay.valueOf());
60
+ if(week === 1 && cfg.jan1DayOfTheWeek < 5) {
61
+ endDay = new Date(endDay.setDate(endDay.getDate() + 7 - cfg.jan1DayOfTheWeek));
62
+ } else {
63
+ endDay = new Date(endDay.setDate(endDay.getDate() + 6));
64
+ }
65
+
66
+ // forza l'ultmo giorno dell'ultima settimana al 31 dic anche se non è domenica
67
+ // e si tratta dell'ultima settimana
68
+ if(endDay.getFullYear() > year || week === cfg.weeks) {
69
+ endDay = dec31;
70
+ }
71
+
72
+
73
+ // nel caso in cui la settimana sia la prima o l'ultima,viene restituito un terzo elemento
74
+ // a indicare, rispettivamente, se 1 gennaio corrisponde all'inizio reale della 1a settimana
75
+ // o se 31 dic corrisponde all'ultimo giorno dell'ultima settimana
76
+
77
+ if(week === 1) {
78
+ return [startDay, endDay, +firstMonday === +cfg.jan1];
79
+
80
+ } else if (week === cfg.weeks) {
81
+ return [startDay, endDay, +dec31 === +lastDayOfLastWeek];
82
+
83
+ } else {
84
+ return [startDay, endDay];
85
+ }
86
+
87
+ } else {
88
+ return null;
89
+ }
90
+
91
+
92
+ };
93
+
94
+ if(data) {
95
+
96
+ const weekDates = getDatesOfWeek(data.w),
97
+ dateToLocalOptions = {
98
+ month: 'long',
99
+ day: 'numeric'
100
+ },
101
+ setDateRangeText = () => {
102
+ if(data.w === 0) {
103
+ return null;
104
+
105
+ } else {
106
+ return <>
107
+ <span className="text-nowrap">
108
+ {weekDates[0].toLocaleString('it-IT',
109
+ weekDates[0].getMonth() !== weekDates[1].getMonth()? dateToLocalOptions
110
+ : {day: 'numeric'}
111
+ )}
112
+ </span>
113
+ {' \u2013 '}
114
+ <span className="text-nowrap">{weekDates[1].toLocaleString('it-IT', dateToLocalOptions)}</span>
115
+ </>;
116
+ }
117
+ };
118
+
119
+ //weeks:
120
+ //props.data : {
121
+ // "w": 0, <- settimana, 0 = anno prec.
122
+ // "s": 519096, <- budget standard
123
+ // "p": 812136, <- budget positivo
124
+ // "n": 43242, <- budget negativo
125
+ // "c": 674824 <- budget consolidato (null se non presente)
126
+ // "cp": 612345 <- budget consolidato anno precedente
127
+ // }
128
+
129
+
130
+
131
+ setContent(<>
132
+
133
+ // {weekMode?
134
+ // <>
135
+ // <div className={styles.infoBoxTitle}>{props.data.w? <>Settimana {props.data.w}</> : <>Anno precedente</>}</div>
136
+ // <div className={styles.infoBoxDescr}>{setDateRangeText()}</div>
137
+ // </>
138
+ // :
139
+ // <>{mesi[props.month]}</>
140
+ // }
141
+
142
+ <div className={styles.infoBoxTitle}>{data.w? <>Settimana {data.w}</> : <>Anno precedente</>}</div>
143
+ <div className={styles.infoBoxDescr}>{setDateRangeText()}</div>
144
+
145
+ <table className={styles.infoBoxTable}>
146
+ <tbody>
147
+ {infoBoxItems.map((item, idx) => {
148
+
149
+ return <tr key={nanoid()}>
150
+ <th scope="row" className={item.tdClassName}>
151
+ {item.flagClassName && <span className={classnames(styles.infoBoxFlag, item.flagClassName)} />}
152
+ {item.label}
153
+ </th>
154
+ <td className={item.tdClassName}>{data[item.key] != null?
155
+ <span className="euro">{data[item.key].toLocaleString('it-IT')}</span>
156
+ : '\u2014'}
157
+ </td>
158
+ // =>> infobox: incremento
159
+ {(data[item.key] != null && idx === 0)?
160
+ <td className='pl-2 align-baseline' rowSpan={Object.keys(infoBoxItems).length}>
161
+ {formatDelta(data.c, data.cp)}
162
+ </td>
163
+ : ''
164
+ }
165
+ </tr>;
166
+ })}
167
+ </tbody>
168
+ </table>
169
+
170
+
171
+ // weekDates[3] (true/false) è presente solo per la prima e l'ultima settimana
172
+ {weekMode && <>
173
+ {data.w === 1 && !weekDates[3] &&
174
+ <div className={styles.infoBoxNote}>
175
+ NB: sono inclusi anche i giorni precedenti al primo lunedì dell’anno.
176
+ </div>
177
+ }
178
+ {data.w === cfg.weeks && !weekDates[3] &&
179
+ <div className={styles.infoBoxNote}>
180
+ NB: sono inclusi anche i giorni successivi alla domenica dell’ultima settimana.
181
+ </div>
182
+ }
183
+ </>}
184
+
185
+ </>);
186
+ }
187
+ }, [cfg.jan1, cfg.jan1DayOfTheWeek, cfg.weeks, data, infoBoxItems, month, year, weekMode]);
188
+
189
+ useEffect(() => {
190
+ if(dataGroupEl && (week != null || month != null)) {
191
+
192
+ const infoBoxMargin = 8; // distanza dalla linea della griglia della settimana in esame
193
+
194
+ // lato in cui posizionare InfoBox rispetto all'asse della settimana
195
+ let side;
196
+ if(weekMode) {
197
+ side = week > cfg.weeks/2? 'left' : 'right';
198
+ } else {
199
+ side = month > 5? 'left' : 'right';
200
+ }
201
+
202
+ dataGroupEl?.classList.add(styles.dataGroupOn);
203
+ dataGroupEl?.closest(`.${styles.chart}`)?.classList.add(styles.infoBoxWrapperOn);
204
+
205
+ infoBoxWrapperRef.current.setAttribute('transform-origin',
206
+ `${side === 'left'? 'right' : 'left'} top`
207
+ );
208
+
209
+ infoBoxWrapperRef.current.dataset.side = side;
210
+ const infoBoxSize = infoBoxWrapperRef.current.querySelector(':scope > div').getBoundingClientRect();
211
+ // infoBoxWrapperRef.current.setAttribute('height', infoBoxSize.height);
212
+ // infoBoxWrapperRef.current.setAttribute('width', infoBoxSize.width);
213
+
214
+ // let puntoRif;
215
+ // for(const ref of infoBoxPositionRefs) {
216
+ // puntoRif = dataGroupEl.querySelector(`.${styles[ref]}`);
217
+ // if(puntoRif) {
218
+ // break;
219
+ // }
220
+ // }
221
+
222
+ // let y = puntoRif? +puntoRif.getAttribute('cy') : Infinity;
223
+ // y = Math.min(y, cfg.chart_area.top + cfg.chart_area.height - infoBoxSize.height - 5);
224
+
225
+ // posizionamento vicino alle asse X
226
+ let y = cfg.chart_area.top + cfg.chart_area.height - infoBoxSize.height - 5;
227
+ infoBoxWrapperRef.current.setAttribute('y', y);
228
+
229
+ let transformX = weekMode?
230
+ cfg.chart_area.left + ((week - (skipWeek0? 1 : 0)) * cfg.xStep) +
231
+ (side === 'left'? -infoBoxWidth - infoBoxMargin : infoBoxMargin)
232
+ :
233
+ cfg.chart_area.left + ((month - 1) * cfg.xStep) +
234
+ (side === 'left'? -infoBoxWidth - infoBoxMargin: infoBoxMargin) +
235
+ cfg.xStep / 2;
236
+
237
+ infoBoxWrapperRef.current.setAttribute('transform', `translate(${transformX} 0)`);
238
+
239
+
240
+ }
241
+
242
+ }, [infoBoxWidth, cfg, dataGroupEl, infoBoxPositionRefs, month, skipWeek0, week, weekMode]);
243
+
244
+
245
+ return (
246
+ <foreignObject className={styles.infoBoxWrapper}
247
+ x="0" y="-1000"
248
+ width={infoBoxWidth}
249
+ height={300}
250
+ ref={infoBoxWrapperRef}
251
+ >
252
+ <div xmlns="http://www.w3.org/1999/xhtml">
253
+ {content}
254
+ </div>
255
+ // <div xmlns="http://www.w3.org/1999/xhtml" style={{
256
+ // position: 'absolute',
257
+ // top: 0, left: 0,
258
+ // width: '100%', height: '100%',
259
+ // backgroundColor: 'rgba(255,0,0, .2)'
260
+ // }}></div>
261
+ </foreignObject>
262
+ );
263
+
264
+ InfoBox.propTypes = {
265
+ data : PropTypes.object,
266
+ week : PropTypes.number,
267
+ month : PropTypes.number,
268
+ dataGroupEl : PropTypes.any,
269
+ year : PropTypes.number,
270
+ cfg : PropTypes.object,
271
+ mode : PropTypes.oneOf(['month', 'week']),
272
+
273
+ // array di classi di elementi all'interno di dataGroupEl dai quali ricavare
274
+ // la coordinata y per il posizionamento di InfoBox
275
+ // almeno uno deve essere sicuramente presente
276
+ infoBoxPositionRefs : PropTypes.arrayOf(PropTypes.string),
277
+
278
+ // elementi, etichette, classe td e classe indicatore colorato per la costruzione dell'infoBox
279
+ // nell'ordine in cui verranno mostrate
280
+ infoBoxItems : PropTypes.arrayOf(
281
+ PropTypes.shape({
282
+ key : PropTypes.string,
283
+ label : PropTypes.string,
284
+ tdClassName : PropTypes.string,
285
+ flagClassName : PropTypes.string,
286
+ dataPointClassName : PropTypes.string
287
+ })
288
+ )
289
+
290
+ };
291
+
292
+ */
293
+
294
+
295
+ function InfoBox({
296
+ data,
297
+ dataGroupEl,
298
+ cfg,
299
+ // mode, // da eliminare
300
+ infoBoxWidth,
301
+ elementsCount,
302
+ styles,
303
+ title,
304
+ year = new Date().getFullYear(),
305
+ infoBoxItems = [],
306
+ // infoBoxPositionRefs = [],
307
+ extraRows = null
308
+ }) {
309
+ const [content, setContent] = useState(null),
310
+ infoBoxWrapperRef = useRef();
311
+
312
+ useEffect(() => {
313
+
314
+ if(data) {
315
+
316
+
317
+ setContent(<>
318
+
319
+ <div className={styles.infoBoxTitle}>{title}</div>
320
+
321
+ <table className={styles.infoBoxTable}>
322
+ <tbody>
323
+ {infoBoxItems.map(item => {
324
+ return <tr key={nanoid()}>
325
+ <th scope="row" className={classnames(item.tdClassName)}>
326
+ {item.flagClassName && <span className={classnames(styles.infoBoxFlag, item.flagClassName)} />}
327
+ {item.label}
328
+ </th>
329
+ <td className={classnames(item.tdClassName)}>{data[item.key] != null?
330
+ <span className="euro">{data[item.key].toLocaleString('it-IT')}</span>
331
+ :
332
+ '—'}
333
+ </td>
334
+ </tr>;
335
+ })}
336
+ {extraRows.map(row => {
337
+ return <tr key={nanoid()}>
338
+ <th scope="row">{row.label}</th>
339
+ <td>{row.value? row.value : '—'} </td>
340
+ </tr>;
341
+ })}
342
+ </tbody>
343
+ </table>
344
+
345
+ </>);
346
+ }
347
+ }, [cfg, data, extraRows, infoBoxItems, styles, title, year]);
348
+
349
+ useEffect(() => {
350
+ if(dataGroupEl) {
351
+
352
+ const infoBoxMargin = 8; // distanza dalla linea della griglia della settimana in esame
353
+
354
+ // lato in cui posizionare InfoBox rispetto all'asse della settimana
355
+ const xKey = dataGroupEl.dataset.xKey,
356
+ side = xKey > Math.floor(elementsCount/2)-1? 'left' : 'right';
357
+
358
+
359
+ dataGroupEl.classList.add(styles.dataGroupOn);
360
+ dataGroupEl.closest(`.${styles.chart}`).classList.add(styles.infoBoxWrapperOn);
361
+
362
+ infoBoxWrapperRef.current.setAttribute('transform-origin',
363
+ `${side === 'left'? 'right' : 'left'} top`
364
+ );
365
+
366
+ infoBoxWrapperRef.current.dataset.side = side;
367
+ // const infoBoxSize = infoBoxWrapperRef.current.querySelector(':scope > div').getBoundingClientRect();
368
+ // infoBoxWrapperRef.current.setAttribute('height', infoBoxSize.height);
369
+ // infoBoxWrapperRef.current.setAttribute('width', infoBoxSize.width);
370
+
371
+ // let puntoRif;
372
+ // for(const ref of infoBoxPositionRefs) {
373
+ // puntoRif = dataGroupEl.querySelector(`.${styles[ref]}`);
374
+ // if(puntoRif) {
375
+ // break;
376
+ // }
377
+ // }
378
+
379
+ // let y = puntoRif? +puntoRif.getAttribute('cy') : Infinity;
380
+ // y = Math.min(y, cfg.chart_area.top + cfg.chart_area.height - infoBoxSize.height - 5);
381
+
382
+ // posizionamento vicino alle asse X
383
+ // let y = cfg.chart_area.top + cfg.chart_area.height - infoBoxSize.height - 5;
384
+ // infoBoxWrapperRef.current.setAttribute('y', y);
385
+
386
+ // il metodo precedente provoca all'inizio un posizionamento errato sull'asse y
387
+ infoBoxWrapperRef.current.setAttribute('y', cfg.chart_area.top +10);
388
+
389
+ let transformX = cfg.chart_area.left + (xKey * cfg.xStep) +
390
+ (side === 'left'? -infoBoxWidth - infoBoxMargin - cfg.xStep * .8 : infoBoxMargin);
391
+
392
+ infoBoxWrapperRef.current.setAttribute('transform', `translate(${transformX} 0)`);
393
+
394
+ }
395
+
396
+ }, [infoBoxWidth, cfg, dataGroupEl, styles, elementsCount]);
397
+
398
+
399
+ return (
400
+ <foreignObject className={styles.infoBoxWrapper}
401
+ x="0" y="-1000"
402
+ width={infoBoxWidth}
403
+ height={300}
404
+ ref={infoBoxWrapperRef}
405
+ >
406
+ <div xmlns="http://www.w3.org/1999/xhtml">
407
+ {content}
408
+ </div>
409
+ {/* <div xmlns="http://www.w3.org/1999/xhtml" style={{
410
+ position: 'absolute',
411
+ top: 0, left: 0,
412
+ width: '100%', height: '100%',
413
+ backgroundColor: 'rgba(255,0,0, .2)'
414
+ }}></div> */}
415
+ </foreignObject>
416
+ );
417
+ }
418
+
419
+ InfoBox.propTypes = {
420
+ data : PropTypes.object,
421
+ dataGroupEl : PropTypes.any,
422
+ year : PropTypes.number,
423
+ cfg : PropTypes.object,
424
+
425
+ // da eliminare
426
+ // mode : PropTypes.string,
427
+
428
+ // array di classi di elementi all'interno di dataGroupEl dai quali ricavare
429
+ // la coordinata y per il posizionamento di InfoBox
430
+ // almeno uno deve essere sicuramente presente
431
+ // infoBoxPositionRefs : PropTypes.arrayOf(PropTypes.string),
432
+
433
+ // elementi, etichette, classe td e classe indicatore colorato per la costruzione dell'infoBox
434
+ // nell'ordine in cui verranno mostrate
435
+ infoBoxItems : PropTypes.arrayOf(
436
+ PropTypes.shape({
437
+ key : PropTypes.string,
438
+ label : PropTypes.string,
439
+ tdClassName : PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
440
+ flagClassName : PropTypes.oneOfType([PropTypes.array, PropTypes.string]),
441
+ })
442
+ ),
443
+
444
+ // larghezza da assegnare all'elemento foreignObject
445
+ infoBoxWidth: PropTypes.number,
446
+
447
+ // numero di elementi sui quali mostrare infoBox (per la posizione dx o sx)
448
+ elementsCount: PropTypes.number,
449
+
450
+ /** righe extra da aggiungere alla infobox */
451
+ extraRows: PropTypes.array
452
+
453
+ };
454
+
455
+
456
+ export default InfoBox;
@@ -0,0 +1,53 @@
1
+ nelle funzioni dei singoli grafici aggiungere `const chartInstance = this;` e sostituire i `this` riferiti ad `adaChart` con `chartInstance`
2
+
3
+
4
+ ****
5
+
6
+ Tutte le funzioni condivise, ad eccezione di `createSvgCanvas`, sono ora standalone e vanno importate dove necessario.
7
+
8
+ `chartUtils`, `textToSvgPath` e `parseStdAxisOpts` vanno importate e utilizzate direttamente, rimuovendo `this.` o `this.utils.` nel caso di quelle in `chart-utils.js`
9
+
10
+ * `import { parseContainer, truncateDecimal, toRadians, polarToCartesian, classnames, classnamesNull, calcArcCoords, calcAttrD, getElementFromContainer } from '../chart-utils.js';`
11
+ * `import { textToSvgPath } from '../svg-text-to-path.js'`;
12
+ * `import { parseStdAxisOpts } from '../parse-std-axis-opts.js'`;
13
+
14
+
15
+ `cartesianAxis`, `createTextEl`, `legenda`, vanno invocate passando come primo parametro l'istanza della classe, esempio:
16
+
17
+ * `import { cartesianAxis } from '../cartesian-axis.js';`
18
+ * `import { createTextEl } from '../create-text-element.js';`
19
+ * `import { legenda } from '../legenda.js';`
20
+
21
+ ```javascript
22
+ const titleEl = await createTextEl (chartInstance, {
23
+ text: yAxisTitle,
24
+ textFill: yAxisTitleAttrs.fill?? '#000',
25
+ fontAttr: yAxisTitleAttrs,
26
+ fontFilePath: yAxisTitleFontFilePath,
27
+ parentElement: titleGroup
28
+ });
29
+ ```
30
+
31
+ ****
32
+
33
+ `createTextEl` non restituisce più bbox ed elemento ma solo quest'ultimo.
34
+
35
+ ```javascript
36
+ // Cambiare
37
+
38
+ const [labelBbox, labelEl] = await chartInstance.createTextEl({...})
39
+
40
+ // in
41
+
42
+ const labelEl = await createTextEl(chartInstance, {...}),
43
+ labelBbox = labelEl.bbox()
44
+ ```
45
+
46
+ ****
47
+
48
+ L'argomento di parseContainer è ora un oggetto (`function parseContainer({container = null, width = null, height = null, emptyContainer = true}) {...}`), la funzione va quindi invocata specificando i parametri
49
+
50
+ parseContainer ora non svuota più l'elemento
51
+ ****
52
+
53
+ gli argomenti di polarToCartesian non utilizzano più un oggetto per x e y
@@ -0,0 +1 @@
1
+ Da fare
@@ -0,0 +1,39 @@
1
+ decidere se includere anche il grafico settimanale o no
2
+
3
+
4
+ documentare modalità di estensione della classe
5
+
6
+ https://claude.ai/share/551e5453-02fd-4a6c-8147-1197d6908a8d
7
+
8
+ ```javascript
9
+ // my-project/charts/index.js
10
+ import { AdaCharts, barsChart, goalChart } from 'ada-charts'; // re-export originali
11
+ import { myCustomBar } from './my-custom-bar.js';
12
+ import { myTimeline } from './my-timeline.js';
13
+
14
+ // wrapper per i grafici del progetto (stesso pattern)
15
+ export const myCustomBarChart = (chartInstance, params) =>
16
+ myCustomBar.call(chartInstance, params);
17
+
18
+ export const myTimelineChart = (chartInstance, params) =>
19
+ myTimeline.call(chartInstance, params);
20
+
21
+ // re-esporta tutto dalla libreria base
22
+ export { AdaCharts, barsChart, goalChart };
23
+ ```
24
+
25
+ custom chart:
26
+
27
+ ```javascript
28
+ // my-project/charts/my-custom-bar.js
29
+ export function myCustomBar(params) {
30
+ // `this` è l'istanza AdaCharts
31
+ const { data, color = '#333' } = params;
32
+
33
+ // usa i metodi/proprietà di AdaCharts normalmente
34
+ const svg = this.createSVG(); // o come AdaCharts espone il canvas
35
+
36
+ // logica del grafico...
37
+ return svg;
38
+ }
39
+ ```
@@ -0,0 +1,66 @@
1
+ // parametri di configurazione
2
+
3
+ export default function () {
4
+
5
+ const cfg = {
6
+
7
+ asseY_steps : 4, // suddivisioni asse y
8
+ legenda : {
9
+ h : 25, // altezza spazio legenda
10
+ lines_width : 20, // larghezza righe legenda
11
+ circles_radius : 8, // raggio legenda aree
12
+ text_gap : 4, // spazio tra il simbolo e il testo
13
+ text_dy : 4,
14
+ elements_gap : 20 // spazio tra gli elementi della legenda
15
+ },
16
+
17
+ eti_asseY_width : 60, // spazio etichette asse y
18
+ eti_asseX_height : 30, // spazio etichette asse x (grafico settimanale)
19
+ padding : 10, // spazio extra attorno al bordo
20
+
21
+ // altezza o larghezza ticks (secondo l'orientamento)
22
+ ticks : 5,
23
+
24
+ // spazio tra le barre dello stesso gruppo negli istogrammi
25
+ bar_gap : 3,
26
+
27
+ // margine dx e sx tra ogni gruppo di barre dalla sezione
28
+ bar_margin : 6,
29
+
30
+ // altezza aggiuntiva delle aree di evidenziazione dei mesi (solo g. settimanale)
31
+ months_bg_extra_height : 30
32
+ };
33
+
34
+ return cfg;
35
+ }
36
+
37
+
38
+ // =>> chart area
39
+ // coordinate del rettangolo interno all'svg entro cui viene disegnato il grafico
40
+ // i lati sx e inferiore corrispondono agli assi
41
+ // la variabile cfg.chart_area contiene le distanze dal bordo dei 4 lati del rettangolo
42
+ // e le dimensioni dei lati
43
+ export function setChartArea(cfg, svgWidth, svgHeight) {
44
+ return {
45
+ top : cfg.legenda.h + cfg.padding,
46
+ right : svgWidth - cfg.padding,
47
+ bottom : svgHeight - cfg.eti_asseX_height - cfg.padding,
48
+ left : cfg.eti_asseY_width + cfg.padding,
49
+ width : svgWidth - (cfg.padding * 2) - cfg.eti_asseY_width,
50
+ height : svgHeight - (cfg.padding * 2) - cfg.legenda.h - cfg.eti_asseX_height
51
+ };
52
+ }
53
+
54
+ // console.log(cfg.chart_area);
55
+
56
+ // =>> conversione valori in coordinate relative al grafico
57
+ export function valueToYCoord(value, cfg) {
58
+ // la coordinata y è ricavata dalla proporzione con il valore massimo e altezza del grafico
59
+ // => cfg.max_value : cfg.chart_area.height = value : y
60
+ // arrotondata a 4 cifre decimali
61
+
62
+ if(value == null) {
63
+ return 0;
64
+ }
65
+ return Math.round((cfg.chart_area.top + cfg.chart_area.height - ((value * cfg.chart_area.height) / cfg.max_value)) * 1e4) / 1e4;
66
+ }