@visionaris-bruno/vs-echarts 8.4.0 → 8.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -188,11 +188,11 @@ class BaseEchartsComponent {
|
|
|
188
188
|
data = { dimensions: [], source: [] };
|
|
189
189
|
optionsOverrides = defaultOptionsOverrides();
|
|
190
190
|
/** Paleta de colores básica */
|
|
191
|
-
palette;
|
|
191
|
+
palette = getDefaultPalette();
|
|
192
192
|
/** Resolver de colores dinámico (Callback) */
|
|
193
193
|
colorResolver;
|
|
194
194
|
/** Formateador de valores para etiquetas y tooltips */
|
|
195
|
-
valueFormatter;
|
|
195
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
196
196
|
chartClick = new EventEmitter();
|
|
197
197
|
/** Subject para debouncing de actualizaciones. ReplaySubject asegura no perder el primer renderizado. */
|
|
198
198
|
updateSubject = new ReplaySubject(1);
|
|
@@ -1030,11 +1030,10 @@ class BoxPlotBuilder {
|
|
|
1030
1030
|
this.result.series = [serie];
|
|
1031
1031
|
}
|
|
1032
1032
|
addTooltip(data, overrides) {
|
|
1033
|
-
const trigger = overrides.trigger;
|
|
1034
1033
|
const mainMeassureKey = data.dimensions.filter(d => d.name != 'category')[0].name;
|
|
1035
1034
|
const valueFormatter = this.valueFormatter;
|
|
1036
1035
|
function tooltipFormatter(params) {
|
|
1037
|
-
const tooltipEventData = params[0];
|
|
1036
|
+
const tooltipEventData = Array.isArray(params) ? params[0] : params;
|
|
1038
1037
|
const title = `<b>${tooltipEventData.name}</b></br>`;
|
|
1039
1038
|
let htmlbody = ``;
|
|
1040
1039
|
for (const datakey in tooltipEventData.data) {
|
|
@@ -1129,344 +1128,236 @@ class BoxPlotBuilder {
|
|
|
1129
1128
|
}
|
|
1130
1129
|
|
|
1131
1130
|
/**
|
|
1132
|
-
*
|
|
1131
|
+
* Builder principal.
|
|
1132
|
+
*
|
|
1133
|
+
* Es muy completo, tiene soporte para ejes y sistema cartesiano polar.
|
|
1134
|
+
*
|
|
1135
|
+
* Puede verse utilizado en graficos como Lineas y Bars. Siempre que se pueda priorizar utilizar este.
|
|
1133
1136
|
*/
|
|
1134
|
-
class
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
// TODO agregar radius y angle axis
|
|
1144
|
-
} } = opts;
|
|
1145
|
-
this.builder.reset();
|
|
1146
|
-
// El orden importa, primero callbaks y despues componentes.
|
|
1147
|
-
//chart callbacks
|
|
1148
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1149
|
-
this.builder.setPalette(palette);
|
|
1150
|
-
this.builder.setColorResolver(colorResolver);
|
|
1151
|
-
const product = this.builder.baseProduct;
|
|
1152
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1153
|
-
// chart components
|
|
1154
|
-
this.builder.addCommons();
|
|
1155
|
-
const layoutOpts = { axisTypes };
|
|
1156
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1157
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1158
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1159
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1160
|
-
this.builder.addLegend();
|
|
1161
|
-
}
|
|
1162
|
-
makeBarRadial(data, overrides, opts = {}) {
|
|
1163
|
-
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1164
|
-
x: 'category',
|
|
1165
|
-
y: 'value',
|
|
1166
|
-
// TODO agregar radius y angle axis
|
|
1167
|
-
} } = opts;
|
|
1168
|
-
this.builder.reset();
|
|
1169
|
-
// El orden importa, primero callbaks y despues componentes.
|
|
1170
|
-
//chart callbacks
|
|
1171
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1172
|
-
this.builder.setPalette(palette);
|
|
1173
|
-
this.builder.setColorResolver(colorResolver);
|
|
1174
|
-
const product = this.builder.baseProduct;
|
|
1175
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1176
|
-
// chart components
|
|
1177
|
-
this.builder.addCommons();
|
|
1178
|
-
const layoutOpts = { axisTypes, coordinateSystem: 'polar' };
|
|
1179
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1180
|
-
this.builder.addPolar();
|
|
1181
|
-
this.builder.addAngleAxis(data, overrides['axis']);
|
|
1182
|
-
this.builder.addRadiusAxis(data, overrides['axis']);
|
|
1183
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1184
|
-
this.builder.addLegend();
|
|
1185
|
-
}
|
|
1186
|
-
makeLine(data, overrides, opts = {}) {
|
|
1187
|
-
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1188
|
-
x: 'category',
|
|
1189
|
-
y: 'value',
|
|
1190
|
-
// TODO agregar radius y angle axis
|
|
1191
|
-
} } = opts;
|
|
1192
|
-
this.builder.reset();
|
|
1193
|
-
// El orden importa, primero callbaks y despues componentes.
|
|
1194
|
-
//chart callbacks
|
|
1195
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1196
|
-
this.builder.setPalette(palette);
|
|
1197
|
-
this.builder.setColorResolver(colorResolver);
|
|
1198
|
-
const product = this.builder.baseProduct;
|
|
1199
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1200
|
-
// chart components
|
|
1201
|
-
this.builder.addCommons();
|
|
1202
|
-
const layoutOpts = { axisTypes };
|
|
1203
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1204
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1205
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1206
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1207
|
-
this.builder.addLegend();
|
|
1137
|
+
class EChartBuilder {
|
|
1138
|
+
baseProduct = undefined;
|
|
1139
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
1140
|
+
palette = [];
|
|
1141
|
+
// TODO: Hay que implementar un valor por defecto.
|
|
1142
|
+
colorResolver;
|
|
1143
|
+
result = {};
|
|
1144
|
+
constructor(baseProduct) {
|
|
1145
|
+
this.baseProduct = baseProduct;
|
|
1208
1146
|
}
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
x: 'category',
|
|
1212
|
-
y: 'value',
|
|
1213
|
-
} } = opts;
|
|
1214
|
-
this.builder.reset();
|
|
1215
|
-
// El orden importa, primero callbacks y despues componentes.
|
|
1216
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1217
|
-
this.builder.setPalette(palette);
|
|
1218
|
-
this.builder.setColorResolver(colorResolver);
|
|
1219
|
-
const product = this.builder.baseProduct;
|
|
1220
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1221
|
-
// chart components
|
|
1222
|
-
this.builder.addCommons();
|
|
1223
|
-
const layoutOpts = { axisTypes };
|
|
1224
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1225
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1226
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1227
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1228
|
-
this.builder.addLegend();
|
|
1147
|
+
reset() {
|
|
1148
|
+
this.result = {};
|
|
1229
1149
|
}
|
|
1230
|
-
|
|
1231
|
-
const
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
this.
|
|
1235
|
-
this.builder.setPalette(palette);
|
|
1236
|
-
this.builder.setColorResolver(colorResolver);
|
|
1237
|
-
const product = this.builder.baseProduct;
|
|
1238
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1239
|
-
// chart components
|
|
1240
|
-
this.builder.addCommons();
|
|
1241
|
-
const layoutOpts = {};
|
|
1242
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1243
|
-
this.builder.addGraphic();
|
|
1244
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1245
|
-
this.builder.addLegend();
|
|
1150
|
+
addCommons() {
|
|
1151
|
+
const opts = {
|
|
1152
|
+
palette: this.palette,
|
|
1153
|
+
};
|
|
1154
|
+
merge$1(this.result, getCommons(opts));
|
|
1246
1155
|
}
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1156
|
+
/**
|
|
1157
|
+
*
|
|
1158
|
+
* @param data
|
|
1159
|
+
* @param overrides
|
|
1160
|
+
* @returns
|
|
1161
|
+
*/
|
|
1162
|
+
addSeries(data, overrides, opts) {
|
|
1163
|
+
if (!data || !data.dimensions || !data.source || data.source.length === 0)
|
|
1164
|
+
return;
|
|
1165
|
+
this.result.dataset = {
|
|
1166
|
+
dimensions: data.dimensions,
|
|
1167
|
+
source: data.source
|
|
1168
|
+
};
|
|
1169
|
+
const measureDims = data.dimensions.filter(d => d.name !== 'category');
|
|
1170
|
+
const isPolar = opts?.coordinateSystem === 'polar';
|
|
1171
|
+
const isHorizontal = opts?.axisTypes?.x === 'value' && opts?.axisTypes?.y === 'category';
|
|
1172
|
+
const series = measureDims.map((dim) => {
|
|
1173
|
+
const friendlyName = dim.displayName || dim.name;
|
|
1174
|
+
const dimKey = dim.name;
|
|
1175
|
+
let encode = {
|
|
1176
|
+
x: 'category',
|
|
1177
|
+
y: dimKey
|
|
1178
|
+
};
|
|
1179
|
+
if (isPolar) {
|
|
1180
|
+
encode = {
|
|
1181
|
+
angle: 'category',
|
|
1182
|
+
radius: dimKey
|
|
1183
|
+
};
|
|
1184
|
+
}
|
|
1185
|
+
else if (isHorizontal) {
|
|
1186
|
+
encode = {
|
|
1187
|
+
x: dimKey,
|
|
1188
|
+
y: 'category'
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
const dynamicOverrides = {
|
|
1192
|
+
name: friendlyName,
|
|
1193
|
+
encode,
|
|
1194
|
+
label: {
|
|
1195
|
+
formatter: (params) => {
|
|
1196
|
+
const row = params.value;
|
|
1197
|
+
const rawValue = (row && typeof row === 'object') ? row[dimKey] : params.value;
|
|
1198
|
+
return this.formatCellValue(Number(rawValue ?? 0), dimKey);
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
const seriesOption = merge$1(dynamicOverrides, overrides);
|
|
1203
|
+
// Inyectar el resolver de color si existe
|
|
1204
|
+
if (this.colorResolver && seriesOption.itemStyle) {
|
|
1205
|
+
seriesOption.itemStyle.color = this.colorResolver;
|
|
1206
|
+
}
|
|
1207
|
+
return seriesOption;
|
|
1208
|
+
});
|
|
1209
|
+
this.result.series = series;
|
|
1262
1210
|
}
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1276
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1277
|
-
this.builder.addLegend();
|
|
1211
|
+
/**
|
|
1212
|
+
* TODO: Mejorar funcion, no me convence como se implemento el tooltip formatter.
|
|
1213
|
+
* @param data
|
|
1214
|
+
* @param overrides
|
|
1215
|
+
*/
|
|
1216
|
+
addTooltip(data, overrides) {
|
|
1217
|
+
// inyecto formateador a overrides de tooltip
|
|
1218
|
+
merge$1(overrides, {
|
|
1219
|
+
formatter: getTooltipFormatter(overrides.trigger, data, this.formatCellValue.bind(this)),
|
|
1220
|
+
});
|
|
1221
|
+
const tooltip = getTooltipOptions(overrides);
|
|
1222
|
+
this.result.tooltip = tooltip;
|
|
1278
1223
|
}
|
|
1279
|
-
|
|
1280
|
-
const
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
this.
|
|
1286
|
-
const product = this.builder.baseProduct;
|
|
1287
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1288
|
-
// chart components
|
|
1289
|
-
this.builder.addCommons();
|
|
1290
|
-
const layoutOpts = {};
|
|
1291
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1292
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1293
|
-
// this.builder.addLegend();
|
|
1224
|
+
addPolar() {
|
|
1225
|
+
const polar = [];
|
|
1226
|
+
polar.push({
|
|
1227
|
+
radius: '65%',
|
|
1228
|
+
center: ["50%", "44%"],
|
|
1229
|
+
});
|
|
1230
|
+
this.result.polar = polar;
|
|
1294
1231
|
}
|
|
1295
|
-
|
|
1296
|
-
const
|
|
1297
|
-
this.
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
this.
|
|
1306
|
-
const layoutOpts = {};
|
|
1307
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1308
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1232
|
+
addXAxis(data, overrides, type = 'category') {
|
|
1233
|
+
const xAxis = [];
|
|
1234
|
+
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1235
|
+
const valueAxisOptions = this.getValueAxisOptions(data, overrides);
|
|
1236
|
+
if (type == 'category') {
|
|
1237
|
+
xAxis.push(categoryAxisOptions);
|
|
1238
|
+
}
|
|
1239
|
+
else if (type == 'value') {
|
|
1240
|
+
xAxis.push(valueAxisOptions);
|
|
1241
|
+
}
|
|
1242
|
+
this.result.xAxis = xAxis;
|
|
1309
1243
|
}
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1244
|
+
addYAxis(data, overrides, type = 'value') {
|
|
1245
|
+
const yAxis = [];
|
|
1246
|
+
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1247
|
+
const valueAxisOptions = this.getValueAxisOptions(data, overrides);
|
|
1248
|
+
if (type == 'category') {
|
|
1249
|
+
yAxis.push(categoryAxisOptions);
|
|
1313
1250
|
}
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
this.builder.reset();
|
|
1319
|
-
// El orden importa, primero callbacks y despues componentes.
|
|
1320
|
-
this.builder.setValueFormatter(valueFormatter);
|
|
1321
|
-
this.builder.setPalette(palette);
|
|
1322
|
-
this.builder.setColorResolver(colorResolver);
|
|
1323
|
-
const product = this.builder.baseProduct;
|
|
1324
|
-
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1325
|
-
// chart components
|
|
1326
|
-
this.builder.addCommons();
|
|
1327
|
-
const layoutOpts = { axisTypes };
|
|
1328
|
-
this.builder.addDataset(data, { statisticsKeys });
|
|
1329
|
-
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1330
|
-
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1331
|
-
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1332
|
-
this.builder.addTooltip(data, overrides.tooltip);
|
|
1333
|
-
this.builder.addDataZoom();
|
|
1251
|
+
else if (type == 'value') {
|
|
1252
|
+
yAxis.push(valueAxisOptions);
|
|
1253
|
+
}
|
|
1254
|
+
this.result.yAxis = yAxis;
|
|
1334
1255
|
}
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
/**
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
*/
|
|
1343
|
-
class EchartsRingComponent extends BaseEchartsComponent {
|
|
1344
|
-
baseSeriesOptions = {
|
|
1345
|
-
type: 'pie',
|
|
1346
|
-
center: ['50%', '50%'],
|
|
1347
|
-
avoidLabelOverlap: true,
|
|
1348
|
-
minAngle: 3,
|
|
1349
|
-
selectedMode: 'single',
|
|
1350
|
-
selectedOffset: 4,
|
|
1351
|
-
itemStyle: {
|
|
1352
|
-
borderColor: '#fff',
|
|
1353
|
-
},
|
|
1354
|
-
label: { show: false },
|
|
1355
|
-
emphasis: {
|
|
1356
|
-
scale: true,
|
|
1357
|
-
scaleSize: 2,
|
|
1358
|
-
},
|
|
1359
|
-
select: {
|
|
1360
|
-
itemStyle: {
|
|
1361
|
-
borderColor: EChartsTokens.sBorderColor,
|
|
1362
|
-
shadowColor: EChartsTokens.sShadowColor,
|
|
1363
|
-
borderWidth: 1,
|
|
1364
|
-
shadowBlur: 4,
|
|
1256
|
+
addRadiusAxis(data, overrides) {
|
|
1257
|
+
const radiusAxis = [];
|
|
1258
|
+
/** estilos exclusivos hardcodeados para el eje de valores del sistema de coordenadas polar*/
|
|
1259
|
+
const radiusAxisOverrides = {
|
|
1260
|
+
zlevel: 10,
|
|
1261
|
+
axisTick: {
|
|
1262
|
+
show: false,
|
|
1365
1263
|
},
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
make() {
|
|
1386
|
-
const makeOpts = {
|
|
1387
|
-
valueFormatter: this.valueFormatter,
|
|
1388
|
-
palette: this.palette,
|
|
1389
|
-
colorResolver: this.colorResolver,
|
|
1264
|
+
axisLabel: {
|
|
1265
|
+
margin: 2,
|
|
1266
|
+
fontSize: 8,
|
|
1267
|
+
align: 'right',
|
|
1268
|
+
rotate: 20,
|
|
1269
|
+
verticalAlign: 'top',
|
|
1270
|
+
},
|
|
1271
|
+
splitLine: {
|
|
1272
|
+
show: true,
|
|
1273
|
+
lineStyle: {
|
|
1274
|
+
opacity: 0.2,
|
|
1275
|
+
type: 'solid',
|
|
1276
|
+
}
|
|
1277
|
+
},
|
|
1278
|
+
axisLine: {
|
|
1279
|
+
lineStyle: {
|
|
1280
|
+
type: 'dashed',
|
|
1281
|
+
},
|
|
1282
|
+
}
|
|
1390
1283
|
};
|
|
1391
|
-
|
|
1284
|
+
const radialAxisOptions = getValueAxisOptions(radiusAxisOverrides);
|
|
1285
|
+
radiusAxis.push(radialAxisOptions);
|
|
1286
|
+
this.result.radiusAxis = radiusAxis;
|
|
1392
1287
|
}
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1288
|
+
addAngleAxis(data, overrides) {
|
|
1289
|
+
const angleAxis = [];
|
|
1290
|
+
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1291
|
+
angleAxis.push(categoryAxisOptions);
|
|
1292
|
+
this.result.angleAxis = angleAxis;
|
|
1293
|
+
}
|
|
1294
|
+
addLegend() {
|
|
1295
|
+
this.result.legend = getLegendOptions();
|
|
1296
|
+
}
|
|
1297
|
+
// No-ops for ring charts
|
|
1298
|
+
addGraphic() { }
|
|
1299
|
+
addDataset(data) { }
|
|
1300
|
+
addDataZoom() {
|
|
1301
|
+
this.result.dataZoom = [
|
|
1302
|
+
{
|
|
1303
|
+
type: 'inside'
|
|
1304
|
+
},
|
|
1305
|
+
{
|
|
1306
|
+
type: 'slider',
|
|
1307
|
+
height: 20,
|
|
1308
|
+
bottom: 60
|
|
1309
|
+
}
|
|
1310
|
+
];
|
|
1311
|
+
}
|
|
1312
|
+
getResult() {
|
|
1313
|
+
return this.result;
|
|
1402
1314
|
}
|
|
1315
|
+
;
|
|
1403
1316
|
/**
|
|
1404
|
-
*
|
|
1405
|
-
* Soporta múltiples series (anillos) y actualiza el KPI central.
|
|
1317
|
+
* Formatea un valor utilizando el callback inyectado.
|
|
1406
1318
|
*/
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
const isSameSelection = event.seriesIndex === this.lastSelectedSeriesIndex &&
|
|
1410
|
-
event.dataIndex === this.lastSelectedDataIndex;
|
|
1411
|
-
if (isSameSelection) {
|
|
1412
|
-
// Toggle OFF
|
|
1413
|
-
this.lastSelectedSeriesIndex = null;
|
|
1414
|
-
this.lastSelectedDataIndex = null;
|
|
1415
|
-
this.selectedPercent = null;
|
|
1416
|
-
this.setGraphicText('');
|
|
1417
|
-
}
|
|
1418
|
-
else {
|
|
1419
|
-
// SELECT
|
|
1420
|
-
this.lastSelectedSeriesIndex = event.seriesIndex;
|
|
1421
|
-
this.lastSelectedDataIndex = event.dataIndex;
|
|
1422
|
-
this.selectedPercent = (event.percent !== undefined) ? event.percent + '%' : '';
|
|
1423
|
-
this.setGraphicText(this.selectedPercent);
|
|
1424
|
-
}
|
|
1425
|
-
this.chartClick.emit({
|
|
1426
|
-
type: 'cross-filter',
|
|
1427
|
-
data: {
|
|
1428
|
-
category: event.name,
|
|
1429
|
-
serie: event.seriesName,
|
|
1430
|
-
value: event.value
|
|
1431
|
-
}
|
|
1432
|
-
});
|
|
1433
|
-
}
|
|
1319
|
+
formatCellValue(value, key) {
|
|
1320
|
+
return this.valueFormatter(value, key);
|
|
1434
1321
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1322
|
+
// Setters
|
|
1323
|
+
/**
|
|
1324
|
+
* Permite inyectar un formateador de valores externo.
|
|
1325
|
+
*/
|
|
1326
|
+
setValueFormatter(formatter) {
|
|
1327
|
+
if (formatter) {
|
|
1328
|
+
this.valueFormatter = formatter;
|
|
1438
1329
|
}
|
|
1439
1330
|
}
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1331
|
+
/**
|
|
1332
|
+
* Permite inyectar una paleta de colores básica.
|
|
1333
|
+
*/
|
|
1334
|
+
setPalette(palette) {
|
|
1335
|
+
if (palette) {
|
|
1336
|
+
this.palette = palette;
|
|
1443
1337
|
}
|
|
1444
1338
|
}
|
|
1445
1339
|
/**
|
|
1446
|
-
*
|
|
1340
|
+
* Permite inyectar un resolver de colores dinámico.
|
|
1447
1341
|
*/
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
}
|
|
1342
|
+
setColorResolver(resolver) {
|
|
1343
|
+
if (resolver) {
|
|
1344
|
+
this.colorResolver = resolver;
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
// Utils
|
|
1348
|
+
getCategoryAxisOptions(data, overrides) {
|
|
1349
|
+
// No explicit data needed on category axis when using ECharts dataset
|
|
1350
|
+
const categoryAxisOptionsOverrides = {
|
|
1351
|
+
...overrides.categoryAxis[0]
|
|
1352
|
+
};
|
|
1353
|
+
const categoryAxisOptions = getCategoryAxisOptions(categoryAxisOptionsOverrides);
|
|
1354
|
+
return categoryAxisOptions;
|
|
1355
|
+
}
|
|
1356
|
+
getValueAxisOptions(data, overrides) {
|
|
1357
|
+
const valueAxisOptions = getValueAxisOptions();
|
|
1358
|
+
return valueAxisOptions;
|
|
1459
1359
|
}
|
|
1460
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1461
|
-
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 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"] }] });
|
|
1462
1360
|
}
|
|
1463
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, decorators: [{
|
|
1464
|
-
type: Component,
|
|
1465
|
-
args: [{ selector: 'vs-echarts-ring', standalone: true, imports: [
|
|
1466
|
-
CommonModule,
|
|
1467
|
-
NgxEchartsDirective,
|
|
1468
|
-
], providers: [provideVSEcharts()], 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"] }]
|
|
1469
|
-
}], ctorParameters: () => [] });
|
|
1470
1361
|
|
|
1471
1362
|
/**
|
|
1472
1363
|
* PieBuilder
|
|
@@ -1631,78 +1522,18 @@ class PieBuilder {
|
|
|
1631
1522
|
}
|
|
1632
1523
|
|
|
1633
1524
|
/**
|
|
1634
|
-
*
|
|
1525
|
+
* FunnelBuilder
|
|
1635
1526
|
*
|
|
1636
|
-
*
|
|
1637
|
-
* La primera serie se dibuja como un gráfico de torta tradicional (lleno) y
|
|
1638
|
-
* las subsecuentes como anillos concéntricos alrededor.
|
|
1527
|
+
* Concrete builder for Funnel charts.
|
|
1639
1528
|
*/
|
|
1640
|
-
class
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
emphasis: {
|
|
1649
|
-
scale: true,
|
|
1650
|
-
scaleSize: 2,
|
|
1651
|
-
},
|
|
1652
|
-
select: {
|
|
1653
|
-
itemStyle: {
|
|
1654
|
-
borderColor: EChartsTokens.sBorderColor,
|
|
1655
|
-
shadowColor: EChartsTokens.sShadowColor,
|
|
1656
|
-
borderWidth: 1,
|
|
1657
|
-
shadowBlur: 4,
|
|
1658
|
-
},
|
|
1659
|
-
},
|
|
1660
|
-
animationType: 'scale',
|
|
1661
|
-
animationEasing: 'elasticOut',
|
|
1662
|
-
};
|
|
1663
|
-
baseProduct = {
|
|
1664
|
-
chartKey: 'pie',
|
|
1665
|
-
baseOptions: {
|
|
1666
|
-
series: this.baseSeriesOptions,
|
|
1667
|
-
}
|
|
1668
|
-
};
|
|
1669
|
-
builder = new PieBuilder(this.baseProduct);
|
|
1670
|
-
director = new VSECDirector(this.builder);
|
|
1671
|
-
constructor() {
|
|
1672
|
-
super();
|
|
1673
|
-
}
|
|
1674
|
-
make() {
|
|
1675
|
-
const makeOpts = {
|
|
1676
|
-
valueFormatter: this.valueFormatter,
|
|
1677
|
-
palette: this.palette,
|
|
1678
|
-
colorResolver: this.colorResolver,
|
|
1679
|
-
};
|
|
1680
|
-
this.director.makePie(this.data, this.optionsOverrides, makeOpts);
|
|
1681
|
-
}
|
|
1682
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1683
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsPieComponent, isStandalone: true, selector: "vs-echarts-pie", providers: [provideVSEcharts()], 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"] }] });
|
|
1684
|
-
}
|
|
1685
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, decorators: [{
|
|
1686
|
-
type: Component,
|
|
1687
|
-
args: [{ selector: 'vs-echarts-pie', standalone: true, imports: [
|
|
1688
|
-
CommonModule,
|
|
1689
|
-
NgxEchartsDirective,
|
|
1690
|
-
], providers: [provideVSEcharts()], 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"] }]
|
|
1691
|
-
}], ctorParameters: () => [] });
|
|
1692
|
-
|
|
1693
|
-
/**
|
|
1694
|
-
* FunnelBuilder
|
|
1695
|
-
*
|
|
1696
|
-
* Concrete builder for Funnel charts.
|
|
1697
|
-
*/
|
|
1698
|
-
class FunnelBuilder {
|
|
1699
|
-
baseProduct;
|
|
1700
|
-
valueFormatter = (value) => value.toLocaleString();
|
|
1701
|
-
palette = [];
|
|
1702
|
-
colorResolver;
|
|
1703
|
-
result = {};
|
|
1704
|
-
constructor(baseProduct) {
|
|
1705
|
-
this.baseProduct = baseProduct;
|
|
1529
|
+
class FunnelBuilder {
|
|
1530
|
+
baseProduct;
|
|
1531
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
1532
|
+
palette = [];
|
|
1533
|
+
colorResolver;
|
|
1534
|
+
result = {};
|
|
1535
|
+
constructor(baseProduct) {
|
|
1536
|
+
this.baseProduct = baseProduct;
|
|
1706
1537
|
}
|
|
1707
1538
|
reset() {
|
|
1708
1539
|
this.result = {};
|
|
@@ -1794,91 +1625,10 @@ class FunnelBuilder {
|
|
|
1794
1625
|
}
|
|
1795
1626
|
}
|
|
1796
1627
|
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
*
|
|
1800
|
-
* Component for Funnel visualization. Supports single and multiple measures.
|
|
1801
|
-
*/
|
|
1802
|
-
class EchartsFunnelComponent extends BaseEchartsComponent {
|
|
1803
|
-
baseSeriesOptions = {
|
|
1804
|
-
type: 'funnel',
|
|
1805
|
-
left: '10%',
|
|
1806
|
-
width: '80%',
|
|
1807
|
-
minSize: '0.01%',
|
|
1808
|
-
maxSize: '100%',
|
|
1809
|
-
sort: 'descending',
|
|
1810
|
-
gap: 2,
|
|
1811
|
-
label: {
|
|
1812
|
-
show: true,
|
|
1813
|
-
position: 'inside'
|
|
1814
|
-
},
|
|
1815
|
-
labelLine: {
|
|
1816
|
-
show: false
|
|
1817
|
-
},
|
|
1818
|
-
itemStyle: {
|
|
1819
|
-
borderColor: '#fff',
|
|
1820
|
-
borderWidth: 1
|
|
1821
|
-
},
|
|
1822
|
-
emphasis: {
|
|
1823
|
-
label: {
|
|
1824
|
-
fontSize: 16
|
|
1825
|
-
}
|
|
1826
|
-
},
|
|
1827
|
-
selectedMode: 'single',
|
|
1828
|
-
select: {
|
|
1829
|
-
label: {
|
|
1830
|
-
fontSize: 16
|
|
1831
|
-
},
|
|
1832
|
-
itemStyle: {
|
|
1833
|
-
borderWidth: 1,
|
|
1834
|
-
borderColor: EChartsTokens.sBorderColor,
|
|
1835
|
-
shadowColor: EChartsTokens.sShadowColor,
|
|
1836
|
-
shadowBlur: 6,
|
|
1837
|
-
}
|
|
1838
|
-
},
|
|
1839
|
-
};
|
|
1840
|
-
baseProduct = {
|
|
1841
|
-
chartKey: 'funnel',
|
|
1842
|
-
baseOptions: {
|
|
1843
|
-
series: this.baseSeriesOptions,
|
|
1844
|
-
}
|
|
1845
|
-
};
|
|
1846
|
-
builder = new FunnelBuilder(this.baseProduct);
|
|
1847
|
-
director = new VSECDirector(this.builder);
|
|
1848
|
-
constructor() {
|
|
1849
|
-
super();
|
|
1850
|
-
}
|
|
1851
|
-
make() {
|
|
1852
|
-
const makeOpts = {
|
|
1853
|
-
valueFormatter: this.valueFormatter,
|
|
1854
|
-
palette: this.palette,
|
|
1855
|
-
colorResolver: this.colorResolver,
|
|
1856
|
-
};
|
|
1857
|
-
this.director.makeFunnel(this.data, this.optionsOverrides, makeOpts);
|
|
1858
|
-
}
|
|
1859
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1860
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsFunnelComponent, isStandalone: true, selector: "vs-echarts-funnel", providers: [provideVSEcharts()], 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"] }] });
|
|
1861
|
-
}
|
|
1862
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, decorators: [{
|
|
1863
|
-
type: Component,
|
|
1864
|
-
args: [{ selector: 'vs-echarts-funnel', standalone: true, imports: [
|
|
1865
|
-
CommonModule,
|
|
1866
|
-
NgxEchartsDirective,
|
|
1867
|
-
], providers: [provideVSEcharts()], 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"] }]
|
|
1868
|
-
}], ctorParameters: () => [] });
|
|
1869
|
-
|
|
1870
|
-
/**
|
|
1871
|
-
* Builder principal.
|
|
1872
|
-
*
|
|
1873
|
-
* Es muy completo, tiene soporte para ejes y sistema cartesiano polar.
|
|
1874
|
-
*
|
|
1875
|
-
* Puede verse utilizado en graficos como Lineas y Bars. Siempre que se pueda priorizar utilizar este.
|
|
1876
|
-
*/
|
|
1877
|
-
class EChartBuilder {
|
|
1878
|
-
baseProduct = undefined;
|
|
1628
|
+
class SunburstBuilder {
|
|
1629
|
+
baseProduct;
|
|
1879
1630
|
valueFormatter = (value) => value.toLocaleString();
|
|
1880
1631
|
palette = [];
|
|
1881
|
-
// TODO: Hay que implementar un valor por defecto.
|
|
1882
1632
|
colorResolver;
|
|
1883
1633
|
result = {};
|
|
1884
1634
|
constructor(baseProduct) {
|
|
@@ -1887,217 +1637,779 @@ class EChartBuilder {
|
|
|
1887
1637
|
reset() {
|
|
1888
1638
|
this.result = {};
|
|
1889
1639
|
}
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
palette: this.palette,
|
|
1893
|
-
};
|
|
1894
|
-
merge$1(this.result, getCommons(opts));
|
|
1895
|
-
}
|
|
1896
|
-
/**
|
|
1897
|
-
*
|
|
1898
|
-
* @param data
|
|
1899
|
-
* @param overrides
|
|
1900
|
-
* @returns
|
|
1901
|
-
*/
|
|
1902
|
-
addSeries(data, overrides, opts) {
|
|
1903
|
-
if (!data || !data.dimensions || !data.source || data.source.length === 0)
|
|
1640
|
+
addSeries(data, overrides) {
|
|
1641
|
+
if (!data || !data.source || data.source.length === 0) {
|
|
1904
1642
|
return;
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1910
|
-
|
|
1911
|
-
const isHorizontal = opts?.axisTypes?.x === 'value' && opts?.axisTypes?.y === 'category';
|
|
1912
|
-
const series = measureDims.map((dim) => {
|
|
1913
|
-
const friendlyName = dim.displayName || dim.name;
|
|
1914
|
-
const dimKey = dim.name;
|
|
1915
|
-
let encode = {
|
|
1916
|
-
x: 'category',
|
|
1917
|
-
y: dimKey
|
|
1918
|
-
};
|
|
1919
|
-
if (isPolar) {
|
|
1920
|
-
encode = {
|
|
1921
|
-
angle: 'category',
|
|
1922
|
-
radius: dimKey
|
|
1923
|
-
};
|
|
1924
|
-
}
|
|
1925
|
-
else if (isHorizontal) {
|
|
1926
|
-
encode = {
|
|
1927
|
-
x: dimKey,
|
|
1928
|
-
y: 'category'
|
|
1929
|
-
};
|
|
1930
|
-
}
|
|
1931
|
-
const dynamicOverrides = {
|
|
1932
|
-
name: friendlyName,
|
|
1933
|
-
encode,
|
|
1643
|
+
}
|
|
1644
|
+
const sunburstData = mapHierarchicalData(data.source, data.dimensions);
|
|
1645
|
+
const depth = getTreeDepth(sunburstData);
|
|
1646
|
+
const levels = [];
|
|
1647
|
+
for (let i = 0; i <= depth; i++) {
|
|
1648
|
+
levels.push({
|
|
1934
1649
|
label: {
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
|
|
1650
|
+
show: false,
|
|
1651
|
+
},
|
|
1652
|
+
});
|
|
1653
|
+
}
|
|
1654
|
+
const dynamiSerieOptions = {
|
|
1655
|
+
name: '',
|
|
1656
|
+
data: sunburstData,
|
|
1657
|
+
levels: levels
|
|
1658
|
+
};
|
|
1659
|
+
const serie = merge$1({}, dynamiSerieOptions, overrides);
|
|
1660
|
+
if (this.colorResolver) {
|
|
1661
|
+
if (!serie.itemStyle) {
|
|
1662
|
+
serie.itemStyle = {};
|
|
1946
1663
|
}
|
|
1947
|
-
|
|
1948
|
-
}
|
|
1949
|
-
this.result.series =
|
|
1664
|
+
serie.itemStyle.color = this.colorResolver;
|
|
1665
|
+
}
|
|
1666
|
+
this.result.series = serie;
|
|
1950
1667
|
}
|
|
1951
|
-
/**
|
|
1952
|
-
* TODO: Mejorar funcion, no me convence como se implemento el tooltip formatter.
|
|
1953
|
-
* @param data
|
|
1954
|
-
* @param overrides
|
|
1955
|
-
*/
|
|
1956
1668
|
addTooltip(data, overrides) {
|
|
1957
|
-
// inyecto formateador a overrides de tooltip
|
|
1958
1669
|
merge$1(overrides, {
|
|
1959
|
-
formatter: getTooltipFormatter(overrides.trigger, data, this.
|
|
1670
|
+
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
1960
1671
|
});
|
|
1961
1672
|
const tooltip = getTooltipOptions(overrides);
|
|
1962
1673
|
this.result.tooltip = tooltip;
|
|
1963
1674
|
}
|
|
1964
|
-
|
|
1965
|
-
const
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
});
|
|
1970
|
-
this.result.polar = polar;
|
|
1675
|
+
addCommons() {
|
|
1676
|
+
const opts = {
|
|
1677
|
+
palette: this.palette,
|
|
1678
|
+
};
|
|
1679
|
+
merge$1(this.result, getCommons(opts));
|
|
1971
1680
|
}
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
const categoryAxisOptions = this.getCategoryAxisOptions(data, overrides);
|
|
1975
|
-
const valueAxisOptions = this.getValueAxisOptions(data, overrides);
|
|
1976
|
-
if (type == 'category') {
|
|
1977
|
-
xAxis.push(categoryAxisOptions);
|
|
1978
|
-
}
|
|
1979
|
-
else if (type == 'value') {
|
|
1980
|
-
xAxis.push(valueAxisOptions);
|
|
1981
|
-
}
|
|
1982
|
-
this.result.xAxis = xAxis;
|
|
1681
|
+
getResult() {
|
|
1682
|
+
return this.result;
|
|
1983
1683
|
}
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1684
|
+
;
|
|
1685
|
+
// No-ops
|
|
1686
|
+
addPolar() { }
|
|
1687
|
+
addXAxis(data, overrides, type) { }
|
|
1688
|
+
addYAxis(data, overrides, type) { }
|
|
1689
|
+
addRadiusAxis(data, overrides) { }
|
|
1690
|
+
addAngleAxis(data, overrides) { }
|
|
1691
|
+
addLegend() { }
|
|
1692
|
+
addDataZoom() { }
|
|
1693
|
+
addDataset(data, opts) { }
|
|
1694
|
+
addGraphic() { }
|
|
1695
|
+
// Setters
|
|
1696
|
+
/**
|
|
1697
|
+
* Permite inyectar un formateador de valores externo.
|
|
1698
|
+
*/
|
|
1699
|
+
setValueFormatter(formatter) {
|
|
1700
|
+
if (formatter) {
|
|
1701
|
+
this.valueFormatter = formatter;
|
|
1993
1702
|
}
|
|
1994
|
-
this.result.yAxis = yAxis;
|
|
1995
1703
|
}
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
|
|
2002
|
-
|
|
1704
|
+
/**
|
|
1705
|
+
* Permite inyectar una paleta de colores básica.
|
|
1706
|
+
*/
|
|
1707
|
+
setPalette(palette) {
|
|
1708
|
+
if (palette) {
|
|
1709
|
+
this.palette = palette;
|
|
1710
|
+
}
|
|
1711
|
+
}
|
|
1712
|
+
/**
|
|
1713
|
+
* Permite inyectar un resolver de colores dinámico.
|
|
1714
|
+
*/
|
|
1715
|
+
setColorResolver(resolver) {
|
|
1716
|
+
if (resolver) {
|
|
1717
|
+
this.colorResolver = resolver;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
/**
|
|
1723
|
+
* SankeyBuilder
|
|
1724
|
+
*
|
|
1725
|
+
* Builder concreto para el gráfico Sankey (diagrama de flujos de izquierda a derecha).
|
|
1726
|
+
*/
|
|
1727
|
+
class SankeyBuilder {
|
|
1728
|
+
baseProduct;
|
|
1729
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
1730
|
+
palette = [];
|
|
1731
|
+
colorResolver;
|
|
1732
|
+
result = {};
|
|
1733
|
+
constructor(baseProduct) {
|
|
1734
|
+
this.baseProduct = baseProduct;
|
|
1735
|
+
}
|
|
1736
|
+
reset() {
|
|
1737
|
+
this.result = {};
|
|
1738
|
+
}
|
|
1739
|
+
addSeries(data, overrides) {
|
|
1740
|
+
if (!data || !data.source || data.source.length === 0) {
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
// Identificar medidas (todas las dimensiones excepto 'category')
|
|
1744
|
+
const measureKeys = data.dimensions
|
|
1745
|
+
.filter((d) => d.name !== "category")
|
|
1746
|
+
.map((d) => d.name);
|
|
1747
|
+
// Función auxiliar para sumarizar valores de medidas en caso de haber más de una
|
|
1748
|
+
const getNodeValue = (node) => {
|
|
1749
|
+
return measureKeys.reduce((sum, key) => sum + (Number(node[key]) || 0), 0);
|
|
1750
|
+
};
|
|
1751
|
+
const nodesMap = new Map();
|
|
1752
|
+
const linksMap = new Map();
|
|
1753
|
+
// Función recursiva para aplanar datos jerárquicos a nodos y enlaces
|
|
1754
|
+
const traverse = (nodeList, level, parentId) => {
|
|
1755
|
+
for (const node of nodeList) {
|
|
1756
|
+
const category = node.category;
|
|
1757
|
+
const currentId = `${category}___${level}`;
|
|
1758
|
+
const value = getNodeValue(node);
|
|
1759
|
+
nodesMap.set(currentId, (nodesMap.get(currentId) || 0) + value);
|
|
1760
|
+
if (parentId) {
|
|
1761
|
+
const linkKey = `${parentId}--->${currentId}`;
|
|
1762
|
+
if (linksMap.has(linkKey)) {
|
|
1763
|
+
linksMap.get(linkKey).value += value;
|
|
1764
|
+
}
|
|
1765
|
+
else {
|
|
1766
|
+
linksMap.set(linkKey, {
|
|
1767
|
+
source: parentId,
|
|
1768
|
+
target: currentId,
|
|
1769
|
+
value: value,
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
if (node.children && node.children.length > 0) {
|
|
1774
|
+
traverse(node.children, level + 1, currentId);
|
|
1775
|
+
}
|
|
1776
|
+
}
|
|
1777
|
+
};
|
|
1778
|
+
// Comenzar el recorrido en el nivel 0
|
|
1779
|
+
traverse(data.source, 0);
|
|
1780
|
+
// al menos un nivel de links para dibujar.
|
|
1781
|
+
if (linksMap.size === 0)
|
|
1782
|
+
return;
|
|
1783
|
+
// Mapear nodos acumulados a la estructura requerida por ECharts (name y opcionalmente color, sin value redundante)
|
|
1784
|
+
const nodes = Array.from(nodesMap.keys()).map((currentId) => {
|
|
1785
|
+
const category = currentId.split("___")[0];
|
|
1786
|
+
const nodeItem = {
|
|
1787
|
+
name: currentId,
|
|
1788
|
+
};
|
|
1789
|
+
if (this.colorResolver) {
|
|
1790
|
+
const color = this.colorResolver({ name: category, data: nodeItem });
|
|
1791
|
+
if (color) {
|
|
1792
|
+
nodeItem.itemStyle = { color };
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
return nodeItem;
|
|
1796
|
+
});
|
|
1797
|
+
const dynamicSerieOptions = {
|
|
1798
|
+
type: "sankey",
|
|
1799
|
+
orient: "horizontal", // De izquierda a derecha
|
|
1800
|
+
draggable: true,
|
|
1801
|
+
emphasis: {
|
|
1802
|
+
focus: "adjacency",
|
|
2003
1803
|
},
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
rotate: 20,
|
|
2009
|
-
verticalAlign: 'top',
|
|
1804
|
+
lineStyle: {
|
|
1805
|
+
color: "source",
|
|
1806
|
+
opacity: 0.25,
|
|
1807
|
+
curveness: 0.5,
|
|
2010
1808
|
},
|
|
2011
|
-
|
|
1809
|
+
label: {
|
|
2012
1810
|
show: true,
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
lineStyle: {
|
|
2020
|
-
type: 'dashed',
|
|
1811
|
+
position: "right",
|
|
1812
|
+
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif",
|
|
1813
|
+
fontSize: 10,
|
|
1814
|
+
formatter: (params) => {
|
|
1815
|
+
// Remover el sufijo de nivel de la etiqueta visual
|
|
1816
|
+
return params.name.split("___")[0];
|
|
2021
1817
|
},
|
|
2022
|
-
}
|
|
1818
|
+
},
|
|
1819
|
+
roam: true,
|
|
1820
|
+
data: nodes,
|
|
1821
|
+
links: Array.from(linksMap.values()),
|
|
2023
1822
|
};
|
|
2024
|
-
const
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
this.result.angleAxis = angleAxis;
|
|
1823
|
+
const serie = merge$1({}, dynamicSerieOptions, overrides);
|
|
1824
|
+
if (this.colorResolver && !serie.itemStyle) {
|
|
1825
|
+
serie.itemStyle = {};
|
|
1826
|
+
}
|
|
1827
|
+
if (this.colorResolver && serie.itemStyle) {
|
|
1828
|
+
serie.itemStyle.color = this.colorResolver;
|
|
1829
|
+
}
|
|
1830
|
+
this.result.series = serie;
|
|
2033
1831
|
}
|
|
2034
|
-
|
|
2035
|
-
|
|
1832
|
+
addTooltip(data, overrides) {
|
|
1833
|
+
merge$1(overrides, {
|
|
1834
|
+
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
1835
|
+
});
|
|
1836
|
+
const tooltip = getTooltipOptions(overrides);
|
|
1837
|
+
this.result.tooltip = tooltip;
|
|
2036
1838
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
1839
|
+
addPolar() { }
|
|
1840
|
+
addXAxis(data, overrides, type) { }
|
|
1841
|
+
addYAxis(data, overrides, type) { }
|
|
1842
|
+
addRadiusAxis(data, overrides) { }
|
|
1843
|
+
addAngleAxis(data, overrides) { }
|
|
1844
|
+
addLegend() { }
|
|
1845
|
+
addDataZoom() { }
|
|
2039
1846
|
addDataset(data, opts) { }
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
{
|
|
2046
|
-
type: 'slider',
|
|
2047
|
-
height: 20,
|
|
2048
|
-
bottom: 60
|
|
2049
|
-
}
|
|
2050
|
-
];
|
|
1847
|
+
addCommons() {
|
|
1848
|
+
const opts = {
|
|
1849
|
+
palette: this.palette,
|
|
1850
|
+
};
|
|
1851
|
+
merge$1(this.result, getCommons(opts));
|
|
2051
1852
|
}
|
|
1853
|
+
addGraphic() { }
|
|
2052
1854
|
getResult() {
|
|
2053
1855
|
return this.result;
|
|
2054
1856
|
}
|
|
2055
|
-
;
|
|
2056
|
-
/**
|
|
2057
|
-
* Formatea un valor utilizando el callback inyectado.
|
|
2058
|
-
*/
|
|
2059
|
-
formatCellValue(value, key) {
|
|
2060
|
-
return this.valueFormatter(value, key);
|
|
2061
|
-
}
|
|
2062
|
-
// Setters
|
|
2063
|
-
/**
|
|
2064
|
-
* Permite inyectar un formateador de valores externo.
|
|
2065
|
-
*/
|
|
2066
1857
|
setValueFormatter(formatter) {
|
|
2067
1858
|
if (formatter) {
|
|
2068
1859
|
this.valueFormatter = formatter;
|
|
2069
1860
|
}
|
|
2070
1861
|
}
|
|
2071
|
-
/**
|
|
2072
|
-
* Permite inyectar una paleta de colores básica.
|
|
2073
|
-
*/
|
|
2074
1862
|
setPalette(palette) {
|
|
2075
1863
|
if (palette) {
|
|
2076
1864
|
this.palette = palette;
|
|
2077
1865
|
}
|
|
2078
1866
|
}
|
|
2079
|
-
/**
|
|
2080
|
-
* Permite inyectar un resolver de colores dinámico.
|
|
2081
|
-
*/
|
|
2082
1867
|
setColorResolver(resolver) {
|
|
2083
1868
|
if (resolver) {
|
|
2084
1869
|
this.colorResolver = resolver;
|
|
2085
1870
|
}
|
|
2086
1871
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
/**
|
|
1875
|
+
* Director de Builds.
|
|
1876
|
+
*/
|
|
1877
|
+
class VSECDirector {
|
|
1878
|
+
builder = undefined;
|
|
1879
|
+
constructor(builder) {
|
|
1880
|
+
this.builder = builder;
|
|
2095
1881
|
}
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
1882
|
+
makeBar(data, overrides, opts = {}) {
|
|
1883
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
1884
|
+
return;
|
|
1885
|
+
}
|
|
1886
|
+
;
|
|
1887
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1888
|
+
x: 'category',
|
|
1889
|
+
y: 'value',
|
|
1890
|
+
// TODO agregar radius y angle axis
|
|
1891
|
+
} } = opts;
|
|
1892
|
+
this.builder.reset();
|
|
1893
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1894
|
+
// chart callbaks
|
|
1895
|
+
if (valueFormatter)
|
|
1896
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1897
|
+
if (palette)
|
|
1898
|
+
this.builder.setPalette(palette);
|
|
1899
|
+
if (colorResolver)
|
|
1900
|
+
this.builder.setColorResolver(colorResolver);
|
|
1901
|
+
const product = this.builder.baseProduct;
|
|
1902
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1903
|
+
// chart components
|
|
1904
|
+
this.builder.addCommons();
|
|
1905
|
+
const seriesOptions = { axisTypes };
|
|
1906
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
1907
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1908
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1909
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
1910
|
+
this.builder.addLegend();
|
|
1911
|
+
}
|
|
1912
|
+
makeBarRadial(data, overrides, opts = {}) {
|
|
1913
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
1914
|
+
return;
|
|
1915
|
+
}
|
|
1916
|
+
;
|
|
1917
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1918
|
+
x: 'category',
|
|
1919
|
+
y: 'value',
|
|
1920
|
+
// TODO agregar radius y angle axis
|
|
1921
|
+
} } = opts;
|
|
1922
|
+
this.builder.reset();
|
|
1923
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1924
|
+
// chart callbaks
|
|
1925
|
+
if (valueFormatter)
|
|
1926
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1927
|
+
if (palette)
|
|
1928
|
+
this.builder.setPalette(palette);
|
|
1929
|
+
if (colorResolver)
|
|
1930
|
+
this.builder.setColorResolver(colorResolver);
|
|
1931
|
+
const product = this.builder.baseProduct;
|
|
1932
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1933
|
+
// chart components
|
|
1934
|
+
this.builder.addCommons();
|
|
1935
|
+
const seriesOptions = { axisTypes, coordinateSystem: 'polar' };
|
|
1936
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
1937
|
+
this.builder.addPolar();
|
|
1938
|
+
this.builder.addAngleAxis(data, overrides['axis']);
|
|
1939
|
+
this.builder.addRadiusAxis(data, overrides['axis']);
|
|
1940
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
1941
|
+
this.builder.addLegend();
|
|
1942
|
+
}
|
|
1943
|
+
makeLine(data, overrides, opts = {}) {
|
|
1944
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
1945
|
+
return;
|
|
1946
|
+
}
|
|
1947
|
+
;
|
|
1948
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1949
|
+
x: 'category',
|
|
1950
|
+
y: 'value',
|
|
1951
|
+
// TODO agregar radius y angle axis
|
|
1952
|
+
} } = opts;
|
|
1953
|
+
this.builder.reset();
|
|
1954
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1955
|
+
// chart callbaks
|
|
1956
|
+
if (valueFormatter)
|
|
1957
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1958
|
+
if (palette)
|
|
1959
|
+
this.builder.setPalette(palette);
|
|
1960
|
+
if (colorResolver)
|
|
1961
|
+
this.builder.setColorResolver(colorResolver);
|
|
1962
|
+
const product = this.builder.baseProduct;
|
|
1963
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1964
|
+
// chart components
|
|
1965
|
+
this.builder.addCommons();
|
|
1966
|
+
const seriesOptions = { axisTypes };
|
|
1967
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
1968
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1969
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1970
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
1971
|
+
this.builder.addLegend();
|
|
1972
|
+
}
|
|
1973
|
+
makeScatter(data, overrides, opts = {}) {
|
|
1974
|
+
if (this.builder instanceof EChartBuilder == false) {
|
|
1975
|
+
return;
|
|
1976
|
+
}
|
|
1977
|
+
;
|
|
1978
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
1979
|
+
x: 'category',
|
|
1980
|
+
y: 'value',
|
|
1981
|
+
} } = opts;
|
|
1982
|
+
this.builder.reset();
|
|
1983
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1984
|
+
// chart callbaks
|
|
1985
|
+
if (valueFormatter)
|
|
1986
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1987
|
+
if (palette)
|
|
1988
|
+
this.builder.setPalette(palette);
|
|
1989
|
+
if (colorResolver)
|
|
1990
|
+
this.builder.setColorResolver(colorResolver);
|
|
1991
|
+
const product = this.builder.baseProduct;
|
|
1992
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1993
|
+
// chart components
|
|
1994
|
+
this.builder.addCommons();
|
|
1995
|
+
const seriesOptions = { axisTypes };
|
|
1996
|
+
this.builder.addSeries(data, seriesOverrides, seriesOptions);
|
|
1997
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
1998
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
1999
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2000
|
+
this.builder.addLegend();
|
|
2001
|
+
}
|
|
2002
|
+
makeRing(data, overrides, opts = {}) {
|
|
2003
|
+
if (this.builder instanceof RingBuilder == false) {
|
|
2004
|
+
return;
|
|
2005
|
+
}
|
|
2006
|
+
;
|
|
2007
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2008
|
+
this.builder.reset();
|
|
2009
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2010
|
+
// chart callbaks
|
|
2011
|
+
if (valueFormatter)
|
|
2012
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2013
|
+
if (palette)
|
|
2014
|
+
this.builder.setPalette(palette);
|
|
2015
|
+
if (colorResolver)
|
|
2016
|
+
this.builder.setColorResolver(colorResolver);
|
|
2017
|
+
const product = this.builder.baseProduct;
|
|
2018
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2019
|
+
// chart components
|
|
2020
|
+
this.builder.addCommons();
|
|
2021
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2022
|
+
this.builder.addGraphic();
|
|
2023
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2024
|
+
this.builder.addLegend();
|
|
2025
|
+
}
|
|
2026
|
+
makePie(data, overrides, opts = {}) {
|
|
2027
|
+
if (this.builder instanceof PieBuilder == false) {
|
|
2028
|
+
return;
|
|
2029
|
+
}
|
|
2030
|
+
;
|
|
2031
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2032
|
+
this.builder.reset();
|
|
2033
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2034
|
+
// chart callbaks
|
|
2035
|
+
if (valueFormatter)
|
|
2036
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2037
|
+
if (palette)
|
|
2038
|
+
this.builder.setPalette(palette);
|
|
2039
|
+
if (colorResolver)
|
|
2040
|
+
this.builder.setColorResolver(colorResolver);
|
|
2041
|
+
const product = this.builder.baseProduct;
|
|
2042
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2043
|
+
// chart components
|
|
2044
|
+
this.builder.addCommons();
|
|
2045
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2046
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2047
|
+
this.builder.addLegend();
|
|
2048
|
+
}
|
|
2049
|
+
makeFunnel(data, overrides, opts = {}) {
|
|
2050
|
+
if (this.builder instanceof FunnelBuilder == false) {
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
;
|
|
2054
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2055
|
+
this.builder.reset();
|
|
2056
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2057
|
+
// chart callbaks
|
|
2058
|
+
if (valueFormatter)
|
|
2059
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2060
|
+
if (palette)
|
|
2061
|
+
this.builder.setPalette(palette);
|
|
2062
|
+
if (colorResolver)
|
|
2063
|
+
this.builder.setColorResolver(colorResolver);
|
|
2064
|
+
const product = this.builder.baseProduct;
|
|
2065
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2066
|
+
// chart components
|
|
2067
|
+
this.builder.addCommons();
|
|
2068
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2069
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2070
|
+
this.builder.addLegend();
|
|
2071
|
+
}
|
|
2072
|
+
makeSunburst(data, overrides, opts = {}) {
|
|
2073
|
+
if (this.builder instanceof SunburstBuilder == false) {
|
|
2074
|
+
return;
|
|
2075
|
+
}
|
|
2076
|
+
;
|
|
2077
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2078
|
+
this.builder.reset();
|
|
2079
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2080
|
+
// chart callbaks
|
|
2081
|
+
if (valueFormatter)
|
|
2082
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2083
|
+
if (palette)
|
|
2084
|
+
this.builder.setPalette(palette);
|
|
2085
|
+
if (colorResolver)
|
|
2086
|
+
this.builder.setColorResolver(colorResolver);
|
|
2087
|
+
const product = this.builder.baseProduct;
|
|
2088
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2089
|
+
// chart components
|
|
2090
|
+
this.builder.addCommons();
|
|
2091
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2092
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2093
|
+
}
|
|
2094
|
+
makeSankey(data, overrides, opts = {}) {
|
|
2095
|
+
if (this.builder instanceof SankeyBuilder == false) {
|
|
2096
|
+
return;
|
|
2097
|
+
}
|
|
2098
|
+
;
|
|
2099
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
2100
|
+
this.builder.reset();
|
|
2101
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2102
|
+
// chart callbaks
|
|
2103
|
+
if (valueFormatter)
|
|
2104
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2105
|
+
if (palette)
|
|
2106
|
+
this.builder.setPalette(palette);
|
|
2107
|
+
if (colorResolver)
|
|
2108
|
+
this.builder.setColorResolver(colorResolver);
|
|
2109
|
+
const product = this.builder.baseProduct;
|
|
2110
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2111
|
+
// chart components
|
|
2112
|
+
this.builder.addCommons();
|
|
2113
|
+
this.builder.addSeries(data, seriesOverrides);
|
|
2114
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2115
|
+
}
|
|
2116
|
+
makeBoxplot(data, overrides, opts = {}) {
|
|
2117
|
+
if (this.builder instanceof BoxPlotBuilder == false) {
|
|
2118
|
+
return;
|
|
2119
|
+
}
|
|
2120
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, axisTypes = {
|
|
2121
|
+
x: 'value',
|
|
2122
|
+
y: 'category',
|
|
2123
|
+
}, statisticsKeys = undefined, } = opts;
|
|
2124
|
+
this.builder.reset();
|
|
2125
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
2126
|
+
// chart callbaks
|
|
2127
|
+
if (valueFormatter)
|
|
2128
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
2129
|
+
if (palette)
|
|
2130
|
+
this.builder.setPalette(palette);
|
|
2131
|
+
if (colorResolver)
|
|
2132
|
+
this.builder.setColorResolver(colorResolver);
|
|
2133
|
+
const product = this.builder.baseProduct;
|
|
2134
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
2135
|
+
// chart components
|
|
2136
|
+
this.builder.addCommons();
|
|
2137
|
+
const configOpts = { axisTypes };
|
|
2138
|
+
this.builder.addDataset(data, { statisticsKeys });
|
|
2139
|
+
this.builder.addSeries(data, seriesOverrides, configOpts);
|
|
2140
|
+
this.builder.addXAxis(data, overrides.axis, axisTypes.x);
|
|
2141
|
+
this.builder.addYAxis(data, overrides.axis, axisTypes.y);
|
|
2142
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
2143
|
+
this.builder.addDataZoom();
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
|
|
2147
|
+
/**
|
|
2148
|
+
* EchartsRingComponent
|
|
2149
|
+
*
|
|
2150
|
+
* Especialista en visualización de tipo Ring. Soporta multi-medidas y KPI central.
|
|
2151
|
+
* @see {@link vs-echarts/docs/charts/ring-patterns.md}
|
|
2152
|
+
*/
|
|
2153
|
+
class EchartsRingComponent extends BaseEchartsComponent {
|
|
2154
|
+
baseSeriesOptions = {
|
|
2155
|
+
type: 'pie',
|
|
2156
|
+
center: ['50%', '50%'],
|
|
2157
|
+
avoidLabelOverlap: true,
|
|
2158
|
+
minAngle: 3,
|
|
2159
|
+
selectedMode: 'single',
|
|
2160
|
+
selectedOffset: 4,
|
|
2161
|
+
itemStyle: {
|
|
2162
|
+
borderColor: '#fff',
|
|
2163
|
+
},
|
|
2164
|
+
label: { show: false },
|
|
2165
|
+
emphasis: {
|
|
2166
|
+
scale: true,
|
|
2167
|
+
scaleSize: 2,
|
|
2168
|
+
},
|
|
2169
|
+
select: {
|
|
2170
|
+
itemStyle: {
|
|
2171
|
+
borderColor: EChartsTokens.sBorderColor,
|
|
2172
|
+
shadowColor: EChartsTokens.sShadowColor,
|
|
2173
|
+
borderWidth: 1,
|
|
2174
|
+
shadowBlur: 4,
|
|
2175
|
+
},
|
|
2176
|
+
},
|
|
2177
|
+
animationType: 'scale',
|
|
2178
|
+
animationEasing: 'elasticOut',
|
|
2179
|
+
};
|
|
2180
|
+
baseProduct = {
|
|
2181
|
+
chartKey: 'ring',
|
|
2182
|
+
baseOptions: {
|
|
2183
|
+
series: this.baseSeriesOptions,
|
|
2184
|
+
}
|
|
2185
|
+
};
|
|
2186
|
+
builder = new RingBuilder(this.baseProduct);
|
|
2187
|
+
director = new VSECDirector(this.builder);
|
|
2188
|
+
lastSelectedSeriesIndex = null;
|
|
2189
|
+
lastSelectedDataIndex = null;
|
|
2190
|
+
selectedPercent = null;
|
|
2191
|
+
currentGraphicText = '';
|
|
2192
|
+
constructor() {
|
|
2193
|
+
super();
|
|
2194
|
+
}
|
|
2195
|
+
make() {
|
|
2196
|
+
const makeOpts = {
|
|
2197
|
+
valueFormatter: this.valueFormatter,
|
|
2198
|
+
palette: this.palette,
|
|
2199
|
+
colorResolver: this.colorResolver,
|
|
2200
|
+
};
|
|
2201
|
+
this.director.makeRing(this.data, this.optionsOverrides, makeOpts);
|
|
2202
|
+
}
|
|
2203
|
+
onInputChanges(changes) {
|
|
2204
|
+
// Reset selection only if data changed
|
|
2205
|
+
if (changes['data']) {
|
|
2206
|
+
this.lastSelectedSeriesIndex = null;
|
|
2207
|
+
this.lastSelectedDataIndex = null;
|
|
2208
|
+
this.selectedPercent = null;
|
|
2209
|
+
this.currentGraphicText = '';
|
|
2210
|
+
}
|
|
2211
|
+
super.onInputChanges(changes);
|
|
2212
|
+
}
|
|
2213
|
+
/**
|
|
2214
|
+
* Maneja clics en los sectores del ring.
|
|
2215
|
+
* Soporta múltiples series (anillos) y actualiza el KPI central.
|
|
2216
|
+
*/
|
|
2217
|
+
onChartClick(event) {
|
|
2218
|
+
if (this.chartInstance && event && event.dataIndex !== undefined) {
|
|
2219
|
+
const isSameSelection = event.seriesIndex === this.lastSelectedSeriesIndex &&
|
|
2220
|
+
event.dataIndex === this.lastSelectedDataIndex;
|
|
2221
|
+
if (isSameSelection) {
|
|
2222
|
+
// Toggle OFF
|
|
2223
|
+
this.lastSelectedSeriesIndex = null;
|
|
2224
|
+
this.lastSelectedDataIndex = null;
|
|
2225
|
+
this.selectedPercent = null;
|
|
2226
|
+
this.setGraphicText('');
|
|
2227
|
+
}
|
|
2228
|
+
else {
|
|
2229
|
+
// SELECT
|
|
2230
|
+
this.lastSelectedSeriesIndex = event.seriesIndex;
|
|
2231
|
+
this.lastSelectedDataIndex = event.dataIndex;
|
|
2232
|
+
this.selectedPercent = (event.percent !== undefined) ? event.percent + '%' : '';
|
|
2233
|
+
this.setGraphicText(this.selectedPercent);
|
|
2234
|
+
}
|
|
2235
|
+
this.chartClick.emit({
|
|
2236
|
+
type: 'cross-filter',
|
|
2237
|
+
data: {
|
|
2238
|
+
category: event.name,
|
|
2239
|
+
serie: event.seriesName,
|
|
2240
|
+
value: event.value
|
|
2241
|
+
}
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
}
|
|
2245
|
+
onChartMouseOver(event) {
|
|
2246
|
+
if (this.selectedPercent === null && event && event.percent !== undefined) {
|
|
2247
|
+
this.setGraphicText(event.percent + '%');
|
|
2248
|
+
}
|
|
2249
|
+
}
|
|
2250
|
+
onChartMouseOut(event) {
|
|
2251
|
+
if (this.selectedPercent === null) {
|
|
2252
|
+
this.setGraphicText('');
|
|
2253
|
+
}
|
|
2254
|
+
}
|
|
2255
|
+
/**
|
|
2256
|
+
* Actualiza el texto del Graphic central y persiste la selección en el modelo de opciones.
|
|
2257
|
+
*/
|
|
2258
|
+
setGraphicText(text) {
|
|
2259
|
+
this.currentGraphicText = text;
|
|
2260
|
+
// Persistencia de GRAPHIC (KPI central)
|
|
2261
|
+
this.chartInstance?.setOption({
|
|
2262
|
+
graphic: {
|
|
2263
|
+
style: {
|
|
2264
|
+
text: this.currentGraphicText,
|
|
2265
|
+
opacity: this.currentGraphicText ? 1 : 0,
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
});
|
|
2269
|
+
}
|
|
2270
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2271
|
+
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 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"] }] });
|
|
2272
|
+
}
|
|
2273
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsRingComponent, decorators: [{
|
|
2274
|
+
type: Component,
|
|
2275
|
+
args: [{ selector: 'vs-echarts-ring', standalone: true, imports: [
|
|
2276
|
+
CommonModule,
|
|
2277
|
+
NgxEchartsDirective,
|
|
2278
|
+
], providers: [provideVSEcharts()], 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"] }]
|
|
2279
|
+
}], ctorParameters: () => [] });
|
|
2280
|
+
|
|
2281
|
+
/**
|
|
2282
|
+
* EchartsPieComponent
|
|
2283
|
+
*
|
|
2284
|
+
* Especialista en visualización de tipo Pie (Torta y Anillos concéntricos).
|
|
2285
|
+
* La primera serie se dibuja como un gráfico de torta tradicional (lleno) y
|
|
2286
|
+
* las subsecuentes como anillos concéntricos alrededor.
|
|
2287
|
+
*/
|
|
2288
|
+
class EchartsPieComponent extends BaseEchartsComponent {
|
|
2289
|
+
baseSeriesOptions = {
|
|
2290
|
+
type: 'pie',
|
|
2291
|
+
center: ['50%', '50%'],
|
|
2292
|
+
avoidLabelOverlap: true,
|
|
2293
|
+
minAngle: 3,
|
|
2294
|
+
selectedMode: 'single',
|
|
2295
|
+
selectedOffset: 4,
|
|
2296
|
+
emphasis: {
|
|
2297
|
+
scale: true,
|
|
2298
|
+
scaleSize: 2,
|
|
2299
|
+
},
|
|
2300
|
+
select: {
|
|
2301
|
+
itemStyle: {
|
|
2302
|
+
borderColor: EChartsTokens.sBorderColor,
|
|
2303
|
+
shadowColor: EChartsTokens.sShadowColor,
|
|
2304
|
+
borderWidth: 1,
|
|
2305
|
+
shadowBlur: 4,
|
|
2306
|
+
},
|
|
2307
|
+
},
|
|
2308
|
+
animationType: 'scale',
|
|
2309
|
+
animationEasing: 'elasticOut',
|
|
2310
|
+
};
|
|
2311
|
+
baseProduct = {
|
|
2312
|
+
chartKey: 'pie',
|
|
2313
|
+
baseOptions: {
|
|
2314
|
+
series: this.baseSeriesOptions,
|
|
2315
|
+
}
|
|
2316
|
+
};
|
|
2317
|
+
builder = new PieBuilder(this.baseProduct);
|
|
2318
|
+
director = new VSECDirector(this.builder);
|
|
2319
|
+
constructor() {
|
|
2320
|
+
super();
|
|
2321
|
+
}
|
|
2322
|
+
make() {
|
|
2323
|
+
const makeOpts = {
|
|
2324
|
+
valueFormatter: this.valueFormatter,
|
|
2325
|
+
palette: this.palette,
|
|
2326
|
+
colorResolver: this.colorResolver,
|
|
2327
|
+
};
|
|
2328
|
+
this.director.makePie(this.data, this.optionsOverrides, makeOpts);
|
|
2329
|
+
}
|
|
2330
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2331
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsPieComponent, isStandalone: true, selector: "vs-echarts-pie", providers: [provideVSEcharts()], 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"] }] });
|
|
2332
|
+
}
|
|
2333
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsPieComponent, decorators: [{
|
|
2334
|
+
type: Component,
|
|
2335
|
+
args: [{ selector: 'vs-echarts-pie', standalone: true, imports: [
|
|
2336
|
+
CommonModule,
|
|
2337
|
+
NgxEchartsDirective,
|
|
2338
|
+
], providers: [provideVSEcharts()], 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"] }]
|
|
2339
|
+
}], ctorParameters: () => [] });
|
|
2340
|
+
|
|
2341
|
+
/**
|
|
2342
|
+
* EchartsFunnelComponent
|
|
2343
|
+
*
|
|
2344
|
+
* Component for Funnel visualization. Supports single and multiple measures.
|
|
2345
|
+
*/
|
|
2346
|
+
class EchartsFunnelComponent extends BaseEchartsComponent {
|
|
2347
|
+
baseSeriesOptions = {
|
|
2348
|
+
type: 'funnel',
|
|
2349
|
+
left: '10%',
|
|
2350
|
+
width: '80%',
|
|
2351
|
+
minSize: '0.01%',
|
|
2352
|
+
maxSize: '100%',
|
|
2353
|
+
sort: 'descending',
|
|
2354
|
+
gap: 2,
|
|
2355
|
+
label: {
|
|
2356
|
+
show: true,
|
|
2357
|
+
position: 'inside'
|
|
2358
|
+
},
|
|
2359
|
+
labelLine: {
|
|
2360
|
+
show: false
|
|
2361
|
+
},
|
|
2362
|
+
itemStyle: {
|
|
2363
|
+
borderColor: '#fff',
|
|
2364
|
+
borderWidth: 1
|
|
2365
|
+
},
|
|
2366
|
+
emphasis: {
|
|
2367
|
+
label: {
|
|
2368
|
+
fontSize: 16
|
|
2369
|
+
}
|
|
2370
|
+
},
|
|
2371
|
+
selectedMode: 'single',
|
|
2372
|
+
select: {
|
|
2373
|
+
label: {
|
|
2374
|
+
fontSize: 16
|
|
2375
|
+
},
|
|
2376
|
+
itemStyle: {
|
|
2377
|
+
borderWidth: 1,
|
|
2378
|
+
borderColor: EChartsTokens.sBorderColor,
|
|
2379
|
+
shadowColor: EChartsTokens.sShadowColor,
|
|
2380
|
+
shadowBlur: 6,
|
|
2381
|
+
}
|
|
2382
|
+
},
|
|
2383
|
+
};
|
|
2384
|
+
baseProduct = {
|
|
2385
|
+
chartKey: 'funnel',
|
|
2386
|
+
baseOptions: {
|
|
2387
|
+
series: this.baseSeriesOptions,
|
|
2388
|
+
}
|
|
2389
|
+
};
|
|
2390
|
+
builder = new FunnelBuilder(this.baseProduct);
|
|
2391
|
+
director = new VSECDirector(this.builder);
|
|
2392
|
+
constructor() {
|
|
2393
|
+
super();
|
|
2394
|
+
}
|
|
2395
|
+
make() {
|
|
2396
|
+
const makeOpts = {
|
|
2397
|
+
valueFormatter: this.valueFormatter,
|
|
2398
|
+
palette: this.palette,
|
|
2399
|
+
colorResolver: this.colorResolver,
|
|
2400
|
+
};
|
|
2401
|
+
this.director.makeFunnel(this.data, this.optionsOverrides, makeOpts);
|
|
2099
2402
|
}
|
|
2403
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2404
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsFunnelComponent, isStandalone: true, selector: "vs-echarts-funnel", providers: [provideVSEcharts()], 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"] }] });
|
|
2100
2405
|
}
|
|
2406
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsFunnelComponent, decorators: [{
|
|
2407
|
+
type: Component,
|
|
2408
|
+
args: [{ selector: 'vs-echarts-funnel', standalone: true, imports: [
|
|
2409
|
+
CommonModule,
|
|
2410
|
+
NgxEchartsDirective,
|
|
2411
|
+
], providers: [provideVSEcharts()], 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"] }]
|
|
2412
|
+
}], ctorParameters: () => [] });
|
|
2101
2413
|
|
|
2102
2414
|
class EchartsBarComponent extends BaseEchartsComponent {
|
|
2103
2415
|
/**
|
|
@@ -2503,100 +2815,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2503
2815
|
], providers: [provideVSEcharts()], 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"] }]
|
|
2504
2816
|
}], ctorParameters: () => [] });
|
|
2505
2817
|
|
|
2506
|
-
class SunburstBuilder {
|
|
2507
|
-
baseProduct;
|
|
2508
|
-
valueFormatter = (value) => value.toLocaleString();
|
|
2509
|
-
palette = [];
|
|
2510
|
-
// TODO: Hay que implementar un valor por defecto.
|
|
2511
|
-
colorResolver;
|
|
2512
|
-
result = {};
|
|
2513
|
-
constructor(baseProduct) {
|
|
2514
|
-
this.baseProduct = baseProduct;
|
|
2515
|
-
}
|
|
2516
|
-
reset() {
|
|
2517
|
-
this.result = {};
|
|
2518
|
-
}
|
|
2519
|
-
addSeries(data, overrides) {
|
|
2520
|
-
if (!data || !data.source || data.source.length === 0) {
|
|
2521
|
-
return;
|
|
2522
|
-
}
|
|
2523
|
-
const sunburstData = mapHierarchicalData(data.source, data.dimensions);
|
|
2524
|
-
const depth = getTreeDepth(sunburstData);
|
|
2525
|
-
const levels = [];
|
|
2526
|
-
for (let i = 0; i <= depth; i++) {
|
|
2527
|
-
levels.push({
|
|
2528
|
-
label: {
|
|
2529
|
-
show: false,
|
|
2530
|
-
},
|
|
2531
|
-
});
|
|
2532
|
-
}
|
|
2533
|
-
const dynamiSerieOptions = {
|
|
2534
|
-
name: '',
|
|
2535
|
-
data: sunburstData,
|
|
2536
|
-
levels: levels
|
|
2537
|
-
};
|
|
2538
|
-
const serie = merge$1({}, dynamiSerieOptions, overrides);
|
|
2539
|
-
if (this.colorResolver) {
|
|
2540
|
-
if (!serie.itemStyle) {
|
|
2541
|
-
serie.itemStyle = {};
|
|
2542
|
-
}
|
|
2543
|
-
serie.itemStyle.color = this.colorResolver;
|
|
2544
|
-
}
|
|
2545
|
-
this.result.series = serie;
|
|
2546
|
-
}
|
|
2547
|
-
addTooltip(data, overrides) {
|
|
2548
|
-
merge$1(overrides, {
|
|
2549
|
-
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
2550
|
-
});
|
|
2551
|
-
const tooltip = getTooltipOptions(overrides);
|
|
2552
|
-
this.result.tooltip = tooltip;
|
|
2553
|
-
}
|
|
2554
|
-
addCommons() {
|
|
2555
|
-
const opts = {
|
|
2556
|
-
palette: this.palette,
|
|
2557
|
-
};
|
|
2558
|
-
merge$1(this.result, getCommons(opts));
|
|
2559
|
-
}
|
|
2560
|
-
addGraphic() { }
|
|
2561
|
-
getResult() {
|
|
2562
|
-
return this.result;
|
|
2563
|
-
}
|
|
2564
|
-
;
|
|
2565
|
-
addPolar() { }
|
|
2566
|
-
addXAxis(data, overrides, type) { }
|
|
2567
|
-
addYAxis(data, overrides, type) { }
|
|
2568
|
-
addRadiusAxis(data, overrides) { }
|
|
2569
|
-
addAngleAxis(data, overrides) { }
|
|
2570
|
-
addLegend() { }
|
|
2571
|
-
addDataZoom() { }
|
|
2572
|
-
addDataset(data, opts) { }
|
|
2573
|
-
// Setters
|
|
2574
|
-
/**
|
|
2575
|
-
* Permite inyectar un formateador de valores externo.
|
|
2576
|
-
*/
|
|
2577
|
-
setValueFormatter(formatter) {
|
|
2578
|
-
if (formatter) {
|
|
2579
|
-
this.valueFormatter = formatter;
|
|
2580
|
-
}
|
|
2581
|
-
}
|
|
2582
|
-
/**
|
|
2583
|
-
* Permite inyectar una paleta de colores básica.
|
|
2584
|
-
*/
|
|
2585
|
-
setPalette(palette) {
|
|
2586
|
-
if (palette) {
|
|
2587
|
-
this.palette = palette;
|
|
2588
|
-
}
|
|
2589
|
-
}
|
|
2590
|
-
/**
|
|
2591
|
-
* Permite inyectar un resolver de colores dinámico.
|
|
2592
|
-
*/
|
|
2593
|
-
setColorResolver(resolver) {
|
|
2594
|
-
if (resolver) {
|
|
2595
|
-
this.colorResolver = resolver;
|
|
2596
|
-
}
|
|
2597
|
-
}
|
|
2598
|
-
}
|
|
2599
|
-
|
|
2600
2818
|
class EChartsSunburstComponent extends BaseEchartsComponent {
|
|
2601
2819
|
baseSeriesOptions = {
|
|
2602
2820
|
type: 'sunburst',
|
|
@@ -2645,158 +2863,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2645
2863
|
], providers: [provideVSEcharts()], 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"] }]
|
|
2646
2864
|
}] });
|
|
2647
2865
|
|
|
2648
|
-
/**
|
|
2649
|
-
* SankeyBuilder
|
|
2650
|
-
*
|
|
2651
|
-
* Builder concreto para el gráfico Sankey (diagrama de flujos de izquierda a derecha).
|
|
2652
|
-
*/
|
|
2653
|
-
class SankeyBuilder {
|
|
2654
|
-
baseProduct;
|
|
2655
|
-
valueFormatter = (value) => value.toLocaleString();
|
|
2656
|
-
palette = [];
|
|
2657
|
-
colorResolver;
|
|
2658
|
-
result = {};
|
|
2659
|
-
constructor(baseProduct) {
|
|
2660
|
-
this.baseProduct = baseProduct;
|
|
2661
|
-
}
|
|
2662
|
-
reset() {
|
|
2663
|
-
this.result = {};
|
|
2664
|
-
}
|
|
2665
|
-
addSeries(data, overrides) {
|
|
2666
|
-
if (!data || !data.source || data.source.length === 0) {
|
|
2667
|
-
return;
|
|
2668
|
-
}
|
|
2669
|
-
// Identificar medidas (todas las dimensiones excepto 'category')
|
|
2670
|
-
const measureKeys = data.dimensions
|
|
2671
|
-
.filter((d) => d.name !== "category")
|
|
2672
|
-
.map((d) => d.name);
|
|
2673
|
-
// Función auxiliar para sumarizar valores de medidas en caso de haber más de una
|
|
2674
|
-
const getNodeValue = (node) => {
|
|
2675
|
-
return measureKeys.reduce((sum, key) => sum + (Number(node[key]) || 0), 0);
|
|
2676
|
-
};
|
|
2677
|
-
const nodesMap = new Map();
|
|
2678
|
-
const linksMap = new Map();
|
|
2679
|
-
// Función recursiva para aplanar datos jerárquicos a nodos y enlaces
|
|
2680
|
-
const traverse = (nodeList, level, parentId) => {
|
|
2681
|
-
for (const node of nodeList) {
|
|
2682
|
-
const category = node.category;
|
|
2683
|
-
const currentId = `${category}___${level}`;
|
|
2684
|
-
const value = getNodeValue(node);
|
|
2685
|
-
nodesMap.set(currentId, (nodesMap.get(currentId) || 0) + value);
|
|
2686
|
-
if (parentId) {
|
|
2687
|
-
const linkKey = `${parentId}--->${currentId}`;
|
|
2688
|
-
if (linksMap.has(linkKey)) {
|
|
2689
|
-
linksMap.get(linkKey).value += value;
|
|
2690
|
-
}
|
|
2691
|
-
else {
|
|
2692
|
-
linksMap.set(linkKey, {
|
|
2693
|
-
source: parentId,
|
|
2694
|
-
target: currentId,
|
|
2695
|
-
value: value,
|
|
2696
|
-
});
|
|
2697
|
-
}
|
|
2698
|
-
}
|
|
2699
|
-
if (node.children && node.children.length > 0) {
|
|
2700
|
-
traverse(node.children, level + 1, currentId);
|
|
2701
|
-
}
|
|
2702
|
-
}
|
|
2703
|
-
};
|
|
2704
|
-
// Comenzar el recorrido en el nivel 0
|
|
2705
|
-
traverse(data.source, 0);
|
|
2706
|
-
// al menos un nivel de links para dibujar.
|
|
2707
|
-
if (linksMap.size === 0)
|
|
2708
|
-
return;
|
|
2709
|
-
// Mapear nodos acumulados a la estructura requerida por ECharts (name y opcionalmente color, sin value redundante)
|
|
2710
|
-
const nodes = Array.from(nodesMap.keys()).map((currentId) => {
|
|
2711
|
-
const category = currentId.split("___")[0];
|
|
2712
|
-
const nodeItem = {
|
|
2713
|
-
name: currentId,
|
|
2714
|
-
};
|
|
2715
|
-
if (this.colorResolver) {
|
|
2716
|
-
const color = this.colorResolver({ name: category, data: nodeItem });
|
|
2717
|
-
if (color) {
|
|
2718
|
-
nodeItem.itemStyle = { color };
|
|
2719
|
-
}
|
|
2720
|
-
}
|
|
2721
|
-
return nodeItem;
|
|
2722
|
-
});
|
|
2723
|
-
const dynamicSerieOptions = {
|
|
2724
|
-
type: "sankey",
|
|
2725
|
-
orient: "horizontal", // De izquierda a derecha
|
|
2726
|
-
draggable: true,
|
|
2727
|
-
emphasis: {
|
|
2728
|
-
focus: "adjacency",
|
|
2729
|
-
},
|
|
2730
|
-
lineStyle: {
|
|
2731
|
-
color: "source",
|
|
2732
|
-
opacity: 0.25,
|
|
2733
|
-
curveness: 0.5,
|
|
2734
|
-
},
|
|
2735
|
-
label: {
|
|
2736
|
-
show: true,
|
|
2737
|
-
position: "right",
|
|
2738
|
-
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif",
|
|
2739
|
-
fontSize: 10,
|
|
2740
|
-
formatter: (params) => {
|
|
2741
|
-
// Remover el sufijo de nivel de la etiqueta visual
|
|
2742
|
-
return params.name.split("___")[0];
|
|
2743
|
-
},
|
|
2744
|
-
},
|
|
2745
|
-
roam: true,
|
|
2746
|
-
data: nodes,
|
|
2747
|
-
links: Array.from(linksMap.values()),
|
|
2748
|
-
};
|
|
2749
|
-
const serie = merge$1({}, dynamicSerieOptions, overrides);
|
|
2750
|
-
if (this.colorResolver && !serie.itemStyle) {
|
|
2751
|
-
serie.itemStyle = {};
|
|
2752
|
-
}
|
|
2753
|
-
if (this.colorResolver && serie.itemStyle) {
|
|
2754
|
-
serie.itemStyle.color = this.colorResolver;
|
|
2755
|
-
}
|
|
2756
|
-
this.result.series = serie;
|
|
2757
|
-
}
|
|
2758
|
-
addTooltip(data, overrides) {
|
|
2759
|
-
merge$1(overrides, {
|
|
2760
|
-
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
2761
|
-
});
|
|
2762
|
-
const tooltip = getTooltipOptions(overrides);
|
|
2763
|
-
this.result.tooltip = tooltip;
|
|
2764
|
-
}
|
|
2765
|
-
addPolar() { }
|
|
2766
|
-
addXAxis(data, overrides, type) { }
|
|
2767
|
-
addYAxis(data, overrides, type) { }
|
|
2768
|
-
addRadiusAxis(data, overrides) { }
|
|
2769
|
-
addAngleAxis(data, overrides) { }
|
|
2770
|
-
addLegend() { }
|
|
2771
|
-
addDataZoom() { }
|
|
2772
|
-
addDataset(data, opts) { }
|
|
2773
|
-
addCommons() {
|
|
2774
|
-
const opts = {
|
|
2775
|
-
palette: this.palette,
|
|
2776
|
-
};
|
|
2777
|
-
merge$1(this.result, getCommons(opts));
|
|
2778
|
-
}
|
|
2779
|
-
addGraphic() { }
|
|
2780
|
-
getResult() {
|
|
2781
|
-
return this.result;
|
|
2782
|
-
}
|
|
2783
|
-
setValueFormatter(formatter) {
|
|
2784
|
-
if (formatter) {
|
|
2785
|
-
this.valueFormatter = formatter;
|
|
2786
|
-
}
|
|
2787
|
-
}
|
|
2788
|
-
setPalette(palette) {
|
|
2789
|
-
if (palette) {
|
|
2790
|
-
this.palette = palette;
|
|
2791
|
-
}
|
|
2792
|
-
}
|
|
2793
|
-
setColorResolver(resolver) {
|
|
2794
|
-
if (resolver) {
|
|
2795
|
-
this.colorResolver = resolver;
|
|
2796
|
-
}
|
|
2797
|
-
}
|
|
2798
|
-
}
|
|
2799
|
-
|
|
2800
2866
|
class EchartsSankeyComponent extends BaseEchartsComponent {
|
|
2801
2867
|
baseSeriesOptions = {
|
|
2802
2868
|
type: 'sankey',
|