apexchart built in legend 를 사용하지 않고 custom 버튼을 생성한 후 built in legend 와 연결해 보도록 하겠습니다.
chart 컴포넌트 템플릿
<apx-chart
class="block w-full h-full"
[series]="chartOptions.series!"
[chart]="chartOptions.chart!"
[xaxis]="chartOptions.xaxis!"
[dataLabels]="chartOptions.dataLabels!"
[stroke]="chartOptions.stroke!"
[yaxis]="chartOptions.yaxis!"
[responsive]="chartOptions.responsive!"
[legend]="chartOptions.legend"
*ngIf="!isLoading"
>
</apx-chart>
chart 컴포넌트
import {
Component,
HostBinding,
Input,
OnInit,
ViewChild,
} from '@angular/core';
import { CommonModule } from '@angular/common';
import {
ApexAxisChartSeries,
ApexChart,
ApexDataLabels,
ApexLegend,
ApexResponsive,
ApexStroke,
ApexTitleSubtitle,
ApexXAxis,
ApexYAxis,
NgApexchartsModule,
ChartComponent as ApexChartComponent, // as 를 활용해서 자신 컴포넌트 이름 변경
} from 'ng-apexcharts';
export type ChartOptions = {
series: ApexAxisChartSeries;
chart: ApexChart;
xaxis: ApexXAxis;
stroke: ApexStroke;
dataLabels: ApexDataLabels;
yaxis: ApexYAxis;
labels: string[];
legend: ApexLegend;
subtitle: ApexTitleSubtitle;
responsive: ApexResponsive[];
};
@Component({
selector: 'app-chart',
standalone: true,
imports: [CommonModule, NgApexchartsModule],
templateUrl: './chart.component.html',
styleUrls: ['./chart.component.scss'],
})
export class ChartComponent implements OnInit {
// 이름을 변경한 컴포넌트를 viewChild 데코 타입으로 선언하기
@ViewChild(ApexChartComponent) chartComponent!: ApexChartComponent;
@Input() chartOptions!: ChartOptions;
@Input() categories: ApexXAxis['categories'] = [
'1월',
'2월',
'3월',
'4월',
'5월',
'6월',
'7월',
'8월',
'9월',
'10월',
'11월',
'12월',
];
@Input({ required: true }) series!: ApexAxisChartSeries;
isLoading: boolean = true;
@HostBinding('class') class = 'block w-full h-full';
constructor() {}
ngOnInit() {
if (!this.chartOptions) {
this.chartOptions = {
series: this.series,
responsive: [{ breakpoint: undefined, options: {} }],
chart: {
type: 'line',
fontFamily: 'Pretendard',
width: '100%',
height: '100%',
toolbar: {
show: false,
},
zoom: {
enabled: false,
},
},
dataLabels: {
enabled: false,
},
stroke: {
curve: 'straight',
width: 2,
},
subtitle: {
text: 'Price Movements',
align: 'left',
},
labels: ['labels'],
xaxis: {
categories: this.categories,
},
yaxis: {
opposite: false,
},
legend: {
show: false,
},
};
}
}
async ngAfterViewInit() {
setTimeout(() => {
this.isLoading = false;
}, 1000);
}
}
차트 컴포넌트 호출
<app-chart #salesChart [series]="salesSeries"></app-chart>
차트 컴포넌트를 호출하는 컴포넌트
// 차트 컴포넌트 타입으로 viewchild 변수 선언
@ViewChild('salesChart') salesChartComponent!: ChartComponent;
// 예시 용도 시리즈 데이터
salesSeries: ApexAxisChartSeries = [
{
name: '2023',
data: [
1000, 1100, 1200, 1300, 1200, 1100, 1000, 1200, 1300, 1400, 1300, 1350,
],
color: '#22C55E',
},
{
name: '2022',
data: [10, 50, 100, 110, 120, 120, 130, 140, 150, 165, 170, 350],
color: '#a855f7',
},
{
name: '2021',
data: [1000, 900, 700, 650, 600, 650, 700, 705, 700, 600, 750, 900],
color: '#eab308',
},
{
name: '2020',
data: [
1500, 1300, 1200, 1100, 1000, 900, 1000, 1100, 1200, 1300, 1400, 1500,
],
color: '#3b82f6',
},
];
// 클릭 시 토글 핸들링 메소드
handleSalesChartSegments(toBeShown?: string) {
const seriesNames = this.salesSeries.map((series) => series.name!);
// 전체가 아닌 경우
if (toBeShown) {
for (const name of seriesNames.filter((_name) => _name !== toBeShown)) {
// 자식 컴포넌트에 접근하여 apex 내장 함수를 활용해 원하는 범위만 가리기
this.salesChartComponent.chartComponent.hideSeries(name);
}
// 특정 범위만 보여주기
this.salesChartComponent.chartComponent.showSeries(toBeShown);
// 전체 클릭 시
} else {
for (const name of seriesNames) {
// 전부 보여주기
this.salesChartComponent.chartComponent.showSeries(name);
}
}
}
부모 컴포넌트 템플릿
<div class="flex items-center justify-between">
<lepi-segment>
<!-- 클릭 함수 호출 -->
<lepi-segment-item (click)="handleSalesChartSegments()"
>모두</lepi-segment-item
>
<!-- 클릭 함수 호출 -->
<lepi-segment-item
*ngFor="let series of salesSeries"
(click)="handleSalesChartSegments(series.name)"
>
<div class="flex items-center gap-1">
<div
class="w-3 h-3 rounded-full"
[ngStyle]="{'background-color': series.color}"
></div>
<div>{{series.name}}</div>
</div>
</lepi-segment-item>
</lepi-segment>
<app-select
formControlName="type"
[search]="false"
placeholder="연간 매출"
>
<app-option-group>
<app-option>2023</app-option>
<app-option>2022</app-option>
<app-option>2021</app-option>
<app-option>2020</app-option>
</app-option-group>
</app-select>
</div>
<!-- 차트 컴포넌트 -->
<app-chart #salesChart [series]="salesSeries"></app-chart>
</div>
custom legend 를 활용하여 apexchart 내장 legend 를 활용하는 것과 동일한 효과를 누릴 수 있습니다.