响应数据中的动态剑道网格列



我一直在尝试创建一个剑道网格,其中包含基于日期项的动态列值,作为响应数据的一部分。

我拥有的数据如下所示:

[
    { 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-types 但这不是我想做的,它要求我将列作为响应的一部分发送。

我正在使用 GridOptions 的包装器,该包装器通过静态定义的 json 填充列。由于我的列是动态的,因此我在那里定义它们时遇到了问题。

最重要的是,除了暴力强制通过值并将所有唯一的日期条目存储为列之外,我无法挑选日期的值。如果我有它们,那么如何将它们与正确的数据输入相匹配以在网格中显示正确的值?

您可以使用

kendo UI PivotGrid组件。 它是为处理分类数据而构建的。但是,您可能会发现这占用了大量空间。

这就剩下自己手动透视数据的任务了。 如果您假设所有数据的Date值永远不会有来自两个不同年份的月份(如果有 01-01-2018 和 01-01-2017,它们都是 Jan(,并且每个日期/名称组合只有一行,则该任务相对简单。 (如果一个日期/名称有两个值,你必须决定如何处理这个值?最小值、最大值、第一个、最后一个值、平均值?(

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);

我希望这对您有所帮助。我为你做了一个道场,并粘贴了下面的代码以备将来使用。我使用了具有回调传输进行读取的可能性。

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>

最新更新