PageSourceSearch

https://www.hacienda.cl/assets/@confidare/chart-bundle/controller-M-Li6mN.js

js hacienda.cl collected 2026-09-24 08:41:47 UTC 27,180 bytes, 558 lines download raw bytes

1import { Chart, registerables } from 'chart.js';
2
3Chart.register(...registerables);
4
5import { LineWithErrorBarsChart, ScatterWithErrorBarsChart } from 'chartjs-chart-error-bars';
6
7import regression from 'regression';
8
9import ChartDataLabels from 'chartjs-plugin-datalabels';
10Chart.register(ChartDataLabels);
11
12import annotationPlugin from 'chartjs-plugin-annotation';
13Chart.register(annotationPlugin);
14
15import { Controller } from '@hotwired/stimulus';
16
17export default class extends Controller {
18    static values = {
19        config: String
20    };
21
22    connect() {
23        var e = this.element
24
25        const config = JSON.parse(this.configValue);
26
27        switch (config.tipo) {
28
29            case 'bar':
30            case 'line':
31                var chart = new Chart(e, {
32                    type: config.tipo,
33                    data: {
34                        labels: config.labels,
35                    },
36                    options: {
37                        aspectRatio: config.aspect,
38                        maintainAspectRatio: false,
39                        responsive: true,
40                        layout: {
41                            padding: {
42                                top: 20,
43                                bottom: 20,
44                                left: 0,
45                                right: 0,
46                            },
47                        },
48                        indexAxis: config.flip? 'y': 'x',
49                        scales: {
50                            x: {
51                                stacked: config.stacked,
52                                display: !config.thumb,
53                                max: config.xMax ?? undefined,
54                                grid: {
55                                    color: ({ tick }) => tick?.value == 0 ? (config.flip? config.gridZeroYColor: config.gridZeroXColor) : (config.flip? config.gridYColor: config.gridXColor),
56                                },
57                                title: {
58                                    display: config.scaleXLabel != '',
59                                    text: config.scaleXLabel,
60                                },
61                            },
62                            y: {
63                                stacked: config.stacked,
64                                display: !config.thumb,
65                                max: config.yMax ?? undefined,
66                                grid: {
67                                    color: ({ tick }) => tick?.value == 0 ? (config.flip? config.gridZeroXColor: config.gridZeroYColor) : (config.flip? config.gridXColor: config.gridYColor),
68                                },
69                                border: {
70                                    color: config.flip? config.gridEdgeXColor: config.gridEdgeYColor,
71                                },
72                                title: {
73                                    display: config.scaleYLabel != '',
74                                    text: config.scaleYLabel,
75                                },
76                            },
77                        },
78                        plugins: {
79                            title: {
80                                display: config.title != null,
81                                text: config.title,
82                                padding: { bottom: 30 },
83                            },
84                            legend: {
85                                display: !config.thumb && (
86                                    config.legend || config.stacked || config.series.length > 1
87                                ),
88                                position: config.legendPosition,
89                                labels: {
90                                    usePointStyle: true,
91                                    generateLabels: (chart) => {
92                                        return chart.data.datasets.map((dataset, i) => {
93                                            const meta = chart.getDatasetMeta(i);
94                                            const backgroundColor = Array.isArray(dataset.backgroundColor)? dataset.backgroundColor[i]: dataset.backgroundColor;
95                                            const borderColor = Array.isArray(dataset.borderColor)? dataset.borderColor[i]: dataset.borderColor;
96                                            const borderWidth = Array.isArray(dataset.borderWidth)? dataset.borderWidth[i]: dataset.borderWidth;
97
98                                            var ps = 'rect';
99                                            if (config.subtipos[i] == 'line') {
100                                                var ps = 'line';
101                                                if (config.pointRadius[i % config.pointRadius.length] > 0) {
102                                                    var svg;
103                                                    if (config.pointStyle[i % config.pointStyle.length] != 'circle') {
104                                                        svg = `
105                                                        <svg width="20" height="50" xmlns="http://www.w3.org/2000/svg">
106                                                            <line x1="0" y1="25" x2="32" y2="25" stroke="${borderColor}" stroke-width="${borderWidth}"/>
107                                                            <rect x="7" y="22" width="6" height="6" fill="${backgroundColor}" stroke="${borderColor}" stroke-width="1"/>
108                                                        </svg>`;
109                                                    } else {
110                                                        svg = `
111                                                        <svg width="20" height="50" xmlns="http://www.w3.org/2000/svg">
112                                                            <line x1="0" y1="25" x2="32" y2="25" stroke="${borderColor}" stroke-width="${borderWidth}"/>
113                                                            <circle cx="10" cy="25" r="3" fill="${backgroundColor}" stroke="${borderColor}" stroke-width="1"/>
114                                                        </svg>`;
115                                                    }
116                                                    let blob = new Blob([svg], {type: 'image/svg+xml'});
117                                                    let url = URL.createObjectURL(blob);
118
119                                                    var ps = document.createElement('img');
120                                                    ps.src = url;
121                                                    ps.addEventListener('load', () => URL.revokeObjectURL(url), {once: true});
122                                                }
123                                            }
124
125                                            // https://www.chartjs.org/docs/latest/configuration/legend.html#legend-item-interface
126                                            return {
127                                                // Base
128                                                datasetIndex: i,
129                                                hidden: meta.hidden,
130                                                strokeStyle: borderColor,
131                                                fillStyle: backgroundColor,
132                                                text: dataset.label,
133                                                fontColor: '#666',
134                                                // Custom style
135                                                pointStyle: ps,
136                                                lineDash: config.borderDash[i % config.borderDash.length],
137                                                lineDashOffset: 4,
138                                                lineWidth: dataset.borderWidth,
139                                            };
140                                        });
141                                    },
142                                },
143                            },
144                            datalabels: {
145                                display: config.datalabels && !(config.stacked) && !(config.thumb),
146                                clamp: true,
147                                color: '#666',
148                                anchor: 'end',
149                                align: config.flip? '10': 'top',
150                                formatter: function (val, ctx) {
151                                    if (val == null) {
152                                        return null;
153                                    }
154                                    if (config.unit != '') {
155                                        return val + ' ' + config.unit;
156                                    }
157                                    return val;
158                                },
159                            },
160                            tooltip: {
161                                callbacks: {
162                                    label: function(ctx) {
163                                        if (config.unit != '') {
164                                            return ctx.formattedValue + ' ' + config.unit;
165                                        }
166                                    }
167                                }
168                            },
169                            beforeInit: function(chart, options) {
170                                chart.legend.afterFit = function() {
171                                    this.height = this.height + 200;
172                                };
173                            }
174                        },
175                        animation: {
176                            onComplete: function(ctx) {
177                                const scales = ctx.chart.scales
178
179                                // Fondos sombreados
180                                if (ctx.initial && config.shadesX.length > 0) {
181                                    config.shadesX.forEach(function(j, serie) {
182                                        ctx.chart.options.plugins.annotation.annotations['' + serie] = {
183                                            type: 'box',
184                                            xMin: j[0],
185                                            xMax: j[1],
186                                            yMin: scales.y.min,
187                                            yMax: scales.y.max,
188                                            backgroundColor: '#ECF1F4',
189                                            borderWidth: 0,
190                                            drawTime: 'beforeDraw',
191                                        }
192                                    })
193
194                                    chart.update();
195                                }
196                                // Flechas
197                                if (ctx.initial && config.arrows.length > 0) {
198                                    config.arrows.forEach(function(j, serie) {
199                                        j.forEach(function(i, el) {
200                                            const ratio_x = (scales.x.max - scales.x.min) / scales.x.width
201                                            const ratio_y = (scales.y.max - scales.y.min) / scales.y.height
202
203                                            const arrow_pos = Number(i[0]) - .5  + (serie * (1 / config.bySerie.length)) + (.5 / config.bySerie.length)
204                                                           // ^ valor              ^ al margen izq del valor               ^ al centro del valor
205                                                           //                ^ al margen izq de la serie
206
207                                            //console.log("serie: " + config.series[serie] + " (" + serie + ")", "valor: " + i[0], "pos: " + x_pos)
208
209                                            ctx.chart.options.plugins.annotation.annotations['' + serie + el] = {
210                                                type: 'line',
211                                                arrowHeads: {
212                                                    start: { display: i[1] < 0 },
213                                                    end:   { display: i[1] > 0 },
214                                                },
215                                                borderColor: i[1] > 0? '#22B14C': '#FF7F27',
216                                                borderWidth: 3,
217
218                                                xMin: config.flip?
219                                                    Number(config.bySerie[serie][i[0]]) + ratio_x * 40:
220                                                    arrow_pos,
221
222                                                xMax: config.flip?
223                                                    Number(config.bySerie[serie][i[0]]) + ratio_x * 70:
224                                                    arrow_pos,
225
226                                                yMin: config.flip?
227                                                    arrow_pos:
228                                                    Number(config.bySerie[serie][i[0]]) + ratio_y * 30,
229
230                                                yMax: config.flip?
231                                                    arrow_pos:
232                                                    Number(config.bySerie[serie][i[0]]) + ratio_y * 60,
233                                            }
234                                        })
235                                    })
236
237                                    chart.update();
238                                }
239                            },
240                        },
241                        onClick: (event, elements, chart) => {
242                            if (config.link != '') {
243                                window.location = config.link;
244                            }
245                        },
246                    },
247                    plugins: [{
248                        beforeInit: function(chart) {
249                            chart.data.labels.forEach(function(e, i, a) {
250                                a[i] = e.split('|');
251                            });
252                        },
253                    }],
254                })
255
256                if (config.disableAnimation) {
257                    chart.options.animation = false;
258                }
259
260                for (var i = 0; i < config.bySerie.length; i++) {
261
262                    chart.data.datasets.push({
263                        barPercentage: .9,
264                        categoryPercentage: .975,
265                        type: config.subtipos[i],
266                        label: config.series[i],
267                        data: config.bySerie[i],
268                        lineTension: 0,
269                        spanGaps: false,
270                        backgroundColor: config.backgroundColor[i % config.backgroundColor.length],
271                        borderColor: config.borderColor[i % config.borderColor.length],
272                        borderWidth: config.borderWidth[i % config.borderWidth.length],
273                        pointStyle: config.pointStyle[i % config.pointStyle.length],
274                        pointRadius: config.pointRadius[i % config.pointRadius.length],
275                        pointBackgroundColor: config.pointBackgroundColor[i % config.pointBackgroundColor.length ],
276                        pointBorderWidth: config.pointBorderWidth[i % config.pointBorderWidth.length],
277                        borderDash: config.borderDash[i % config.borderDash.length],
278                        fill: config.fill? 'origin': false,
279                        order: config.order? config.order[i]: i,
280                        stack: (config.subtipos[i] == 'bar' || config.fill )? 'stack_group': 'stack_' + i,
281                    }) }
282
283                chart.update();
284
285                break;
286
287            case 'pie':
288            case 'doughnut':
289
290                var chart = new Chart(e, {
291                    type: config.tipo,
292                    data: {
293                        labels: config.labels,
294                    },
295                    options: {
296                        aspectRatio: config.aspect,
297                        maintainAspectRatio: false,
298                        responsive: true,
299                        layout: {
300                            padding: {
301                                top: 20,
302                                bottom: 20,
303                                left:  70,
304                                right: 70,
305                            },
306                        },
307                        plugins: {
308                            title: {
309                                display: config.title != null,
310                                text: (config.title),
311                                padding: { bottom: 30 },
312                            },
313                            legend: {
314                                display: config.legend || config.stacked,
315                                position: config.legendPosition,
316                            },
317                            datalabels: {
318                                display: config.datalabels,
319                                clamp: true,
320                                color: '#666',
321                                anchor: 'end',
322                                align: 'end',
323                                formatter: function (val, ctx) {
324                                    return val == 0? null: ctx.chart.data.labels[ctx.dataIndex];
325                                },
326                            },
327                            tooltip: {
328                                callbacks: {
329                                    label: function(ctx) {
330                                        if (config.unit != '') {
331                                            return ctx.formattedValue + ' ' + config.unit;
332                                        }
333                                        if ((typeof config.unit) == 'undefined') {
334                                            return ctx.parsed + ' %';
335                                        }
336                                        return ctx.parsed;
337                                    }
338                                }
339                            }
340                        },
341                    },
342                    plugins: [{
343                        beforeInit: function(chart) {
344                            chart.data.labels.forEach(function(e, i, a) {
345                                a[i] = e.split('|');
346                            });
347                        },
348                    }],
349                })
350
351                if (config.disableAnimation) {
352                    chart.options.animation = false;
353                }
354
355                for (var i = 0; i < config.bySerie.length; i++) {
356                    chart.data.datasets.push({
357                        label: config.series[i],
358                        data: config.bySerie[i],
359                        backgroundColor: Array.isArray(config.backgroundColor[0])? config.backgroundColor[i]: config.backgroundColor,
360                        borderColor: config.borderColor,
361                        borderWidth: config.borderWidth,
362                        fill: false,
363                        pointRadius: 1,
364                        lineTension: 0,
365                        spanGaps: false,
366                    });
367                }
368                chart.update();
369
370                break;
371
372            case 'lineWithErrorBars':
373            case 'scatterWithErrorBars':
374
375                var errorData = []
376                config.series.forEach(function(el, i) {
377                    errorData.push([])
378                    Object.keys(config.raw).forEach(function(j, el) {
379                        if (config.flip) {
380                            errorData[i].push({
381                                x: (config.raw[j][0 + i * 3] == null)? null: Number(config.raw[j][0 + i * 3]),
382                                xMin: (config.raw[j][0 + i * 3] == null)? null: Number(config.raw[j][1 + i * 3]),
383                                xMax: (config.raw[j][0 + i * 3] == null)? null: Number(config.raw[j][2 + i * 3]),
384                            })
385                        } else {
386                            errorData[i].push({
387                                y: (config.raw[j][0 + i * 3] == null)? null: Number(config.raw[j][0 + i * 3]),
388                                yMin: (config.raw[j][0 + i * 3] == null)? null: Number(config.raw[j][1 + i * 3]),
389                                yMax: (config.raw[j][0 + i * 3] == null)? null: Number(config.raw[j][2 + i * 3]),
390                            })
391                        }
392                    })
393                })
394
395                var chart = new LineWithErrorBarsChart(e, {
396                    type: 'lineWithErrorBars',
397                    data: {
398                        labels: config.labels,
399                    },
400                    options: {
401                        aspectRatio: config.aspect,
402                        maintainAspectRatio: false,
403                        responsive: true,
404                        layout: {
405                            padding: {
406                                top: 30,
407                                bottom: 0,
408                                left: 20,
409                                right: 30,
410                            },
411                        },
412                        indexAxis: config.flip? 'y': 'x',
413                        plugins: {
414                            title: {
415                                display: config.title != null,
416                                text: (config.title),
417                            },
418                            legend: {
419                                display: true,
420                                position: 'bottom',
421                            },
422                            datalabels: {
423                                display: config.datalabels,
424                            },
425                            tooltip: {
426                                callbacks: {
427                                    label: function(ctx) {
428                                        if (config.flip) {
429                                            return ctx.dataset.label + ': ' + ctx.parsed.x + ' (' + ctx.parsed.xMin + ' … ' + ctx.parsed.xMax + ')';
430                                        } else {
431                                            return ctx.dataset.label + ': ' + ctx.parsed.y + ' (' + ctx.parsed.yMin + ' … ' + ctx.parsed.yMax + ')';
432                                        }
433                                    }
434                                }
435                            }
436                        },
437                    },
438                })
439
440                if (config.disableAnimation) {
441                    chart.options.animation = false;
442                }
443
444                config.series.forEach(function(el, i) {
445                    chart.data.datasets.push({
446                        label: config.series[i],
447                        data: errorData[i],
448                        backgroundColor: config.backgroundColor[i % config.backgroundColor.length],
449                        borderColor: config.borderColor[i % config.borderColor.length],
450                        borderWidth: config.borderWidth[i % config.borderWidth.length],
451                        showLine: false,
452                    });
453                })
454                chart.update();
455
456                break;
457
458            case 'scatter':
459                var data = [];
460                Object.keys(config.raw).forEach(function(x, i) {
461                    config.raw[x].forEach(function(y, j) {
462                        data.push({
463                            x: x,
464                            y: y,
465                        })
466                    })
467                })
468
469                var chart = new Chart(e, {
470                    type: config.tipo,
471                    data: {
472                        datasets: [
473                            {
474                                data: data,
475                                backgroundColor: config.backgroundColor[0],
476                                label: config.series[0] ?? null,
477                            },
478                        ],
479                    },
480                    options: {
481                        aspectRatio: config.aspect,
482                        maintainAspectRatio: false,
483                        responsive: true,
484                        indexAxis: config.flip? 'y': 'x',
485                        scales: {
486                            x: {
487                                title: {
488                                    display: config.x != '',
489                                    text: config.x,
490                                },
491                            },
492                            y: {
493                                title: {
494                                    display: config.y != '',
495                                    text: config.y,
496                                },
497                            },
498                        },
499                        plugins: {
500                            title: {
501                                display: config.title != null,
502                                text: (config.title),
503                            },
504                            legend: {
505                                display: config.legend && ((config.series[0] ?? '') != ''),
506                                position: 'top',
507                                labels: {
508                                    filter: function(labelItem) {
509                                        return labelItem.datasetIndex < 1
510                                    }
511                                }
512                            },
513                            datalabels: {
514                                display: config.datalabels,
515                            },
516                            tooltip: {
517                                filter: function(tooltipItem) {
518                                    return tooltipItem.datasetIndex < 1
519                                },
520                            },
521                        },
522                    },
523                })
524
525                if (config.disableAnimation) {
526                    chart.options.animation = false;
527                }
528
529                if (config.regression) {
530                    var data_reg = [];
531                    Object.keys(config.raw).forEach(function(x, i) {
532                        config.raw[x].forEach(function(y, j) {
533                            data_reg.push([Number(x), Number(y)])
534                        })
535                    })
536
537                    const reg = regression.linear(data_reg)
538
539                    chart.data.datasets.push({
540                        type: 'line',
541                        data: reg.points,
542                        pointRadius: 0,
543                        label: '',
544                        plugins: {
545                            tooltip: {
546                                display: false,
547                            },
548                        }
549                    });
550
551                    chart.update();
552                }
553                break;
554
555        }
556
557    }
558}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.