Изучаю как работают графики в
DevExtreme
на
Angular 17
. Сначала попробовал простой пример графика. Список с телефонами и количеством продажей за некий год. Сам список:
public getPhonesData(): ChartDataItem[] {
return [
{ name: "iPhone 14", count: 5000 },
{ name: "iPhone 14 Pro", count: 5200 },
{ name: "iPhone SE (2023)", count: 3000 },
{ name: "Samsung Galaxy S23", count: 4500 },
{ name: "Samsung Galaxy S23 Ultra", count: 4800 },
{ name: "Samsung Galaxy A54", count: 4000 },
{ name: "Google Pixel 7", count: 3200 },
{ name: "Google Pixel 7 Pro", count: 3500 },
{ name: "Xiaomi Mi 13", count: 2700 },
{ name: "Xiaomi Mi 13 Pro", count: 2900 },
{ name: "OnePlus 11", count: 2100 },
{ name: "Sony Xperia 1 V", count: 1800 },
{ name: "Sony Xperia 5 V", count: 1600 },
{ name: "Huawei P60 Pro", count: 1500 },
{ name: "Oppo Find X6", count: 1300 },
{ name: "Realme GT 3", count: 1200 },
{ name: "Motorola Edge 40", count: 1100 },
{ name: "Asus ROG Phone 7", count: 900 },
{ name: "Nokia G22", count: 800 }
];
}
Компонент:
@Component({
selector: 'app-charts',
standalone: true,
imports: [CommonModule,
DxChartModule],
templateUrl: './charts.component.html',
styleUrl: './charts.component.css'
})
export class ChartsComponent {
constructor(private source: ChartDataSources) {
this.phones = source.getPhonesData();
}
protected phones: ChartDataItem[];
}
@Injectable({
providedIn: 'root'
})
export class ChartDataSources {
public getPhonesData(): ChartDataItem[] {
return [ ... ];
}
}
html
:
<dx-chart [dataSource]="phones">
<dxi-series [valueField]="'name'" [argumentField]="'count'"></dxi-series>
<dxo-legend [visible]="true"></dxo-legend>
<dxo-export [enabled]="true"></dxo-export>
</dx-chart>
По я попробовал вывести более сложный объект, над котором ломаю голову уже пол дня:
public getPhoneSalesData() : PhoneSalesDataItem[] {
return [
{
country: "USA",
statistic: [
{ name: "iPhone 14", count: 5000 },
{ name: "iPhone 14", count: 5001 },
{ name: "iPhone 14 Pro", count: 4500 },
{ name: "iPhone SE (2023)", count: 3000 },
{ name: "Samsung Galaxy S23", count: 4800 },
{ name: "Samsung Galaxy S23 Ultra", count: 4200 },
{ name: "Google Pixel 7", count: 3200 },
{ name: "Google Pixel 7 Pro", count: 2800 },
{ name: "OnePlus 11", count: 2100 },
{ name: "Sony Xperia 1 V", count: 1800 }
]
},
{
country: "Germany",
statistic: [
{ name: "iPhone 14", count: 4000 },
{ name: "iPhone 14 Pro", count: 3700 },
{ name: "Samsung Galaxy S23", count: 4100 },
{ name: "Samsung Galaxy S23 Ultra", count: 3900 },
{ name: "Xiaomi Mi 13", count: 2900 },
{ name: "Xiaomi Mi 13 Pro", count: 2600 },
{ name: "Google Pixel 7", count: 2200 },
{ name: "Huawei P60 Pro", count: 1800 },
{ name: "Oppo Find X6", count: 1700 }
]
},
{
country: "India",
statistic: [
{ name: "Xiaomi Mi 13", count: 3100 },
{ name: "Xiaomi Mi 13 Pro", count: 2900 },
{ name: "Samsung Galaxy A54", count: 3600 },
{ name: "OnePlus 11", count: 3400 },
{ name: "Realme GT 3", count: 2800 },
{ name: "Oppo Find X5", count: 2500 },
{ name: "iPhone 14", count: 3000 },
{ name: "Samsung Galaxy S22", count: 2200 }
]
},
{
country: "China",
statistic: [
{ name: "Huawei P60 Pro", count: 3400 },
{ name: "Huawei Mate 60", count: 3200 },
{ name: "Oppo Find X6", count: 3100 },
{ name: "Xiaomi Mi 13", count: 3300 },
{ name: "Xiaomi Mi 13 Pro", count: 3500 },
{ name: "Realme GT 3", count: 2800 },
{ name: "OnePlus 11", count: 2700 },
{ name: "iPhone 14", count: 2900 }
]
},
{
country: "Japan",
statistic: [
{ name: "Sony Xperia 1 V", count: 2500 },
{ name: "Sony Xperia 5 V", count: 2300 },
{ name: "iPhone 14", count: 3000 },
{ name: "iPhone 14 Pro", count: 2900 },
{ name: "Google Pixel 7", count: 2000 },
{ name: "Samsung Galaxy S23", count: 2200 },
{ name: "Xiaomi Mi 13", count: 1800 }
]
},
{
country: "UK",
statistic: [
{ name: "iPhone 14", count: 2800 },
{ name: "iPhone 14 Pro", count: 2600 },
{ name: "Samsung Galaxy S23", count: 2300 },
{ name: "Google Pixel 7", count: 1900 },
{ name: "OnePlus 11", count: 2000 },
{ name: "Sony Xperia 1 V", count: 1700 },
{ name: "Realme GT 3", count: 1600 }
]
},
{
country: "France",
statistic: [
{ name: "Samsung Galaxy S23", count: 2500 },
{ name: "Samsung Galaxy S23 Ultra", count: 2300 },
{ name: "iPhone 14", count: 2400 },
{ name: "iPhone 14 Pro", count: 2200 },
{ name: "Asus ROG Phone 7", count: 2000 },
{ name: "Google Pixel 7", count: 1800 },
{ name: "Xiaomi Mi 13", count: 1900 }
]
},
{
country: "Brazil",
statistic: [
{ name: "Motorola Edge 40", count: 1700 },
{ name: "Samsung Galaxy A54", count: 1600 },
{ name: "Xiaomi Mi 13", count: 1500 },
{ name: "iPhone SE (2023)", count: 1400 },
{ name: "Oppo Find X5", count: 1300 }
]
},
{
country: "UA",
statistic: [
{ name: "Nokia G22", count: 900 },
{ name: "Samsung Galaxy A54", count: 1100 },
{ name: "iPhone 14", count: 1000 },
{ name: "Xiaomi Mi 13", count: 950 },
{ name: "Motorola Edge 40", count: 870 }
]
},
{
country: "South Korea",
statistic: [
{ name: "Samsung Galaxy S23", count: 3400 },
{ name: "Samsung Galaxy S23 Ultra", count: 3200 },
{ name: "Samsung Galaxy Z Fold 4", count: 3000 },
{ name: "Samsung Galaxy Z Flip 4", count: 2800 },
{ name: "iPhone 14", count: 2600 }
]
},
{
country: "Italy",
statistic: [
{ name: "iPhone 14", count: 2100 },
{ name: "Samsung Galaxy S23", count: 1900 },
{ name: "Google Pixel 7", count: 1700 },
{ name: "Xiaomi Mi 13", count: 1600 },
{ name: "Oppo Find X6", count: 1500 }
]
}
];
}
В этом случае мы берём ту же статистику, только привязываем её уже к некоторым странам. Суть в том, что бы вывести несколько "линий" на один график разного цвета. Компонент:
@Component({
selector: 'app-charts',
standalone: true,
imports: [CommonModule,
DxChartModule],
templateUrl: './charts.component.html',
styleUrl: './charts.component.css'
})
export class ChartsComponent {
constructor(private source: ChartDataSources) {
this.phoneSales = source.getPhoneSalesData();
}
protected phoneSales: PhoneSalesDataItem[];
}
@Injectable({
providedIn: 'root'
})
export class ChartDataSources {
public getPhoneSalesData() : PhoneSalesDataItem[] {
return [ ... ];
}
}
Разметка:
<dx-chart [dataSource]="phoneSales">
<dxi-series *ngFor="let sale of phoneSales" [valueField]="'sale.statistic.name'" [argumentField]="'sale.statistic.count'" [name]="sale.country"></dxi-series>
<dxo-common-axis-settings>
<dxo-grid [visible]="true"></dxo-grid>
</dxo-common-axis-settings>
<dxo-export [enabled]="true"></dxo-export>
</dx-chart>
В таком виде данные не выводятся на график, а в консоли получаю ошибку:
main.ts:5 W2002 - The Italy series cannot be drawn because the sale.statistic.count data field is missing.
For additional information on this warning message, see: https://js.devexpress.com/error/24_1/W2002
Как правильно вывести такую структуру данных на график?