Динамические столбцы сетки кендо из данных ответов

Я пытался создать сетку кендо с динамическими значениями столбца на основе элемента даты как части данных ответа.

Данные у меня выглядят так:

[
    { Date: '01-01-2018', Name: 'Foo', Value: 1000},
    { Date: '02-01-2018', Name: 'Foo', Value: 2000},
    { Date: '03-01-2018', Name: 'Foo', Value: 3000},
    { Date: '01-01-2018', Name: 'Bar', Value: 1400},
    { Date: '02-01-2018', Name: 'Bar', Value: 2000},
    { Date: '03-01-2018', Name: 'Bar', Value: 5000}
]

Моя предполагаемая структура сетки следующая:

| Name |  Jan | Feb  | Mar  |
|------|------|------|------|
| Foo  | 1000 | 2000 | 3000 |
| Bar  | 1400 | 2000 | 5000 |

Я просмотрел https://docs.telerik.com/kendo-ui/controls/data-management/grid/how-to/various/create-with-dynamic-columns-and-data-типы но это было не совсем то, что я пытался сделать, и требовалось, чтобы столбцы были отправлены как часть ответа.

Я работаю с оболочкой для GridOptions, которая заполняет столбцы через статически определенный json. Поскольку мои столбцы динамические, у меня возникла проблема с их определением.

Кроме того, я не могу выбрать значения для даты, кроме грубого перебора значений и сохранения всех уникальных записей даты в виде столбцов. И если они у меня есть, то как мне сопоставить их с правильным вводом данных, чтобы отобразить правильное значение в сетке?


person O. Khan    schedule 07.03.2018    source источник


Ответы (2)


Я надеюсь, это поможет вам. Я сделал для вас додзё и вставил код ниже на будущее. Я использовал возможность иметь транспорт обратного вызова для чтения.

https://dojo.telerik.com/imeNOdUh/2

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Untitled</title>

  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.common.min.css">
  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.rtl.min.css">
  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.default.min.css">
  <link rel="stylesheet" href="https://kendo.cdn.telerik.com/2018.1.221/styles/kendo.mobile.all.min.css">

  <script src="https://code.jquery.com/jquery-1.12.3.min.js"></script>
  <script src="https://kendo.cdn.telerik.com/2018.1.221/js/angular.min.js"></script>
  <script src="https://kendo.cdn.telerik.com/2018.1.221/js/jszip.min.js"></script>
  <script src="https://kendo.cdn.telerik.com/2018.1.221/js/kendo.all.min.js"></script></head>
<body>
  <div id="my-grid"></div>

  <script>

    function fetchData(success, fail) {
        success([
        { Date: '01-01-2018', Name: 'Foo', Value: 1000},
        { Date: '02-01-2018', Name: 'Foo', Value: 2000},
        { Date: '03-01-2018', Name: 'Foo', Value: 3000},
        { Date: '01-01-2018', Name: 'Bar', Value: 1400},
        { Date: '02-01-2018', Name: 'Bar', Value: 2000},
        { Date: '03-01-2018', Name: 'Bar', Value: 5000}
      ]); 
    }    

    var $gridElement = $('#my-grid');
    $gridElement.kendoGrid({
        dataSource: {
            transport: {
            read: function(options) {

              fetchData(function(data) {

                // get month names
                var monthNames = data
                    .map(function(t) {
                    var monthName = kendo.format("{0:MMM}", kendo.parseDate(t.Date, 'MM-dd-yyyy'));
                    return monthName;
                  })
                    .reduce(function(p, t) {
                        if (p.indexOf(t) == -1)
                        p.push(t);

                        return p;                        
                  }, []);

                // transform
                var result = data.reduce(function(p, t) {
                    var monthName = kendo.format("{0:MMM}", kendo.parseDate(t.Date, 'MM-dd-yyyy'));

                  var existing = p.filter(function(t2) {
                    return t2.Name == t.Name;
                  });

                  if (existing.length) {
                    existing[0][monthName] = t.Value;
                  } else {
                    var n = {
                        Name: t.Name
                    };
                    monthNames.forEach(function(m) {
                      n[m] = 0;
                    });

                    n[monthName] = t.Value;
                    p.push(n);
                  }

                  return p;
                }, []);

                options.success(result);

              });


            }
          }
        }
    });

  </script>
</body>
</html>
person David Lebee    schedule 08.03.2018

Вы можете использовать компонент kendo ui PivotGrid. Он создан для работы с категориальными данными. Тем не менее, вы, вероятно, обнаружите, что это занимает много недвижимости.

Это оставляет задачу самостоятельного поворота данных вручную. Задача, которая относительно проста, если вы сделаете предположение, что значения Date по всем данным никогда не имеют месяца из двух разных лет (если были 01-01-2018 и 01-01-2017, они оба являются январем) и только одна строка для каждой комбинации даты/имени. (Если бы для даты/имени было два значения, вам пришлось бы решить, что делать со значением? min, max, first, last, mean?)

data = 
[
    { Date: '01-01-2018', Name: 'Foo', Value: 1000},
    { Date: '02-01-2018', Name: 'Foo', Value: 2000},
    { Date: '03-01-2018', Name: 'Foo', Value: 3000},
    { Date: '01-01-2018', Name: 'Bar', Value: 1400},
    { Date: '02-01-2018', Name: 'Bar', Value: 2000},
    { Date: '03-01-2018', Name: 'Bar', Value: 5000}
];

// distinct month nums over all data
months = [];
data.forEach(function(item) {
  var parts = item.Date.split('-');
  var month = parts[0] - 1;
  if (months.indexOf(month) == -1) months.push(month);
});

// sort and convert month num to month name (for columns)
months.sort();
months.forEach(function(monthNum,index,arr) {
  arr[index] = new Date(2018,monthNum,1).toLocaleString("en-US", { month: "short" });
});

function mmddyyyyToMon(mmddyyyy) {
  var parts = mmddyyyy.split("-");
  var jsMonth = parts[0] - 1;
  var jsDay = parts[1];
  var jsYear = parts[2];
  return new Date(jsYear,jsMonth,jsDay).toLocaleString("en-US", { month: "short" });
}

// helper to make sure pivot item has one field for every month observed over all data
function newPivotItem () {
  var result = { Name: '' };
  months.forEach(function(month) {
    result[month] = undefined;
  })
  return result;
}

// presume data grouped by Name and ordered by month within
var pivotData = [];
var pivotItem = {};
data.forEach (function (item) {
  var parts = item.Date.split("-");
  var jsMonth = parts[0] - 1;
  var jsDay = parts[1];
  var jsYear = parts[2];
  var month = new Date(jsYear,jsMonth,jsDay).toLocaleString("en-US", { month: "short" });

  if (pivotItem.Name != item.Name) {
    // start next group of data for a name
    pivotItem = newPivotItem();
    pivotData.push(pivotItem);
    pivotItem.Name = item.Name;
  }

  // set value for month for the name
  pivotItem[month] = item.Value;
})

console.log (pivotData);
person Richard    schedule 08.03.2018