@visionaris-bruno/vs-echarts 0.0.1
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 +48 -0
- package/fesm2022/visionaris-bruno-vs-echarts.mjs +874 -0
- package/fesm2022/visionaris-bruno-vs-echarts.mjs.map +1 -0
- package/index.d.ts +232 -0
- package/package.json +26 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# vs-echarts Library
|
|
2
|
+
|
|
3
|
+
Biblioteca de componentes de visualización de datos basada en **Apache ECharts** para la suite Visionaris.
|
|
4
|
+
|
|
5
|
+
## 🚀 Características
|
|
6
|
+
- **Arquitectura de Builders**: Separación total entre la configuración de ECharts y los componentes de Angular.
|
|
7
|
+
- **Especialistas**: Componentes dedicados para tipos específicos de gráficos (`Ring`, `Vertical Bands`).
|
|
8
|
+
- **Responsive**: Gestión automática del redimensionamiento.
|
|
9
|
+
- **Interactividad**: Soporte nativo para Cross-filtering de Visionaris.
|
|
10
|
+
|
|
11
|
+
## 📦 Instalación
|
|
12
|
+
|
|
13
|
+
En tu aplicación Angular (ej. `VisionarisFrontEnd`), asegúrate de que el `package.json` apunte a la librería:
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"vs-echarts": "file:../reusable/vs-ng-library/dist/vs-echarts"
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Luego, importa los componentes necesarios o el módulo si aplica.
|
|
22
|
+
|
|
23
|
+
## 🛠️ Uso Básico
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { EchartsRingComponent } from 'vs-echarts';
|
|
27
|
+
|
|
28
|
+
// En tu componente wrapper
|
|
29
|
+
@Component({
|
|
30
|
+
standalone: true,
|
|
31
|
+
imports: [EchartsRingComponent],
|
|
32
|
+
template: `
|
|
33
|
+
<vs-echarts-ring
|
|
34
|
+
[data]="miData"
|
|
35
|
+
[palette]="miPaleta"
|
|
36
|
+
(chartClick)="manejarClick($event)">
|
|
37
|
+
</vs-echarts-ring>
|
|
38
|
+
`
|
|
39
|
+
})
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## 📖 Documentación Detallada
|
|
43
|
+
|
|
44
|
+
- [**Arquitectura Interna (Builders & Specialists)**](./docs/internal-architecture.md)
|
|
45
|
+
- [**Referencia de API e Interfaces**](./docs/api-reference.md)
|
|
46
|
+
- **Patrones por Componente**:
|
|
47
|
+
- [ECharts Ring Patterns](./docs/charts/ring-patterns.md)
|
|
48
|
+
- [ECharts Vertical Bands Patterns](./docs/charts/vertical-bands-patterns.md)
|
|
@@ -0,0 +1,874 @@
|
|
|
1
|
+
import { provideEchartsCore, NgxEchartsDirective } from 'ngx-echarts';
|
|
2
|
+
import * as echarts from 'echarts/core';
|
|
3
|
+
import { BarChart, PieChart } from 'echarts/charts';
|
|
4
|
+
import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, GraphicComponent, ToolboxComponent } from 'echarts/components';
|
|
5
|
+
import { CanvasRenderer } from 'echarts/renderers';
|
|
6
|
+
import * as i0 from '@angular/core';
|
|
7
|
+
import { EventEmitter, Output, Input, ViewChild, Directive, Component } from '@angular/core';
|
|
8
|
+
import { ReplaySubject } from 'rxjs';
|
|
9
|
+
import { debounceTime } from 'rxjs/operators';
|
|
10
|
+
import { CommonModule } from '@angular/common';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Inicialización centralizada de ECharts para evitar duplicación y efectos secundarios
|
|
14
|
+
* no controlados en componentes standalone.
|
|
15
|
+
*/
|
|
16
|
+
let initialized = false;
|
|
17
|
+
function initializeEcharts() {
|
|
18
|
+
if (initialized)
|
|
19
|
+
return;
|
|
20
|
+
echarts.use([
|
|
21
|
+
BarChart,
|
|
22
|
+
PieChart,
|
|
23
|
+
TitleComponent,
|
|
24
|
+
TooltipComponent,
|
|
25
|
+
GridComponent,
|
|
26
|
+
LegendComponent,
|
|
27
|
+
CanvasRenderer,
|
|
28
|
+
GraphicComponent,
|
|
29
|
+
ToolboxComponent
|
|
30
|
+
]);
|
|
31
|
+
initialized = true;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Provee la configuración de ECharts para ngx-echarts.
|
|
35
|
+
* Llama automáticamente a la inicialización de módulos.
|
|
36
|
+
*/
|
|
37
|
+
function provideVSEcharts() {
|
|
38
|
+
initializeEcharts();
|
|
39
|
+
return provideEchartsCore({ echarts });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* BaseEchartsComponent
|
|
44
|
+
*
|
|
45
|
+
* Clase base para componentes especialistas de ECharts.
|
|
46
|
+
* Gestiona el ciclo de vida, redimensionado dinámico y debouncing de actualizaciones.
|
|
47
|
+
*
|
|
48
|
+
* @see {@link vs-echarts/docs/internal-architecture.md}
|
|
49
|
+
*/
|
|
50
|
+
class BaseEchartsComponent {
|
|
51
|
+
chartContainer;
|
|
52
|
+
/** Datos normalizados para graficar */
|
|
53
|
+
data = { categories: [], series: [] };
|
|
54
|
+
/** Configuración visual agnóstica */
|
|
55
|
+
chartConfig = {};
|
|
56
|
+
/** Paleta de colores básica */
|
|
57
|
+
palette;
|
|
58
|
+
/** Resolver de colores dinámico (Callback) */
|
|
59
|
+
colorResolver;
|
|
60
|
+
/** Formateador de valores para etiquetas y tooltips */
|
|
61
|
+
valueFormatter;
|
|
62
|
+
chartClick = new EventEmitter();
|
|
63
|
+
/** Opciones configuradas para ngx-echarts */
|
|
64
|
+
chartOptions = {};
|
|
65
|
+
/** Subject para debouncing de actualizaciones. ReplaySubject asegura no perder el primer renderizado. */
|
|
66
|
+
updateSubject = new ReplaySubject(1);
|
|
67
|
+
updateSubscription;
|
|
68
|
+
constructor() {
|
|
69
|
+
this.updateSubscription = this.updateSubject.pipe(debounceTime(150)).subscribe(options => {
|
|
70
|
+
this.updateOptions(options);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
chartInstance;
|
|
74
|
+
ngOnChanges(changes) {
|
|
75
|
+
this.onInputChanges(changes);
|
|
76
|
+
}
|
|
77
|
+
ngOnDestroy() {
|
|
78
|
+
this.updateSubscription?.unsubscribe();
|
|
79
|
+
this.chartInstance?.dispose();
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Captura la instancia de echarts (usado por ngx-echarts)
|
|
83
|
+
*/
|
|
84
|
+
onChartInit(instance) {
|
|
85
|
+
this.chartInstance = instance;
|
|
86
|
+
this.updateChartOptions();
|
|
87
|
+
}
|
|
88
|
+
updateOptions(options) {
|
|
89
|
+
this.chartOptions = { ...options };
|
|
90
|
+
this.chartInstance?.setOption(options, { notMerge: true });
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Hook de template method invocado por `ngOnChanges`.
|
|
94
|
+
* Las subclases lo sobreescriben para añadir lógica propia
|
|
95
|
+
* y deben llamar a `super.onInputChanges(changes)` para preservar
|
|
96
|
+
* el comportamiento base (detectar inputs relevantes y actualizar el chart).
|
|
97
|
+
*/
|
|
98
|
+
onInputChanges(changes) {
|
|
99
|
+
if (changes['data'] || changes['chartConfig'] || changes['palette'] || changes['colorResolver'] || changes['valueFormatter']) {
|
|
100
|
+
this.updateChartOptions();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Gatilla actualización en ngx-echarts
|
|
105
|
+
*/
|
|
106
|
+
triggerUpdate(options) {
|
|
107
|
+
this.updateSubject.next(options);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Método público para forzar el redimensionado desde el padre
|
|
111
|
+
*/
|
|
112
|
+
resize() {
|
|
113
|
+
this.chartInstance?.resize();
|
|
114
|
+
}
|
|
115
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BaseEchartsComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
|
|
116
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.3.19", type: BaseEchartsComponent, isStandalone: true, inputs: { data: "data", chartConfig: "chartConfig", palette: "palette", colorResolver: "colorResolver", valueFormatter: "valueFormatter" }, outputs: { chartClick: "chartClick" }, viewQueries: [{ propertyName: "chartContainer", first: true, predicate: ["chartContainer"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0 });
|
|
117
|
+
}
|
|
118
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: BaseEchartsComponent, decorators: [{
|
|
119
|
+
type: Directive,
|
|
120
|
+
args: [{
|
|
121
|
+
standalone: true
|
|
122
|
+
}]
|
|
123
|
+
}], ctorParameters: () => [], propDecorators: { chartContainer: [{
|
|
124
|
+
type: ViewChild,
|
|
125
|
+
args: ['chartContainer', { static: true }]
|
|
126
|
+
}], data: [{
|
|
127
|
+
type: Input
|
|
128
|
+
}], chartConfig: [{
|
|
129
|
+
type: Input
|
|
130
|
+
}], palette: [{
|
|
131
|
+
type: Input
|
|
132
|
+
}], colorResolver: [{
|
|
133
|
+
type: Input
|
|
134
|
+
}], valueFormatter: [{
|
|
135
|
+
type: Input
|
|
136
|
+
}], chartClick: [{
|
|
137
|
+
type: Output
|
|
138
|
+
}] } });
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* ECharts Options Standard Library
|
|
142
|
+
*
|
|
143
|
+
* Biblioteca de fragmentos de configuración y tokens de diseño para asegurar
|
|
144
|
+
* una estética cohesiva en todos los gráficos de Visionaris.
|
|
145
|
+
*
|
|
146
|
+
* @see {@link VisionarisFrontEnd/docs/technical/echarts-architecture.md}
|
|
147
|
+
*/
|
|
148
|
+
// Pre-cached native formatter for performance in axis ticks
|
|
149
|
+
const compactFormatter = new Intl.NumberFormat('es-AR', {
|
|
150
|
+
notation: 'compact',
|
|
151
|
+
compactDisplay: 'short',
|
|
152
|
+
maximumFractionDigits: 1
|
|
153
|
+
});
|
|
154
|
+
/**
|
|
155
|
+
* Formats a value using native browser SI suffixes (k, M, B).
|
|
156
|
+
*/
|
|
157
|
+
function formatAxisValue(value) {
|
|
158
|
+
return compactFormatter.format(value);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Global Design Tokens for ECharts
|
|
162
|
+
*/
|
|
163
|
+
const EChartsTokens = {
|
|
164
|
+
fontFamily: "'Inter', 'Roboto', sans-serif",
|
|
165
|
+
fontSize: 11,
|
|
166
|
+
axisColor: '#666',
|
|
167
|
+
lineColor: '#ddd',
|
|
168
|
+
primaryColor: '#08B1D5',
|
|
169
|
+
tooltipBg: 'rgba(255, 255, 255, 0.95)',
|
|
170
|
+
defaultPalette: ['#08B1D5', '#2C3E50', '#F39C12', '#E74C3C', '#27AE60', '#8E44AD', '#3498DB', '#16A085', '#D35400', '#2980B9']
|
|
171
|
+
};
|
|
172
|
+
/**
|
|
173
|
+
* Exposes the default Visionaris palette for internal fallbacks.
|
|
174
|
+
*/
|
|
175
|
+
function getDefaultPalette() {
|
|
176
|
+
return [...EChartsTokens.defaultPalette];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Common legend configuration with scroll to prevent "cannibalization".
|
|
180
|
+
* Atomic Pattern: Provides the scrollable container with Visionaris styling.
|
|
181
|
+
*/
|
|
182
|
+
function getLegendOptions(overrides) {
|
|
183
|
+
const defaults = {
|
|
184
|
+
show: true,
|
|
185
|
+
type: 'scroll',
|
|
186
|
+
orient: 'horizontal',
|
|
187
|
+
bottom: 0,
|
|
188
|
+
left: 'center',
|
|
189
|
+
height: 60,
|
|
190
|
+
textStyle: {
|
|
191
|
+
color: '#333',
|
|
192
|
+
fontSize: EChartsTokens.fontSize,
|
|
193
|
+
fontFamily: EChartsTokens.fontFamily
|
|
194
|
+
},
|
|
195
|
+
pageButtonPosition: 'end',
|
|
196
|
+
pageIconColor: EChartsTokens.primaryColor,
|
|
197
|
+
pageIconInactiveColor: '#ccc',
|
|
198
|
+
pageIconSize: 12,
|
|
199
|
+
pageTextStyle: {
|
|
200
|
+
color: '#666'
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
return { ...defaults, ...overrides };
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Common XAxis configuration for category-based charts.
|
|
207
|
+
* Atomic Pattern: Handles category mapping and adaptive label rotation.
|
|
208
|
+
*/
|
|
209
|
+
function getXAxisOptions(overrides) {
|
|
210
|
+
const categories = overrides?.data || [];
|
|
211
|
+
const autoRotate = categories.length > 10 ? 45 : 0;
|
|
212
|
+
const defaults = {
|
|
213
|
+
type: 'category',
|
|
214
|
+
triggerEvent: true,
|
|
215
|
+
axisLabel: {
|
|
216
|
+
rotate: autoRotate,
|
|
217
|
+
interval: 'auto',
|
|
218
|
+
color: EChartsTokens.axisColor,
|
|
219
|
+
fontSize: EChartsTokens.fontSize
|
|
220
|
+
},
|
|
221
|
+
axisLine: {
|
|
222
|
+
lineStyle: {
|
|
223
|
+
color: EChartsTokens.lineColor
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
// Deep merge for axisLabel if provided
|
|
228
|
+
const result = { ...defaults, ...overrides };
|
|
229
|
+
if (overrides?.axisLabel) {
|
|
230
|
+
result.axisLabel = { ...defaults.axisLabel, ...overrides.axisLabel };
|
|
231
|
+
}
|
|
232
|
+
return result;
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Common YAxis configuration for value-based charts.
|
|
236
|
+
* Atomic Pattern: Standardizes value formatting and grid lines.
|
|
237
|
+
*/
|
|
238
|
+
function getYAxisOptions(overrides) {
|
|
239
|
+
const defaults = {
|
|
240
|
+
type: 'value',
|
|
241
|
+
splitLine: {
|
|
242
|
+
show: true,
|
|
243
|
+
lineStyle: {
|
|
244
|
+
type: 'dashed',
|
|
245
|
+
color: '#f0f0f0'
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
axisLabel: {
|
|
249
|
+
formatter: (value) => formatAxisValue(value),
|
|
250
|
+
color: EChartsTokens.axisColor,
|
|
251
|
+
fontSize: EChartsTokens.fontSize
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
const result = { ...defaults, ...overrides };
|
|
255
|
+
if (overrides?.splitLine) {
|
|
256
|
+
result.splitLine = { ...defaults.splitLine, ...overrides.splitLine };
|
|
257
|
+
}
|
|
258
|
+
return result;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Common Tooltip configuration.
|
|
262
|
+
* Atomic Pattern: Enforces consistent glassmorphism and pointer styles.
|
|
263
|
+
*/
|
|
264
|
+
function getTooltipOptions(overrides) {
|
|
265
|
+
const trigger = overrides?.trigger || 'axis';
|
|
266
|
+
const isAxis = trigger === 'axis';
|
|
267
|
+
const defaults = {
|
|
268
|
+
show: true,
|
|
269
|
+
trigger: trigger,
|
|
270
|
+
backgroundColor: EChartsTokens.tooltipBg,
|
|
271
|
+
borderColor: '#eee',
|
|
272
|
+
borderWidth: 1,
|
|
273
|
+
textStyle: {
|
|
274
|
+
color: '#333',
|
|
275
|
+
fontSize: 12
|
|
276
|
+
},
|
|
277
|
+
extraCssText: 'box-shadow: 0 0 10px rgba(0,0,0,0.1); border-radius: 8px;',
|
|
278
|
+
...(isAxis ? {
|
|
279
|
+
axisPointer: {
|
|
280
|
+
type: 'shadow'
|
|
281
|
+
}
|
|
282
|
+
} : {})
|
|
283
|
+
};
|
|
284
|
+
return { ...defaults, ...overrides };
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/**
|
|
288
|
+
* BaseEchartBuilder
|
|
289
|
+
*
|
|
290
|
+
* Clase base para la construcción de opciones de ECharts.
|
|
291
|
+
* Implementa lógica compartida de paletas y opciones comunes.
|
|
292
|
+
*
|
|
293
|
+
* @see {@link vs-echarts/docs/internal-architecture.md}
|
|
294
|
+
*/
|
|
295
|
+
class BaseEchartBuilder {
|
|
296
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
297
|
+
palette = [];
|
|
298
|
+
colorResolver;
|
|
299
|
+
constructor() { }
|
|
300
|
+
/**
|
|
301
|
+
* Permite inyectar un formateador de valores externo.
|
|
302
|
+
*/
|
|
303
|
+
setValueFormatter(formatter) {
|
|
304
|
+
if (formatter) {
|
|
305
|
+
this.valueFormatter = formatter;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Permite inyectar una paleta de colores básica.
|
|
310
|
+
*/
|
|
311
|
+
setPalette(palette) {
|
|
312
|
+
if (palette) {
|
|
313
|
+
this.palette = palette;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Permite inyectar un resolver de colores dinámico.
|
|
318
|
+
*/
|
|
319
|
+
setColorResolver(resolver) {
|
|
320
|
+
if (resolver) {
|
|
321
|
+
this.colorResolver = resolver;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Retorna configuraciones comunes para todos los gráficos.
|
|
326
|
+
*/
|
|
327
|
+
getCommonOptions(chartConfig) {
|
|
328
|
+
const common = {
|
|
329
|
+
backgroundColor: 'transparent',
|
|
330
|
+
textStyle: {
|
|
331
|
+
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif"
|
|
332
|
+
},
|
|
333
|
+
grid: {
|
|
334
|
+
left: '3%',
|
|
335
|
+
right: '4%',
|
|
336
|
+
bottom: '15%',
|
|
337
|
+
top: '20px',
|
|
338
|
+
containLabel: true
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
// Aplicar paleta global: Prioridad Palette Inyectada > Default Visionaris
|
|
342
|
+
common.color = (this.palette && this.palette.length > 0) ? this.palette : getDefaultPalette();
|
|
343
|
+
return common;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Formatea un valor utilizando el callback inyectado.
|
|
347
|
+
*/
|
|
348
|
+
formatCellValue(value, key) {
|
|
349
|
+
return this.valueFormatter(value, key);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* RingBuilder
|
|
355
|
+
*
|
|
356
|
+
* Especializado en construir opciones para gráficos de tipo Ring (Donas concéntricas).
|
|
357
|
+
* @see {@link vs-echarts/docs/charts/ring-patterns.md}
|
|
358
|
+
*/
|
|
359
|
+
class RingBuilder extends BaseEchartBuilder {
|
|
360
|
+
build(data, chartConfig) {
|
|
361
|
+
if (!data || !data.series.length)
|
|
362
|
+
return {};
|
|
363
|
+
const totalRings = data.series.length; // Cada serie es un anillo
|
|
364
|
+
// Configuración dinámica de radios y márgenes
|
|
365
|
+
const margin = totalRings > 1 ? Math.max(0.5, 2.5 - (totalRings * 0.1)) : 0;
|
|
366
|
+
const minInnerRadius = totalRings === 1 ? 45 : (totalRings > 5 ? Math.max(15, 40 - (totalRings * 1.2)) : 40);
|
|
367
|
+
const maxOuterRadius = totalRings === 1 ? 78 : (totalRings > 5 ? Math.min(90, 78 + (totalRings * 0.5)) : 78);
|
|
368
|
+
const availableSpan = maxOuterRadius - minInnerRadius - (margin * (totalRings - 1));
|
|
369
|
+
const thickness = availableSpan / totalRings;
|
|
370
|
+
const borderRadius = totalRings === 1 ? 10 : Math.max(2, Math.min(10, thickness * 0.8));
|
|
371
|
+
const borderWidth = totalRings === 1 ? 2 : Math.max(0.5, Math.min(2, thickness * 0.15));
|
|
372
|
+
const series = data.series.map((s, ringIndex) => {
|
|
373
|
+
const inner = minInnerRadius + (ringIndex * (thickness + margin));
|
|
374
|
+
const outer = inner + thickness;
|
|
375
|
+
const pieData = data.categories.map((catName, catIndex) => ({
|
|
376
|
+
name: catName,
|
|
377
|
+
value: s.data[catIndex],
|
|
378
|
+
originalMeassureKey: s.originalKey || (data.categoryKeys ? data.categoryKeys[catIndex] : '')
|
|
379
|
+
}));
|
|
380
|
+
const seriesOption = {
|
|
381
|
+
name: s.name,
|
|
382
|
+
type: 'pie',
|
|
383
|
+
radius: [`${inner}%`, `${outer}%`],
|
|
384
|
+
center: ['50%', '45%'],
|
|
385
|
+
avoidLabelOverlap: true,
|
|
386
|
+
minAngle: 3,
|
|
387
|
+
selectedMode: 'single',
|
|
388
|
+
selectedOffset: 4,
|
|
389
|
+
itemStyle: {
|
|
390
|
+
borderRadius: borderRadius,
|
|
391
|
+
borderColor: '#fff',
|
|
392
|
+
borderWidth: borderWidth
|
|
393
|
+
},
|
|
394
|
+
label: { show: false },
|
|
395
|
+
emphasis: {
|
|
396
|
+
scale: true,
|
|
397
|
+
scaleSize: 2,
|
|
398
|
+
itemStyle: {
|
|
399
|
+
borderColor: '#fff',
|
|
400
|
+
borderWidth: borderWidth
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
select: {
|
|
404
|
+
itemStyle: {
|
|
405
|
+
borderColor: '#fff',
|
|
406
|
+
borderWidth: borderWidth
|
|
407
|
+
}
|
|
408
|
+
},
|
|
409
|
+
animationType: 'scale',
|
|
410
|
+
animationEasing: 'elasticOut',
|
|
411
|
+
data: pieData,
|
|
412
|
+
id: `ring_${ringIndex}`
|
|
413
|
+
};
|
|
414
|
+
// Inyectar el resolver de color si existe
|
|
415
|
+
if (this.colorResolver) {
|
|
416
|
+
seriesOption.itemStyle.color = this.colorResolver;
|
|
417
|
+
}
|
|
418
|
+
return seriesOption;
|
|
419
|
+
});
|
|
420
|
+
const common = this.getCommonOptions(chartConfig);
|
|
421
|
+
return {
|
|
422
|
+
...common,
|
|
423
|
+
tooltip: {
|
|
424
|
+
...getTooltipOptions({ trigger: 'item' }),
|
|
425
|
+
formatter: (params) => {
|
|
426
|
+
const key = params.data.originalMeassureKey || '';
|
|
427
|
+
const valFormatted = this.formatCellValue(params.value, key);
|
|
428
|
+
const seriesHeader = totalRings > 1 ? `<b>${params.seriesName}</b><br/>` : '';
|
|
429
|
+
return `${seriesHeader}${params.name}<br/>${params.marker} <b>${valFormatted}</b> (${params.percent}%)`;
|
|
430
|
+
}
|
|
431
|
+
},
|
|
432
|
+
legend: getLegendOptions(),
|
|
433
|
+
graphic: [{
|
|
434
|
+
id: 'center-kpi',
|
|
435
|
+
type: 'text',
|
|
436
|
+
left: 'center',
|
|
437
|
+
top: '43%',
|
|
438
|
+
z: 100,
|
|
439
|
+
transition: ['style'],
|
|
440
|
+
style: {
|
|
441
|
+
text: '',
|
|
442
|
+
fontSize: 22,
|
|
443
|
+
fontWeight: 'bold',
|
|
444
|
+
fill: '#333',
|
|
445
|
+
stroke: '#fff',
|
|
446
|
+
lineWidth: 1,
|
|
447
|
+
paintOrder: 'stroke',
|
|
448
|
+
textAlign: 'center',
|
|
449
|
+
textVerticalAlign: 'middle',
|
|
450
|
+
opacity: 0
|
|
451
|
+
}
|
|
452
|
+
}],
|
|
453
|
+
series: series,
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* EchartsRingComponent
|
|
460
|
+
*
|
|
461
|
+
* Especialista en visualización de tipo Ring. Soporta multi-medidas y KPI central.
|
|
462
|
+
* @see {@link vs-echarts/docs/charts/ring-patterns.md}
|
|
463
|
+
*/
|
|
464
|
+
class EchartsRingComponent extends BaseEchartsComponent {
|
|
465
|
+
lastSelectedSeriesIndex = null;
|
|
466
|
+
lastSelectedDataIndex = null;
|
|
467
|
+
selectedPercent = null;
|
|
468
|
+
currentLegendSelected = null;
|
|
469
|
+
currentGraphicText = '';
|
|
470
|
+
builder;
|
|
471
|
+
constructor() {
|
|
472
|
+
super();
|
|
473
|
+
this.builder = new RingBuilder();
|
|
474
|
+
}
|
|
475
|
+
onInputChanges(changes) {
|
|
476
|
+
// Reset selection only if data changed
|
|
477
|
+
if (changes['data']) {
|
|
478
|
+
this.lastSelectedSeriesIndex = null;
|
|
479
|
+
this.lastSelectedDataIndex = null;
|
|
480
|
+
this.selectedPercent = null;
|
|
481
|
+
this.currentLegendSelected = null;
|
|
482
|
+
this.currentGraphicText = '';
|
|
483
|
+
}
|
|
484
|
+
super.onInputChanges(changes);
|
|
485
|
+
}
|
|
486
|
+
/**
|
|
487
|
+
* Maneja clics en los sectores del ring.
|
|
488
|
+
* Soporta múltiples series (anillos) y actualiza el KPI central.
|
|
489
|
+
*/
|
|
490
|
+
onChartClick(event) {
|
|
491
|
+
if (this.chartInstance && event && event.dataIndex !== undefined) {
|
|
492
|
+
const isSameSelection = event.seriesIndex === this.lastSelectedSeriesIndex &&
|
|
493
|
+
event.dataIndex === this.lastSelectedDataIndex;
|
|
494
|
+
if (isSameSelection) {
|
|
495
|
+
// Toggle OFF
|
|
496
|
+
this.lastSelectedSeriesIndex = null;
|
|
497
|
+
this.lastSelectedDataIndex = null;
|
|
498
|
+
this.selectedPercent = null;
|
|
499
|
+
this.setGraphicText('');
|
|
500
|
+
this.chartInstance.dispatchAction({
|
|
501
|
+
type: 'unselect',
|
|
502
|
+
seriesIndex: event.seriesIndex,
|
|
503
|
+
dataIndex: event.dataIndex
|
|
504
|
+
});
|
|
505
|
+
}
|
|
506
|
+
else {
|
|
507
|
+
// SELECT
|
|
508
|
+
this.lastSelectedSeriesIndex = event.seriesIndex;
|
|
509
|
+
this.lastSelectedDataIndex = event.dataIndex;
|
|
510
|
+
this.selectedPercent = (event.percent !== undefined) ? event.percent + '%' : '';
|
|
511
|
+
this.setGraphicText(this.selectedPercent);
|
|
512
|
+
}
|
|
513
|
+
this.chartClick.emit({
|
|
514
|
+
type: 'cross-filter',
|
|
515
|
+
data: {
|
|
516
|
+
category: event.name,
|
|
517
|
+
serie: event.seriesName,
|
|
518
|
+
value: event.value
|
|
519
|
+
}
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
onChartMouseOver(event) {
|
|
524
|
+
if (this.selectedPercent === null && event && event.percent !== undefined) {
|
|
525
|
+
this.setGraphicText(event.percent + '%');
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
onChartMouseOut(event) {
|
|
529
|
+
if (this.selectedPercent === null) {
|
|
530
|
+
this.setGraphicText('');
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
/**
|
|
534
|
+
* Captura los cambios en la selección de la leyenda para persistirlos.
|
|
535
|
+
*/
|
|
536
|
+
onLegendSelectChanged(event) {
|
|
537
|
+
if (event && event.selected) {
|
|
538
|
+
this.currentLegendSelected = event.selected;
|
|
539
|
+
// Resetear la selección actual al cambiar el contexto de la leyenda
|
|
540
|
+
this.lastSelectedSeriesIndex = null;
|
|
541
|
+
this.lastSelectedDataIndex = null;
|
|
542
|
+
this.selectedPercent = null;
|
|
543
|
+
this.currentGraphicText = '';
|
|
544
|
+
this.updateChartOptions();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
/**
|
|
548
|
+
* Actualiza el texto del Graphic central y persiste la selección en el modelo de opciones.
|
|
549
|
+
*/
|
|
550
|
+
setGraphicText(text) {
|
|
551
|
+
this.currentGraphicText = text;
|
|
552
|
+
this.updateChartOptions();
|
|
553
|
+
}
|
|
554
|
+
updateChartOptions() {
|
|
555
|
+
if (!this.chartInstance)
|
|
556
|
+
return;
|
|
557
|
+
if (!this.data)
|
|
558
|
+
return;
|
|
559
|
+
// 1. Configuramos el builder (Formateadores, Colores, etc se manejan en la base)
|
|
560
|
+
// Pero aquí necesitamos llamar a super o duplicar la lógica de inyección de inputs
|
|
561
|
+
if (this.valueFormatter)
|
|
562
|
+
this.builder.setValueFormatter(this.valueFormatter);
|
|
563
|
+
if (this.palette)
|
|
564
|
+
this.builder.setPalette(this.palette);
|
|
565
|
+
if (this.colorResolver)
|
|
566
|
+
this.builder.setColorResolver(this.colorResolver);
|
|
567
|
+
// 2. Obtenemos las bases del chart usando el builder
|
|
568
|
+
let options = this.builder.build(this.data, this.chartConfig);
|
|
569
|
+
// 3. Persistencia de GRAPHIC (KPI central)
|
|
570
|
+
if (options.graphic && Array.isArray(options.graphic)) {
|
|
571
|
+
const graphic = options.graphic[0];
|
|
572
|
+
if (graphic && graphic.style) {
|
|
573
|
+
graphic.style.text = this.currentGraphicText;
|
|
574
|
+
graphic.style.opacity = this.currentGraphicText ? 1 : 0;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
// 4. Persistencia de SELECCIÓN (sector elevado)
|
|
578
|
+
if (options.series && Array.isArray(options.series)) {
|
|
579
|
+
options.series.forEach((s, sIdx) => {
|
|
580
|
+
if (s.data && Array.isArray(s.data)) {
|
|
581
|
+
s.data.forEach((item, dIdx) => {
|
|
582
|
+
if (typeof item === 'object') {
|
|
583
|
+
item.selected = (sIdx === this.lastSelectedSeriesIndex && dIdx === this.lastSelectedDataIndex);
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
}
|
|
587
|
+
});
|
|
588
|
+
}
|
|
589
|
+
// 5. Persistencia de LEYENDA (filtros de usuario)
|
|
590
|
+
if (this.currentLegendSelected && options.legend) {
|
|
591
|
+
options.legend = {
|
|
592
|
+
...options.legend,
|
|
593
|
+
selected: { ...this.currentLegendSelected }
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
// Gatillar actualización en ngx-echarts
|
|
597
|
+
this.triggerUpdate(options);
|
|
598
|
+
}
|
|
599
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
600
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsRingComponent, isStandalone: true, selector: "vs-echarts-ring", providers: [provideVSEcharts()], usesInheritance: true, ngImport: i0, template: "<div class=\"echarts-container\">\n <div class=\"ring-chart\" \n echarts \n [options]=\"chartOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartLegendSelectChanged)=\"onLegendSelectChanged($event)\"\n ></div>\n</div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative;background-color:#fff;border-radius:8px;padding:1rem;box-sizing:border-box}.ring-chart{width:100%;height:100%}.empty-state{display:flex;justify-content:center;align-items:center;height:100%;color:#666;font-family:Roboto,sans-serif;text-align:center;padding:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] });
|
|
601
|
+
}
|
|
602
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, decorators: [{
|
|
603
|
+
type: Component,
|
|
604
|
+
args: [{ selector: 'vs-echarts-ring', standalone: true, imports: [
|
|
605
|
+
CommonModule,
|
|
606
|
+
NgxEchartsDirective,
|
|
607
|
+
], providers: [provideVSEcharts()], template: "<div class=\"echarts-container\">\n <div class=\"ring-chart\" \n echarts \n [options]=\"chartOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartLegendSelectChanged)=\"onLegendSelectChanged($event)\"\n ></div>\n</div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative;background-color:#fff;border-radius:8px;padding:1rem;box-sizing:border-box}.ring-chart{width:100%;height:100%}.empty-state{display:flex;justify-content:center;align-items:center;height:100%;color:#666;font-family:Roboto,sans-serif;text-align:center;padding:2rem}\n"] }]
|
|
608
|
+
}], ctorParameters: () => [] });
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* VerticalBandsBuilder
|
|
612
|
+
*
|
|
613
|
+
* Especializado en construir opciones para gráficos de barras verticales.
|
|
614
|
+
* @see {@link vs-echarts/docs/charts/vertical-bands-patterns.md}
|
|
615
|
+
*/
|
|
616
|
+
class VerticalBandsBuilder extends BaseEchartBuilder {
|
|
617
|
+
constructor() {
|
|
618
|
+
super();
|
|
619
|
+
}
|
|
620
|
+
build(data, chartConfig) {
|
|
621
|
+
if (!data || !data.series.length)
|
|
622
|
+
return {};
|
|
623
|
+
const series = data.series.map((s) => {
|
|
624
|
+
const seriesOption = {
|
|
625
|
+
name: s.name,
|
|
626
|
+
type: 'bar',
|
|
627
|
+
barMaxWidth: 50,
|
|
628
|
+
barGap: '15%',
|
|
629
|
+
barCategoryGap: '35%',
|
|
630
|
+
animation: true,
|
|
631
|
+
animationDuration: 1000,
|
|
632
|
+
animationEasing: 'cubicOut',
|
|
633
|
+
itemStyle: {
|
|
634
|
+
borderRadius: [4, 4, 0, 0]
|
|
635
|
+
},
|
|
636
|
+
data: s.data,
|
|
637
|
+
emphasis: {
|
|
638
|
+
focus: 'none'
|
|
639
|
+
},
|
|
640
|
+
blur: {
|
|
641
|
+
itemStyle: {
|
|
642
|
+
opacity: 0.2
|
|
643
|
+
}
|
|
644
|
+
},
|
|
645
|
+
select: {
|
|
646
|
+
itemStyle: {
|
|
647
|
+
opacity: 1,
|
|
648
|
+
shadowBlur: 10,
|
|
649
|
+
shadowColor: 'rgba(0,0,0,0.3)'
|
|
650
|
+
}
|
|
651
|
+
},
|
|
652
|
+
label: {
|
|
653
|
+
show: false,
|
|
654
|
+
position: 'top',
|
|
655
|
+
formatter: (params) => {
|
|
656
|
+
const key = s.originalKey || (data.categoryKeys ? data.categoryKeys[params.dataIndex] : String(params.dataIndex));
|
|
657
|
+
return this.formatCellValue(params.value, key);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
};
|
|
661
|
+
// Inyectar el resolver de color si existe
|
|
662
|
+
if (this.colorResolver) {
|
|
663
|
+
seriesOption.itemStyle.color = this.colorResolver;
|
|
664
|
+
}
|
|
665
|
+
return seriesOption;
|
|
666
|
+
});
|
|
667
|
+
const common = this.getCommonOptions(chartConfig);
|
|
668
|
+
return {
|
|
669
|
+
...common,
|
|
670
|
+
tooltip: {
|
|
671
|
+
...getTooltipOptions({ trigger: 'axis' }),
|
|
672
|
+
formatter: (params) => {
|
|
673
|
+
let html = `<b>${params[0].name}</b><br/>`;
|
|
674
|
+
params.forEach((p) => {
|
|
675
|
+
const seriesObj = data.series[p.seriesIndex];
|
|
676
|
+
const key = seriesObj.originalKey || (data.categoryKeys ? data.categoryKeys[p.dataIndex] : String(p.dataIndex));
|
|
677
|
+
const valFormatted = this.formatCellValue(p.value, key);
|
|
678
|
+
html += `${p.marker} ${p.seriesName}: <b>${valFormatted}</b><br/>`;
|
|
679
|
+
});
|
|
680
|
+
return html;
|
|
681
|
+
}
|
|
682
|
+
},
|
|
683
|
+
legend: getLegendOptions(),
|
|
684
|
+
xAxis: getXAxisOptions({ data: data.categories }),
|
|
685
|
+
yAxis: getYAxisOptions(),
|
|
686
|
+
series: series
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* EchartsVerticalBandsComponent
|
|
693
|
+
*
|
|
694
|
+
* Especialista en visualización de bandas/barras verticales.
|
|
695
|
+
* Implementa patrones de interacción ZRender y resaltado de grupos.
|
|
696
|
+
* @see {@link vs-echarts/docs/charts/vertical-bands-patterns.md}
|
|
697
|
+
*/
|
|
698
|
+
class EchartsVerticalBandsComponent extends BaseEchartsComponent {
|
|
699
|
+
selectedSectorIndex = null;
|
|
700
|
+
selectedSeriesIndex = null;
|
|
701
|
+
currentLegendSelected = null;
|
|
702
|
+
builder;
|
|
703
|
+
constructor() {
|
|
704
|
+
super();
|
|
705
|
+
this.builder = new VerticalBandsBuilder();
|
|
706
|
+
}
|
|
707
|
+
onChartInit(instance) {
|
|
708
|
+
super.onChartInit(instance);
|
|
709
|
+
this.setupInteractions();
|
|
710
|
+
}
|
|
711
|
+
onInputChanges(changes) {
|
|
712
|
+
if (changes['data']) {
|
|
713
|
+
this.selectedSectorIndex = null;
|
|
714
|
+
this.selectedSeriesIndex = null;
|
|
715
|
+
this.currentLegendSelected = null;
|
|
716
|
+
}
|
|
717
|
+
super.onInputChanges(changes);
|
|
718
|
+
}
|
|
719
|
+
setupInteractions() {
|
|
720
|
+
if (!this.chartInstance)
|
|
721
|
+
return;
|
|
722
|
+
// 1. ZRender click for background "sectors"
|
|
723
|
+
const zr = this.chartInstance.getZr();
|
|
724
|
+
zr.on('click', (params) => {
|
|
725
|
+
if (!params.target) {
|
|
726
|
+
const pointInPixel = [params.offsetX, params.offsetY];
|
|
727
|
+
if (this.chartInstance.containPixel('grid', pointInPixel)) {
|
|
728
|
+
// Fix TS2352: convertFromPixel return type cast
|
|
729
|
+
const xIndexResult = this.chartInstance.convertFromPixel({ xAxisIndex: 0 }, pointInPixel);
|
|
730
|
+
const xIndex = Array.isArray(xIndexResult) ? xIndexResult[0] : xIndexResult;
|
|
731
|
+
if (typeof xIndex === 'number' && xIndex >= 0) {
|
|
732
|
+
this.toggleSectorSelection(xIndex);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
// 2. Mouseover for Group Highlighting
|
|
738
|
+
this.chartInstance.on('mouseover', (params) => {
|
|
739
|
+
if (params.dataIndex !== undefined) {
|
|
740
|
+
this.highlightSector(params.dataIndex);
|
|
741
|
+
}
|
|
742
|
+
});
|
|
743
|
+
this.chartInstance.on('mouseout', () => {
|
|
744
|
+
this.clearHighlight();
|
|
745
|
+
});
|
|
746
|
+
}
|
|
747
|
+
toggleSectorSelection(index, seriesIndex = null) {
|
|
748
|
+
const isSameBar = this.selectedSectorIndex === index && this.selectedSeriesIndex === seriesIndex;
|
|
749
|
+
if (isSameBar) {
|
|
750
|
+
this.selectedSectorIndex = null;
|
|
751
|
+
this.selectedSeriesIndex = null;
|
|
752
|
+
}
|
|
753
|
+
else {
|
|
754
|
+
this.selectedSectorIndex = index;
|
|
755
|
+
this.selectedSeriesIndex = seriesIndex;
|
|
756
|
+
}
|
|
757
|
+
// Refresh options to apply selection logic
|
|
758
|
+
this.updateChartOptions();
|
|
759
|
+
}
|
|
760
|
+
highlightSector(index) {
|
|
761
|
+
if (!this.chartInstance)
|
|
762
|
+
return;
|
|
763
|
+
const seriesCount = Array.isArray(this.chartOptions.series) ? this.chartOptions.series.length : 0;
|
|
764
|
+
this.chartInstance.dispatchAction({
|
|
765
|
+
type: 'highlight',
|
|
766
|
+
seriesIndex: Array.from({ length: seriesCount }, (_, i) => i),
|
|
767
|
+
dataIndex: index
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
clearHighlight() {
|
|
771
|
+
if (!this.chartInstance)
|
|
772
|
+
return;
|
|
773
|
+
const seriesCount = Array.isArray(this.chartOptions.series) ? this.chartOptions.series.length : 0;
|
|
774
|
+
this.chartInstance.dispatchAction({
|
|
775
|
+
type: 'downplay',
|
|
776
|
+
seriesIndex: Array.from({ length: seriesCount }, (_, i) => i)
|
|
777
|
+
});
|
|
778
|
+
}
|
|
779
|
+
onChartClick(event) {
|
|
780
|
+
// 3. ECharts click only for bars (to avoid unwanted axis filtering)
|
|
781
|
+
if (event.componentType === 'series') {
|
|
782
|
+
const index = event.dataIndex;
|
|
783
|
+
if (index !== undefined && index >= 0) {
|
|
784
|
+
let seriesIndex = null;
|
|
785
|
+
if (event.componentType === 'series') {
|
|
786
|
+
seriesIndex = event.seriesIndex;
|
|
787
|
+
}
|
|
788
|
+
this.toggleSectorSelection(index, seriesIndex);
|
|
789
|
+
// Emit standardized payload for cross-filtering
|
|
790
|
+
this.chartClick.emit({
|
|
791
|
+
type: 'cross-filter',
|
|
792
|
+
data: {
|
|
793
|
+
category: event.name,
|
|
794
|
+
serie: event.seriesName,
|
|
795
|
+
value: event.value
|
|
796
|
+
}
|
|
797
|
+
});
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Maneja clics en la leyenda para persistir filtros.
|
|
803
|
+
*/
|
|
804
|
+
onLegendSelectChanged(event) {
|
|
805
|
+
if (event && event.selected) {
|
|
806
|
+
this.currentLegendSelected = event.selected;
|
|
807
|
+
this.updateChartOptions();
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
updateChartOptions() {
|
|
811
|
+
if (!this.chartInstance)
|
|
812
|
+
return;
|
|
813
|
+
if (!this.data)
|
|
814
|
+
return;
|
|
815
|
+
// 1. Configuramos el builder (Formateadores, Colores, etc se manejan en la base)
|
|
816
|
+
if (this.valueFormatter)
|
|
817
|
+
this.builder.setValueFormatter(this.valueFormatter);
|
|
818
|
+
if (this.palette)
|
|
819
|
+
this.builder.setPalette(this.palette);
|
|
820
|
+
if (this.colorResolver)
|
|
821
|
+
this.builder.setColorResolver(this.colorResolver);
|
|
822
|
+
// 2. Obtenemos las bases del chart usando el builder
|
|
823
|
+
let baseOptions = this.builder.build(this.data, this.chartConfig);
|
|
824
|
+
// 3. Re-apply legend selection state if exists
|
|
825
|
+
if (this.currentLegendSelected && baseOptions.legend) {
|
|
826
|
+
baseOptions.legend.selected = { ...this.currentLegendSelected };
|
|
827
|
+
}
|
|
828
|
+
// 4. Apply persistent selection style if a sector is selected
|
|
829
|
+
if (this.selectedSectorIndex !== null && baseOptions.series) {
|
|
830
|
+
const seriesArray = baseOptions.series;
|
|
831
|
+
baseOptions.series = seriesArray.map((s, sIdx) => {
|
|
832
|
+
if (s.type === 'bar' && Array.isArray(s.data)) {
|
|
833
|
+
return {
|
|
834
|
+
...s,
|
|
835
|
+
data: s.data.map((val, idx) => {
|
|
836
|
+
const isSelected = idx === this.selectedSectorIndex;
|
|
837
|
+
const isBarSelected = isSelected && sIdx === this.selectedSeriesIndex;
|
|
838
|
+
const itemVal = (val && typeof val === 'object' && val.value !== undefined) ? val.value : val;
|
|
839
|
+
return {
|
|
840
|
+
value: itemVal,
|
|
841
|
+
itemStyle: {
|
|
842
|
+
opacity: isSelected ? (isBarSelected ? 1 : 0.5) : 0.15,
|
|
843
|
+
borderWidth: 0
|
|
844
|
+
}
|
|
845
|
+
};
|
|
846
|
+
})
|
|
847
|
+
};
|
|
848
|
+
}
|
|
849
|
+
return s;
|
|
850
|
+
});
|
|
851
|
+
}
|
|
852
|
+
this.triggerUpdate(baseOptions);
|
|
853
|
+
}
|
|
854
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsVerticalBandsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
855
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsVerticalBandsComponent, isStandalone: true, selector: "vs-echarts-vertical-bands", providers: [provideVSEcharts()], usesInheritance: true, ngImport: i0, template: "<div class=\"echarts-container\">\n <div echarts [options]=\"chartOptions\" [autoResize]=\"true\" (chartInit)=\"onChartInit($event)\" (chartClick)=\"onChartClick($event)\" (legendSelectChanged)=\"onLegendSelectChanged($event)\" class=\"demo-chart\"></div>\n</div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative;background-color:#fff;border-radius:8px;padding:1rem;box-sizing:border-box}.demo-chart{width:100%;height:100%}.empty-state{display:flex;justify-content:center;align-items:center;height:100%;color:#666;font-family:Roboto,sans-serif;text-align:center;padding:2rem}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: NgxEchartsDirective, selector: "echarts, [echarts]", inputs: ["options", "theme", "initOpts", "merge", "autoResize", "loading", "loadingType", "loadingOpts"], outputs: ["chartInit", "optionsError", "chartClick", "chartDblClick", "chartMouseDown", "chartMouseMove", "chartMouseUp", "chartMouseOver", "chartMouseOut", "chartGlobalOut", "chartContextMenu", "chartHighlight", "chartDownplay", "chartSelectChanged", "chartLegendSelectChanged", "chartLegendSelected", "chartLegendUnselected", "chartLegendLegendSelectAll", "chartLegendLegendInverseSelect", "chartLegendScroll", "chartDataZoom", "chartDataRangeSelected", "chartGraphRoam", "chartGeoRoam", "chartTreeRoam", "chartTimelineChanged", "chartTimelinePlayChanged", "chartRestore", "chartDataViewChanged", "chartMagicTypeChanged", "chartGeoSelectChanged", "chartGeoSelected", "chartGeoUnselected", "chartAxisAreaSelected", "chartBrush", "chartBrushEnd", "chartBrushSelected", "chartGlobalCursorTaken", "chartRendered", "chartFinished"], exportAs: ["echarts"] }] });
|
|
856
|
+
}
|
|
857
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsVerticalBandsComponent, decorators: [{
|
|
858
|
+
type: Component,
|
|
859
|
+
args: [{ selector: 'vs-echarts-vertical-bands', standalone: true, imports: [
|
|
860
|
+
CommonModule,
|
|
861
|
+
NgxEchartsDirective,
|
|
862
|
+
], providers: [provideVSEcharts()], template: "<div class=\"echarts-container\">\n <div echarts [options]=\"chartOptions\" [autoResize]=\"true\" (chartInit)=\"onChartInit($event)\" (chartClick)=\"onChartClick($event)\" (legendSelectChanged)=\"onLegendSelectChanged($event)\" class=\"demo-chart\"></div>\n</div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative;background-color:#fff;border-radius:8px;padding:1rem;box-sizing:border-box}.demo-chart{width:100%;height:100%}.empty-state{display:flex;justify-content:center;align-items:center;height:100%;color:#666;font-family:Roboto,sans-serif;text-align:center;padding:2rem}\n"] }]
|
|
863
|
+
}], ctorParameters: () => [] });
|
|
864
|
+
|
|
865
|
+
/*
|
|
866
|
+
* Public API Surface of echarts
|
|
867
|
+
*/
|
|
868
|
+
|
|
869
|
+
/**
|
|
870
|
+
* Generated bundle index. Do not edit.
|
|
871
|
+
*/
|
|
872
|
+
|
|
873
|
+
export { BaseEchartsComponent, EchartsRingComponent, EchartsVerticalBandsComponent, initializeEcharts, provideVSEcharts };
|
|
874
|
+
//# sourceMappingURL=visionaris-bruno-vs-echarts.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visionaris-bruno-vs-echarts.mjs","sources":["../../../projects/vs-echarts/src/lib/vs-echarts.config.ts","../../../projects/vs-echarts/src/lib/base-echart.component.ts","../../../projects/vs-echarts/src/lib/echarts-options.ts","../../../projects/vs-echarts/src/lib/builders/base-echart.builder.ts","../../../projects/vs-echarts/src/lib/builders/ring.builder.ts","../../../projects/vs-echarts/src/lib/charts/echarts-ring/echarts-ring.component.ts","../../../projects/vs-echarts/src/lib/charts/echarts-ring/echarts-ring.component.html","../../../projects/vs-echarts/src/lib/builders/vertical-bands.builder.ts","../../../projects/vs-echarts/src/lib/charts/echarts-vertical-bands/echarts-vertical-bands.component.ts","../../../projects/vs-echarts/src/lib/charts/echarts-vertical-bands/echarts-vertical-bands.component.html","../../../projects/vs-echarts/src/public-api.ts","../../../projects/vs-echarts/src/visionaris-bruno-vs-echarts.ts"],"sourcesContent":["import { provideEchartsCore } from 'ngx-echarts';\nimport * as echarts from 'echarts/core';\nimport { BarChart, PieChart } from 'echarts/charts';\nimport {\n TitleComponent,\n TooltipComponent,\n GridComponent,\n LegendComponent,\n GraphicComponent,\n ToolboxComponent\n} from 'echarts/components';\nimport { CanvasRenderer } from 'echarts/renderers';\n\n/**\n * Inicialización centralizada de ECharts para evitar duplicación y efectos secundarios \n * no controlados en componentes standalone.\n */\nlet initialized = false;\n\nexport function initializeEcharts() {\n if (initialized) return;\n \n echarts.use([\n BarChart,\n PieChart,\n TitleComponent,\n TooltipComponent,\n GridComponent,\n LegendComponent,\n CanvasRenderer,\n GraphicComponent,\n ToolboxComponent\n ]);\n \n initialized = true;\n}\n\n/**\n * Provee la configuración de ECharts para ngx-echarts.\n * Llama automáticamente a la inicialización de módulos.\n */\nexport function provideVSEcharts() {\n initializeEcharts();\n return provideEchartsCore({ echarts });\n}\n","import { Input, OnChanges, SimpleChanges, ViewChild, ElementRef, Output, EventEmitter, OnDestroy, Directive } from '@angular/core';\nimport { ReplaySubject, Subscription } from 'rxjs';\nimport { debounceTime } from 'rxjs/operators';\nimport type * as echarts from 'echarts';\n\nimport { IEChartData, EChartValueFormatter, EChartColorResolver, IEChartConfiguration } from './echarts-data.interfaces';\nimport { EChartClickType } from './echarts.interfaces';\nimport { BaseEchartBuilder } from './builders/base-echart.builder';\n\n@Directive({\n standalone: true\n})\n/**\n * BaseEchartsComponent\n * \n * Clase base para componentes especialistas de ECharts.\n * Gestiona el ciclo de vida, redimensionado dinámico y debouncing de actualizaciones.\n * \n * @see {@link vs-echarts/docs/internal-architecture.md}\n */\nexport abstract class BaseEchartsComponent implements OnChanges, OnDestroy {\n @ViewChild('chartContainer', { static: true }) chartContainer!: ElementRef;\n \n /** Datos normalizados para graficar */\n @Input() data: IEChartData = { categories: [], series: [] };\n \n /** Configuración visual agnóstica */\n @Input() chartConfig: IEChartConfiguration = {};\n\n /** Paleta de colores básica */\n @Input() palette?: string[];\n\n /** Resolver de colores dinámico (Callback) */\n @Input() colorResolver?: EChartColorResolver;\n\n /** Formateador de valores para etiquetas y tooltips */\n @Input() valueFormatter?: EChartValueFormatter;\n \n @Output() chartClick = new EventEmitter<{type: EChartClickType, data: any}>();\n\n /** Opciones configuradas para ngx-echarts */\n public chartOptions: any = {};\n\n /** Subject para debouncing de actualizaciones. ReplaySubject asegura no perder el primer renderizado. */\n private updateSubject = new ReplaySubject<echarts.EChartsOption>(1);\n private updateSubscription?: Subscription;\n\n constructor() {\n this.updateSubscription = this.updateSubject.pipe(\n debounceTime(150)\n ).subscribe(options => {\n this.updateOptions(options);\n });\n }\n\n protected chartInstance?: echarts.ECharts;\n protected abstract builder: BaseEchartBuilder;\n\n ngOnChanges(changes: SimpleChanges) {\n this.onInputChanges(changes);\n }\n\n ngOnDestroy() {\n this.updateSubscription?.unsubscribe();\n this.chartInstance?.dispose();\n }\n\n /**\n * Captura la instancia de echarts (usado por ngx-echarts)\n */\n onChartInit(instance: any) {\n this.chartInstance = instance;\n this.updateChartOptions();\n }\n\n private updateOptions(options: echarts.EChartsOption) {\n this.chartOptions = { ...options };\n this.chartInstance?.setOption(options, { notMerge: true });\n }\n\n /**\n * Hook de template method invocado por `ngOnChanges`.\n * Las subclases lo sobreescriben para añadir lógica propia\n * y deben llamar a `super.onInputChanges(changes)` para preservar\n * el comportamiento base (detectar inputs relevantes y actualizar el chart).\n */\n protected onInputChanges(changes: SimpleChanges): void {\n if (changes['data'] || changes['chartConfig'] || changes['palette'] || changes['colorResolver'] || changes['valueFormatter']) {\n this.updateChartOptions();\n }\n }\n\n protected abstract updateChartOptions(): void;\n \n /**\n * Gatilla actualización en ngx-echarts\n */\n protected triggerUpdate(options: echarts.EChartsOption) {\n this.updateSubject.next(options);\n }\n\n /**\n * Método público para forzar el redimensionado desde el padre\n */\n public resize() {\n this.chartInstance?.resize();\n }\n}\n","/**\n * ECharts Options Standard Library\n * \n * Biblioteca de fragmentos de configuración y tokens de diseño para asegurar \n * una estética cohesiva en todos los gráficos de Visionaris.\n * \n * @see {@link VisionarisFrontEnd/docs/technical/echarts-architecture.md}\n */\n\n// Pre-cached native formatter for performance in axis ticks\nexport const compactFormatter = new Intl.NumberFormat('es-AR', {\n notation: 'compact',\n compactDisplay: 'short',\n maximumFractionDigits: 1\n});\n\n/**\n * Formats a value using native browser SI suffixes (k, M, B).\n */\nexport function formatAxisValue(value: number): string {\n return compactFormatter.format(value);\n}\n\n/**\n * Global Design Tokens for ECharts\n */\nconst EChartsTokens = {\n fontFamily: \"'Inter', 'Roboto', sans-serif\",\n fontSize: 11,\n axisColor: '#666',\n lineColor: '#ddd',\n primaryColor: '#08B1D5',\n tooltipBg: 'rgba(255, 255, 255, 0.95)',\n defaultPalette: ['#08B1D5', '#2C3E50', '#F39C12', '#E74C3C', '#27AE60', '#8E44AD', '#3498DB', '#16A085', '#D35400', '#2980B9']\n};\n\n/**\n * Exposes the default Visionaris palette for internal fallbacks.\n */\nexport function getDefaultPalette(): string[] {\n return [...EChartsTokens.defaultPalette];\n}\n\n/**\n * Common legend configuration with scroll to prevent \"cannibalization\".\n * Atomic Pattern: Provides the scrollable container with Visionaris styling.\n */\nexport function getLegendOptions(overrides?: any): any {\n const defaults = {\n show: true,\n type: 'scroll',\n orient: 'horizontal',\n bottom: 0,\n left: 'center',\n height: 60,\n textStyle: {\n color: '#333',\n fontSize: EChartsTokens.fontSize,\n fontFamily: EChartsTokens.fontFamily\n },\n pageButtonPosition: 'end',\n pageIconColor: EChartsTokens.primaryColor,\n pageIconInactiveColor: '#ccc',\n pageIconSize: 12,\n pageTextStyle: {\n color: '#666'\n }\n };\n\n return { ...defaults, ...overrides };\n}\n\n/**\n * Common XAxis configuration for category-based charts.\n * Atomic Pattern: Handles category mapping and adaptive label rotation.\n */\nexport function getXAxisOptions(overrides?: any): any {\n const categories = overrides?.data || [];\n const autoRotate = categories.length > 10 ? 45 : 0;\n\n const defaults = {\n type: 'category',\n triggerEvent: true,\n axisLabel: {\n rotate: autoRotate,\n interval: 'auto',\n color: EChartsTokens.axisColor,\n fontSize: EChartsTokens.fontSize\n },\n axisLine: {\n lineStyle: {\n color: EChartsTokens.lineColor\n }\n }\n };\n\n // Deep merge for axisLabel if provided\n const result = { ...defaults, ...overrides };\n if (overrides?.axisLabel) {\n result.axisLabel = { ...defaults.axisLabel, ...overrides.axisLabel };\n }\n\n return result;\n}\n\n/**\n * Common YAxis configuration for value-based charts.\n * Atomic Pattern: Standardizes value formatting and grid lines.\n */\nexport function getYAxisOptions(overrides?: any): any {\n const defaults = {\n type: 'value',\n splitLine: { \n show: true,\n lineStyle: { \n type: 'dashed',\n color: '#f0f0f0'\n } \n },\n axisLabel: {\n formatter: (value: number) => formatAxisValue(value),\n color: EChartsTokens.axisColor,\n fontSize: EChartsTokens.fontSize\n }\n };\n\n const result = { ...defaults, ...overrides };\n if (overrides?.splitLine) {\n result.splitLine = { ...defaults.splitLine, ...overrides.splitLine };\n }\n\n return result;\n}\n\n/**\n * Common Tooltip configuration.\n * Atomic Pattern: Enforces consistent glassmorphism and pointer styles.\n */\nexport function getTooltipOptions(overrides?: any): any {\n const trigger = overrides?.trigger || 'axis';\n const isAxis = trigger === 'axis';\n\n const defaults = {\n show: true,\n trigger: trigger,\n backgroundColor: EChartsTokens.tooltipBg,\n borderColor: '#eee',\n borderWidth: 1,\n textStyle: {\n color: '#333',\n fontSize: 12\n },\n extraCssText: 'box-shadow: 0 0 10px rgba(0,0,0,0.1); border-radius: 8px;',\n ...(isAxis ? {\n axisPointer: {\n type: 'shadow'\n }\n } : {})\n };\n\n return { ...defaults, ...overrides };\n}\n","import { EChartsOption } from 'echarts';\nimport { IEChartData, EChartValueFormatter, EChartColorResolver, IEChartConfiguration } from '../echarts-data.interfaces';\nimport * as EChartsOptions from '../echarts-options';\n\n/**\n * BaseEchartBuilder\n * \n * Clase base para la construcción de opciones de ECharts.\n * Implementa lógica compartida de paletas y opciones comunes.\n * \n * @see {@link vs-echarts/docs/internal-architecture.md}\n */\nexport abstract class BaseEchartBuilder {\n \n protected valueFormatter: EChartValueFormatter = (value: number) => value.toLocaleString();\n protected palette: string[] = [];\n protected colorResolver?: EChartColorResolver;\n\n constructor() {}\n\n /**\n * Permite inyectar un formateador de valores externo.\n */\n public setValueFormatter(formatter: EChartValueFormatter): void {\n if (formatter) {\n this.valueFormatter = formatter;\n }\n }\n\n /**\n * Permite inyectar una paleta de colores básica.\n */\n public setPalette(palette: string[]): void {\n if (palette) {\n this.palette = palette;\n }\n }\n\n /**\n * Permite inyectar un resolver de colores dinámico.\n */\n public setColorResolver(resolver: EChartColorResolver): void {\n if (resolver) {\n this.colorResolver = resolver;\n }\n }\n\n /**\n * Método principal para construir el objeto EChartsOption.\n */\n abstract build(\n data: IEChartData,\n chartConfig: IEChartConfiguration\n ): EChartsOption;\n\n /**\n * Retorna configuraciones comunes para todos los gráficos.\n */\n protected getCommonOptions(chartConfig?: IEChartConfiguration): EChartsOption {\n const common: EChartsOption = {\n backgroundColor: 'transparent',\n textStyle: {\n fontFamily: \"'Inter', 'Roboto', 'Open Sans', sans-serif\"\n },\n grid: {\n left: '3%',\n right: '4%',\n bottom: '15%',\n top: '20px',\n containLabel: true\n }\n };\n\n // Aplicar paleta global: Prioridad Palette Inyectada > Default Visionaris\n common.color = (this.palette && this.palette.length > 0) ? this.palette : EChartsOptions.getDefaultPalette();\n\n return common;\n }\n\n /**\n * Formatea un valor utilizando el callback inyectado.\n */\n protected formatCellValue(value: number, key: string): string {\n return this.valueFormatter(value, key);\n }\n}\n","import { EChartsOption } from 'echarts';\nimport { BaseEchartBuilder } from './base-echart.builder';\nimport { IEChartData, IEChartConfiguration } from '../echarts-data.interfaces';\nimport * as EChartsOptions from '../echarts-options';\n\n/**\n * RingBuilder\n * \n * Especializado en construir opciones para gráficos de tipo Ring (Donas concéntricas).\n * @see {@link vs-echarts/docs/charts/ring-patterns.md}\n */\nexport class RingBuilder extends BaseEchartBuilder {\n \n build(\n data: IEChartData,\n chartConfig: IEChartConfiguration\n ): EChartsOption {\n if (!data || !data.series.length) return {};\n\n const totalRings = data.series.length; // Cada serie es un anillo\n \n // Configuración dinámica de radios y márgenes\n const margin = totalRings > 1 ? Math.max(0.5, 2.5 - (totalRings * 0.1)) : 0;\n const minInnerRadius = totalRings === 1 ? 45 : (totalRings > 5 ? Math.max(15, 40 - (totalRings * 1.2)) : 40);\n const maxOuterRadius = totalRings === 1 ? 78 : (totalRings > 5 ? Math.min(90, 78 + (totalRings * 0.5)) : 78);\n\n const availableSpan = maxOuterRadius - minInnerRadius - (margin * (totalRings - 1));\n const thickness = availableSpan / totalRings;\n\n const borderRadius = totalRings === 1 ? 10 : Math.max(2, Math.min(10, thickness * 0.8));\n const borderWidth = totalRings === 1 ? 2 : Math.max(0.5, Math.min(2, thickness * 0.15));\n\n const series = data.series.map((s, ringIndex) => {\n const inner = minInnerRadius + (ringIndex * (thickness + margin));\n const outer = inner + thickness;\n\n const pieData = data.categories.map((catName, catIndex) => ({\n name: catName,\n value: s.data[catIndex],\n originalMeassureKey: s.originalKey || (data.categoryKeys ? data.categoryKeys[catIndex] : '')\n }));\n\n const seriesOption: any = {\n name: s.name,\n type: 'pie' as const,\n radius: [`${inner}%`, `${outer}%`],\n center: ['50%', '45%'],\n avoidLabelOverlap: true,\n minAngle: 3,\n selectedMode: 'single' as const,\n selectedOffset: 4,\n itemStyle: {\n borderRadius: borderRadius,\n borderColor: '#fff',\n borderWidth: borderWidth\n },\n label: { show: false },\n emphasis: { \n scale: true,\n scaleSize: 2,\n itemStyle: {\n borderColor: '#fff',\n borderWidth: borderWidth\n }\n },\n select: {\n itemStyle: {\n borderColor: '#fff',\n borderWidth: borderWidth\n }\n },\n animationType: 'scale',\n animationEasing: 'elasticOut',\n data: pieData,\n id: `ring_${ringIndex}`\n };\n\n // Inyectar el resolver de color si existe\n if (this.colorResolver) {\n seriesOption.itemStyle.color = this.colorResolver;\n }\n\n return seriesOption;\n });\n\n const common = this.getCommonOptions(chartConfig);\n\n return {\n ...common,\n tooltip: {\n ...EChartsOptions.getTooltipOptions({ trigger: 'item' }),\n formatter: (params: any) => {\n const key = (params.data as any).originalMeassureKey || '';\n const valFormatted = this.formatCellValue(params.value as number, key);\n const seriesHeader = totalRings > 1 ? `<b>${params.seriesName}</b><br/>` : '';\n return `${seriesHeader}${params.name}<br/>${params.marker} <b>${valFormatted}</b> (${params.percent}%)`;\n }\n },\n legend: EChartsOptions.getLegendOptions(),\n graphic: [{\n id: 'center-kpi',\n type: 'text' as const,\n left: 'center',\n top: '43%',\n z: 100,\n transition: ['style'],\n style: {\n text: '',\n fontSize: 22,\n fontWeight: 'bold',\n fill: '#333',\n stroke: '#fff',\n lineWidth: 1,\n paintOrder: 'stroke',\n textAlign: 'center',\n textVerticalAlign: 'middle',\n opacity: 0\n } as any\n } as any],\n series: series as any,\n };\n }\n}\n","import { Component, SimpleChanges } from '@angular/core';\nimport { BaseEchartsComponent } from '../../base-echart.component';\nimport { RingBuilder } from '../../builders/ring.builder';\nimport { NgxEchartsDirective } from 'ngx-echarts';\nimport { CommonModule } from '@angular/common';\nimport { provideVSEcharts } from '../../vs-echarts.config';\n\n/**\n * EchartsRingComponent\n * \n * Especialista en visualización de tipo Ring. Soporta multi-medidas y KPI central.\n * @see {@link vs-echarts/docs/charts/ring-patterns.md}\n */\n@Component({\n selector: 'vs-echarts-ring',\n standalone: true,\n imports: [\n CommonModule,\n NgxEchartsDirective,\n ],\n templateUrl: './echarts-ring.component.html',\n styleUrls: ['./echarts-ring.component.scss'],\n providers: [provideVSEcharts()]\n})\nexport class EchartsRingComponent extends BaseEchartsComponent {\n \n private lastSelectedSeriesIndex: number | null = null;\n private lastSelectedDataIndex: number | null = null;\n private selectedPercent: string | null = null;\n private currentLegendSelected: any = null;\n private currentGraphicText: string = '';\n \n protected override builder: RingBuilder;\n\n constructor() {\n super();\n this.builder = new RingBuilder();\n }\n\n protected override onInputChanges(changes: SimpleChanges): void {\n // Reset selection only if data changed\n if (changes['data']) {\n this.lastSelectedSeriesIndex = null;\n this.lastSelectedDataIndex = null;\n this.selectedPercent = null;\n this.currentLegendSelected = null;\n this.currentGraphicText = '';\n }\n super.onInputChanges(changes);\n }\n\n /**\n * Maneja clics en los sectores del ring.\n * Soporta múltiples series (anillos) y actualiza el KPI central.\n */\n onChartClick(event: any): void {\n if (this.chartInstance && event && event.dataIndex !== undefined) {\n const isSameSelection = \n event.seriesIndex === this.lastSelectedSeriesIndex && \n event.dataIndex === this.lastSelectedDataIndex;\n\n if (isSameSelection) {\n // Toggle OFF\n this.lastSelectedSeriesIndex = null;\n this.lastSelectedDataIndex = null;\n this.selectedPercent = null;\n this.setGraphicText('');\n \n this.chartInstance.dispatchAction({\n type: 'unselect',\n seriesIndex: event.seriesIndex,\n dataIndex: event.dataIndex\n });\n } else {\n // SELECT\n this.lastSelectedSeriesIndex = event.seriesIndex;\n this.lastSelectedDataIndex = event.dataIndex;\n this.selectedPercent = (event.percent !== undefined) ? event.percent + '%' : '';\n this.setGraphicText(this.selectedPercent);\n }\n\n this.chartClick.emit({\n type: 'cross-filter',\n data: {\n category: event.name,\n serie: event.seriesName,\n value: event.value\n }\n });\n }\n }\n\n onChartMouseOver(event: any): void {\n if (this.selectedPercent === null && event && event.percent !== undefined) {\n this.setGraphicText(event.percent + '%');\n }\n }\n\n onChartMouseOut(event: any): void {\n if (this.selectedPercent === null) {\n this.setGraphicText('');\n }\n }\n\n /**\n * Captura los cambios en la selección de la leyenda para persistirlos.\n */\n onLegendSelectChanged(event: any): void {\n if (event && event.selected) {\n this.currentLegendSelected = event.selected;\n \n // Resetear la selección actual al cambiar el contexto de la leyenda\n this.lastSelectedSeriesIndex = null;\n this.lastSelectedDataIndex = null;\n this.selectedPercent = null;\n this.currentGraphicText = '';\n \n this.updateChartOptions();\n }\n }\n\n /**\n * Actualiza el texto del Graphic central y persiste la selección en el modelo de opciones.\n */\n private setGraphicText(text: string): void {\n this.currentGraphicText = text;\n this.updateChartOptions();\n }\n\n protected updateChartOptions(): void {\n if (!this.chartInstance) return;\n if (!this.data) return;\n \n // 1. Configuramos el builder (Formateadores, Colores, etc se manejan en la base)\n // Pero aquí necesitamos llamar a super o duplicar la lógica de inyección de inputs\n if (this.valueFormatter) this.builder.setValueFormatter(this.valueFormatter);\n if (this.palette) this.builder.setPalette(this.palette);\n if (this.colorResolver) this.builder.setColorResolver(this.colorResolver);\n\n // 2. Obtenemos las bases del chart usando el builder\n let options = this.builder.build(\n this.data, \n this.chartConfig\n );\n\n // 3. Persistencia de GRAPHIC (KPI central)\n if (options.graphic && Array.isArray(options.graphic)) {\n const graphic = (options.graphic as any)[0];\n if (graphic && graphic.style) {\n graphic.style.text = this.currentGraphicText;\n graphic.style.opacity = this.currentGraphicText ? 1 : 0;\n }\n }\n\n // 4. Persistencia de SELECCIÓN (sector elevado)\n if (options.series && Array.isArray(options.series)) {\n options.series.forEach((s: any, sIdx: number) => {\n if (s.data && Array.isArray(s.data)) {\n s.data.forEach((item: any, dIdx: number) => {\n if (typeof item === 'object') {\n item.selected = (sIdx === this.lastSelectedSeriesIndex && dIdx === this.lastSelectedDataIndex);\n }\n });\n }\n });\n }\n\n // 5. Persistencia de LEYENDA (filtros de usuario)\n if (this.currentLegendSelected && options.legend) {\n options.legend = {\n ...(options.legend as any),\n selected: { ...this.currentLegendSelected }\n };\n }\n\n // Gatillar actualización en ngx-echarts\n this.triggerUpdate(options);\n }\n}\n","<div class=\"echarts-container\">\n <div class=\"ring-chart\" \n echarts \n [options]=\"chartOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartLegendSelectChanged)=\"onLegendSelectChanged($event)\"\n ></div>\n</div>\n","import { EChartsOption } from 'echarts';\nimport { BaseEchartBuilder } from './base-echart.builder';\nimport { IEChartData, IEChartConfiguration } from '../echarts-data.interfaces';\nimport * as EChartsOptions from '../echarts-options';\n\n/**\n * VerticalBandsBuilder\n * \n * Especializado en construir opciones para gráficos de barras verticales.\n * @see {@link vs-echarts/docs/charts/vertical-bands-patterns.md}\n */\nexport class VerticalBandsBuilder extends BaseEchartBuilder {\n \n constructor() {\n super();\n }\n\n build(\n data: IEChartData,\n chartConfig: IEChartConfiguration\n ): EChartsOption {\n if (!data || !data.series.length) return {};\n\n const series = data.series.map((s) => {\n const seriesOption: any = {\n name: s.name,\n type: 'bar',\n barMaxWidth: 50,\n barGap: '15%',\n barCategoryGap: '35%',\n animation: true,\n animationDuration: 1000,\n animationEasing: 'cubicOut',\n itemStyle: {\n borderRadius: [4, 4, 0, 0]\n },\n data: s.data,\n emphasis: {\n focus: 'none'\n },\n blur: {\n itemStyle: {\n opacity: 0.2\n }\n },\n select: {\n itemStyle: {\n opacity: 1,\n shadowBlur: 10,\n shadowColor: 'rgba(0,0,0,0.3)'\n }\n },\n label: {\n show: false,\n position: 'top',\n formatter: (params: any) => {\n const key = s.originalKey || (data.categoryKeys ? data.categoryKeys[params.dataIndex] : String(params.dataIndex));\n return this.formatCellValue(params.value as number, key);\n }\n }\n };\n\n // Inyectar el resolver de color si existe\n if (this.colorResolver) {\n seriesOption.itemStyle.color = this.colorResolver;\n }\n\n return seriesOption;\n });\n\n const common = this.getCommonOptions(chartConfig);\n\n return {\n ...common,\n tooltip: {\n ...EChartsOptions.getTooltipOptions({ trigger: 'axis' }),\n formatter: (params: any) => {\n let html = `<b>${params[0].name}</b><br/>`;\n params.forEach((p: any) => {\n const seriesObj = data.series[p.seriesIndex];\n const key = seriesObj.originalKey || (data.categoryKeys ? data.categoryKeys[p.dataIndex] : String(p.dataIndex));\n const valFormatted = this.formatCellValue(p.value, key);\n html += `${p.marker} ${p.seriesName}: <b>${valFormatted}</b><br/>`;\n });\n return html;\n }\n },\n legend: EChartsOptions.getLegendOptions(),\n xAxis: EChartsOptions.getXAxisOptions({ data: data.categories }),\n yAxis: EChartsOptions.getYAxisOptions(),\n series: series as any\n };\n }\n}\n","import { Component, EventEmitter, Output, SimpleChanges } from '@angular/core';\nimport { BaseEchartsComponent } from '../../base-echart.component';\nimport { VerticalBandsBuilder } from '../../builders/vertical-bands.builder';\nimport { NgxEchartsDirective } from 'ngx-echarts';\nimport { CommonModule } from '@angular/common';\nimport { provideVSEcharts } from '../../vs-echarts.config';\n\n/**\n * EchartsVerticalBandsComponent\n * \n * Especialista en visualización de bandas/barras verticales. \n * Implementa patrones de interacción ZRender y resaltado de grupos.\n * @see {@link vs-echarts/docs/charts/vertical-bands-patterns.md}\n */\n@Component({\n selector: 'vs-echarts-vertical-bands',\n standalone: true,\n imports: [\n CommonModule,\n NgxEchartsDirective,\n ],\n templateUrl: './echarts-vertical-bands.component.html',\n styleUrls: ['./echarts-vertical-bands.component.scss'],\n providers: [provideVSEcharts()]\n})\nexport class EchartsVerticalBandsComponent extends BaseEchartsComponent {\n \n selectedSectorIndex: number | null = null;\n selectedSeriesIndex: number | null = null;\n private currentLegendSelected: any = null;\n \n protected override builder: VerticalBandsBuilder;\n\n constructor() {\n super();\n this.builder = new VerticalBandsBuilder();\n }\n\n override onChartInit(instance: any): void {\n super.onChartInit(instance);\n this.setupInteractions();\n }\n\n protected override onInputChanges(changes: SimpleChanges): void {\n if (changes['data']) {\n this.selectedSectorIndex = null;\n this.selectedSeriesIndex = null;\n this.currentLegendSelected = null;\n }\n super.onInputChanges(changes);\n }\n\n private setupInteractions(): void {\n if (!this.chartInstance) return;\n\n // 1. ZRender click for background \"sectors\"\n const zr = this.chartInstance.getZr();\n zr.on('click', (params: any) => {\n if (!params.target) {\n const pointInPixel = [params.offsetX, params.offsetY];\n if (this.chartInstance!.containPixel('grid', pointInPixel)) {\n // Fix TS2352: convertFromPixel return type cast\n const xIndexResult = this.chartInstance!.convertFromPixel({ xAxisIndex: 0 }, pointInPixel);\n const xIndex = Array.isArray(xIndexResult) ? xIndexResult[0] : xIndexResult;\n \n if (typeof xIndex === 'number' && xIndex >= 0) {\n this.toggleSectorSelection(xIndex);\n }\n }\n }\n });\n\n // 2. Mouseover for Group Highlighting\n this.chartInstance.on('mouseover', (params: any) => {\n if (params.dataIndex !== undefined) {\n this.highlightSector(params.dataIndex);\n }\n });\n\n this.chartInstance.on('mouseout', () => {\n this.clearHighlight();\n });\n }\n\n private toggleSectorSelection(index: number, seriesIndex: number | null = null): void {\n const isSameBar = this.selectedSectorIndex === index && this.selectedSeriesIndex === seriesIndex;\n\n if (isSameBar) {\n this.selectedSectorIndex = null;\n this.selectedSeriesIndex = null;\n } else {\n this.selectedSectorIndex = index;\n this.selectedSeriesIndex = seriesIndex;\n }\n \n // Refresh options to apply selection logic\n this.updateChartOptions();\n }\n\n private highlightSector(index: number): void {\n if (!this.chartInstance) return;\n const seriesCount = Array.isArray(this.chartOptions.series) ? this.chartOptions.series.length : 0;\n this.chartInstance.dispatchAction({\n type: 'highlight',\n seriesIndex: Array.from({length: seriesCount}, (_, i) => i),\n dataIndex: index\n });\n }\n\n private clearHighlight(): void {\n if (!this.chartInstance) return;\n const seriesCount = Array.isArray(this.chartOptions.series) ? this.chartOptions.series.length : 0;\n this.chartInstance.dispatchAction({\n type: 'downplay',\n seriesIndex: Array.from({length: seriesCount}, (_, i) => i)\n });\n }\n\n onChartClick(event: any): void {\n // 3. ECharts click only for bars (to avoid unwanted axis filtering)\n if (event.componentType === 'series') {\n const index = event.dataIndex;\n\n if (index !== undefined && index >= 0) {\n let seriesIndex: number | null = null;\n if (event.componentType === 'series') {\n seriesIndex = event.seriesIndex;\n }\n this.toggleSectorSelection(index, seriesIndex);\n \n // Emit standardized payload for cross-filtering\n this.chartClick.emit({\n type: 'cross-filter',\n data: {\n category: event.name,\n serie: event.seriesName,\n value: event.value\n }\n });\n }\n }\n }\n\n /**\n * Maneja clics en la leyenda para persistir filtros.\n */\n onLegendSelectChanged(event: any): void {\n if (event && event.selected) {\n this.currentLegendSelected = event.selected;\n this.updateChartOptions();\n }\n }\n\n protected updateChartOptions(): void {\n if (!this.chartInstance) return;\n if (!this.data) return;\n\n // 1. Configuramos el builder (Formateadores, Colores, etc se manejan en la base)\n if (this.valueFormatter) this.builder.setValueFormatter(this.valueFormatter);\n if (this.palette) this.builder.setPalette(this.palette);\n if (this.colorResolver) this.builder.setColorResolver(this.colorResolver);\n\n // 2. Obtenemos las bases del chart usando el builder\n let baseOptions = this.builder.build(\n this.data, \n this.chartConfig\n );\n\n // 3. Re-apply legend selection state if exists\n if (this.currentLegendSelected && baseOptions.legend) {\n (baseOptions.legend as any).selected = { ...this.currentLegendSelected };\n }\n\n // 4. Apply persistent selection style if a sector is selected\n if (this.selectedSectorIndex !== null && baseOptions.series) {\n const seriesArray = baseOptions.series as any[];\n baseOptions.series = seriesArray.map((s, sIdx) => {\n if (s.type === 'bar' && Array.isArray(s.data)) {\n return {\n ...s,\n data: s.data.map((val: any, idx: number) => {\n const isSelected = idx === this.selectedSectorIndex;\n const isBarSelected = isSelected && sIdx === this.selectedSeriesIndex;\n \n const itemVal = (val && typeof val === 'object' && val.value !== undefined) ? val.value : val;\n \n return {\n value: itemVal,\n itemStyle: {\n opacity: isSelected ? (isBarSelected ? 1 : 0.5) : 0.15,\n borderWidth: 0\n }\n };\n })\n };\n }\n return s;\n });\n }\n\n this.triggerUpdate(baseOptions)\n }\n}\n","<div class=\"echarts-container\">\n <div echarts [options]=\"chartOptions\" [autoResize]=\"true\" (chartInit)=\"onChartInit($event)\" (chartClick)=\"onChartClick($event)\" (legendSelectChanged)=\"onLegendSelectChanged($event)\" class=\"demo-chart\"></div>\n</div>\n","/*\n * Public API Surface of echarts\n */\n\nexport * from './lib/vs-echarts.config';\nexport * from './lib/charts/echarts-ring/echarts-ring.component';\nexport * from './lib/charts/echarts-vertical-bands/echarts-vertical-bands.component';\nexport * from './lib/base-echart.component';\nexport * from './lib/echarts-data.interfaces';\nexport * from './lib/echarts.interfaces';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["EChartsOptions.getDefaultPalette","EChartsOptions.getTooltipOptions","EChartsOptions.getLegendOptions","EChartsOptions.getXAxisOptions","EChartsOptions.getYAxisOptions"],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { OnChanges, OnDestroy, ElementRef, EventEmitter, SimpleChanges } from '@angular/core';
|
|
3
|
+
import * as echarts from 'echarts';
|
|
4
|
+
import { EChartsOption } from 'echarts';
|
|
5
|
+
|
|
6
|
+
declare function initializeEcharts(): void;
|
|
7
|
+
/**
|
|
8
|
+
* Provee la configuración de ECharts para ngx-echarts.
|
|
9
|
+
* Llama automáticamente a la inicialización de módulos.
|
|
10
|
+
*/
|
|
11
|
+
declare function provideVSEcharts(): i0.Provider;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* IEChartSeries
|
|
15
|
+
*
|
|
16
|
+
* Estructura de datos para una serie de ECharts.
|
|
17
|
+
*/
|
|
18
|
+
interface IEChartSeries {
|
|
19
|
+
name: string;
|
|
20
|
+
data: number[];
|
|
21
|
+
originalKey?: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* IEChartData
|
|
25
|
+
*
|
|
26
|
+
* Interfaz unificada para el paso de datos a componentes de ECharts.
|
|
27
|
+
* Desacoplada de IDataFrame de Visionaris.
|
|
28
|
+
*/
|
|
29
|
+
interface IEChartData {
|
|
30
|
+
categories: string[];
|
|
31
|
+
categoryKeys?: string[];
|
|
32
|
+
series: IEChartSeries[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* EChartValueFormatter
|
|
36
|
+
*
|
|
37
|
+
* Callback para formatear los valores numéricos de las celdas/series.
|
|
38
|
+
*/
|
|
39
|
+
type EChartValueFormatter = (value: number, key: string) => string;
|
|
40
|
+
/**
|
|
41
|
+
* EChartColorResolver
|
|
42
|
+
*
|
|
43
|
+
* Callback para determinar el color de un elemento gráfico basado en sus parámetros.
|
|
44
|
+
*/
|
|
45
|
+
type EChartColorResolver = (params: any) => string;
|
|
46
|
+
/**
|
|
47
|
+
* IEChartConfiguration
|
|
48
|
+
*
|
|
49
|
+
* Interfaz agnóstica para la configuración visual básica de ECharts.
|
|
50
|
+
*/
|
|
51
|
+
interface IEChartConfiguration {
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
type EChartClickType = 'cross-filter';
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* BaseEchartBuilder
|
|
58
|
+
*
|
|
59
|
+
* Clase base para la construcción de opciones de ECharts.
|
|
60
|
+
* Implementa lógica compartida de paletas y opciones comunes.
|
|
61
|
+
*
|
|
62
|
+
* @see {@link vs-echarts/docs/internal-architecture.md}
|
|
63
|
+
*/
|
|
64
|
+
declare abstract class BaseEchartBuilder {
|
|
65
|
+
protected valueFormatter: EChartValueFormatter;
|
|
66
|
+
protected palette: string[];
|
|
67
|
+
protected colorResolver?: EChartColorResolver;
|
|
68
|
+
constructor();
|
|
69
|
+
/**
|
|
70
|
+
* Permite inyectar un formateador de valores externo.
|
|
71
|
+
*/
|
|
72
|
+
setValueFormatter(formatter: EChartValueFormatter): void;
|
|
73
|
+
/**
|
|
74
|
+
* Permite inyectar una paleta de colores básica.
|
|
75
|
+
*/
|
|
76
|
+
setPalette(palette: string[]): void;
|
|
77
|
+
/**
|
|
78
|
+
* Permite inyectar un resolver de colores dinámico.
|
|
79
|
+
*/
|
|
80
|
+
setColorResolver(resolver: EChartColorResolver): void;
|
|
81
|
+
/**
|
|
82
|
+
* Método principal para construir el objeto EChartsOption.
|
|
83
|
+
*/
|
|
84
|
+
abstract build(data: IEChartData, chartConfig: IEChartConfiguration): EChartsOption;
|
|
85
|
+
/**
|
|
86
|
+
* Retorna configuraciones comunes para todos los gráficos.
|
|
87
|
+
*/
|
|
88
|
+
protected getCommonOptions(chartConfig?: IEChartConfiguration): EChartsOption;
|
|
89
|
+
/**
|
|
90
|
+
* Formatea un valor utilizando el callback inyectado.
|
|
91
|
+
*/
|
|
92
|
+
protected formatCellValue(value: number, key: string): string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
declare abstract class BaseEchartsComponent implements OnChanges, OnDestroy {
|
|
96
|
+
chartContainer: ElementRef;
|
|
97
|
+
/** Datos normalizados para graficar */
|
|
98
|
+
data: IEChartData;
|
|
99
|
+
/** Configuración visual agnóstica */
|
|
100
|
+
chartConfig: IEChartConfiguration;
|
|
101
|
+
/** Paleta de colores básica */
|
|
102
|
+
palette?: string[];
|
|
103
|
+
/** Resolver de colores dinámico (Callback) */
|
|
104
|
+
colorResolver?: EChartColorResolver;
|
|
105
|
+
/** Formateador de valores para etiquetas y tooltips */
|
|
106
|
+
valueFormatter?: EChartValueFormatter;
|
|
107
|
+
chartClick: EventEmitter<{
|
|
108
|
+
type: EChartClickType;
|
|
109
|
+
data: any;
|
|
110
|
+
}>;
|
|
111
|
+
/** Opciones configuradas para ngx-echarts */
|
|
112
|
+
chartOptions: any;
|
|
113
|
+
/** Subject para debouncing de actualizaciones. ReplaySubject asegura no perder el primer renderizado. */
|
|
114
|
+
private updateSubject;
|
|
115
|
+
private updateSubscription?;
|
|
116
|
+
constructor();
|
|
117
|
+
protected chartInstance?: echarts.ECharts;
|
|
118
|
+
protected abstract builder: BaseEchartBuilder;
|
|
119
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
120
|
+
ngOnDestroy(): void;
|
|
121
|
+
/**
|
|
122
|
+
* Captura la instancia de echarts (usado por ngx-echarts)
|
|
123
|
+
*/
|
|
124
|
+
onChartInit(instance: any): void;
|
|
125
|
+
private updateOptions;
|
|
126
|
+
/**
|
|
127
|
+
* Hook de template method invocado por `ngOnChanges`.
|
|
128
|
+
* Las subclases lo sobreescriben para añadir lógica propia
|
|
129
|
+
* y deben llamar a `super.onInputChanges(changes)` para preservar
|
|
130
|
+
* el comportamiento base (detectar inputs relevantes y actualizar el chart).
|
|
131
|
+
*/
|
|
132
|
+
protected onInputChanges(changes: SimpleChanges): void;
|
|
133
|
+
protected abstract updateChartOptions(): void;
|
|
134
|
+
/**
|
|
135
|
+
* Gatilla actualización en ngx-echarts
|
|
136
|
+
*/
|
|
137
|
+
protected triggerUpdate(options: echarts.EChartsOption): void;
|
|
138
|
+
/**
|
|
139
|
+
* Método público para forzar el redimensionado desde el padre
|
|
140
|
+
*/
|
|
141
|
+
resize(): void;
|
|
142
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<BaseEchartsComponent, never>;
|
|
143
|
+
static ɵdir: i0.ɵɵDirectiveDeclaration<BaseEchartsComponent, never, never, { "data": { "alias": "data"; "required": false; }; "chartConfig": { "alias": "chartConfig"; "required": false; }; "palette": { "alias": "palette"; "required": false; }; "colorResolver": { "alias": "colorResolver"; "required": false; }; "valueFormatter": { "alias": "valueFormatter"; "required": false; }; }, { "chartClick": "chartClick"; }, never, never, true, never>;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* RingBuilder
|
|
148
|
+
*
|
|
149
|
+
* Especializado en construir opciones para gráficos de tipo Ring (Donas concéntricas).
|
|
150
|
+
* @see {@link vs-echarts/docs/charts/ring-patterns.md}
|
|
151
|
+
*/
|
|
152
|
+
declare class RingBuilder extends BaseEchartBuilder {
|
|
153
|
+
build(data: IEChartData, chartConfig: IEChartConfiguration): EChartsOption;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* EchartsRingComponent
|
|
158
|
+
*
|
|
159
|
+
* Especialista en visualización de tipo Ring. Soporta multi-medidas y KPI central.
|
|
160
|
+
* @see {@link vs-echarts/docs/charts/ring-patterns.md}
|
|
161
|
+
*/
|
|
162
|
+
declare class EchartsRingComponent extends BaseEchartsComponent {
|
|
163
|
+
private lastSelectedSeriesIndex;
|
|
164
|
+
private lastSelectedDataIndex;
|
|
165
|
+
private selectedPercent;
|
|
166
|
+
private currentLegendSelected;
|
|
167
|
+
private currentGraphicText;
|
|
168
|
+
protected builder: RingBuilder;
|
|
169
|
+
constructor();
|
|
170
|
+
protected onInputChanges(changes: SimpleChanges): void;
|
|
171
|
+
/**
|
|
172
|
+
* Maneja clics en los sectores del ring.
|
|
173
|
+
* Soporta múltiples series (anillos) y actualiza el KPI central.
|
|
174
|
+
*/
|
|
175
|
+
onChartClick(event: any): void;
|
|
176
|
+
onChartMouseOver(event: any): void;
|
|
177
|
+
onChartMouseOut(event: any): void;
|
|
178
|
+
/**
|
|
179
|
+
* Captura los cambios en la selección de la leyenda para persistirlos.
|
|
180
|
+
*/
|
|
181
|
+
onLegendSelectChanged(event: any): void;
|
|
182
|
+
/**
|
|
183
|
+
* Actualiza el texto del Graphic central y persiste la selección en el modelo de opciones.
|
|
184
|
+
*/
|
|
185
|
+
private setGraphicText;
|
|
186
|
+
protected updateChartOptions(): void;
|
|
187
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EchartsRingComponent, never>;
|
|
188
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<EchartsRingComponent, "vs-echarts-ring", never, {}, {}, never, never, true, never>;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* VerticalBandsBuilder
|
|
193
|
+
*
|
|
194
|
+
* Especializado en construir opciones para gráficos de barras verticales.
|
|
195
|
+
* @see {@link vs-echarts/docs/charts/vertical-bands-patterns.md}
|
|
196
|
+
*/
|
|
197
|
+
declare class VerticalBandsBuilder extends BaseEchartBuilder {
|
|
198
|
+
constructor();
|
|
199
|
+
build(data: IEChartData, chartConfig: IEChartConfiguration): EChartsOption;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* EchartsVerticalBandsComponent
|
|
204
|
+
*
|
|
205
|
+
* Especialista en visualización de bandas/barras verticales.
|
|
206
|
+
* Implementa patrones de interacción ZRender y resaltado de grupos.
|
|
207
|
+
* @see {@link vs-echarts/docs/charts/vertical-bands-patterns.md}
|
|
208
|
+
*/
|
|
209
|
+
declare class EchartsVerticalBandsComponent extends BaseEchartsComponent {
|
|
210
|
+
selectedSectorIndex: number | null;
|
|
211
|
+
selectedSeriesIndex: number | null;
|
|
212
|
+
private currentLegendSelected;
|
|
213
|
+
protected builder: VerticalBandsBuilder;
|
|
214
|
+
constructor();
|
|
215
|
+
onChartInit(instance: any): void;
|
|
216
|
+
protected onInputChanges(changes: SimpleChanges): void;
|
|
217
|
+
private setupInteractions;
|
|
218
|
+
private toggleSectorSelection;
|
|
219
|
+
private highlightSector;
|
|
220
|
+
private clearHighlight;
|
|
221
|
+
onChartClick(event: any): void;
|
|
222
|
+
/**
|
|
223
|
+
* Maneja clics en la leyenda para persistir filtros.
|
|
224
|
+
*/
|
|
225
|
+
onLegendSelectChanged(event: any): void;
|
|
226
|
+
protected updateChartOptions(): void;
|
|
227
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<EchartsVerticalBandsComponent, never>;
|
|
228
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<EchartsVerticalBandsComponent, "vs-echarts-vertical-bands", never, {}, {}, never, never, true, never>;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
export { BaseEchartsComponent, EchartsRingComponent, EchartsVerticalBandsComponent, initializeEcharts, provideVSEcharts };
|
|
232
|
+
export type { EChartClickType, EChartColorResolver, EChartValueFormatter, IEChartConfiguration, IEChartData, IEChartSeries };
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@visionaris-bruno/vs-echarts",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^20.3.0",
|
|
6
|
+
"@angular/core": "^20.3.0",
|
|
7
|
+
"echarts": "^5.6.0",
|
|
8
|
+
"ngx-echarts": "^20.0.1",
|
|
9
|
+
"rxjs": "^7.8.0"
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"tslib": "^2.3.0"
|
|
13
|
+
},
|
|
14
|
+
"sideEffects": false,
|
|
15
|
+
"module": "fesm2022/visionaris-bruno-vs-echarts.mjs",
|
|
16
|
+
"typings": "index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
"./package.json": {
|
|
19
|
+
"default": "./package.json"
|
|
20
|
+
},
|
|
21
|
+
".": {
|
|
22
|
+
"types": "./index.d.ts",
|
|
23
|
+
"default": "./fesm2022/visionaris-bruno-vs-echarts.mjs"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|