Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | 1x 1x 1x 1x 1x 1x 1x | import {
AfterViewInit,
ChangeDetectionStrategy,
Component,
DOCUMENT,
ElementRef,
inject,
Input,
OnChanges,
ViewChild,
} from '@angular/core';
import { IChartInputChanges } from '../../interfaces/chart-component.interface';
import { IRadarChartDataNode, IRadarChartOptions } from '../../interfaces/radar-chart.interface';
import { D3_CHART_FACTORY } from '../../providers/d3-chart-factory.provider';
import { defaultRadarChartConfig } from '../../util/radar-chart.util';
import { AppD3ChartBase } from '../_base/chart.base';
type TRadarData = IRadarChartDataNode[][];
type TRadarOptions = Partial<IRadarChartOptions>;
/** The radar chart component. */
@Component({
selector: 'app-radar-chart',
templateUrl: './radar-chart.component.html',
styleUrls: ['./radar-chart.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
})
export class AppRadarChartComponent extends AppD3ChartBase<TRadarData, TRadarOptions> implements AfterViewInit, OnChanges {
private readonly doc = inject(DOCUMENT);
private readonly factory = inject(D3_CHART_FACTORY);
/** The chart id. */
@Input() public chartId = 'radar-0';
/** The chart data. */
@Input() public data: TRadarData = [[]];
/** The chart options. */
@Input() public options: TRadarOptions = {};
/** D3 chart view child reference. */
@ViewChild('container') public readonly container?: ElementRef<HTMLDivElement>;
constructor() {
super();
}
/** The chart options constructor. */
protected chartOptions(): TRadarOptions {
const xsOffset = 500;
const smOffset = 800;
const mdOffset = 1024;
const labelFactorDefault = 1.15;
const labelFactorMd = 1.15;
const labelFactorSm = 1.15;
const labelFactorXs = 1.4;
const wrapWidthDefault = 85;
const wrapWidthMd = 80;
const wrapWidthXs = 70;
const bodyWidthAdjustment = 10;
const width = Math.min(
this.options.width ?? defaultRadarChartConfig.width,
this.doc.body.clientWidth - defaultRadarChartConfig.margin.left - defaultRadarChartConfig.margin.right - bodyWidthAdjustment,
);
const height = Math.min(
width,
this.doc.body.clientHeight - defaultRadarChartConfig.margin.top - defaultRadarChartConfig.margin.bottom - bodyWidthAdjustment,
);
const labelFactor =
width <= xsOffset ? labelFactorXs : width <= smOffset ? labelFactorSm : width <= mdOffset ? labelFactorMd : labelFactorDefault;
const labelTextWrapWidth = width <= xsOffset ? wrapWidthXs : width <= mdOffset ? wrapWidthMd : wrapWidthDefault;
const options: TRadarOptions = {
width,
height,
maxValue: this.data[0].reduce((accumulator, item) => (item.value > accumulator ? item.value : accumulator), 0) + 1,
levels: 5,
roundStrokes: true,
labelFactor,
labelTextWrapWidth,
...this.options,
};
return options;
}
/** Draws the chart. */
protected drawChart(): void {
if (typeof this.container !== 'undefined') {
const options = this.chartOptions();
this.factory.drawRadarChart(this.container, this.data, options);
}
}
/** Actually draws the chart after the component view is initialized. */
public ngAfterViewInit(): void {
this.drawChart();
}
/** Redraws the chart on changes. */
public ngOnChanges(changes: IChartInputChanges): void {
const currentValue: TRadarData = changes.data?.currentValue;
const options: TRadarOptions = changes.options?.currentValue;
if ((typeof currentValue !== 'undefined' && currentValue !== null) || (typeof options !== 'undefined' && options !== null)) {
this.drawChart();
}
}
}
|