NikFaraday
@NikFaraday
Student full-stack Developer

Как вывести сложный объект на график в DevExtreme Angular 17?

Изучаю как работают графики в 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


Как правильно вывести такую структуру данных на график?
  • Вопрос задан
  • 91 просмотр
Пригласить эксперта
Ответы на вопрос 1
0xD34F
@0xD34F
Надо найти в документации пример нужного вам графика, посмотреть, в каком виде следует подавать в него данные, привести свои данные к этому виду. Всё.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы