name: delon-chart description: ‘@delon/chart 技能 - 基于 G2Plot 的企业级图表组件,用于 ng-events 建筑工地进度跟踪系统。’
@delon/chart - 企业级图表组件
触发模式:“chart”, “graph”, “visualization”, “@delon/chart”, “G2Plot”, “G2”
概述
@delon/chart 提供基于 G2Plot 构建的企业级图表组件,用于在 ng-alain 应用程序中进行数据可视化。
包: @delon/chart@20.1.0
依赖项: @ant-design/charts (G2Plot 包装器)
核心组件
1. chart-card - 图表卡片容器
import { ChartCardComponent } from '@delon/chart/chart-card';
<chart-card
[title]="'进度统计'"
[total]="totalTasks()"
[action]="action"
[footer]="footer"
>
<trend flag="up" style="margin-right: 16px;">
<span>周增长</span><span>12%</span>
</trend>
<trend flag="down">
<span>日增长</span><span>11%</span>
</trend>
</chart-card>
功能:
- 标题、总计、操作、页脚插槽
- 集成趋势指示器
- 响应式布局
- 加载状态
2. g2-bar - 条形图
import { G2BarComponent } from '@delon/chart/bar';
@Component({
standalone: true,
imports: [G2BarComponent],
template: `
<g2-bar
[data]="barData()"
[height]="300"
[padding]="[20, 40, 50, 40]"
/>
`
})
export class TaskChartComponent {
barData = signal([
{ x: '待办', y: 12 },
{ x: '进行中', y: 8 },
{ x: '已完成', y: 25 }
]);
}
选项:
height(数字) - 图表高度(像素)padding(数字数组) - [上, 右, 下, 左]color(字符串) - 条形颜色autoLabel(布尔值) - 自动标签定位
3. g2-mini-bar - 迷你条形图(迷你图)
<g2-mini-bar
[data]="miniData()"
[height]="50"
[color]="'#1890ff'"
/>
miniData = signal([
{ x: '2024-01', y: 5 },
{ x: '2024-02', y: 8 },
{ x: '2024-03', y: 12 }
]);
4. g2-pie - 饼图/环形图
import { G2PieComponent } from '@delon/chart/pie';
<g2-pie
[data]="pieData()"
[height]="300"
[hasLegend]="true"
[subTitle]="'总任务数'"
[total]="totalTasks()"
[inner]="0.8"
/>
pieData = signal([
{ x: '待办', y: 12 },
{ x: '进行中', y: 8 },
{ x: '已完成', y: 25 }
]);
选项:
inner(数字) - 0-1, 0=饼图, >0=环形图hasLegend(布尔值) - 显示图例subTitle(字符串) - 中心副标题total(字符串) - 中心总计显示
5. g2-radar - 雷达图
import { G2RadarComponent } from '@delon/chart/radar';
<g2-radar
[data]="radarData()"
[height]="300"
[hasLegend]="true"
/>
radarData = signal([
{ name: '设计', label: '计划', value: 85 },
{ name: '设计', label: '执行', value: 70 },
{ name: '开发', label: '计划', value: 90 },
{ name: '开发', label: '执行', value: 80 }
]);
6. timeline - 时间线图表
import { TimelineComponent } from '@delon/chart/timeline';
<timeline
[data]="timelineData()"
[title]="'施工进度'"
[maxAxis]="5"
/>
timelineData = signal([
{ x: new Date('2024-01-01'), y1: 10, y2: 20 },
{ x: new Date('2024-02-01'), y1: 15, y2: 25 },
{ x: new Date('2024-03-01'), y1: 20, y2: 30 }
]);
7. trend - 趋势指示器
import { TrendComponent } from '@delon/chart/trend';
<trend flag="up">
<span>周增长</span>
<span class="pl-sm">12%</span>
</trend>
<trend flag="down" colorful="false">
<span>日增长</span>
<span class="pl-sm">11%</span>
</trend>
标志: up | down
彩色: true (绿/红) | false (灰)
实际示例
带图表的仪表板统计
import { Component, signal, computed, inject } from '@angular/core';
import { ChartCardComponent } from '@delon/chart/chart-card';
import { G2BarComponent } from '@delon/chart/bar';
import { G2PieComponent } from '@delon/chart/pie';
import { TrendComponent } from '@delon/chart/trend';
import { TaskService } from '@core/services/task.service';
@Component({
selector: 'app-dashboard',
standalone: true,
imports: [
ChartCardComponent,
G2BarComponent,
G2PieComponent,
TrendComponent
],
template: `
<div nz-row [nzGutter]="24">
<div nz-col [nzXl]="6" [nzLg]="12" [nzMd]="12" [nzSm]="24">
<chart-card
[title]="'总任务数'"
[total]="totalTasks()"
contentHeight="46px"
>
<trend flag="up" style="margin-right: 16px;">
<span>周增长</span><span>{{ weeklyGrowth() }}%</span>
</trend>
</chart-card>
</div>
<div nz-col [nzSpan]="24">
<nz-card [nzTitle]="'任务状态分布'">
<g2-bar
[data]="taskStatusData()"
[height]="300"
[padding]="[20, 40, 50, 60]"
/>
</nz-card>
</div>
<div nz-col [nzSpan]="12">
<nz-card [nzTitle]="'任务类型比例'">
<g2-pie
[data]="taskTypeData()"
[height]="300"
[hasLegend]="true"
[inner]="0.6"
[total]="totalTasks()"
/>
</nz-card>
</div>
</div>
`
})
export class DashboardComponent {
private taskService = inject(TaskService);
// 用于响应式数据的信号
tasks = this.taskService.tasks;
totalTasks = computed(() => this.tasks().length);
weeklyGrowth = computed(() => {
// 计算增长百分比
const thisWeek = this.tasks().filter(t =>
this.isThisWeek(t.createdAt)
).length;
const lastWeek = this.tasks().filter(t =>
this.isLastWeek(t.createdAt)
).length;
return lastWeek > 0 ?
Math.round((thisWeek - lastWeek) / lastWeek * 100) : 0;
});
taskStatusData = computed(() => [
{ x: '待办', y: this.tasks().filter(t => t.status === 'pending').length },
{ x: '进行中', y: this.tasks().filter(t => t.status === 'in-progress').length },
{ x: '已完成', y: this.tasks().filter(t => t.status === 'completed').length }
]);
taskTypeData = computed(() => [
{ x: '设计', y: this.tasks().filter(t => t.type === 'design').length },
{ x: '开发', y: this.tasks().filter(t => t.type === 'development').length },
{ x: '测试', y: this.tasks().filter(t => t.type === 'testing').length }
]);
private isThisWeek(date: Date): boolean {
const now = new Date();
const weekStart = new Date(now.setDate(now.getDate() - now.getDay()));
return date >= weekStart;
}
private isLastWeek(date: Date): boolean {
const now = new Date();
const weekStart = new Date(now.setDate(now.getDate() - now.getDay() - 7));
const weekEnd = new Date(now.setDate(now.getDate() - now.getDay()));
return date >= weekStart && date < weekEnd;
}
}
最佳实践
1. 使用信号实现响应式图表
✅ 推荐:
chartData = computed(() =>
this.tasks().map(t => ({ x: t.name, y: t.value }))
);
❌ 不推荐:
chartData: any[] = [];
ngOnInit() {
this.taskService.getTasks().subscribe(tasks => {
this.chartData = tasks.map(t => ({ x: t.name, y: t.value }));
});
}
2. 响应式图表高度
✅ 推荐:
@Component({
template: `
<g2-bar
[data]="data()"
[height]="isMobile() ? 200 : 300"
/>
`
})
3. 加载状态
✅ 推荐:
@if (loading()) {
<nz-spin nzSimple />
} @else if (chartData().length > 0) {
<g2-bar [data]="chartData()" />
} @else {
<nz-empty nzNotFoundContent="没有数据" />
}
性能提示
- 数据转换: 在计算信号中转换数据,不要在模板中转换
- 图表复用: 使用不同的数据属性复用图表组件
- 懒加载: 仅在需要时加载图表模块
- 高度优化: 使用固定高度以获得更好的性能
- 数据限制: 限制图表数据点(建议条形图/饼图 < 100)
集成检查清单
- [ ] 安装 @delon/chart@20.1.0
- [ ] 在独立组件中导入图表组件
- [ ] 使用信号实现响应式图表数据
- [ ] 处理加载和空状态
- [ ] 设置响应式图表高度
- [ ] 为图表数据添加适当的 TypeScript 类型
- [ ] 使用空/大数据集测试
- [ ] 使用 computed() 优化数据转换
反模式
❌ 直接修改图表数据:
this.chartData.push({ x: 'new', y: 10 }); // 不会触发变更检测
✅ 使用信号更新:
this.chartData.update(data => [...data, { x: 'new', y: 10 }]);
❌ 模板中的复杂逻辑:
<g2-bar [data]="tasks.filter(t => t.status === 'completed').map(t => ({x: t.name, y: t.value}))" />
✅ 使用计算信号:
completedTasksData = computed(() =>
this.tasks()
.filter(t => t.status === 'completed')
.map(t => ({ x: t.name, y: t.value }))
);
交叉参考
- ng-alain-component - ST 表格用于数据表
- delon-theme - 页面布局和主题定制
- angular-component - 用于响应式图表的信号和计算
.github/instructions/angular.instructions.md- Angular 20 模式
包信息
- 版本: 20.1.0
- 仓库: https://github.com/ng-alain/delon
- 文档: https://ng-alain.com/chart
版本: 1.0
创建日期: 2025-12-25
维护者: ng-events(GigHub) 开发团队