来自响应数据的动态 Kendo 网格列
Dynamic Kendo grid columns from response data
我一直在尝试创建一个 Kendo 网格,其中包含基于日期项的动态列值作为响应数据的一部分。
我的数据是这样的:
[
{ 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 填充列。因为我的专栏是动态的,所以我在定义它们时遇到了问题。
最重要的是,除了强制通过值并将所有唯一日期条目存储为列之外,我无法挑选出日期值。如果我有它们,那么如何将它们与正确的数据条目匹配以在网格中显示正确的值?
希望对您有所帮助。
我为你做了一个 dojo 并粘贴了下面的代码以供将来使用。
我使用了为读取进行回调传输的可能性。
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>
您可以使用 kendo ui PivotGrid
组件。它是 built 用于处理分类数据。但是,您可能会发现这会占用大量空间。
这就留下了您自己手动旋转数据的任务。如果您假设所有数据的 Date
值从来没有来自两个不同年份的月份(如果有 01-01-2018 和 01-01-2017 它们都是Jan) 并且每个 date/name 组合只有一行。 (如果 date/name 有两个值,您将必须决定如何处理该值?最小值、最大值、第一个、最后一个、平均值?)
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);
我一直在尝试创建一个 Kendo 网格,其中包含基于日期项的动态列值作为响应数据的一部分。
我的数据是这样的:
[
{ 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 填充列。因为我的专栏是动态的,所以我在定义它们时遇到了问题。
最重要的是,除了强制通过值并将所有唯一日期条目存储为列之外,我无法挑选出日期值。如果我有它们,那么如何将它们与正确的数据条目匹配以在网格中显示正确的值?
希望对您有所帮助。 我为你做了一个 dojo 并粘贴了下面的代码以供将来使用。 我使用了为读取进行回调传输的可能性。
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>
您可以使用 kendo ui PivotGrid
组件。它是 built 用于处理分类数据。但是,您可能会发现这会占用大量空间。
这就留下了您自己手动旋转数据的任务。如果您假设所有数据的 Date
值从来没有来自两个不同年份的月份(如果有 01-01-2018 和 01-01-2017 它们都是Jan) 并且每个 date/name 组合只有一行。 (如果 date/name 有两个值,您将必须决定如何处理该值?最小值、最大值、第一个、最后一个、平均值?)
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);