@praxisui/charts 9.0.41 → 9.0.42

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,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": "1.0.0",
3
- "generatedAt": "2026-08-30T07:54:09.799Z",
3
+ "generatedAt": "2026-08-30T12:51:40.847Z",
4
4
  "packageName": "@praxisui/charts",
5
- "packageVersion": "9.0.41",
5
+ "packageVersion": "9.0.42",
6
6
  "sourceRegistry": "praxis-component-registry-ingestion",
7
7
  "sourceRegistryVersion": "1.0.0",
8
8
  "componentCount": 3,
@@ -3,7 +3,7 @@ import { Injectable, Optional, Inject, InjectionToken, input, booleanAttribute,
3
3
  import * as i1 from '@praxisui/core';
4
4
  import { buildApiUrl, API_URL, PraxisI18nService, ComponentMetadataRegistry, SETTINGS_PANEL_BRIDGE, normalizePraxisDataQueryContext, resolvePraxisFilterCriteria, BUILTIN_PAGE_THEME_PRESETS, PraxisIconButtonComponent, normalizePraxisPresentationVisualization, AnalyticsStatsRequestBuilderService, AnalyticsPresentationResolver, providePraxisI18n, ResourceDiscoveryService, SETTINGS_PANEL_DATA, createDefaultTableConfig, PRAXIS_TABLE_DETAIL_INLINE_RENDERERS, DynamicWidgetPageComponent } from '@praxisui/core';
5
5
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { throwError, map, of, isObservable, from, firstValueFrom, timeout, BehaviorSubject, Subscription } from 'rxjs';
6
+ import { throwError, map, finalize, shareReplay, of, isObservable, from, firstValueFrom, timeout, BehaviorSubject, Subscription } from 'rxjs';
7
7
  import * as i1$2 from '@angular/material/tooltip';
8
8
  import { MatTooltipModule } from '@angular/material/tooltip';
9
9
  import * as i1$1 from '@angular/common/http';
@@ -1582,6 +1582,7 @@ class PraxisChartStatsApiService {
1582
1582
  http;
1583
1583
  apiUrl;
1584
1584
  i18n;
1585
+ inFlightByRequest = new Map();
1585
1586
  constructor(http, apiUrl, i18n) {
1586
1587
  this.http = http;
1587
1588
  this.apiUrl = apiUrl;
@@ -1595,9 +1596,42 @@ class PraxisChartStatsApiService {
1595
1596
  }
1596
1597
  const categoryField = this.resolveCategoryField(config, statsRequest);
1597
1598
  const url = this.buildStatsUrl(query.statsPath);
1598
- return this.http
1599
+ return this.executeRequest(url, statsRequest).pipe(map((response) => this.toChartRows(response?.data, statsRequest, categoryField, config)), catchError((error) => this.handleHttpError(error)));
1600
+ }
1601
+ executeRequest(url, statsRequest) {
1602
+ const requestKey = `${url}\u001f${this.stableSerialize(statsRequest)}`;
1603
+ const existing = this.inFlightByRequest.get(requestKey);
1604
+ if (existing) {
1605
+ return existing;
1606
+ }
1607
+ let request;
1608
+ request = this.http
1599
1609
  .post(url, statsRequest)
1600
- .pipe(map((response) => this.toChartRows(response?.data, statsRequest, categoryField, config)), catchError((error) => this.handleHttpError(error)));
1610
+ .pipe(finalize(() => {
1611
+ if (this.inFlightByRequest.get(requestKey) === request) {
1612
+ this.inFlightByRequest.delete(requestKey);
1613
+ }
1614
+ }), shareReplay({ bufferSize: 1, refCount: true }));
1615
+ this.inFlightByRequest.set(requestKey, request);
1616
+ return request;
1617
+ }
1618
+ stableSerialize(value) {
1619
+ return JSON.stringify(this.sortSerializableValue(value));
1620
+ }
1621
+ sortSerializableValue(value) {
1622
+ if (Array.isArray(value)) {
1623
+ return value.map((item) => this.sortSerializableValue(item));
1624
+ }
1625
+ if (value === null || typeof value !== 'object') {
1626
+ return value;
1627
+ }
1628
+ const record = value;
1629
+ return Object.keys(record)
1630
+ .sort()
1631
+ .reduce((sorted, key) => {
1632
+ sorted[key] = this.sortSerializableValue(record[key]);
1633
+ return sorted;
1634
+ }, {});
1601
1635
  }
1602
1636
  toChartRows(response, request, categoryField, config) {
1603
1637
  if (!response) {
@@ -4852,6 +4886,7 @@ class EChartsOptionBuilderService {
4852
4886
  ? [...transformed.slices].reverse()
4853
4887
  : transformed.slices;
4854
4888
  const funnelSeries = {
4889
+ id: config.series[0]?.id,
4855
4890
  type: 'funnel',
4856
4891
  sort: 'none',
4857
4892
  funnelAlign: 'center',
@@ -4882,7 +4917,7 @@ class EChartsOptionBuilderService {
4882
4917
  itemStyle: slice.color ? { color: slice.color } : undefined,
4883
4918
  })),
4884
4919
  };
4885
- return {
4920
+ const baseOption = {
4886
4921
  aria: accessibility,
4887
4922
  backgroundColor: config.theme?.backgroundColor,
4888
4923
  color: palette,
@@ -4896,6 +4931,29 @@ class EChartsOptionBuilderService {
4896
4931
  legend: this.buildLegend(config, legendVisible, 'bottom', textColor),
4897
4932
  series: [funnelSeries],
4898
4933
  };
4934
+ return {
4935
+ baseOption,
4936
+ media: [
4937
+ {
4938
+ query: { maxWidth: 420 },
4939
+ option: {
4940
+ series: [
4941
+ {
4942
+ id: config.series[0]?.id,
4943
+ left: '4%',
4944
+ width: '92%',
4945
+ label: {
4946
+ position: 'inside',
4947
+ align: 'center',
4948
+ width: 180,
4949
+ },
4950
+ labelLine: { show: false },
4951
+ },
4952
+ ],
4953
+ },
4954
+ },
4955
+ ],
4956
+ };
4899
4957
  }
4900
4958
  if (transformed.mode === 'treemap') {
4901
4959
  const labelsVisible = config.series[0]?.labels?.visible ?? true;
package/package.json CHANGED
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "name": "@praxisui/charts",
3
- "version": "9.0.41",
3
+ "version": "9.0.42",
4
4
  "description": "Metadata-driven charts library for Praxis UI Angular with engine adapters and Apache ECharts as the initial renderer.",
5
5
  "peerDependencies": {
6
6
  "@angular/common": "^21.0.0",
7
7
  "@angular/core": "^21.0.0",
8
- "@praxisui/core": "^9.0.41",
8
+ "@praxisui/core": "^9.0.42",
9
9
  "@angular/forms": "^21.0.0",
10
10
  "@angular/material": "^21.0.0",
11
- "@praxisui/table": "^9.0.41",
11
+ "@praxisui/table": "^9.0.42",
12
12
  "rxjs": "~7.8.0"
13
13
  },
14
14
  "dependencies": {
@@ -1083,8 +1083,12 @@ declare class PraxisChartStatsApiService {
1083
1083
  private readonly http;
1084
1084
  private readonly apiUrl;
1085
1085
  private readonly i18n;
1086
+ private readonly inFlightByRequest;
1086
1087
  constructor(http: HttpClient, apiUrl: ApiUrlConfig, i18n: PraxisI18nService);
1087
1088
  execute(event: PraxisChartQueryRequestEvent, config: PraxisChartConfig): Observable<PraxisChartDataRow[]>;
1089
+ private executeRequest;
1090
+ private stableSerialize;
1091
+ private sortSerializableValue;
1088
1092
  private toChartRows;
1089
1093
  private resolveBucketCategory;
1090
1094
  private resolveBooleanBucketCategory;