Kendo UI Grid - Build Columns Dynamically - kendo-grid

I have an array with the list of column names, that needs to be displayed in the grid. So, while initializing the grid, I need to loop through each column in the datasource - and if that column is present in the Array, then I need to display it.
For example,
var ColumnNames = ["col1","col3"];
var dataSource = [ {
"col1": "a",
"col2": "1",
"col3": "11",
"col4": "1111"
},
{
"col1": "b",
"col2": "2",
"col3": "22",
"col4": "2222"
},
{
"col1": "c",
"col2": "3",
"col3": "33",
"col4": "3333"
},
.....]
The grid should display only with the columns present in the array. Here, as shown below:
col1 col3
---------------
a 11
b 22
c 33
.......
​
The ColumnNames Array and dataSource actually comes from DB, based on the user selection. So, I can not hardcode column names. I tried various options (using column templates, foreach loops for building the model, etc) , but facing one or the other issue. Can someone help me out on this please?
​
Thanks in advance!
​
Regards
Neelima

Tri This :
var ColumnNames = ["col1","col3"];
var dataSource = [ {
"col1": "a",
"col2": "1",
"col3": "11",
"col4": "1111"
},
{
"col1": "b",
"col2": "2",
"col3": "22",
"col4": "2222"
},
{
"col1": "c",
"col2": "3",
"col3": "33",
"col4": "3333"
}]
$(document).ready(function(){
createGrid();
})
function createGrid(){
var columns = generateColumns(dataSource);
$("#grid").kendoGrid({
dataSource : dataSource,
columns :columns
});
}
function generateColumns(_dataSource){
if(_dataSource.length > 0) {
return Object.keys(_dataSource[0]);
}
}
$("#btnUpdate").click(function(){
var grid = $("#grid").data("kendoGrid");
grid.destroy();
$("#grid").empty();
dataSource = [ {
"col1": "a",
"col2": "1",
"col4": "1111"
},
{
"col1": "b",
"col2": "2",
"col4": "2222"
},
{
"col1": "c",
"col2": "3",
"col4": "3333"
}];
createGrid();
})
<link href="https://kendo.cdn.telerik.com/2017.3.1026/styles/kendo.common.min.css" rel="stylesheet"/>
<link href="https://kendo.cdn.telerik.com/2017.3.1026/styles/kendo.rtl.min.css" rel="stylesheet"/>
<link href="https://kendo.cdn.telerik.com/2017.3.1026/styles/kendo.silver.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2017.3.1026/js/kendo.all.min.js"></script>
<div id = "grid">
</div>
<button id="btnUpdate">update</button>

Related

Can jsonpath-plus move elements to child elements?

What I have:
[
{"Name": "One",
"ID": "1",
"Child": [
{ "ChildName": "Alpha"},
{"ChildName": "Beta"}
]
},
{"Name": "Two",
"ID": "1",
"Child": [
{ "ChildName": "Gamma"},
{"ChildName": "Delta"}
]
}
]
and what I'm looking for:
[
{ "ChildName": "Alpha",
"ID": "1"},
{ "ChildName": "Beta",
"ID": "1"},
{ "ChildName": "Gamma",
"ID": "2"},
{ "ChildName": "Delta",
"ID": "2"}
]
Extensive searching gives 'you cant' or 'here is a JavaScript function'.
But there must be an elegant way to solve this common data handling problem?
try this
var newObj = [];
data.forEach((item) => {
item.Child.forEach((ch) => {
var obj = {};
obj.ChildName = ch.ChildName;
obj.ID = item.ID;
newObj.push(obj);
});
});
console.log(JSON.stringify(newObj));
result
[
{"ChildName":"Alpha","ID":"1"},
{"ChildName":"Beta","ID":"1"},
{"ChildName":"Gamma","ID":"2"},
{"ChildName":"Delta","ID":"2"}
]

TypeScript convert json structure

I cant figure out how to make this conversion iterating a json.
I have this pojo in my backend:
class Part{
Long id;
String name;
Set<Part> parts = new HashSet<>();
}
Every part can have parts and this part more parts and so on.
I get this parts from httpclient in angular and get this json:
[{
"id": 1,
"name": "Parts A and B",
"parts": [{
"id": 2,
"name": "A",
"parts": [{
"id": 4,
"name": "A1",
"parts": []
}]
},
{
"id": 3,
"name": "B",
"parts": []
}
]
},
{
"id": 2,
"name": "A",
"parts": []
},
{
"id": 3,
"name": "B",
"parts": []
},
{
"id": 4,
"name": "A1",
"parts": []
}
]
And need to convert to this to populate a PrimeNG TreeTable:
{
"data": [{
"data": {
"name": "Parts A and B",
"id": "1"
},
"children": [{
"data": {
"name": "Part A",
"id": "2"
},
"children": [{
"data": {
"name": "A1",
"id": "4"
}
}]
},
{
"data": {
"name": "Part B",
"id": "3"
},
"children": []
}
]
},
{
"data": {
"name": "Part A",
"id": "2"
},
"children": []
},
{
"data": {
"name": "Part B",
"id": "3"
},
"children": []
},
{
"data": {
"name": "A1",
"id": "4"
},
"children": []
}
]
}
How can I do that?
In angular I get this in an array parts: Part[] and need partsTree: TreeNode[]
Thanks!!!
Its just a simple conversion by a map;
interface PartAPI{
id: number;
name: string;
parts : PartAPI[];
}
interface Data {
id: number;
name: string;
}
interface Part {
data : Data;
children : Part[];
}
console.log('a')
let convert = (inputArr: PartAPI[] = []) : Part[] => {
return inputArr.map(partApi => ({ data : { id : partApi.id , name : partApi.name }, children: convert(partApi.parts) }) as Part)
}
let data : PartAPI[] = [{
"id": 1,
"name": "Parts A and B",
"parts": [{
"id": 2,
"name": "A",
"parts": [{
"id": 4,
"name": "A1",
"parts": []
}]
},
{
"id": 3,
"name": "B",
"parts": []
}
]
},
{
"id": 2,
"name": "A",
"parts": []
},
{
"id": 3,
"name": "B",
"parts": []
},
{
"id": 4,
"name": "A1",
"parts": []
}
]
console.log(convert(data));

Highchart : How to plot Stacked bar graph with line by below JSON respons

I am using below Json to plot the stacked graph with line (look like below screenshot)
[{
"TD": "2",
"TE": "5",
"TI": "3",
"TLI": "2",
"TR": "2",
"hour": "0",
"totalCount": "14"
},
{
"FINGERVERIFY": "4",
"LI": "1",
"TD": "3",
"TE": "9",
"TI": "4",
"TLI": "3",
"TLIP": "2",
"TR": "3",
"hour": "1",
"totalCount": "29"
},
{
"LI": "1",
"LIP": "1",
"LLI": "1",
"LLIP": "1",
"LR": "1",
"LRP": "1",
"hour": "2",
"totalCount": "6"
},
{
"FE": "2",
"TE": "2",
"hour": "8",
"totalCount": "4"
}
]
Chart Image
Description of chart based on the below points:-
x-axis : "hours" from Json property
tip of the line shows the "totalCount"
stacked bar shows the other property of Json.
Can anyone please help me to achive above graph which is simlar to screenshot, by using above Json?
Based on your data, you need to build a series structure required by Highcharts. Example:
const series = [];
data.forEach(dataEl => {
for (const key in dataEl) {
if (key === 'hour') continue;
const existingSeries = series.find(s => s.name === key);
if (!existingSeries) {
series.push({
name: key,
type: key === 'totalCount' ? 'line' : 'column',
data: [[Number(dataEl.hour), Number(dataEl[key])]]
});
} else {
existingSeries.data.push([Number(dataEl.hour), Number(dataEl[key])]);
}
}
});
Live demo: http://jsfiddle.net/BlackLabel/40pgqn9j/
API Reference: https://api.highcharts.com/highcharts/series

lodash sort an array of objects by a property which has an array of objects

I have a an object. I am able to sort the items by using lodash's _.orderBy().
However, in one of the scenario I have to sort by subject, which is an array of objects. Items inside the subject array are already sorted based on the name.
As subject is an array of the objects, I need to consider the first item for sorting.
[
{
"id": "1",
"name": "peter",
"subject": [
{
"id": "1",
"name": "maths"
},
{
"id": "2",
"name": "social"
}
]
},
{
"id": "2",
"name": "david",
"subject": [
{
"id": "2",
"name": "physics"
},
{
"id": "3",
"name": "science"
}
]
},
{
"id": "3",
"name": "Justin",
"subject": [
]
}
]
You can use _.get() to extract the name (or id) of the 1st item in subjects. If no item exists, _.get() will return undefined, which can be replaced with a default value. In this case, we don't want to use an empty string as a default value, since the order would change. Instead I'm checking if the value is a string, if it is I use lower case on it, if not I return it as is.
const arr = [{"id":"1","name":"peter","subject":[{"id":"1","name":"maths"},{"id":"2","name":"social"}]},{"id":"2","name":"david","subject":[{"id":"2","name":"physics"},{"id":"3","name":"science"}]},{"id":"3","name":"Justin","subject":[]}]
const result = _.orderBy(arr, o => {
const name = _.get(o, 'subject[0].name')
return _.isString(name) ? name.toLowerCase() : name
})
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Use _.sortBy with a comparison/sorting function argument. Your function itself can look into the receiving arguments subject key (I think its the subject you want to compare?)
Since you have the question also tagged with ES6 here is an JS only solution via Array.sort:
let arr = [ { "id": "1", "name": "peter", "subject": [ { "id": "1", "name": "maths" }, { "id": "2", "name": "social" } ] }, { "id": "2", "name": "david", "subject": [ { "id": "2", "name": "physics" }, { "id": "3", "name": "science" } ] }, { "id": "3", "name": "Justin", "subject": [] }, ]
const result = arr.sort((a,b) =>
a.subject.length && b.subject.length
? a.subject[0].name.localeCompare(b.subject[0].name)
: a.subject.length ? -1 : 1)
console.log(result)

What is the most efficient way to aggregate a value from a JSON tree in d3.js?

Assume you have a D3 JSON input with an unordered tree hierarchy like this:
{
"generated": "2017-02-21T14:02:18.652071",
"name": "root",
"children": [
{
"name": "level1",
"module_name": "level1",
"children": [
],
"size": "16"
},
{
"authorid": "46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"name": "child.js",
"weight": "1.0",
"module_name": "child.js",
"children": [
],
"size": "14"
},
{
"authorid": "46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"name": "child_1.js",
"weight": "1.0",
"module_name": "child_1.js",
"children": [
{
"authorid": "e5b333a985d12c2f0ccc878fc81d5e3d04732ef398631022443e25c2372e165f4f0d3d61f3f8caf8ccf4fa6e6af336834062d883d52fd3b67b2e15bd8599207a",
"name": "child_1_1.js",
"module_name": "child_1_1.js",
"children": [
],
"size": "112"
},
],
"size": "14"
},
{
"authorid": "e5b333a985d12c2f0ccc878fc81d5e3d04732ef398631022443e25c2372e165f4f0d3d61f3f8caf8ccf4fa6e6af336834062d883d52fd3b67b2e15bd8599207a",
"name": "child_3.js",
"module_name": "child_3.js",
"children": [
],
"size": "133"
}...
The structure can have any depth.
Now we need to aggregate / group all "authorid" values so we have a grouped array / map of the containing hashes of all authors from the nested JSON tree like this:
[
"46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"e5b333a985d12c2f0ccc878fc81d5e3d04732ef398631022443e25c2372e165f4f0d3d61f3f8caf8ccf4fa6e6af336834062d883d52fd3b67b2e15bd8599207a",
]
All duplicates should be aggregated as string values into a grouped value list.
The purpose of the resulting array is to filter a html table from the according node entrys that are visible in the d3 chart.
What is the most elegant way to reach this without plain javascript recursion. Is it possible to use a nested JSON as input for d3.nest or is there another performant way i.e. filter to get the above result?
If you are free to use ES6 features, one of the cleanest solutions can be implemented using a generator function for recursively walking through the data structure in combination with a Set allowing only unique entries.
function* getAuthorIds(arr) {
for (let {authorid, children} of arr) {
if (authorid) yield authorid;
if (children) yield* getAuthorIds(children);
}
}
var uniqueAuthorIds = [...new Set(getAuthorIds(data))];
The generator function gets passed an array of objects over which it will iterate using a for-of loop. It will yield the authorid if the object contains a property of this name. After that, it checks, if the object contains an array of children and, if it does, delegates to the generator for these children by using yield*. This is where recursion happens to walk through the entire hierarchy.
To get a collection of unique authorids you can construct a Set from all values of authorid, which were found throughout your data. The Set by definition guarantees the values stored in it to be unique. The trick here is to pass the generator created for your data by calling getAuthorIds(data) directly to the Set's constructor. This is possible because the constructor accepts an iterable object, i.e. an object implementing the iterable protocol, which is exactly what a Generator implicitly does.
Because in your question you asked for an array of authorids, as a last step, an array is created from the Set using the spread operator.
Have a look at the following working demo:
var data = [{
"generated": "2017-02-21T14:02:18.652071",
"name": "root",
"children": [{
"name": "level1",
"module_name": "level1",
"children": [
],
"size": "16"
}, {
"authorid": "46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"name": "child.js",
"weight": "1.0",
"module_name": "child.js",
"children": [
],
"size": "14"
}, {
"authorid": "46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"name": "child_1.js",
"weight": "1.0",
"module_name": "child_1.js",
"children": [{
"authorid": "e5b333a985d12c2f0ccc878fc81d5e3d04732ef398631022443e25c2372e165f4f0d3d61f3f8caf8ccf4fa6e6af336834062d883d52fd3b67b2e15bd8599207a",
"name": "child_1_1.js",
"module_name": "child_1_1.js",
"children": [
],
"size": "112"
}],
"size": "14"
}, {
"authorid": "e5b333a985d12c2f0ccc878fc81d5e3d04732ef398631022443e25c2372e165f4f0d3d61f3f8caf8ccf4fa6e6af336834062d883d52fd3b67b2e15bd8599207a",
"name": "child_3.js",
"module_name": "child_3.js",
"children": [
],
"size": "133"
}]
}];
function* getAuthorIds(arr) {
for (let {authorid, children} of arr) {
if (authorid) yield authorid;
if (children) yield* getAuthorIds(children);
}
}
var uniqueAuthorIds = [...new Set(getAuthorIds(data))];
console.log(uniqueAuthorIds);
I think d3 is not needed for this task as a simple recursive function should fit pretty well.
var ids = [];
function collectAuthorIdsRecursively(elem) {
for (var i = 0; i < elem.children.length; i++) {
var child = elem.children[i];
if (child.hasOwnProperty('authorid') && ids.indexOf(child.authorid) < 0) {
ids.push(child.authorid);
}
if (child.hasOwnProperty('children') && child.children instanceof Array) {
collectAuthorIdsRecursively(child);
}
}
}
collectAuthorIdsRecursively(data);
jsfiddle example
Try this :
var jsonObj = {
"generated": "2017-02-21T14:02:18.652071",
"name": "root",
"children": [{
"name": "level1",
"module_name": "level1",
"children": [
],
"size": "16"
}, {
"authorid": "46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"name": "child.js",
"weight": "1.0",
"module_name": "child.js",
"children": [
],
"size": "14"
}, {
"authorid": "46f14ba664314322e217383c4166d9e89892de93cbe2bb6bf2ea1645f910a24955c22fd384924a2f715efa34d07149ba284c2947c788f7c25a99308dfb2d7a6c",
"name": "child_1.js",
"weight": "1.0",
"module_name": "child_1.js",
"children": [{
"authorid": "e5b333a985d12c2f0ccc878fc81d5e3d04732ef398631022443e25c2372e165f4f0d3d61f3f8caf8ccf4fa6e6af336834062d883d52fd3b67b2e15bd8599207a",
"name": "child_1_1.js",
"module_name": "child_1_1.js",
"children": [
],
"size": "112"
}],
"size": "14"
}]
};
var arr = [];
function checkKey(object) {
if(object.hasOwnProperty('authorid'))
arr.push(object.authorid);
for(var i=0;i<Object.keys(object).length;i++) {
if(typeof object[Object.keys(object)[i]]=="object"){
checkKey(object[Object.keys(object)[i]]);
}
}
}
checkKey(jsonObj);
console.log(arr);