@visionaris-bruno/vs-echarts 9.0.3 → 9.0.4
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.
|
@@ -237,11 +237,11 @@ class BaseEchartsComponent {
|
|
|
237
237
|
data = { dimensions: [], source: [] };
|
|
238
238
|
optionsOverrides = defaultOptionsOverrides();
|
|
239
239
|
/** Paleta de colores básica */
|
|
240
|
-
palette;
|
|
240
|
+
palette = getDefaultPalette();
|
|
241
241
|
/** Resolver de colores dinámico (Callback) */
|
|
242
242
|
colorResolver;
|
|
243
243
|
/** Formateador de valores para etiquetas y tooltips */
|
|
244
|
-
valueFormatter;
|
|
244
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
245
245
|
chartClick = new EventEmitter();
|
|
246
246
|
/** Subject para debouncing de actualizaciones. ReplaySubject asegura no perder el primer renderizado. */
|
|
247
247
|
updateSubject = new ReplaySubject(1);
|
|
@@ -1200,344 +1200,236 @@ class BoxPlotBuilder {
|
|
|
1200
1200
|
}
|
|
1201
1201
|
|
|
1202
1202
|
/**
|
|
1203
|
-
*
|
|
1203
|
+
* Builder principal.
|
|
1204
|
+
*
|
|
1205
|
+
* Es muy completo, tiene soporte para ejes y sistema cartesiano polar.
|
|
1206
|
+
*
|
|
1207
|
+
* Puede verse utilizado en graficos como Lineas y Bars. Siempre que se pueda priorizar utilizar este.
|
|
1204
1208
|
*/
|
|
1205
|
-
class
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
// TODO agregar radius y angle axis
|
|
1215
|
-
} } = opts;
|
|
1216
|
-
this.builder.reset();
|
|
1217
|
-
// El orden importa, primero callbaks y despues componentes.
|
|
1218
|
-
//chart callbacks
|
|
1219
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1220
|
-
this.builder.setPalette(palette);
|
|
1221
|
-
this.builder.setColorResolver(colorResolver);
|
|
1222
|
-
const product = this.builder.baseProduct;
|
|
1223
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1224
|
-
// chart components
|
|
1225
|
-
this.builder.addCommons();
|
|
1226
|
-
const layoutOpts = { axisTypes };
|
|
1227
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1228
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1229
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1230
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1231
|
-
this.builder.addLegend();
|
|
1232
|
-
}
|
|
1233
|
-
makeBarRadial(data, overrides, opts = {}) {
|
|
1234
|
-
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1235
|
-
x: 'category',
|
|
1236
|
-
y: 'value',
|
|
1237
|
-
// TODO agregar radius y angle axis
|
|
1238
|
-
} } = opts;
|
|
1239
|
-
this.builder.reset();
|
|
1240
|
-
// El orden importa, primero callbaks y despues componentes.
|
|
1241
|
-
//chart callbacks
|
|
1242
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1243
|
-
this.builder.setPalette(palette);
|
|
1244
|
-
this.builder.setColorResolver(colorResolver);
|
|
1245
|
-
const product = this.builder.baseProduct;
|
|
1246
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1247
|
-
// chart components
|
|
1248
|
-
this.builder.addCommons();
|
|
1249
|
-
const layoutOpts = { axisTypes, coordinateSystem: 'polar' };
|
|
1250
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1251
|
-
this.builder.addPolar();
|
|
1252
|
-
this.builder.addAngleAxis(data, overrides['axis']);
|
|
1253
|
-
this.builder.addRadiusAxis(data, overrides['axis']);
|
|
1254
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1255
|
-
this.builder.addLegend();
|
|
1256
|
-
}
|
|
1257
|
-
makeLine(data, overrides, opts = {}) {
|
|
1258
|
-
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1259
|
-
x: 'category',
|
|
1260
|
-
y: 'value',
|
|
1261
|
-
// TODO agregar radius y angle axis
|
|
1262
|
-
} } = opts;
|
|
1263
|
-
this.builder.reset();
|
|
1264
|
-
// El orden importa, primero callbaks y despues componentes.
|
|
1265
|
-
//chart callbacks
|
|
1266
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1267
|
-
this.builder.setPalette(palette);
|
|
1268
|
-
this.builder.setColorResolver(colorResolver);
|
|
1269
|
-
const product = this.builder.baseProduct;
|
|
1270
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1271
|
-
// chart components
|
|
1272
|
-
this.builder.addCommons();
|
|
1273
|
-
const layoutOpts = { axisTypes };
|
|
1274
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1275
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1276
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1277
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1278
|
-
this.builder.addLegend();
|
|
1209
|
+
class EChartBuilder {
|
|
1210
|
+
baseProduct = undefined;
|
|
1211
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
1212
|
+
palette = [];
|
|
1213
|
+
// TODO: Hay que implementar un valor por defecto.
|
|
1214
|
+
colorResolver;
|
|
1215
|
+
result = {};
|
|
1216
|
+
constructor(baseProduct) {
|
|
1217
|
+
this.baseProduct = baseProduct;
|
|
1279
1218
|
}
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
x: 'category',
|
|
1283
|
-
y: 'value',
|
|
1284
|
-
} } = opts;
|
|
1285
|
-
this.builder.reset();
|
|
1286
|
-
// El orden importa, primero callbacks y despues componentes.
|
|
1287
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1288
|
-
this.builder.setPalette(palette);
|
|
1289
|
-
this.builder.setColorResolver(colorResolver);
|
|
1290
|
-
const product = this.builder.baseProduct;
|
|
1291
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1292
|
-
// chart components
|
|
1293
|
-
this.builder.addCommons();
|
|
1294
|
-
const layoutOpts = { axisTypes };
|
|
1295
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1296
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1297
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1298
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1299
|
-
this.builder.addLegend();
|
|
1219
|
+
reset() {
|
|
1220
|
+
this.result = {};
|
|
1300
1221
|
}
|
|
1301
|
-
|
|
1302
|
-
const
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
this.
|
|
1306
|
-
this.builder.setPalette(palette);
|
|
1307
|
-
this.builder.setColorResolver(colorResolver);
|
|
1308
|
-
const product = this.builder.baseProduct;
|
|
1309
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1310
|
-
// chart components
|
|
1311
|
-
this.builder.addCommons();
|
|
1312
|
-
const layoutOpts = {};
|
|
1313
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1314
|
-
this.builder.addGraphic();
|
|
1315
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1316
|
-
this.builder.addLegend();
|
|
1222
|
+
addCommons() {
|
|
1223
|
+
const opts = {
|
|
1224
|
+
palette: this.palette,
|
|
1225
|
+
};
|
|
1226
|
+
merge$1(this.result, getCommons(opts));
|
|
1317
1227
|
}
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1228
|
+
/**
|
|
1229
|
+
*
|
|
1230
|
+
* @param data
|
|
1231
|
+
* @param overrides
|
|
1232
|
+
* @returns
|
|
1233
|
+
*/
|
|
1234
|
+
addSeries(data, overrides, opts) {
|
|
1235
|
+
if (!data || !data.dimensions || !data.source || data.source.length === 0)
|
|
1236
|
+
return;
|
|
1237
|
+
this.result.dataset = {
|
|
1238
|
+
dimensions: data.dimensions,
|
|
1239
|
+
source: data.source
|
|
1240
|
+
};
|
|
1241
|
+
const measureDims = data.dimensions.filter(d => d.name !== 'category');
|
|
1242
|
+
const isPolar = opts?.coordinateSystem === 'polar';
|
|
1243
|
+
const isHorizontal = opts?.axisTypes?.x === 'value' && opts?.axisTypes?.y === 'category';
|
|
1244
|
+
const series = measureDims.map((dim) => {
|
|
1245
|
+
const friendlyName = dim.displayName || dim.name;
|
|
1246
|
+
const dimKey = dim.name;
|
|
1247
|
+
let encode = {
|
|
1248
|
+
x: 'category',
|
|
1249
|
+
y: dimKey
|
|
1250
|
+
};
|
|
1251
|
+
if (isPolar) {
|
|
1252
|
+
encode = {
|
|
1253
|
+
angle: 'category',
|
|
1254
|
+
radius: dimKey
|
|
1255
|
+
};
|
|
1256
|
+
}
|
|
1257
|
+
else if (isHorizontal) {
|
|
1258
|
+
encode = {
|
|
1259
|
+
x: dimKey,
|
|
1260
|
+
y: 'category'
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
const dynamicOverrides = {
|
|
1264
|
+
name: friendlyName,
|
|
1265
|
+
encode,
|
|
1266
|
+
label: {
|
|
1267
|
+
formatter: (params) => {
|
|
1268
|
+
const row = params.value;
|
|
1269
|
+
const rawValue = (row && typeof row === 'object') ? row[dimKey] : params.value;
|
|
1270
|
+
return this.formatCellValue(Number(rawValue ?? 0), dimKey);
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
const seriesOption = merge$1(dynamicOverrides, overrides);
|
|
1275
|
+
// Inyectar el resolver de color si existe
|
|
1276
|
+
if (this.colorResolver && seriesOption.itemStyle) {
|
|
1277
|
+
seriesOption.itemStyle.color = this.colorResolver;
|
|
1278
|
+
}
|
|
1279
|
+
return seriesOption;
|
|
1280
|
+
});
|
|
1281
|
+
this.result.series = series;
|
|
1333
1282
|
}
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1347
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1348
|
-
this.builder.addLegend();
|
|
1283
|
+
/**
|
|
1284
|
+
* TODO: Mejorar funcion, no me convence como se implemento el tooltip formatter.
|
|
1285
|
+
* @param data
|
|
1286
|
+
* @param overrides
|
|
1287
|
+
*/
|
|
1288
|
+
addTooltip(data, overrides) {
|
|
1289
|
+
// inyecto formateador a overrides de tooltip
|
|
1290
|
+
merge$1(overrides, {
|
|
1291
|
+
formatter: getTooltipFormatter(overrides.trigger, data, this.formatCellValue.bind(this)),
|
|
1292
|
+
});
|
|
1293
|
+
const tooltip = getTooltipOptions(overrides);
|
|
1294
|
+
this.result.tooltip = tooltip;
|
|
1349
1295
|
}
|
|
1350
|
-
|
|
1351
|
-
const
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
this.
|
|
1357
|
-
const product = this.builder.baseProduct;
|
|
1358
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1359
|
-
// chart components
|
|
1360
|
-
this.builder.addCommons();
|
|
1361
|
-
const layoutOpts = {};
|
|
1362
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1363
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1364
|
-
// this.builder.addLegend();
|
|
1296
|
+
addPolar() {
|
|
1297
|
+
const polar = [];
|
|
1298
|
+
polar.push({
|
|
1299
|
+
radius: '65%',
|
|
1300
|
+
center: ["50%", "44%"],
|
|
1301
|
+
});
|
|
1302
|
+
this.result.polar = polar;
|
|
1365
1303
|
}
|
|
1366
|
-
|
|
1367
|
-
const
|
|
1368
|
-
this.
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
this.
|
|
1377
|
-
const layoutOpts = {};
|
|
1378
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1379
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1304
|
+
addXAxis(data, overrides, type = 'category') {
|
|
1305
|
+
const xAxis = [];
|
|
1306
|
+
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1307
|
+
const valueAxisOptions = this.getValueAxisOptions(data, overrides);
|
|
1308
|
+
if (type == 'category') {
|
|
1309
|
+
xAxis.push(categoryAxisOptions);
|
|
1310
|
+
}
|
|
1311
|
+
else if (type == 'value') {
|
|
1312
|
+
xAxis.push(valueAxisOptions);
|
|
1313
|
+
}
|
|
1314
|
+
this.result.xAxis = xAxis;
|
|
1380
1315
|
}
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1316
|
+
addYAxis(data, overrides, type = 'value') {
|
|
1317
|
+
const yAxis = [];
|
|
1318
|
+
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1319
|
+
const valueAxisOptions = this.getValueAxisOptions(data, overrides);
|
|
1320
|
+
if (type == 'category') {
|
|
1321
|
+
yAxis.push(categoryAxisOptions);
|
|
1384
1322
|
}
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
this.builder.reset();
|
|
1390
|
-
// El orden importa, primero callbacks y despues componentes.
|
|
1391
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1392
|
-
this.builder.setPalette(palette);
|
|
1393
|
-
this.builder.setColorResolver(colorResolver);
|
|
1394
|
-
const product = this.builder.baseProduct;
|
|
1395
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1396
|
-
// chart components
|
|
1397
|
-
this.builder.addCommons();
|
|
1398
|
-
const layoutOpts = { axisTypes };
|
|
1399
|
-
this.builder.addDataset(data);
|
|
1400
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1401
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1402
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1403
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1404
|
-
this.builder.addDataZoom();
|
|
1323
|
+
else if (type == 'value') {
|
|
1324
|
+
yAxis.push(valueAxisOptions);
|
|
1325
|
+
}
|
|
1326
|
+
this.result.yAxis = yAxis;
|
|
1405
1327
|
}
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
/**
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
*/
|
|
1414
|
-
class EchartsRingComponent extends BaseEchartsComponent {
|
|
1415
|
-
baseSeriesOptions = {
|
|
1416
|
-
type: 'pie',
|
|
1417
|
-
center: ['50%', '50%'],
|
|
1418
|
-
avoidLabelOverlap: true,
|
|
1419
|
-
minAngle: 3,
|
|
1420
|
-
selectedMode: 'single',
|
|
1421
|
-
selectedOffset: 4,
|
|
1422
|
-
itemStyle: {
|
|
1423
|
-
borderColor: '#fff',
|
|
1424
|
-
},
|
|
1425
|
-
label: { show: false },
|
|
1426
|
-
emphasis: {
|
|
1427
|
-
scale: true,
|
|
1428
|
-
scaleSize: 2,
|
|
1429
|
-
},
|
|
1430
|
-
select: {
|
|
1431
|
-
itemStyle: {
|
|
1432
|
-
borderColor: EChartsTokens.sBorderColor,
|
|
1433
|
-
shadowColor: EChartsTokens.sShadowColor,
|
|
1434
|
-
borderWidth: 1,
|
|
1435
|
-
shadowBlur: 4,
|
|
1328
|
+
addRadiusAxis(data, overrides) {
|
|
1329
|
+
const radiusAxis = [];
|
|
1330
|
+
/** estilos exclusivos hardcodeados para el eje de valores del sistema de coordenadas polar*/
|
|
1331
|
+
const radiusAxisOverrides = {
|
|
1332
|
+
zlevel: 10,
|
|
1333
|
+
axisTick: {
|
|
1334
|
+
show: false,
|
|
1436
1335
|
},
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
make() {
|
|
1457
|
-
const makeOpts = {
|
|
1458
|
-
valueFormatter: this.valueFormatter,
|
|
1459
|
-
palette: this.palette,
|
|
1460
|
-
colorResolver: this.colorResolver,
|
|
1336
|
+
axisLabel: {
|
|
1337
|
+
margin: 2,
|
|
1338
|
+
fontSize: 8,
|
|
1339
|
+
align: 'right',
|
|
1340
|
+
rotate: 20,
|
|
1341
|
+
verticalAlign: 'top',
|
|
1342
|
+
},
|
|
1343
|
+
splitLine: {
|
|
1344
|
+
show: true,
|
|
1345
|
+
lineStyle: {
|
|
1346
|
+
opacity: 0.2,
|
|
1347
|
+
type: 'solid',
|
|
1348
|
+
}
|
|
1349
|
+
},
|
|
1350
|
+
axisLine: {
|
|
1351
|
+
lineStyle: {
|
|
1352
|
+
type: 'dashed',
|
|
1353
|
+
},
|
|
1354
|
+
}
|
|
1461
1355
|
};
|
|
1462
|
-
|
|
1356
|
+
const radialAxisOptions = getValueAxisOptions(radiusAxisOverrides);
|
|
1357
|
+
radiusAxis.push(radialAxisOptions);
|
|
1358
|
+
this.result.radiusAxis = radiusAxis;
|
|
1463
1359
|
}
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1360
|
+
addAngleAxis(data, overrides) {
|
|
1361
|
+
const angleAxis = [];
|
|
1362
|
+
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1363
|
+
angleAxis.push(categoryAxisOptions);
|
|
1364
|
+
this.result.angleAxis = angleAxis;
|
|
1365
|
+
}
|
|
1366
|
+
addLegend() {
|
|
1367
|
+
this.result.legend = getLegendOptions();
|
|
1368
|
+
}
|
|
1369
|
+
// No-ops for ring charts
|
|
1370
|
+
addGraphic() { }
|
|
1371
|
+
addDataset(data) { }
|
|
1372
|
+
addDataZoom() {
|
|
1373
|
+
this.result.dataZoom = [
|
|
1374
|
+
{
|
|
1375
|
+
type: 'inside'
|
|
1376
|
+
},
|
|
1377
|
+
{
|
|
1378
|
+
type: 'slider',
|
|
1379
|
+
height: 20,
|
|
1380
|
+
bottom: 60
|
|
1381
|
+
}
|
|
1382
|
+
];
|
|
1383
|
+
}
|
|
1384
|
+
getResult() {
|
|
1385
|
+
return this.result;
|
|
1473
1386
|
}
|
|
1387
|
+
;
|
|
1474
1388
|
/**
|
|
1475
|
-
*
|
|
1476
|
-
* Soporta múltiples series (anillos) y actualiza el KPI central.
|
|
1389
|
+
* Formatea un valor utilizando el callback inyectado.
|
|
1477
1390
|
*/
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
const isSameSelection = event.seriesIndex === this.lastSelectedSeriesIndex &&
|
|
1481
|
-
event.dataIndex === this.lastSelectedDataIndex;
|
|
1482
|
-
if (isSameSelection) {
|
|
1483
|
-
// Toggle OFF
|
|
1484
|
-
this.lastSelectedSeriesIndex = null;
|
|
1485
|
-
this.lastSelectedDataIndex = null;
|
|
1486
|
-
this.selectedPercent = null;
|
|
1487
|
-
this.setGraphicText('');
|
|
1488
|
-
}
|
|
1489
|
-
else {
|
|
1490
|
-
// SELECT
|
|
1491
|
-
this.lastSelectedSeriesIndex = event.seriesIndex;
|
|
1492
|
-
this.lastSelectedDataIndex = event.dataIndex;
|
|
1493
|
-
this.selectedPercent = (event.percent !== undefined) ? event.percent + '%' : '';
|
|
1494
|
-
this.setGraphicText(this.selectedPercent);
|
|
1495
|
-
}
|
|
1496
|
-
this.chartClick.emit({
|
|
1497
|
-
type: 'cross-filter',
|
|
1498
|
-
data: {
|
|
1499
|
-
category: event.name,
|
|
1500
|
-
serie: event.seriesName,
|
|
1501
|
-
value: event.value
|
|
1502
|
-
}
|
|
1503
|
-
});
|
|
1504
|
-
}
|
|
1391
|
+
formatCellValue(value, key) {
|
|
1392
|
+
return this.valueFormatter(value, key);
|
|
1505
1393
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1394
|
+
// Setters
|
|
1395
|
+
/**
|
|
1396
|
+
* Permite inyectar un formateador de valores externo.
|
|
1397
|
+
*/
|
|
1398
|
+
setValueFormatter(formatter) {
|
|
1399
|
+
if (formatter) {
|
|
1400
|
+
this.valueFormatter = formatter;
|
|
1509
1401
|
}
|
|
1510
1402
|
}
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1403
|
+
/**
|
|
1404
|
+
* Permite inyectar una paleta de colores básica.
|
|
1405
|
+
*/
|
|
1406
|
+
setPalette(palette) {
|
|
1407
|
+
if (palette) {
|
|
1408
|
+
this.palette = palette;
|
|
1514
1409
|
}
|
|
1515
1410
|
}
|
|
1516
1411
|
/**
|
|
1517
|
-
*
|
|
1412
|
+
* Permite inyectar un resolver de colores dinámico.
|
|
1518
1413
|
*/
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
}
|
|
1414
|
+
setColorResolver(resolver) {
|
|
1415
|
+
if (resolver) {
|
|
1416
|
+
this.colorResolver = resolver;
|
|
1417
|
+
}
|
|
1418
|
+
}
|
|
1419
|
+
// Utils
|
|
1420
|
+
getCategoryAxisOptions(data, overrides) {
|
|
1421
|
+
// No explicit data needed on category axis when using ECharts dataset
|
|
1422
|
+
const categoryAxisOptionsOverrides = {
|
|
1423
|
+
...overrides.categoryAxis[0]
|
|
1424
|
+
};
|
|
1425
|
+
const categoryAxisOptions = getCategoryAxisOptions(categoryAxisOptionsOverrides);
|
|
1426
|
+
return categoryAxisOptions;
|
|
1427
|
+
}
|
|
1428
|
+
getValueAxisOptions(data, overrides) {
|
|
1429
|
+
const valueAxisOptions = getValueAxisOptions();
|
|
1430
|
+
return valueAxisOptions;
|
|
1530
1431
|
}
|
|
1531
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1532
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsRingComponent, isStandalone: true, selector: "vs-echarts-ring", usesInheritance: true, ngImport: i0, template: "<div class=\"echarts-container\" \n echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n ", styles: [".echarts-container{width:100%;height:100%;position:relative}\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"] }] });
|
|
1533
1432
|
}
|
|
1534
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, decorators: [{
|
|
1535
|
-
type: Component,
|
|
1536
|
-
args: [{ selector: 'vs-echarts-ring', standalone: true, imports: [
|
|
1537
|
-
CommonModule,
|
|
1538
|
-
NgxEchartsDirective,
|
|
1539
|
-
], template: "<div class=\"echarts-container\" \n echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n ", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
1540
|
-
}], ctorParameters: () => [] });
|
|
1541
1433
|
|
|
1542
1434
|
/**
|
|
1543
1435
|
* PieBuilder
|
|
@@ -1702,78 +1594,18 @@ class PieBuilder {
|
|
|
1702
1594
|
}
|
|
1703
1595
|
|
|
1704
1596
|
/**
|
|
1705
|
-
*
|
|
1597
|
+
* FunnelBuilder
|
|
1706
1598
|
*
|
|
1707
|
-
*
|
|
1708
|
-
* La primera serie se dibuja como un gráfico de torta tradicional (lleno) y
|
|
1709
|
-
* las subsecuentes como anillos concéntricos alrededor.
|
|
1599
|
+
* Concrete builder for Funnel charts.
|
|
1710
1600
|
*/
|
|
1711
|
-
class
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
emphasis: {
|
|
1720
|
-
scale: true,
|
|
1721
|
-
scaleSize: 2,
|
|
1722
|
-
},
|
|
1723
|
-
select: {
|
|
1724
|
-
itemStyle: {
|
|
1725
|
-
borderColor: EChartsTokens.sBorderColor,
|
|
1726
|
-
shadowColor: EChartsTokens.sShadowColor,
|
|
1727
|
-
borderWidth: 1,
|
|
1728
|
-
shadowBlur: 4,
|
|
1729
|
-
},
|
|
1730
|
-
},
|
|
1731
|
-
animationType: 'scale',
|
|
1732
|
-
animationEasing: 'elasticOut',
|
|
1733
|
-
};
|
|
1734
|
-
baseProduct = {
|
|
1735
|
-
chartKey: 'pie',
|
|
1736
|
-
baseOptions: {
|
|
1737
|
-
series: this.baseSeriesOptions,
|
|
1738
|
-
}
|
|
1739
|
-
};
|
|
1740
|
-
builder = new PieBuilder(this.baseProduct);
|
|
1741
|
-
director = new VSECDirector(this.builder);
|
|
1742
|
-
constructor() {
|
|
1743
|
-
super();
|
|
1744
|
-
}
|
|
1745
|
-
make() {
|
|
1746
|
-
const makeOpts = {
|
|
1747
|
-
valueFormatter: this.valueFormatter,
|
|
1748
|
-
palette: this.palette,
|
|
1749
|
-
colorResolver: this.colorResolver,
|
|
1750
|
-
};
|
|
1751
|
-
this.director.makePie(this.data, this.optionsOverrides, makeOpts);
|
|
1752
|
-
}
|
|
1753
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1754
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsPieComponent, isStandalone: true, selector: "vs-echarts-pie", usesInheritance: true, ngImport: i0, template: "<div\n class=\"echarts-container\"\n echarts\n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\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"] }] });
|
|
1755
|
-
}
|
|
1756
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, decorators: [{
|
|
1757
|
-
type: Component,
|
|
1758
|
-
args: [{ selector: 'vs-echarts-pie', standalone: true, imports: [
|
|
1759
|
-
CommonModule,
|
|
1760
|
-
NgxEchartsDirective,
|
|
1761
|
-
], template: "<div\n class=\"echarts-container\"\n echarts\n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
1762
|
-
}], ctorParameters: () => [] });
|
|
1763
|
-
|
|
1764
|
-
/**
|
|
1765
|
-
* FunnelBuilder
|
|
1766
|
-
*
|
|
1767
|
-
* Concrete builder for Funnel charts.
|
|
1768
|
-
*/
|
|
1769
|
-
class FunnelBuilder {
|
|
1770
|
-
baseProduct;
|
|
1771
|
-
valueFormatter = (value) => value.toLocaleString();
|
|
1772
|
-
palette = [];
|
|
1773
|
-
colorResolver;
|
|
1774
|
-
result = {};
|
|
1775
|
-
constructor(baseProduct) {
|
|
1776
|
-
this.baseProduct = baseProduct;
|
|
1601
|
+
class FunnelBuilder {
|
|
1602
|
+
baseProduct;
|
|
1603
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
1604
|
+
palette = [];
|
|
1605
|
+
colorResolver;
|
|
1606
|
+
result = {};
|
|
1607
|
+
constructor(baseProduct) {
|
|
1608
|
+
this.baseProduct = baseProduct;
|
|
1777
1609
|
}
|
|
1778
1610
|
reset() {
|
|
1779
1611
|
this.result = {};
|
|
@@ -1865,91 +1697,10 @@ class FunnelBuilder {
|
|
|
1865
1697
|
}
|
|
1866
1698
|
}
|
|
1867
1699
|
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
*
|
|
1871
|
-
* Component for Funnel visualization. Supports single and multiple measures.
|
|
1872
|
-
*/
|
|
1873
|
-
class EchartsFunnelComponent extends BaseEchartsComponent {
|
|
1874
|
-
baseSeriesOptions = {
|
|
1875
|
-
type: 'funnel',
|
|
1876
|
-
left: '10%',
|
|
1877
|
-
width: '80%',
|
|
1878
|
-
minSize: '0.01%',
|
|
1879
|
-
maxSize: '100%',
|
|
1880
|
-
sort: 'descending',
|
|
1881
|
-
gap: 2,
|
|
1882
|
-
label: {
|
|
1883
|
-
show: true,
|
|
1884
|
-
position: 'inside'
|
|
1885
|
-
},
|
|
1886
|
-
labelLine: {
|
|
1887
|
-
show: false
|
|
1888
|
-
},
|
|
1889
|
-
itemStyle: {
|
|
1890
|
-
borderColor: '#fff',
|
|
1891
|
-
borderWidth: 1
|
|
1892
|
-
},
|
|
1893
|
-
emphasis: {
|
|
1894
|
-
label: {
|
|
1895
|
-
fontSize: 16
|
|
1896
|
-
}
|
|
1897
|
-
},
|
|
1898
|
-
selectedMode: 'single',
|
|
1899
|
-
select: {
|
|
1900
|
-
label: {
|
|
1901
|
-
fontSize: 16
|
|
1902
|
-
},
|
|
1903
|
-
itemStyle: {
|
|
1904
|
-
borderWidth: 1,
|
|
1905
|
-
borderColor: EChartsTokens.sBorderColor,
|
|
1906
|
-
shadowColor: EChartsTokens.sShadowColor,
|
|
1907
|
-
shadowBlur: 6,
|
|
1908
|
-
}
|
|
1909
|
-
},
|
|
1910
|
-
};
|
|
1911
|
-
baseProduct = {
|
|
1912
|
-
chartKey: 'funnel',
|
|
1913
|
-
baseOptions: {
|
|
1914
|
-
series: this.baseSeriesOptions,
|
|
1915
|
-
}
|
|
1916
|
-
};
|
|
1917
|
-
builder = new FunnelBuilder(this.baseProduct);
|
|
1918
|
-
director = new VSECDirector(this.builder);
|
|
1919
|
-
constructor() {
|
|
1920
|
-
super();
|
|
1921
|
-
}
|
|
1922
|
-
make() {
|
|
1923
|
-
const makeOpts = {
|
|
1924
|
-
valueFormatter: this.valueFormatter,
|
|
1925
|
-
palette: this.palette,
|
|
1926
|
-
colorResolver: this.colorResolver,
|
|
1927
|
-
};
|
|
1928
|
-
this.director.makeFunnel(this.data, this.optionsOverrides, makeOpts);
|
|
1929
|
-
}
|
|
1930
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1931
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsFunnelComponent, isStandalone: true, selector: "vs-echarts-funnel", usesInheritance: true, ngImport: i0, template: "<div class=\"echarts-container\" echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\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"] }] });
|
|
1932
|
-
}
|
|
1933
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, decorators: [{
|
|
1934
|
-
type: Component,
|
|
1935
|
-
args: [{ selector: 'vs-echarts-funnel', standalone: true, imports: [
|
|
1936
|
-
CommonModule,
|
|
1937
|
-
NgxEchartsDirective,
|
|
1938
|
-
], template: "<div class=\"echarts-container\" echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
1939
|
-
}], ctorParameters: () => [] });
|
|
1940
|
-
|
|
1941
|
-
/**
|
|
1942
|
-
* Builder principal.
|
|
1943
|
-
*
|
|
1944
|
-
* Es muy completo, tiene soporte para ejes y sistema cartesiano polar.
|
|
1945
|
-
*
|
|
1946
|
-
* Puede verse utilizado en graficos como Lineas y Bars. Siempre que se pueda priorizar utilizar este.
|
|
1947
|
-
*/
|
|
1948
|
-
class EChartBuilder {
|
|
1949
|
-
baseProduct = undefined;
|
|
1700
|
+
class SunburstBuilder {
|
|
1701
|
+
baseProduct;
|
|
1950
1702
|
valueFormatter = (value) => value.toLocaleString();
|
|
1951
1703
|
palette = [];
|
|
1952
|
-
// TODO: Hay que implementar un valor por defecto.
|
|
1953
1704
|
colorResolver;
|
|
1954
1705
|
result = {};
|
|
1955
1706
|
constructor(baseProduct) {
|
|
@@ -1958,217 +1709,779 @@ class EChartBuilder {
|
|
|
1958
1709
|
reset() {
|
|
1959
1710
|
this.result = {};
|
|
1960
1711
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
palette: this.palette,
|
|
1964
|
-
};
|
|
1965
|
-
merge$1(this.result, getCommons(opts));
|
|
1966
|
-
}
|
|
1967
|
-
/**
|
|
1968
|
-
*
|
|
1969
|
-
* @param data
|
|
1970
|
-
* @param overrides
|
|
1971
|
-
* @returns
|
|
1972
|
-
*/
|
|
1973
|
-
addSeries(data, overrides, opts) {
|
|
1974
|
-
if (!data || !data.dimensions || !data.source || data.source.length === 0)
|
|
1712
|
+
addSeries(data, overrides) {
|
|
1713
|
+
if (!data || !data.source || data.source.length === 0) {
|
|
1975
1714
|
return;
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
const isHorizontal = opts?.axisTypes?.x === 'value' && opts?.axisTypes?.y === 'category';
|
|
1983
|
-
const series = measureDims.map((dim) => {
|
|
1984
|
-
const friendlyName = dim.displayName || dim.name;
|
|
1985
|
-
const dimKey = dim.name;
|
|
1986
|
-
let encode = {
|
|
1987
|
-
x: 'category',
|
|
1988
|
-
y: dimKey
|
|
1989
|
-
};
|
|
1990
|
-
if (isPolar) {
|
|
1991
|
-
encode = {
|
|
1992
|
-
angle: 'category',
|
|
1993
|
-
radius: dimKey
|
|
1994
|
-
};
|
|
1995
|
-
}
|
|
1996
|
-
else if (isHorizontal) {
|
|
1997
|
-
encode = {
|
|
1998
|
-
x: dimKey,
|
|
1999
|
-
y: 'category'
|
|
2000
|
-
};
|
|
2001
|
-
}
|
|
2002
|
-
const dynamicOverrides = {
|
|
2003
|
-
name: friendlyName,
|
|
2004
|
-
encode,
|
|
1715
|
+
}
|
|
1716
|
+
const sunburstData = mapHierarchicalData(data.source, data.dimensions);
|
|
1717
|
+
const depth = getTreeDepth(sunburstData);
|
|
1718
|
+
const levels = [];
|
|
1719
|
+
for (let i = 0; i <= depth; i++) {
|
|
1720
|
+
levels.push({
|
|
2005
1721
|
label: {
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
|
|
2009
|
-
|
|
2010
|
-
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
1722
|
+
show: false,
|
|
1723
|
+
},
|
|
1724
|
+
});
|
|
1725
|
+
}
|
|
1726
|
+
const dynamiSerieOptions = {
|
|
1727
|
+
name: '',
|
|
1728
|
+
data: sunburstData,
|
|
1729
|
+
levels: levels
|
|
1730
|
+
};
|
|
1731
|
+
const serie = merge$1({}, dynamiSerieOptions, overrides);
|
|
1732
|
+
if (this.colorResolver) {
|
|
1733
|
+
if (!serie.itemStyle) {
|
|
1734
|
+
serie.itemStyle = {};
|
|
2017
1735
|
}
|
|
2018
|
-
|
|
2019
|
-
}
|
|
2020
|
-
this.result.series =
|
|
1736
|
+
serie.itemStyle.color = this.colorResolver;
|
|
1737
|
+
}
|
|
1738
|
+
this.result.series = serie;
|
|
2021
1739
|
}
|
|
2022
|
-
/**
|
|
2023
|
-
* TODO: Mejorar funcion, no me convence como se implemento el tooltip formatter.
|
|
2024
|
-
* @param data
|
|
2025
|
-
* @param overrides
|
|
2026
|
-
*/
|
|
2027
1740
|
addTooltip(data, overrides) {
|
|
2028
|
-
// inyecto formateador a overrides de tooltip
|
|
2029
1741
|
merge$1(overrides, {
|
|
2030
|
-
formatter: getTooltipFormatter(overrides.trigger, data, this.
|
|
1742
|
+
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
2031
1743
|
});
|
|
2032
1744
|
const tooltip = getTooltipOptions(overrides);
|
|
2033
1745
|
this.result.tooltip = tooltip;
|
|
2034
1746
|
}
|
|
2035
|
-
|
|
2036
|
-
const
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
});
|
|
2041
|
-
this.result.polar = polar;
|
|
1747
|
+
addCommons() {
|
|
1748
|
+
const opts = {
|
|
1749
|
+
palette: this.palette,
|
|
1750
|
+
};
|
|
1751
|
+
merge$1(this.result, getCommons(opts));
|
|
2042
1752
|
}
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
2046
|
-
const valueAxisOptions = this.getValueAxisOptions(data, overrides);
|
|
2047
|
-
if (type == 'category') {
|
|
2048
|
-
xAxis.push(categoryAxisOptions);
|
|
2049
|
-
}
|
|
2050
|
-
else if (type == 'value') {
|
|
2051
|
-
xAxis.push(valueAxisOptions);
|
|
2052
|
-
}
|
|
2053
|
-
this.result.xAxis = xAxis;
|
|
1753
|
+
getResult() {
|
|
1754
|
+
return this.result;
|
|
2054
1755
|
}
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
1756
|
+
;
|
|
1757
|
+
// No-ops
|
|
1758
|
+
addPolar() { }
|
|
1759
|
+
addXAxis(data, overrides, type) { }
|
|
1760
|
+
addYAxis(data, overrides, type) { }
|
|
1761
|
+
addRadiusAxis(data, overrides) { }
|
|
1762
|
+
addAngleAxis(data, overrides) { }
|
|
1763
|
+
addLegend() { }
|
|
1764
|
+
addDataZoom() { }
|
|
1765
|
+
addDataset(data, opts) { }
|
|
1766
|
+
addGraphic() { }
|
|
1767
|
+
// Setters
|
|
1768
|
+
/**
|
|
1769
|
+
* Permite inyectar un formateador de valores externo.
|
|
1770
|
+
*/
|
|
1771
|
+
setValueFormatter(formatter) {
|
|
1772
|
+
if (formatter) {
|
|
1773
|
+
this.valueFormatter = formatter;
|
|
2064
1774
|
}
|
|
2065
|
-
this.result.yAxis = yAxis;
|
|
2066
1775
|
}
|
|
2067
|
-
|
|
2068
|
-
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
1776
|
+
/**
|
|
1777
|
+
* Permite inyectar una paleta de colores básica.
|
|
1778
|
+
*/
|
|
1779
|
+
setPalette(palette) {
|
|
1780
|
+
if (palette) {
|
|
1781
|
+
this.palette = palette;
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
/**
|
|
1785
|
+
* Permite inyectar un resolver de colores dinámico.
|
|
1786
|
+
*/
|
|
1787
|
+
setColorResolver(resolver) {
|
|
1788
|
+
if (resolver) {
|
|
1789
|
+
this.colorResolver = resolver;
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
/**
|
|
1795
|
+
* SankeyBuilder
|
|
1796
|
+
*
|
|
1797
|
+
* Builder concreto para el gráfico Sankey (diagrama de flujos de izquierda a derecha).
|
|
1798
|
+
*/
|
|
1799
|
+
class SankeyBuilder {
|
|
1800
|
+
baseProduct;
|
|
1801
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
1802
|
+
palette = [];
|
|
1803
|
+
colorResolver;
|
|
1804
|
+
result = {};
|
|
1805
|
+
constructor(baseProduct) {
|
|
1806
|
+
this.baseProduct = baseProduct;
|
|
1807
|
+
}
|
|
1808
|
+
reset() {
|
|
1809
|
+
this.result = {};
|
|
1810
|
+
}
|
|
1811
|
+
addSeries(data, overrides) {
|
|
1812
|
+
if (!data || !data.source || data.source.length === 0) {
|
|
1813
|
+
return;
|
|
1814
|
+
}
|
|
1815
|
+
// Identificar medidas (todas las dimensiones excepto 'category')
|
|
1816
|
+
const measureKeys = data.dimensions
|
|
1817
|
+
.filter((d) => d.name !== "category")
|
|
1818
|
+
.map((d) => d.name);
|
|
1819
|
+
// Función auxiliar para sumarizar valores de medidas en caso de haber más de una
|
|
1820
|
+
const getNodeValue = (node) => {
|
|
1821
|
+
return measureKeys.reduce((sum, key) => sum + (Number(node[key]) || 0), 0);
|
|
1822
|
+
};
|
|
1823
|
+
const nodesMap = new Map();
|
|
1824
|
+
const linksMap = new Map();
|
|
1825
|
+
// Función recursiva para aplanar datos jerárquicos a nodos y enlaces
|
|
1826
|
+
const traverse = (nodeList, level, parentId) => {
|
|
1827
|
+
for (const node of nodeList) {
|
|
1828
|
+
const category = node.category;
|
|
1829
|
+
const currentId = `${category}___${level}`;
|
|
1830
|
+
const value = getNodeValue(node);
|
|
1831
|
+
nodesMap.set(currentId, (nodesMap.get(currentId) || 0) + value);
|
|
1832
|
+
if (parentId) {
|
|
1833
|
+
const linkKey = `${parentId}--->${currentId}`;
|
|
1834
|
+
if (linksMap.has(linkKey)) {
|
|
1835
|
+
linksMap.get(linkKey).value += value;
|
|
1836
|
+
}
|
|
1837
|
+
else {
|
|
1838
|
+
linksMap.set(linkKey, {
|
|
1839
|
+
source: parentId,
|
|
1840
|
+
target: currentId,
|
|
1841
|
+
value: value,
|
|
1842
|
+
});
|
|
1843
|
+
}
|
|
1844
|
+
}
|
|
1845
|
+
if (node.children && node.children.length > 0) {
|
|
1846
|
+
traverse(node.children, level + 1, currentId);
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
};
|
|
1850
|
+
// Comenzar el recorrido en el nivel 0
|
|
1851
|
+
traverse(data.source, 0);
|
|
1852
|
+
// al menos un nivel de links para dibujar.
|
|
1853
|
+
if (linksMap.size === 0)
|
|
1854
|
+
return;
|
|
1855
|
+
// Mapear nodos acumulados a la estructura requerida por ECharts (name y opcionalmente color, sin value redundante)
|
|
1856
|
+
const nodes = Array.from(nodesMap.keys()).map((currentId) => {
|
|
1857
|
+
const category = currentId.split("___")[0];
|
|
1858
|
+
const nodeItem = {
|
|
1859
|
+
name: currentId,
|
|
1860
|
+
};
|
|
1861
|
+
if (this.colorResolver) {
|
|
1862
|
+
const color = this.colorResolver({ name: category, data: nodeItem });
|
|
1863
|
+
if (color) {
|
|
1864
|
+
nodeItem.itemStyle = { color };
|
|
1865
|
+
}
|
|
1866
|
+
}
|
|
1867
|
+
return nodeItem;
|
|
1868
|
+
});
|
|
1869
|
+
const dynamicSerieOptions = {
|
|
1870
|
+
type: "sankey",
|
|
1871
|
+
orient: "horizontal", // De izquierda a derecha
|
|
1872
|
+
draggable: true,
|
|
1873
|
+
emphasis: {
|
|
1874
|
+
focus: "adjacency",
|
|
2074
1875
|
},
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
rotate: 20,
|
|
2080
|
-
verticalAlign: 'top',
|
|
1876
|
+
lineStyle: {
|
|
1877
|
+
color: "source",
|
|
1878
|
+
opacity: 0.25,
|
|
1879
|
+
curveness: 0.5,
|
|
2081
1880
|
},
|
|
2082
|
-
|
|
1881
|
+
label: {
|
|
2083
1882
|
show: true,
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
lineStyle: {
|
|
2091
|
-
type: 'dashed',
|
|
1883
|
+
position: "right",
|
|
1884
|
+
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif",
|
|
1885
|
+
fontSize: 10,
|
|
1886
|
+
formatter: (params) => {
|
|
1887
|
+
// Remover el sufijo de nivel de la etiqueta visual
|
|
1888
|
+
return params.name.split("___")[0];
|
|
2092
1889
|
},
|
|
2093
|
-
}
|
|
1890
|
+
},
|
|
1891
|
+
roam: true,
|
|
1892
|
+
data: nodes,
|
|
1893
|
+
links: Array.from(linksMap.values()),
|
|
2094
1894
|
};
|
|
2095
|
-
const
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
this.result.angleAxis = angleAxis;
|
|
1895
|
+
const serie = merge$1({}, dynamicSerieOptions, overrides);
|
|
1896
|
+
if (this.colorResolver && !serie.itemStyle) {
|
|
1897
|
+
serie.itemStyle = {};
|
|
1898
|
+
}
|
|
1899
|
+
if (this.colorResolver && serie.itemStyle) {
|
|
1900
|
+
serie.itemStyle.color = this.colorResolver;
|
|
1901
|
+
}
|
|
1902
|
+
this.result.series = serie;
|
|
2104
1903
|
}
|
|
2105
|
-
|
|
2106
|
-
|
|
1904
|
+
addTooltip(data, overrides) {
|
|
1905
|
+
merge$1(overrides, {
|
|
1906
|
+
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
1907
|
+
});
|
|
1908
|
+
const tooltip = getTooltipOptions(overrides);
|
|
1909
|
+
this.result.tooltip = tooltip;
|
|
2107
1910
|
}
|
|
2108
|
-
|
|
2109
|
-
|
|
1911
|
+
addPolar() { }
|
|
1912
|
+
addXAxis(data, overrides, type) { }
|
|
1913
|
+
addYAxis(data, overrides, type) { }
|
|
1914
|
+
addRadiusAxis(data, overrides) { }
|
|
1915
|
+
addAngleAxis(data, overrides) { }
|
|
1916
|
+
addLegend() { }
|
|
1917
|
+
addDataZoom() { }
|
|
2110
1918
|
addDataset(data, opts) { }
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
{
|
|
2117
|
-
type: 'slider',
|
|
2118
|
-
height: 20,
|
|
2119
|
-
bottom: 60
|
|
2120
|
-
}
|
|
2121
|
-
];
|
|
1919
|
+
addCommons() {
|
|
1920
|
+
const opts = {
|
|
1921
|
+
palette: this.palette,
|
|
1922
|
+
};
|
|
1923
|
+
merge$1(this.result, getCommons(opts));
|
|
2122
1924
|
}
|
|
1925
|
+
addGraphic() { }
|
|
2123
1926
|
getResult() {
|
|
2124
1927
|
return this.result;
|
|
2125
1928
|
}
|
|
2126
|
-
;
|
|
2127
|
-
/**
|
|
2128
|
-
* Formatea un valor utilizando el callback inyectado.
|
|
2129
|
-
*/
|
|
2130
|
-
formatCellValue(value, key) {
|
|
2131
|
-
return this.valueFormatter(value, key);
|
|
2132
|
-
}
|
|
2133
|
-
// Setters
|
|
2134
|
-
/**
|
|
2135
|
-
* Permite inyectar un formateador de valores externo.
|
|
2136
|
-
*/
|
|
2137
1929
|
setValueFormatter(formatter) {
|
|
2138
1930
|
if (formatter) {
|
|
2139
1931
|
this.valueFormatter = formatter;
|
|
2140
1932
|
}
|
|
2141
1933
|
}
|
|
2142
|
-
/**
|
|
2143
|
-
* Permite inyectar una paleta de colores básica.
|
|
2144
|
-
*/
|
|
2145
1934
|
setPalette(palette) {
|
|
2146
1935
|
if (palette) {
|
|
2147
1936
|
this.palette = palette;
|
|
2148
1937
|
}
|
|
2149
1938
|
}
|
|
2150
|
-
/**
|
|
2151
|
-
* Permite inyectar un resolver de colores dinámico.
|
|
2152
|
-
*/
|
|
2153
1939
|
setColorResolver(resolver) {
|
|
2154
1940
|
if (resolver) {
|
|
2155
1941
|
this.colorResolver = resolver;
|
|
2156
1942
|
}
|
|
2157
1943
|
}
|
|
2158
|
-
|
|
2159
|
-
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
/**
|
|
1947
|
+
* Director de Builds.
|
|
1948
|
+
*/
|
|
1949
|
+
class VSECDirector {
|
|
1950
|
+
builder = undefined;
|
|
1951
|
+
constructor(builder) {
|
|
1952
|
+
this.builder = builder;
|
|
2166
1953
|
}
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
1954
|
+
makeBar(data, overrides, opts = {}) {
|
|
1955
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
1956
|
+
return;
|
|
1957
|
+
}
|
|
1958
|
+
;
|
|
1959
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1960
|
+
x: 'category',
|
|
1961
|
+
y: 'value',
|
|
1962
|
+
// TODO agregar radius y angle axis
|
|
1963
|
+
} } = opts;
|
|
1964
|
+
this.builder.reset();
|
|
1965
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1966
|
+
// chart callbaks
|
|
1967
|
+
if (valueFormatter)
|
|
1968
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1969
|
+
if (palette)
|
|
1970
|
+
this.builder.setPalette(palette);
|
|
1971
|
+
if (colorResolver)
|
|
1972
|
+
this.builder.setColorResolver(colorResolver);
|
|
1973
|
+
const product = this.builder.baseProduct;
|
|
1974
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1975
|
+
// chart components
|
|
1976
|
+
this.builder.addCommons();
|
|
1977
|
+
const seriesOptions = { axisTypes };
|
|
1978
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
1979
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1980
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1981
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
1982
|
+
this.builder.addLegend();
|
|
1983
|
+
}
|
|
1984
|
+
makeBarRadial(data, overrides, opts = {}) {
|
|
1985
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
1986
|
+
return;
|
|
1987
|
+
}
|
|
1988
|
+
;
|
|
1989
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1990
|
+
x: 'category',
|
|
1991
|
+
y: 'value',
|
|
1992
|
+
// TODO agregar radius y angle axis
|
|
1993
|
+
} } = opts;
|
|
1994
|
+
this.builder.reset();
|
|
1995
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1996
|
+
// chart callbaks
|
|
1997
|
+
if (valueFormatter)
|
|
1998
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1999
|
+
if (palette)
|
|
2000
|
+
this.builder.setPalette(palette);
|
|
2001
|
+
if (colorResolver)
|
|
2002
|
+
this.builder.setColorResolver(colorResolver);
|
|
2003
|
+
const product = this.builder.baseProduct;
|
|
2004
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2005
|
+
// chart components
|
|
2006
|
+
this.builder.addCommons();
|
|
2007
|
+
const seriesOptions = { axisTypes, coordinateSystem: 'polar' };
|
|
2008
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
2009
|
+
this.builder.addPolar();
|
|
2010
|
+
this.builder.addAngleAxis(data, overrides['axis']);
|
|
2011
|
+
this.builder.addRadiusAxis(data, overrides['axis']);
|
|
2012
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2013
|
+
this.builder.addLegend();
|
|
2014
|
+
}
|
|
2015
|
+
makeLine(data, overrides, opts = {}) {
|
|
2016
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
2017
|
+
return;
|
|
2018
|
+
}
|
|
2019
|
+
;
|
|
2020
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
2021
|
+
x: 'category',
|
|
2022
|
+
y: 'value',
|
|
2023
|
+
// TODO agregar radius y angle axis
|
|
2024
|
+
} } = opts;
|
|
2025
|
+
this.builder.reset();
|
|
2026
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2027
|
+
// chart callbaks
|
|
2028
|
+
if (valueFormatter)
|
|
2029
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2030
|
+
if (palette)
|
|
2031
|
+
this.builder.setPalette(palette);
|
|
2032
|
+
if (colorResolver)
|
|
2033
|
+
this.builder.setColorResolver(colorResolver);
|
|
2034
|
+
const product = this.builder.baseProduct;
|
|
2035
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2036
|
+
// chart components
|
|
2037
|
+
this.builder.addCommons();
|
|
2038
|
+
const seriesOptions = { axisTypes };
|
|
2039
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
2040
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
2041
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
2042
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2043
|
+
this.builder.addLegend();
|
|
2044
|
+
}
|
|
2045
|
+
makeScatter(data, overrides, opts = {}) {
|
|
2046
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
2047
|
+
return;
|
|
2048
|
+
}
|
|
2049
|
+
;
|
|
2050
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
2051
|
+
x: 'category',
|
|
2052
|
+
y: 'value',
|
|
2053
|
+
} } = opts;
|
|
2054
|
+
this.builder.reset();
|
|
2055
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2056
|
+
// chart callbaks
|
|
2057
|
+
if (valueFormatter)
|
|
2058
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2059
|
+
if (palette)
|
|
2060
|
+
this.builder.setPalette(palette);
|
|
2061
|
+
if (colorResolver)
|
|
2062
|
+
this.builder.setColorResolver(colorResolver);
|
|
2063
|
+
const product = this.builder.baseProduct;
|
|
2064
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2065
|
+
// chart components
|
|
2066
|
+
this.builder.addCommons();
|
|
2067
|
+
const seriesOptions = { axisTypes };
|
|
2068
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
2069
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
2070
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
2071
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2072
|
+
this.builder.addLegend();
|
|
2073
|
+
}
|
|
2074
|
+
makeRing(data, overrides, opts = {}) {
|
|
2075
|
+
if (this.builder instanceof RingBuilder == false) {
|
|
2076
|
+
return;
|
|
2077
|
+
}
|
|
2078
|
+
;
|
|
2079
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2080
|
+
this.builder.reset();
|
|
2081
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2082
|
+
// chart callbaks
|
|
2083
|
+
if (valueFormatter)
|
|
2084
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2085
|
+
if (palette)
|
|
2086
|
+
this.builder.setPalette(palette);
|
|
2087
|
+
if (colorResolver)
|
|
2088
|
+
this.builder.setColorResolver(colorResolver);
|
|
2089
|
+
const product = this.builder.baseProduct;
|
|
2090
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2091
|
+
// chart components
|
|
2092
|
+
this.builder.addCommons();
|
|
2093
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2094
|
+
this.builder.addGraphic();
|
|
2095
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2096
|
+
this.builder.addLegend();
|
|
2097
|
+
}
|
|
2098
|
+
makePie(data, overrides, opts = {}) {
|
|
2099
|
+
if (this.builder instanceof PieBuilder == false) {
|
|
2100
|
+
return;
|
|
2101
|
+
}
|
|
2102
|
+
;
|
|
2103
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2104
|
+
this.builder.reset();
|
|
2105
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2106
|
+
// chart callbaks
|
|
2107
|
+
if (valueFormatter)
|
|
2108
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2109
|
+
if (palette)
|
|
2110
|
+
this.builder.setPalette(palette);
|
|
2111
|
+
if (colorResolver)
|
|
2112
|
+
this.builder.setColorResolver(colorResolver);
|
|
2113
|
+
const product = this.builder.baseProduct;
|
|
2114
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2115
|
+
// chart components
|
|
2116
|
+
this.builder.addCommons();
|
|
2117
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2118
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2119
|
+
this.builder.addLegend();
|
|
2120
|
+
}
|
|
2121
|
+
makeFunnel(data, overrides, opts = {}) {
|
|
2122
|
+
if (this.builder instanceof FunnelBuilder == false) {
|
|
2123
|
+
return;
|
|
2124
|
+
}
|
|
2125
|
+
;
|
|
2126
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2127
|
+
this.builder.reset();
|
|
2128
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2129
|
+
// chart callbaks
|
|
2130
|
+
if (valueFormatter)
|
|
2131
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2132
|
+
if (palette)
|
|
2133
|
+
this.builder.setPalette(palette);
|
|
2134
|
+
if (colorResolver)
|
|
2135
|
+
this.builder.setColorResolver(colorResolver);
|
|
2136
|
+
const product = this.builder.baseProduct;
|
|
2137
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2138
|
+
// chart components
|
|
2139
|
+
this.builder.addCommons();
|
|
2140
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2141
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2142
|
+
this.builder.addLegend();
|
|
2143
|
+
}
|
|
2144
|
+
makeSunburst(data, overrides, opts = {}) {
|
|
2145
|
+
if (this.builder instanceof SunburstBuilder == false) {
|
|
2146
|
+
return;
|
|
2147
|
+
}
|
|
2148
|
+
;
|
|
2149
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2150
|
+
this.builder.reset();
|
|
2151
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2152
|
+
// chart callbaks
|
|
2153
|
+
if (valueFormatter)
|
|
2154
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2155
|
+
if (palette)
|
|
2156
|
+
this.builder.setPalette(palette);
|
|
2157
|
+
if (colorResolver)
|
|
2158
|
+
this.builder.setColorResolver(colorResolver);
|
|
2159
|
+
const product = this.builder.baseProduct;
|
|
2160
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2161
|
+
// chart components
|
|
2162
|
+
this.builder.addCommons();
|
|
2163
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2164
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2165
|
+
}
|
|
2166
|
+
makeSankey(data, overrides, opts = {}) {
|
|
2167
|
+
if (this.builder instanceof SankeyBuilder == false) {
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2170
|
+
;
|
|
2171
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2172
|
+
this.builder.reset();
|
|
2173
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2174
|
+
// chart callbaks
|
|
2175
|
+
if (valueFormatter)
|
|
2176
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2177
|
+
if (palette)
|
|
2178
|
+
this.builder.setPalette(palette);
|
|
2179
|
+
if (colorResolver)
|
|
2180
|
+
this.builder.setColorResolver(colorResolver);
|
|
2181
|
+
const product = this.builder.baseProduct;
|
|
2182
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2183
|
+
// chart components
|
|
2184
|
+
this.builder.addCommons();
|
|
2185
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2186
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2187
|
+
}
|
|
2188
|
+
makeBoxplot(data, overrides, opts = {}) {
|
|
2189
|
+
if (this.builder instanceof BoxPlotBuilder == false) {
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
2193
|
+
x: 'value',
|
|
2194
|
+
y: 'category',
|
|
2195
|
+
}, } = opts;
|
|
2196
|
+
this.builder.reset();
|
|
2197
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2198
|
+
// chart callbaks
|
|
2199
|
+
if (valueFormatter)
|
|
2200
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2201
|
+
if (palette)
|
|
2202
|
+
this.builder.setPalette(palette);
|
|
2203
|
+
if (colorResolver)
|
|
2204
|
+
this.builder.setColorResolver(colorResolver);
|
|
2205
|
+
const product = this.builder.baseProduct;
|
|
2206
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2207
|
+
// chart components
|
|
2208
|
+
this.builder.addCommons();
|
|
2209
|
+
const configOpts = { axisTypes };
|
|
2210
|
+
this.builder.addDataset(data);
|
|
2211
|
+
this.builder.addSeries(data, seriesOverrides, configOpts);
|
|
2212
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
2213
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
2214
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2215
|
+
this.builder.addDataZoom();
|
|
2216
|
+
}
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
/**
|
|
2220
|
+
* EchartsRingComponent
|
|
2221
|
+
*
|
|
2222
|
+
* Especialista en visualización de tipo Ring. Soporta multi-medidas y KPI central.
|
|
2223
|
+
* @see {@link vs-echarts/docs/charts/ring-patterns.md}
|
|
2224
|
+
*/
|
|
2225
|
+
class EchartsRingComponent extends BaseEchartsComponent {
|
|
2226
|
+
baseSeriesOptions = {
|
|
2227
|
+
type: 'pie',
|
|
2228
|
+
center: ['50%', '50%'],
|
|
2229
|
+
avoidLabelOverlap: true,
|
|
2230
|
+
minAngle: 3,
|
|
2231
|
+
selectedMode: 'single',
|
|
2232
|
+
selectedOffset: 4,
|
|
2233
|
+
itemStyle: {
|
|
2234
|
+
borderColor: '#fff',
|
|
2235
|
+
},
|
|
2236
|
+
label: { show: false },
|
|
2237
|
+
emphasis: {
|
|
2238
|
+
scale: true,
|
|
2239
|
+
scaleSize: 2,
|
|
2240
|
+
},
|
|
2241
|
+
select: {
|
|
2242
|
+
itemStyle: {
|
|
2243
|
+
borderColor: EChartsTokens.sBorderColor,
|
|
2244
|
+
shadowColor: EChartsTokens.sShadowColor,
|
|
2245
|
+
borderWidth: 1,
|
|
2246
|
+
shadowBlur: 4,
|
|
2247
|
+
},
|
|
2248
|
+
},
|
|
2249
|
+
animationType: 'scale',
|
|
2250
|
+
animationEasing: 'elasticOut',
|
|
2251
|
+
};
|
|
2252
|
+
baseProduct = {
|
|
2253
|
+
chartKey: 'ring',
|
|
2254
|
+
baseOptions: {
|
|
2255
|
+
series: this.baseSeriesOptions,
|
|
2256
|
+
}
|
|
2257
|
+
};
|
|
2258
|
+
builder = new RingBuilder(this.baseProduct);
|
|
2259
|
+
director = new VSECDirector(this.builder);
|
|
2260
|
+
lastSelectedSeriesIndex = null;
|
|
2261
|
+
lastSelectedDataIndex = null;
|
|
2262
|
+
selectedPercent = null;
|
|
2263
|
+
currentGraphicText = '';
|
|
2264
|
+
constructor() {
|
|
2265
|
+
super();
|
|
2266
|
+
}
|
|
2267
|
+
make() {
|
|
2268
|
+
const makeOpts = {
|
|
2269
|
+
valueFormatter: this.valueFormatter,
|
|
2270
|
+
palette: this.palette,
|
|
2271
|
+
colorResolver: this.colorResolver,
|
|
2272
|
+
};
|
|
2273
|
+
this.director.makeRing(this.data, this.optionsOverrides, makeOpts);
|
|
2274
|
+
}
|
|
2275
|
+
onInputChanges(changes) {
|
|
2276
|
+
// Reset selection only if data changed
|
|
2277
|
+
if (changes['data']) {
|
|
2278
|
+
this.lastSelectedSeriesIndex = null;
|
|
2279
|
+
this.lastSelectedDataIndex = null;
|
|
2280
|
+
this.selectedPercent = null;
|
|
2281
|
+
this.currentGraphicText = '';
|
|
2282
|
+
}
|
|
2283
|
+
super.onInputChanges(changes);
|
|
2284
|
+
}
|
|
2285
|
+
/**
|
|
2286
|
+
* Maneja clics en los sectores del ring.
|
|
2287
|
+
* Soporta múltiples series (anillos) y actualiza el KPI central.
|
|
2288
|
+
*/
|
|
2289
|
+
onChartClick(event) {
|
|
2290
|
+
if (this.chartInstance && event && event.dataIndex !== undefined) {
|
|
2291
|
+
const isSameSelection = event.seriesIndex === this.lastSelectedSeriesIndex &&
|
|
2292
|
+
event.dataIndex === this.lastSelectedDataIndex;
|
|
2293
|
+
if (isSameSelection) {
|
|
2294
|
+
// Toggle OFF
|
|
2295
|
+
this.lastSelectedSeriesIndex = null;
|
|
2296
|
+
this.lastSelectedDataIndex = null;
|
|
2297
|
+
this.selectedPercent = null;
|
|
2298
|
+
this.setGraphicText('');
|
|
2299
|
+
}
|
|
2300
|
+
else {
|
|
2301
|
+
// SELECT
|
|
2302
|
+
this.lastSelectedSeriesIndex = event.seriesIndex;
|
|
2303
|
+
this.lastSelectedDataIndex = event.dataIndex;
|
|
2304
|
+
this.selectedPercent = (event.percent !== undefined) ? event.percent + '%' : '';
|
|
2305
|
+
this.setGraphicText(this.selectedPercent);
|
|
2306
|
+
}
|
|
2307
|
+
this.chartClick.emit({
|
|
2308
|
+
type: 'cross-filter',
|
|
2309
|
+
data: {
|
|
2310
|
+
category: event.name,
|
|
2311
|
+
serie: event.seriesName,
|
|
2312
|
+
value: event.value
|
|
2313
|
+
}
|
|
2314
|
+
});
|
|
2315
|
+
}
|
|
2316
|
+
}
|
|
2317
|
+
onChartMouseOver(event) {
|
|
2318
|
+
if (this.selectedPercent === null && event && event.percent !== undefined) {
|
|
2319
|
+
this.setGraphicText(event.percent + '%');
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2322
|
+
onChartMouseOut(event) {
|
|
2323
|
+
if (this.selectedPercent === null) {
|
|
2324
|
+
this.setGraphicText('');
|
|
2325
|
+
}
|
|
2326
|
+
}
|
|
2327
|
+
/**
|
|
2328
|
+
* Actualiza el texto del Graphic central y persiste la selección en el modelo de opciones.
|
|
2329
|
+
*/
|
|
2330
|
+
setGraphicText(text) {
|
|
2331
|
+
this.currentGraphicText = text;
|
|
2332
|
+
// Persistencia de GRAPHIC (KPI central)
|
|
2333
|
+
this.chartInstance?.setOption({
|
|
2334
|
+
graphic: {
|
|
2335
|
+
style: {
|
|
2336
|
+
text: this.currentGraphicText,
|
|
2337
|
+
opacity: this.currentGraphicText ? 1 : 0,
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
});
|
|
2341
|
+
}
|
|
2342
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2343
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsRingComponent, isStandalone: true, selector: "vs-echarts-ring", usesInheritance: true, ngImport: i0, template: "<div class=\"echarts-container\" \n echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n ", styles: [".echarts-container{width:100%;height:100%;position:relative}\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"] }] });
|
|
2344
|
+
}
|
|
2345
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, decorators: [{
|
|
2346
|
+
type: Component,
|
|
2347
|
+
args: [{ selector: 'vs-echarts-ring', standalone: true, imports: [
|
|
2348
|
+
CommonModule,
|
|
2349
|
+
NgxEchartsDirective,
|
|
2350
|
+
], template: "<div class=\"echarts-container\" \n echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartMouseOver)=\"onChartMouseOver($event)\" \n (chartMouseOut)=\"onChartMouseOut($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n ", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
2351
|
+
}], ctorParameters: () => [] });
|
|
2352
|
+
|
|
2353
|
+
/**
|
|
2354
|
+
* EchartsPieComponent
|
|
2355
|
+
*
|
|
2356
|
+
* Especialista en visualización de tipo Pie (Torta y Anillos concéntricos).
|
|
2357
|
+
* La primera serie se dibuja como un gráfico de torta tradicional (lleno) y
|
|
2358
|
+
* las subsecuentes como anillos concéntricos alrededor.
|
|
2359
|
+
*/
|
|
2360
|
+
class EchartsPieComponent extends BaseEchartsComponent {
|
|
2361
|
+
baseSeriesOptions = {
|
|
2362
|
+
type: 'pie',
|
|
2363
|
+
center: ['50%', '50%'],
|
|
2364
|
+
avoidLabelOverlap: true,
|
|
2365
|
+
minAngle: 3,
|
|
2366
|
+
selectedMode: 'single',
|
|
2367
|
+
selectedOffset: 4,
|
|
2368
|
+
emphasis: {
|
|
2369
|
+
scale: true,
|
|
2370
|
+
scaleSize: 2,
|
|
2371
|
+
},
|
|
2372
|
+
select: {
|
|
2373
|
+
itemStyle: {
|
|
2374
|
+
borderColor: EChartsTokens.sBorderColor,
|
|
2375
|
+
shadowColor: EChartsTokens.sShadowColor,
|
|
2376
|
+
borderWidth: 1,
|
|
2377
|
+
shadowBlur: 4,
|
|
2378
|
+
},
|
|
2379
|
+
},
|
|
2380
|
+
animationType: 'scale',
|
|
2381
|
+
animationEasing: 'elasticOut',
|
|
2382
|
+
};
|
|
2383
|
+
baseProduct = {
|
|
2384
|
+
chartKey: 'pie',
|
|
2385
|
+
baseOptions: {
|
|
2386
|
+
series: this.baseSeriesOptions,
|
|
2387
|
+
}
|
|
2388
|
+
};
|
|
2389
|
+
builder = new PieBuilder(this.baseProduct);
|
|
2390
|
+
director = new VSECDirector(this.builder);
|
|
2391
|
+
constructor() {
|
|
2392
|
+
super();
|
|
2393
|
+
}
|
|
2394
|
+
make() {
|
|
2395
|
+
const makeOpts = {
|
|
2396
|
+
valueFormatter: this.valueFormatter,
|
|
2397
|
+
palette: this.palette,
|
|
2398
|
+
colorResolver: this.colorResolver,
|
|
2399
|
+
};
|
|
2400
|
+
this.director.makePie(this.data, this.optionsOverrides, makeOpts);
|
|
2401
|
+
}
|
|
2402
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2403
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsPieComponent, isStandalone: true, selector: "vs-echarts-pie", usesInheritance: true, ngImport: i0, template: "<div\n class=\"echarts-container\"\n echarts\n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\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"] }] });
|
|
2404
|
+
}
|
|
2405
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, decorators: [{
|
|
2406
|
+
type: Component,
|
|
2407
|
+
args: [{ selector: 'vs-echarts-pie', standalone: true, imports: [
|
|
2408
|
+
CommonModule,
|
|
2409
|
+
NgxEchartsDirective,
|
|
2410
|
+
], template: "<div\n class=\"echarts-container\"\n echarts\n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\"\n (chartClick)=\"onChartClick($event)\"\n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
2411
|
+
}], ctorParameters: () => [] });
|
|
2412
|
+
|
|
2413
|
+
/**
|
|
2414
|
+
* EchartsFunnelComponent
|
|
2415
|
+
*
|
|
2416
|
+
* Component for Funnel visualization. Supports single and multiple measures.
|
|
2417
|
+
*/
|
|
2418
|
+
class EchartsFunnelComponent extends BaseEchartsComponent {
|
|
2419
|
+
baseSeriesOptions = {
|
|
2420
|
+
type: 'funnel',
|
|
2421
|
+
left: '10%',
|
|
2422
|
+
width: '80%',
|
|
2423
|
+
minSize: '0.01%',
|
|
2424
|
+
maxSize: '100%',
|
|
2425
|
+
sort: 'descending',
|
|
2426
|
+
gap: 2,
|
|
2427
|
+
label: {
|
|
2428
|
+
show: true,
|
|
2429
|
+
position: 'inside'
|
|
2430
|
+
},
|
|
2431
|
+
labelLine: {
|
|
2432
|
+
show: false
|
|
2433
|
+
},
|
|
2434
|
+
itemStyle: {
|
|
2435
|
+
borderColor: '#fff',
|
|
2436
|
+
borderWidth: 1
|
|
2437
|
+
},
|
|
2438
|
+
emphasis: {
|
|
2439
|
+
label: {
|
|
2440
|
+
fontSize: 16
|
|
2441
|
+
}
|
|
2442
|
+
},
|
|
2443
|
+
selectedMode: 'single',
|
|
2444
|
+
select: {
|
|
2445
|
+
label: {
|
|
2446
|
+
fontSize: 16
|
|
2447
|
+
},
|
|
2448
|
+
itemStyle: {
|
|
2449
|
+
borderWidth: 1,
|
|
2450
|
+
borderColor: EChartsTokens.sBorderColor,
|
|
2451
|
+
shadowColor: EChartsTokens.sShadowColor,
|
|
2452
|
+
shadowBlur: 6,
|
|
2453
|
+
}
|
|
2454
|
+
},
|
|
2455
|
+
};
|
|
2456
|
+
baseProduct = {
|
|
2457
|
+
chartKey: 'funnel',
|
|
2458
|
+
baseOptions: {
|
|
2459
|
+
series: this.baseSeriesOptions,
|
|
2460
|
+
}
|
|
2461
|
+
};
|
|
2462
|
+
builder = new FunnelBuilder(this.baseProduct);
|
|
2463
|
+
director = new VSECDirector(this.builder);
|
|
2464
|
+
constructor() {
|
|
2465
|
+
super();
|
|
2466
|
+
}
|
|
2467
|
+
make() {
|
|
2468
|
+
const makeOpts = {
|
|
2469
|
+
valueFormatter: this.valueFormatter,
|
|
2470
|
+
palette: this.palette,
|
|
2471
|
+
colorResolver: this.colorResolver,
|
|
2472
|
+
};
|
|
2473
|
+
this.director.makeFunnel(this.data, this.optionsOverrides, makeOpts);
|
|
2170
2474
|
}
|
|
2475
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2476
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsFunnelComponent, isStandalone: true, selector: "vs-echarts-funnel", usesInheritance: true, ngImport: i0, template: "<div class=\"echarts-container\" echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\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"] }] });
|
|
2171
2477
|
}
|
|
2478
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, decorators: [{
|
|
2479
|
+
type: Component,
|
|
2480
|
+
args: [{ selector: 'vs-echarts-funnel', standalone: true, imports: [
|
|
2481
|
+
CommonModule,
|
|
2482
|
+
NgxEchartsDirective,
|
|
2483
|
+
], template: "<div class=\"echarts-container\" echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event, { fixPieDataIndexInside: true })\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
2484
|
+
}], ctorParameters: () => [] });
|
|
2172
2485
|
|
|
2173
2486
|
class EchartsBarComponent extends BaseEchartsComponent {
|
|
2174
2487
|
/**
|
|
@@ -2570,100 +2883,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2570
2883
|
], template: "<div class=\"echarts-container\" echarts \n [options]=\"{}\"\n [initOpts]=\"initOptions\" \n [autoResize]=\"true\" \n (chartInit)=\"onChartInit($event)\" \n (chartClick)=\"onChartClick($event)\" \n (chartSelectChanged)=\"onChartSelectChanged($event)\"\n></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
2571
2884
|
}], ctorParameters: () => [] });
|
|
2572
2885
|
|
|
2573
|
-
class SunburstBuilder {
|
|
2574
|
-
baseProduct;
|
|
2575
|
-
valueFormatter = (value) => value.toLocaleString();
|
|
2576
|
-
palette = [];
|
|
2577
|
-
// TODO: Hay que implementar un valor por defecto.
|
|
2578
|
-
colorResolver;
|
|
2579
|
-
result = {};
|
|
2580
|
-
constructor(baseProduct) {
|
|
2581
|
-
this.baseProduct = baseProduct;
|
|
2582
|
-
}
|
|
2583
|
-
reset() {
|
|
2584
|
-
this.result = {};
|
|
2585
|
-
}
|
|
2586
|
-
addSeries(data, overrides) {
|
|
2587
|
-
if (!data || !data.source || data.source.length === 0) {
|
|
2588
|
-
return;
|
|
2589
|
-
}
|
|
2590
|
-
const sunburstData = mapHierarchicalData(data.source, data.dimensions);
|
|
2591
|
-
const depth = getTreeDepth(sunburstData);
|
|
2592
|
-
const levels = [];
|
|
2593
|
-
for (let i = 0; i <= depth; i++) {
|
|
2594
|
-
levels.push({
|
|
2595
|
-
label: {
|
|
2596
|
-
show: false,
|
|
2597
|
-
},
|
|
2598
|
-
});
|
|
2599
|
-
}
|
|
2600
|
-
const dynamiSerieOptions = {
|
|
2601
|
-
name: '',
|
|
2602
|
-
data: sunburstData,
|
|
2603
|
-
levels: levels
|
|
2604
|
-
};
|
|
2605
|
-
const serie = merge$1({}, dynamiSerieOptions, overrides);
|
|
2606
|
-
if (this.colorResolver) {
|
|
2607
|
-
if (!serie.itemStyle) {
|
|
2608
|
-
serie.itemStyle = {};
|
|
2609
|
-
}
|
|
2610
|
-
serie.itemStyle.color = this.colorResolver;
|
|
2611
|
-
}
|
|
2612
|
-
this.result.series = serie;
|
|
2613
|
-
}
|
|
2614
|
-
addTooltip(data, overrides) {
|
|
2615
|
-
merge$1(overrides, {
|
|
2616
|
-
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
2617
|
-
});
|
|
2618
|
-
const tooltip = getTooltipOptions(overrides);
|
|
2619
|
-
this.result.tooltip = tooltip;
|
|
2620
|
-
}
|
|
2621
|
-
addCommons() {
|
|
2622
|
-
const opts = {
|
|
2623
|
-
palette: this.palette,
|
|
2624
|
-
};
|
|
2625
|
-
merge$1(this.result, getCommons(opts));
|
|
2626
|
-
}
|
|
2627
|
-
addGraphic() { }
|
|
2628
|
-
getResult() {
|
|
2629
|
-
return this.result;
|
|
2630
|
-
}
|
|
2631
|
-
;
|
|
2632
|
-
addPolar() { }
|
|
2633
|
-
addXAxis(data, overrides, type) { }
|
|
2634
|
-
addYAxis(data, overrides, type) { }
|
|
2635
|
-
addRadiusAxis(data, overrides) { }
|
|
2636
|
-
addAngleAxis(data, overrides) { }
|
|
2637
|
-
addLegend() { }
|
|
2638
|
-
addDataZoom() { }
|
|
2639
|
-
addDataset(data, opts) { }
|
|
2640
|
-
// Setters
|
|
2641
|
-
/**
|
|
2642
|
-
* Permite inyectar un formateador de valores externo.
|
|
2643
|
-
*/
|
|
2644
|
-
setValueFormatter(formatter) {
|
|
2645
|
-
if (formatter) {
|
|
2646
|
-
this.valueFormatter = formatter;
|
|
2647
|
-
}
|
|
2648
|
-
}
|
|
2649
|
-
/**
|
|
2650
|
-
* Permite inyectar una paleta de colores básica.
|
|
2651
|
-
*/
|
|
2652
|
-
setPalette(palette) {
|
|
2653
|
-
if (palette) {
|
|
2654
|
-
this.palette = palette;
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
/**
|
|
2658
|
-
* Permite inyectar un resolver de colores dinámico.
|
|
2659
|
-
*/
|
|
2660
|
-
setColorResolver(resolver) {
|
|
2661
|
-
if (resolver) {
|
|
2662
|
-
this.colorResolver = resolver;
|
|
2663
|
-
}
|
|
2664
|
-
}
|
|
2665
|
-
}
|
|
2666
|
-
|
|
2667
2886
|
class EChartsSunburstComponent extends BaseEchartsComponent {
|
|
2668
2887
|
baseSeriesOptions = {
|
|
2669
2888
|
type: 'sunburst',
|
|
@@ -2712,158 +2931,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2712
2931
|
], template: "<div\n class=\"echarts-container\"\n echarts\n [options]=\"{}\"\n [initOpts]=\"initOptions\"\n [autoResize]=\"true\"\n (chartInit)=\"onChartInit($event)\"\n></div>", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
2713
2932
|
}] });
|
|
2714
2933
|
|
|
2715
|
-
/**
|
|
2716
|
-
* SankeyBuilder
|
|
2717
|
-
*
|
|
2718
|
-
* Builder concreto para el gráfico Sankey (diagrama de flujos de izquierda a derecha).
|
|
2719
|
-
*/
|
|
2720
|
-
class SankeyBuilder {
|
|
2721
|
-
baseProduct;
|
|
2722
|
-
valueFormatter = (value) => value.toLocaleString();
|
|
2723
|
-
palette = [];
|
|
2724
|
-
colorResolver;
|
|
2725
|
-
result = {};
|
|
2726
|
-
constructor(baseProduct) {
|
|
2727
|
-
this.baseProduct = baseProduct;
|
|
2728
|
-
}
|
|
2729
|
-
reset() {
|
|
2730
|
-
this.result = {};
|
|
2731
|
-
}
|
|
2732
|
-
addSeries(data, overrides) {
|
|
2733
|
-
if (!data || !data.source || data.source.length === 0) {
|
|
2734
|
-
return;
|
|
2735
|
-
}
|
|
2736
|
-
// Identificar medidas (todas las dimensiones excepto 'category')
|
|
2737
|
-
const measureKeys = data.dimensions
|
|
2738
|
-
.filter((d) => d.name !== "category")
|
|
2739
|
-
.map((d) => d.name);
|
|
2740
|
-
// Función auxiliar para sumarizar valores de medidas en caso de haber más de una
|
|
2741
|
-
const getNodeValue = (node) => {
|
|
2742
|
-
return measureKeys.reduce((sum, key) => sum + (Number(node[key]) || 0), 0);
|
|
2743
|
-
};
|
|
2744
|
-
const nodesMap = new Map();
|
|
2745
|
-
const linksMap = new Map();
|
|
2746
|
-
// Función recursiva para aplanar datos jerárquicos a nodos y enlaces
|
|
2747
|
-
const traverse = (nodeList, level, parentId) => {
|
|
2748
|
-
for (const node of nodeList) {
|
|
2749
|
-
const category = node.category;
|
|
2750
|
-
const currentId = `${category}___${level}`;
|
|
2751
|
-
const value = getNodeValue(node);
|
|
2752
|
-
nodesMap.set(currentId, (nodesMap.get(currentId) || 0) + value);
|
|
2753
|
-
if (parentId) {
|
|
2754
|
-
const linkKey = `${parentId}--->${currentId}`;
|
|
2755
|
-
if (linksMap.has(linkKey)) {
|
|
2756
|
-
linksMap.get(linkKey).value += value;
|
|
2757
|
-
}
|
|
2758
|
-
else {
|
|
2759
|
-
linksMap.set(linkKey, {
|
|
2760
|
-
source: parentId,
|
|
2761
|
-
target: currentId,
|
|
2762
|
-
value: value,
|
|
2763
|
-
});
|
|
2764
|
-
}
|
|
2765
|
-
}
|
|
2766
|
-
if (node.children && node.children.length > 0) {
|
|
2767
|
-
traverse(node.children, level + 1, currentId);
|
|
2768
|
-
}
|
|
2769
|
-
}
|
|
2770
|
-
};
|
|
2771
|
-
// Comenzar el recorrido en el nivel 0
|
|
2772
|
-
traverse(data.source, 0);
|
|
2773
|
-
// al menos un nivel de links para dibujar.
|
|
2774
|
-
if (linksMap.size === 0)
|
|
2775
|
-
return;
|
|
2776
|
-
// Mapear nodos acumulados a la estructura requerida por ECharts (name y opcionalmente color, sin value redundante)
|
|
2777
|
-
const nodes = Array.from(nodesMap.keys()).map((currentId) => {
|
|
2778
|
-
const category = currentId.split("___")[0];
|
|
2779
|
-
const nodeItem = {
|
|
2780
|
-
name: currentId,
|
|
2781
|
-
};
|
|
2782
|
-
if (this.colorResolver) {
|
|
2783
|
-
const color = this.colorResolver({ name: category, data: nodeItem });
|
|
2784
|
-
if (color) {
|
|
2785
|
-
nodeItem.itemStyle = { color };
|
|
2786
|
-
}
|
|
2787
|
-
}
|
|
2788
|
-
return nodeItem;
|
|
2789
|
-
});
|
|
2790
|
-
const dynamicSerieOptions = {
|
|
2791
|
-
type: "sankey",
|
|
2792
|
-
orient: "horizontal", // De izquierda a derecha
|
|
2793
|
-
draggable: true,
|
|
2794
|
-
emphasis: {
|
|
2795
|
-
focus: "adjacency",
|
|
2796
|
-
},
|
|
2797
|
-
lineStyle: {
|
|
2798
|
-
color: "source",
|
|
2799
|
-
opacity: 0.25,
|
|
2800
|
-
curveness: 0.5,
|
|
2801
|
-
},
|
|
2802
|
-
label: {
|
|
2803
|
-
show: true,
|
|
2804
|
-
position: "right",
|
|
2805
|
-
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif",
|
|
2806
|
-
fontSize: 10,
|
|
2807
|
-
formatter: (params) => {
|
|
2808
|
-
// Remover el sufijo de nivel de la etiqueta visual
|
|
2809
|
-
return params.name.split("___")[0];
|
|
2810
|
-
},
|
|
2811
|
-
},
|
|
2812
|
-
roam: true,
|
|
2813
|
-
data: nodes,
|
|
2814
|
-
links: Array.from(linksMap.values()),
|
|
2815
|
-
};
|
|
2816
|
-
const serie = merge$1({}, dynamicSerieOptions, overrides);
|
|
2817
|
-
if (this.colorResolver && !serie.itemStyle) {
|
|
2818
|
-
serie.itemStyle = {};
|
|
2819
|
-
}
|
|
2820
|
-
if (this.colorResolver && serie.itemStyle) {
|
|
2821
|
-
serie.itemStyle.color = this.colorResolver;
|
|
2822
|
-
}
|
|
2823
|
-
this.result.series = serie;
|
|
2824
|
-
}
|
|
2825
|
-
addTooltip(data, overrides) {
|
|
2826
|
-
merge$1(overrides, {
|
|
2827
|
-
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
2828
|
-
});
|
|
2829
|
-
const tooltip = getTooltipOptions(overrides);
|
|
2830
|
-
this.result.tooltip = tooltip;
|
|
2831
|
-
}
|
|
2832
|
-
addPolar() { }
|
|
2833
|
-
addXAxis(data, overrides, type) { }
|
|
2834
|
-
addYAxis(data, overrides, type) { }
|
|
2835
|
-
addRadiusAxis(data, overrides) { }
|
|
2836
|
-
addAngleAxis(data, overrides) { }
|
|
2837
|
-
addLegend() { }
|
|
2838
|
-
addDataZoom() { }
|
|
2839
|
-
addDataset(data, opts) { }
|
|
2840
|
-
addCommons() {
|
|
2841
|
-
const opts = {
|
|
2842
|
-
palette: this.palette,
|
|
2843
|
-
};
|
|
2844
|
-
merge$1(this.result, getCommons(opts));
|
|
2845
|
-
}
|
|
2846
|
-
addGraphic() { }
|
|
2847
|
-
getResult() {
|
|
2848
|
-
return this.result;
|
|
2849
|
-
}
|
|
2850
|
-
setValueFormatter(formatter) {
|
|
2851
|
-
if (formatter) {
|
|
2852
|
-
this.valueFormatter = formatter;
|
|
2853
|
-
}
|
|
2854
|
-
}
|
|
2855
|
-
setPalette(palette) {
|
|
2856
|
-
if (palette) {
|
|
2857
|
-
this.palette = palette;
|
|
2858
|
-
}
|
|
2859
|
-
}
|
|
2860
|
-
setColorResolver(resolver) {
|
|
2861
|
-
if (resolver) {
|
|
2862
|
-
this.colorResolver = resolver;
|
|
2863
|
-
}
|
|
2864
|
-
}
|
|
2865
|
-
}
|
|
2866
|
-
|
|
2867
2934
|
class EchartsSankeyComponent extends BaseEchartsComponent {
|
|
2868
2935
|
baseSeriesOptions = {
|
|
2869
2936
|
type: 'sankey',
|