Skip to content

Commit 0ecc116

Browse files
Copilotivanvpetrov
andcommitted
feat(extras): auto-hide chart y-axis when no series data
Co-authored-by: ivanvpetrov <110455887+ivanvpetrov@users.noreply.github.com> Agent-Logs-Url: https://github.com/IgniteUI/igniteui-angular/sessions/0938b32f-510b-4e57-aa3b-bc186cb5b085
1 parent 8ddcef2 commit 0ecc116

3 files changed

Lines changed: 66 additions & 8 deletions

File tree

projects/igniteui-angular-extras/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,15 @@ export class AppModule { }
4848
</igx-grid>
4949
```
5050

51+
When integrating charts with dynamic filtering scenarios, you can enable automatic Y-axis hiding when there is no numeric data for the charted series:
52+
53+
```html
54+
<igx-grid #grid1 igxChartIntegration [autoHideYAxisWhenNoData]="true"
55+
igxConditionalFormatting igxContextMenu
56+
[autoGenerate]="true" [paging]="true" [data]="localData" >
57+
</igx-grid>
58+
```
59+
5160
### After Version 19.x
5261

5362
Since version 19.x, Ignite UI for Angular Extras has adopted standalone components and directives, removing the need to add `IgxExtrasModule` to your `app.module.ts`. You can now directly import the required components and directives as standalone elements.

projects/igniteui-angular-extras/src/lib/directives/chart-integration/chart-integration.directive.spec.ts

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -200,9 +200,6 @@ describe('IgxChartIntegrationDirective', () => {
200200

201201
describe('disableCharts and chartData interaction', () => {
202202
it('should not include disabled chart types in emitted chartsForCreation', () => {
203-
let emittedArgs: IDeterminedChartTypesArgs;
204-
directive.chartTypesDetermined.subscribe((args) => emittedArgs = args);
205-
206203
directive.disableCharts([CHART_TYPE.Pie]);
207204

208205
// chartsAvailability is updated but chartsForCreation only populated when chartData is set
@@ -291,6 +288,48 @@ describe('IgxChartIntegrationDirective', () => {
291288
expect(result).toBeUndefined();
292289
expect(emittedChart).toBeUndefined(); // chart is undefined, but event still emits
293290
});
291+
292+
it('should auto-hide y-axis and skip series creation when autoHideYAxisWhenNoData is enabled and no numeric values exist', () => {
293+
directive.autoHideYAxisWhenNoData = true;
294+
directive.chartData = [{ name: 'A', value: Number.NaN }, { name: 'B', value: undefined as any }];
295+
296+
const axisAddArgs: any[] = [];
297+
const seriesAddSpy = jasmine.createSpy('seriesAdd');
298+
const mockChart = {
299+
series: { count: 0, clear: () => {}, add: seriesAddSpy },
300+
axes: {
301+
count: 0,
302+
clear: () => {},
303+
add: (axis) => axisAddArgs.push(axis)
304+
}
305+
} as any;
306+
307+
directive.chartFactory(CHART_TYPE.ColumnGrouped, undefined, mockChart);
308+
309+
expect(seriesAddSpy).not.toHaveBeenCalled();
310+
expect(axisAddArgs[1].labelExtent).toBe(0);
311+
});
312+
313+
it('should keep y-axis visible when autoHideYAxisWhenNoData is enabled and at least one numeric value exists', () => {
314+
directive.autoHideYAxisWhenNoData = true;
315+
directive.chartData = [{ name: 'A', value: Number.NaN }, { name: 'B', value: 10 }];
316+
317+
const axisAddArgs: any[] = [];
318+
const seriesAddSpy = jasmine.createSpy('seriesAdd');
319+
const mockChart = {
320+
series: { count: 0, clear: () => {}, add: seriesAddSpy },
321+
axes: {
322+
count: 0,
323+
clear: () => {},
324+
add: (axis) => axisAddArgs.push(axis)
325+
}
326+
} as any;
327+
328+
directive.chartFactory(CHART_TYPE.ColumnGrouped, undefined, mockChart);
329+
330+
expect(seriesAddSpy).toHaveBeenCalledTimes(1);
331+
expect(axisAddArgs[1].labelExtent).toBeNaN();
332+
});
294333
});
295334

296335
describe('_labelMemberPath fallback', () => {

projects/igniteui-angular-extras/src/lib/directives/chart-integration/chart-integration.directive.ts

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,9 @@ export class IgxChartIntegrationDirective {
8989
@Input()
9090
public defaultLabelMemberPath: string = undefined;
9191

92+
@Input()
93+
public autoHideYAxisWhenNoData = false;
94+
9295
@Input()
9396
public set scatterChartYAxisValueMemberPath(path: string) {
9497
this._scatterChartYAxisValueMemberPath = path;
@@ -282,14 +285,17 @@ export class IgxChartIntegrationDirective {
282285
const customComponentOptions: IChartComponentOptions = this.customChartComponentOptions.get(type) || {};
283286
const customChartOptions = customComponentOptions.chartOptions || {};
284287
const customSeriesModel = customComponentOptions.seriesModel || {};
288+
const valueMemberPathsWithData = this._valueMemberPaths.filter(memberPath => this.hasSeriesData(memberPath));
289+
const valueMemberPathsForSeries = this.autoHideYAxisWhenNoData ? valueMemberPathsWithData : this._valueMemberPaths;
285290
chartComponentOptions.chartOptions = { ...this.dataChartOptions, ...customChartOptions };
286291
if (type.indexOf('Scatter') !== -1) {
287292
this.addScatterChartDataOptions(type, chartComponentOptions);
288293
} else {
289294
chartComponentOptions.seriesModel = { ...this.dataChartSeriesOptionsModel, ...customSeriesModel };
290-
this.setAxisLabelOption(type, chartComponentOptions);
295+
const hideYAxis = this.autoHideYAxisWhenNoData && valueMemberPathsWithData.length === 0;
296+
this.setAxisLabelOption(type, chartComponentOptions, hideYAxis);
291297
const options: IOptions[] = [];
292-
this._valueMemberPaths.forEach(valueMemberPath => {
298+
valueMemberPathsForSeries.forEach(valueMemberPath => {
293299
const dataOptions = {
294300
title: valueMemberPath,
295301
valueMemberPath
@@ -346,13 +352,17 @@ export class IgxChartIntegrationDirective {
346352
return dataRecord;
347353
}
348354

349-
private setAxisLabelOption(type: CHART_TYPE, options: IChartComponentOptions) {
355+
private hasSeriesData(memberPath: string): boolean {
356+
return this._chartData.some(record => Number.isFinite(record[memberPath]));
357+
}
358+
359+
private setAxisLabelOption(type: CHART_TYPE, options: IChartComponentOptions, hideYAxis = false) {
350360
const customOptions = this.customChartComponentOptions.get(type) || {};
351361
if (type.indexOf('Bar') !== -1) {
352362
options.yAxisOptions = Object.assign({
353363
label: this._labelMemberPath,
354364
labelTextColor: null,
355-
labelExtent: NaN,
365+
labelExtent: hideYAxis ? 0 : NaN,
356366
}, customOptions.yAxisOptions);
357367
options.xAxisOptions = Object.assign({
358368
labelTextColor: null,
@@ -366,7 +376,7 @@ export class IgxChartIntegrationDirective {
366376
}, customOptions.xAxisOptions);
367377
options.yAxisOptions = Object.assign({
368378
labelTextColor: null,
369-
labelExtent: NaN,
379+
labelExtent: hideYAxis ? 0 : NaN,
370380
}, customOptions.yAxisOptions);
371381
}
372382
}

0 commit comments

Comments
 (0)