Install any skill in seconds. Free to start, no credit card required.
Get Started Free →@delon/chart skill - G2Plot enterprise charting components with @delon/chart. For ng-events construction site progress tracking system.
.claude/skills/aiskillstore-delon-chart/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 66% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 76% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 70% | 0% |
| case-07 | ✗→✓ | ▲ Improved | 109% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 206% | 0% |
Trigger patterns: "chart", "graph", "visualization", "@delon/chart", "G2Plot", "G2"
@delon/chart provides enterprise-grade charting components built on G2Plot for data visualization in ng-alain applications.
Package: @delon/chart@20.1.0 Dependencies: @ant-design/charts (G2Plot wrapper)
typescriptimport { 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>
Features:
typescriptimport { 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 } ]); }
Options:
height (number) - Chart height in pixelspadding (number]) - top, right, bottom, left]color (string) - Bar colorautoLabel (boolean) - Auto label positioningtypescript<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 } ]);
typescriptimport { 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 } ]);
Options:
inner (number) - 0-1, 0=pie, >0=donuthasLegend (boolean) - Show legendsubTitle (string) - Center subtitletotal (string) - Center total displaytypescriptimport { 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 } ]);
typescriptimport { 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 } ]);
typescriptimport { 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>
Flags: up | down Colorful: true (green/red) | false (gray)
typescriptimport { 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); // Signals for reactive data tasks = this.taskService.tasks; totalTasks = computed(() => this.tasks().length); weeklyGrowth = computed(() => { // Calculate growth percentage 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; } }
✅ DO:
typescriptchartData = computed(() => this.tasks().map(t => ({ x: t.name, y: t.value })) );
❌ DON'T:
typescriptchartData: any[] = []; ngOnInit() { this.taskService.getTasks().subscribe(tasks => { this.chartData = tasks.map(t => ({ x: t.name, y: t.value })); }); }
✅ DO:
typescript@Component({ template: ` <g2-bar [data]="data()" [height]="isMobile() ? 200 : 300" /> ` })
✅ DO:
typescript@if (loading()) { <nz-spin nzSimple /> } @else if (chartData().length > 0) { <g2-bar [data]="chartData()" /> } @else { <nz-empty nzNotFoundContent="沒有資料" /> }
❌ Mutating Chart Data Directly:
typescriptthis.chartData.push({ x: 'new', y: 10 }); // Won't trigger change detection
✅ Use Signal Updates:
typescriptthis.chartData.update(data => [...data, { x: 'new', y: 10 }]);
❌ Complex Logic in Templates:
typescript<g2-bar [data]="tasks.filter(t => t.status === 'completed').map(t => ({x: t.name, y: t.value}))" />
✅ Use Computed Signals:
typescriptcompletedTasksData = computed(() => this.tasks() .filter(t => t.status === 'completed') .map(t => ({ x: t.name, y: t.value })) );
.github/instructions/angular.instructions.md - Angular 20 patternsVersion: 1.0 Created: 2025-12-25 Maintainer: ng-events(GigHub) Development Team
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-05 | pass→pass | 4,453 | 3,957 | -11% | 1 | 1 | 0% | 714 | 3,875 | +443% | 0 | 0 | — |
case-01 | fail→pass | 15,914 | 10,143 | -36% | 1 | 1 | 0% | 3,161 | 5,244 | +66% | 0 | 0 | — |
case-02 | fail→pass | 18,494 | 16,591 | -10% | 1 | 1 | 0% | 3,743 | 6,604 | +76% | 0 | 0 | — |
case-03 | fail→pass | 17,699 | 22,541 | +27% | 1 | 1 | 0% | 3,592 | 6,104 | +70% | 0 | 0 | — |
case-04 | pass→pass | 5,744 | 3,584 | -38% | 1 | 1 | 0% | 1,088 | 3,750 | +245% | 0 | 0 | — |
case-18 | pass→pass | 5,102 | 2,942 | -42% | 1 | 1 | 0% | 770 | 3,458 | +349% | 0 | 0 | — |
case-06 | pass→pass | 8,456 | 4,276 | -49% | 1 | 1 | 0% | 1,444 | 3,898 | +170% | 0 | 0 | — |
case-07 | fail→pass | 11,122 | 5,925 | -47% | 1 | 1 | 0% | 2,019 | 4,218 | +109% | 0 | 0 | — |
case-08 | pass→pass | 5,581 | 4,860 | -13% | 1 | 1 | 0% | 901 | 4,051 | +350% | 0 | 0 | — |
case-09 | fail→pass | 6,997 | 4,145 | -41% | 1 | 1 | 0% | 1,279 | 3,908 | +206% | 0 | 0 | — |
case-10 | pass→pass | 7,938 | 5,812 | -27% | 1 | 1 | 0% | 1,461 | 4,283 | +193% | 0 | 0 | — |
case-11 | pass→pass | 9,397 | 8,179 | -13% | 1 | 1 | 0% | 1,591 | 4,657 | +193% | 0 | 0 | — |
case-12 | fail→pass | 16,327 | 11,823 | -28% | 1 | 1 | 0% | 2,218 | 5,411 | +144% | 0 | 0 | — |
case-13 | pass→pass | 4,540 | 5,069 | +12% | 1 | 1 | 0% | 806 | 3,966 | +392% | 0 | 0 | — |
case-14 | pass→pass | 19,601 | 5,110 | -74% | 1 | 1 | 0% | 1,897 | 3,934 | +107% | 0 | 0 | — |
case-15 | pass→pass | 10,905 | 6,428 | -41% | 1 | 1 | 0% | 1,939 | 4,221 | +118% | 0 | 0 | — |
case-16 | fail→pass | 8,215 | 3,308 | -60% | 1 | 1 | 0% | 1,323 | 3,656 | +176% | 0 | 0 | — |
case-17 | pass→pass | 6,170 | 3,704 | -40% | 1 | 1 | 0% | 989 | 3,769 | +281% | 0 | 0 | — |
case-19 | pass→pass | 5,923 | 5,501 | -7% | 1 | 1 | 0% | 1,059 | 4,153 | +292% | 0 | 0 | — |
case-20 | pass→pass | 15,376 | 14,321 | -7% | 1 | 1 | 0% | 2,831 | 5,893 | +108% | 0 | 0 | — |
case-21 | fail→fail | 14,847 | 14,001 | -6% | 1 | 1 | 0% | 2,527 | 5,643 | +123% | 0 | 0 | — |
case-22 | fail→pass | 12,829 | 14,195 | +11% | 1 | 1 | 0% | 2,344 | 5,629 | +140% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +36 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.