@visionaris-bruno/vs-echarts 8.1.0 → 8.3.0
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.
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { provideEchartsCore, NgxEchartsDirective } from 'ngx-echarts';
|
|
2
2
|
import * as echarts from 'echarts/core';
|
|
3
|
-
import { BarChart, PieChart, LineChart, ScatterChart, FunnelChart, SunburstChart } from 'echarts/charts';
|
|
3
|
+
import { BarChart, PieChart, LineChart, ScatterChart, FunnelChart, SunburstChart, SankeyChart } from 'echarts/charts';
|
|
4
4
|
import { TitleComponent, TooltipComponent, GridComponent, LegendComponent, GraphicComponent, ToolboxComponent, PolarComponent, DatasetComponent } from 'echarts/components';
|
|
5
5
|
import { CanvasRenderer, SVGRenderer } from 'echarts/renderers';
|
|
6
6
|
import * as i0 from '@angular/core';
|
|
@@ -66,6 +66,7 @@ function initializeEcharts() {
|
|
|
66
66
|
ScatterChart,
|
|
67
67
|
FunnelChart,
|
|
68
68
|
SunburstChart,
|
|
69
|
+
SankeyChart,
|
|
69
70
|
TitleComponent,
|
|
70
71
|
TooltipComponent,
|
|
71
72
|
GridComponent,
|
|
@@ -162,6 +163,9 @@ function defaultOptionsOverrides() {
|
|
|
162
163
|
sunburst: {
|
|
163
164
|
series: {},
|
|
164
165
|
},
|
|
166
|
+
sankey: {
|
|
167
|
+
series: {}
|
|
168
|
+
},
|
|
165
169
|
};
|
|
166
170
|
}
|
|
167
171
|
|
|
@@ -618,7 +622,7 @@ function getCellValue(val) {
|
|
|
618
622
|
*/
|
|
619
623
|
function getItemTooltipFormatter(data, formatCellValue, opts) {
|
|
620
624
|
return (params) => {
|
|
621
|
-
let title = '', subtitle = '', valFormatted = '',
|
|
625
|
+
let title = '', subtitle = '', valFormatted = '', percentVal = '';
|
|
622
626
|
const showSerieName = opts?.showSerieName ?? true;
|
|
623
627
|
const row = params.value;
|
|
624
628
|
const dimension = data.dimensions[params.seriesIndex + 1];
|
|
@@ -628,9 +632,30 @@ function getItemTooltipFormatter(data, formatCellValue, opts) {
|
|
|
628
632
|
const rawValue = (row && typeof row === 'object') ? row[dimensionName] : params.value;
|
|
629
633
|
const serieName = showSerieName ? `${params.marker} ${params.seriesName}<br/ >` : '';
|
|
630
634
|
title = params.name || (row && typeof row === 'object' ? row.category : '');
|
|
631
|
-
subtitle =
|
|
635
|
+
subtitle = serieName;
|
|
632
636
|
valFormatted = formatCellValue(Number(rawValue ?? 0), dimensionName);
|
|
633
|
-
|
|
637
|
+
// pie/funnel series
|
|
638
|
+
if (params.percent != undefined) {
|
|
639
|
+
percentVal = ` (${params.percent}%)`;
|
|
640
|
+
if (data.dimensions.length <= 2) {
|
|
641
|
+
subtitle = '';
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
// sankey
|
|
645
|
+
if (params.dataType != undefined) {
|
|
646
|
+
const dataType = params.dataType;
|
|
647
|
+
subtitle = `${params.marker}<br/>`;
|
|
648
|
+
if (dataType === 'edge') {
|
|
649
|
+
const sourceName = params.data.source.split('___')[0];
|
|
650
|
+
const targetName = params.data.target.split('___')[0];
|
|
651
|
+
title = `${sourceName} → ${targetName}`;
|
|
652
|
+
valFormatted = formatCellValue(Number(params.value ?? 0), dimensionName);
|
|
653
|
+
}
|
|
654
|
+
else if (dataType === 'node') {
|
|
655
|
+
title = params.name.split('___')[0];
|
|
656
|
+
valFormatted = formatCellValue(Number(params.value ?? 0), dimensionName);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
634
659
|
// sunburst treemap
|
|
635
660
|
if (params.treePathInfo) {
|
|
636
661
|
const lastLevelIndex = params.treePathInfo.length - 1, parentNodeIndex = lastLevelIndex - 1;
|
|
@@ -641,7 +666,7 @@ function getItemTooltipFormatter(data, formatCellValue, opts) {
|
|
|
641
666
|
subtitle = `${params.marker} ${oldParentNode.name}<br/ >`;
|
|
642
667
|
}
|
|
643
668
|
}
|
|
644
|
-
return `<div style="text-align: center;"><b>${title}</b><br/>${subtitle}<b>${valFormatted}</b>${
|
|
669
|
+
return `<div style="text-align: center;"><b>${title}</b><br/>${subtitle}<b>${valFormatted}</b>${percentVal}</div>`;
|
|
645
670
|
};
|
|
646
671
|
}
|
|
647
672
|
/**
|
|
@@ -1063,6 +1088,21 @@ class VSECDirector {
|
|
|
1063
1088
|
this.builder.addTooltip(data, overrides.tooltip);
|
|
1064
1089
|
// this.builder.addLegend();
|
|
1065
1090
|
}
|
|
1091
|
+
makeSankey(data, overrides, opts = {}) {
|
|
1092
|
+
const { valueFormatter = undefined, palette = undefined, colorResolver = undefined, } = opts;
|
|
1093
|
+
this.builder.reset();
|
|
1094
|
+
// El orden importa, primero callbacks y despues componentes.
|
|
1095
|
+
this.builder.setValueFormatter(valueFormatter);
|
|
1096
|
+
this.builder.setPalette(palette);
|
|
1097
|
+
this.builder.setColorResolver(colorResolver);
|
|
1098
|
+
const product = this.builder.baseProduct;
|
|
1099
|
+
const seriesOverrides = merge$1({}, product.baseOptions.series, overrides[product.chartKey].series);
|
|
1100
|
+
// chart components
|
|
1101
|
+
this.builder.addCommons();
|
|
1102
|
+
const layoutOpts = {};
|
|
1103
|
+
this.builder.addSeries(data, seriesOverrides, layoutOpts);
|
|
1104
|
+
this.builder.addTooltip(data, overrides.tooltip);
|
|
1105
|
+
}
|
|
1066
1106
|
}
|
|
1067
1107
|
|
|
1068
1108
|
/**
|
|
@@ -2357,6 +2397,203 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2357
2397
|
], 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"] }]
|
|
2358
2398
|
}] });
|
|
2359
2399
|
|
|
2400
|
+
/**
|
|
2401
|
+
* SankeyBuilder
|
|
2402
|
+
*
|
|
2403
|
+
* Builder concreto para el gráfico Sankey (diagrama de flujos de izquierda a derecha).
|
|
2404
|
+
*/
|
|
2405
|
+
class SankeyBuilder {
|
|
2406
|
+
baseProduct;
|
|
2407
|
+
valueFormatter = (value) => value.toLocaleString();
|
|
2408
|
+
palette = [];
|
|
2409
|
+
colorResolver;
|
|
2410
|
+
result = {};
|
|
2411
|
+
constructor(baseProduct) {
|
|
2412
|
+
this.baseProduct = baseProduct;
|
|
2413
|
+
}
|
|
2414
|
+
reset() {
|
|
2415
|
+
this.result = {};
|
|
2416
|
+
}
|
|
2417
|
+
addSeries(data, overrides) {
|
|
2418
|
+
if (!data || !data.source || data.source.length === 0) {
|
|
2419
|
+
return;
|
|
2420
|
+
}
|
|
2421
|
+
// Identificar medidas (todas las dimensiones excepto 'category')
|
|
2422
|
+
const measureKeys = data.dimensions
|
|
2423
|
+
.filter((d) => d.name !== "category")
|
|
2424
|
+
.map((d) => d.name);
|
|
2425
|
+
// Función auxiliar para sumarizar valores de medidas en caso de haber más de una
|
|
2426
|
+
const getNodeValue = (node) => {
|
|
2427
|
+
return measureKeys.reduce((sum, key) => sum + (Number(node[key]) || 0), 0);
|
|
2428
|
+
};
|
|
2429
|
+
const nodesMap = new Map();
|
|
2430
|
+
const linksMap = new Map();
|
|
2431
|
+
// Función recursiva para aplanar datos jerárquicos a nodos y enlaces
|
|
2432
|
+
const traverse = (nodeList, level, parentId) => {
|
|
2433
|
+
for (const node of nodeList) {
|
|
2434
|
+
const category = node.category;
|
|
2435
|
+
const currentId = `${category}___${level}`;
|
|
2436
|
+
const value = getNodeValue(node);
|
|
2437
|
+
nodesMap.set(currentId, (nodesMap.get(currentId) || 0) + value);
|
|
2438
|
+
if (parentId) {
|
|
2439
|
+
const linkKey = `${parentId}--->${currentId}`;
|
|
2440
|
+
if (linksMap.has(linkKey)) {
|
|
2441
|
+
linksMap.get(linkKey).value += value;
|
|
2442
|
+
}
|
|
2443
|
+
else {
|
|
2444
|
+
linksMap.set(linkKey, {
|
|
2445
|
+
source: parentId,
|
|
2446
|
+
target: currentId,
|
|
2447
|
+
value: value,
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
if (node.children && node.children.length > 0) {
|
|
2452
|
+
traverse(node.children, level + 1, currentId);
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
};
|
|
2456
|
+
// Comenzar el recorrido en el nivel 0
|
|
2457
|
+
traverse(data.source, 0);
|
|
2458
|
+
// al menos un nivel de links para dibujar.
|
|
2459
|
+
if (linksMap.size === 0)
|
|
2460
|
+
return;
|
|
2461
|
+
// Mapear nodos acumulados a la estructura requerida por ECharts (name y opcionalmente color, sin value redundante)
|
|
2462
|
+
const nodes = Array.from(nodesMap.keys()).map((currentId) => {
|
|
2463
|
+
const category = currentId.split("___")[0];
|
|
2464
|
+
const nodeItem = {
|
|
2465
|
+
name: currentId,
|
|
2466
|
+
};
|
|
2467
|
+
if (this.colorResolver) {
|
|
2468
|
+
const color = this.colorResolver({ name: category, data: nodeItem });
|
|
2469
|
+
if (color) {
|
|
2470
|
+
nodeItem.itemStyle = { color };
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
return nodeItem;
|
|
2474
|
+
});
|
|
2475
|
+
const dynamicSerieOptions = {
|
|
2476
|
+
type: "sankey",
|
|
2477
|
+
orient: "horizontal", // De izquierda a derecha
|
|
2478
|
+
draggable: true,
|
|
2479
|
+
emphasis: {
|
|
2480
|
+
focus: "adjacency",
|
|
2481
|
+
},
|
|
2482
|
+
lineStyle: {
|
|
2483
|
+
color: "source",
|
|
2484
|
+
opacity: 0.25,
|
|
2485
|
+
curveness: 0.5,
|
|
2486
|
+
},
|
|
2487
|
+
label: {
|
|
2488
|
+
show: true,
|
|
2489
|
+
position: "right",
|
|
2490
|
+
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif",
|
|
2491
|
+
fontSize: 10,
|
|
2492
|
+
formatter: (params) => {
|
|
2493
|
+
// Remover el sufijo de nivel de la etiqueta visual
|
|
2494
|
+
return params.name.split("___")[0];
|
|
2495
|
+
},
|
|
2496
|
+
},
|
|
2497
|
+
roam: true,
|
|
2498
|
+
data: nodes,
|
|
2499
|
+
links: Array.from(linksMap.values()),
|
|
2500
|
+
};
|
|
2501
|
+
const serie = merge$1({}, dynamicSerieOptions, overrides);
|
|
2502
|
+
if (this.colorResolver && !serie.itemStyle) {
|
|
2503
|
+
serie.itemStyle = {};
|
|
2504
|
+
}
|
|
2505
|
+
if (this.colorResolver && serie.itemStyle) {
|
|
2506
|
+
serie.itemStyle.color = this.colorResolver;
|
|
2507
|
+
}
|
|
2508
|
+
this.result.series = serie;
|
|
2509
|
+
}
|
|
2510
|
+
addTooltip(data, overrides) {
|
|
2511
|
+
merge$1(overrides, {
|
|
2512
|
+
formatter: getTooltipFormatter(overrides.trigger || 'item', data, this.valueFormatter),
|
|
2513
|
+
});
|
|
2514
|
+
const tooltip = getTooltipOptions(overrides);
|
|
2515
|
+
this.result.tooltip = tooltip;
|
|
2516
|
+
}
|
|
2517
|
+
addPolar() { }
|
|
2518
|
+
addXAxis(data, overrides, type) { }
|
|
2519
|
+
addYAxis(data, overrides, type) { }
|
|
2520
|
+
addRadiusAxis(data, overrides) { }
|
|
2521
|
+
addAngleAxis(data, overrides) { }
|
|
2522
|
+
addLegend() { }
|
|
2523
|
+
addCommons() {
|
|
2524
|
+
const opts = {
|
|
2525
|
+
palette: this.palette,
|
|
2526
|
+
};
|
|
2527
|
+
merge$1(this.result, getCommons(opts));
|
|
2528
|
+
}
|
|
2529
|
+
addGraphic() { }
|
|
2530
|
+
getResult() {
|
|
2531
|
+
return this.result;
|
|
2532
|
+
}
|
|
2533
|
+
setValueFormatter(formatter) {
|
|
2534
|
+
if (formatter) {
|
|
2535
|
+
this.valueFormatter = formatter;
|
|
2536
|
+
}
|
|
2537
|
+
}
|
|
2538
|
+
setPalette(palette) {
|
|
2539
|
+
if (palette) {
|
|
2540
|
+
this.palette = palette;
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
setColorResolver(resolver) {
|
|
2544
|
+
if (resolver) {
|
|
2545
|
+
this.colorResolver = resolver;
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
class EchartsSankeyComponent extends BaseEchartsComponent {
|
|
2551
|
+
baseSeriesOptions = {
|
|
2552
|
+
type: 'sankey',
|
|
2553
|
+
orient: 'horizontal',
|
|
2554
|
+
draggable: true,
|
|
2555
|
+
emphasis: {
|
|
2556
|
+
focus: 'adjacency'
|
|
2557
|
+
},
|
|
2558
|
+
lineStyle: {
|
|
2559
|
+
color: 'source',
|
|
2560
|
+
opacity: 0.25,
|
|
2561
|
+
curveness: 0.5
|
|
2562
|
+
},
|
|
2563
|
+
label: {
|
|
2564
|
+
show: true,
|
|
2565
|
+
position: 'right',
|
|
2566
|
+
fontFamily: "'Inter', 'Roboto', 'Open Sans', sans-serif",
|
|
2567
|
+
fontSize: 10
|
|
2568
|
+
}
|
|
2569
|
+
};
|
|
2570
|
+
baseProduct = {
|
|
2571
|
+
chartKey: 'sankey',
|
|
2572
|
+
baseOptions: {
|
|
2573
|
+
series: this.baseSeriesOptions,
|
|
2574
|
+
},
|
|
2575
|
+
};
|
|
2576
|
+
builder = new SankeyBuilder(this.baseProduct);
|
|
2577
|
+
director = new VSECDirector(this.builder);
|
|
2578
|
+
make() {
|
|
2579
|
+
const makeOpts = {
|
|
2580
|
+
palette: this.palette,
|
|
2581
|
+
colorResolver: this.colorResolver,
|
|
2582
|
+
valueFormatter: this.valueFormatter,
|
|
2583
|
+
};
|
|
2584
|
+
this.director.makeSankey(this.data, this.optionsOverrides, makeOpts);
|
|
2585
|
+
}
|
|
2586
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsSankeyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
|
|
2587
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.19", type: EchartsSankeyComponent, isStandalone: true, selector: "vs-echarts-sankey", 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></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"] }] });
|
|
2588
|
+
}
|
|
2589
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImport: i0, type: EchartsSankeyComponent, decorators: [{
|
|
2590
|
+
type: Component,
|
|
2591
|
+
args: [{ selector: 'vs-echarts-sankey', standalone: true, imports: [
|
|
2592
|
+
CommonModule,
|
|
2593
|
+
NgxEchartsDirective,
|
|
2594
|
+
], 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></div>\n", styles: [".echarts-container{width:100%;height:100%;position:relative}\n"] }]
|
|
2595
|
+
}] });
|
|
2596
|
+
|
|
2360
2597
|
// Interfaces de Inputs de Base EChart Component //
|
|
2361
2598
|
|
|
2362
2599
|
;
|
|
@@ -2371,5 +2608,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.19", ngImpo
|
|
|
2371
2608
|
* Generated bundle index. Do not edit.
|
|
2372
2609
|
*/
|
|
2373
2610
|
|
|
2374
|
-
export { BaseEchartsComponent, EChartsAreaComponent, EChartsAreaStackComponent, EChartsBarStackedComponent, EChartsBarStackedRadialComponent, EChartsHBarComponent, EChartsHBarStackedComponent, EChartsSunburstComponent, EchartsBarComponent, EchartsFunnelComponent, EchartsLineComponent, EchartsPieComponent, EchartsRingComponent, EchartsScatterComponent, defaultOptionsOverrides, initializeEcharts, provideVSEcharts };
|
|
2611
|
+
export { BaseEchartsComponent, EChartsAreaComponent, EChartsAreaStackComponent, EChartsBarStackedComponent, EChartsBarStackedRadialComponent, EChartsHBarComponent, EChartsHBarStackedComponent, EChartsSunburstComponent, EchartsBarComponent, EchartsFunnelComponent, EchartsLineComponent, EchartsPieComponent, EchartsRingComponent, EchartsSankeyComponent, EchartsScatterComponent, defaultOptionsOverrides, initializeEcharts, provideVSEcharts };
|
|
2375
2612
|
//# sourceMappingURL=visionaris-bruno-vs-echarts.mjs.map
|