jqgrid tree reader not working - jqgrid

My sample Json object is shown below:
{
"o": [
{
"level": 0,
"outlineItemId": 8,
"parentItemId": null,
"parentItem": null,
"order": 0,
"text": "section 1",
"isLeaf": "false",
"expanded": "true"
},
{
"level": 1,
"outlineItemId": 9,
"parentItemId": 8,
"parentItem": {
"level": 0,
"outlineItemId": 8,
"parentItemId": null,
"parentItem": null,
"order": 0,
"text": "section 1",
"isLeaf": "false",
"expanded": "true"
},
"order": 0,
"text": "sub 1",
"isLeaf": "false",
"expanded": "true"
},
{
"level": 2,
"outlineItemId": 10,
"parentItemId": 9,
"parentItem": {
"level": 1,
"outlineItemId": 9,
"parentItemId": 8,
"parentItem": {
"level": 0,
"outlineItemId": 8,
"parentItemId": null,
"parentItem": null,
"order": 0,
"text": "section 1",
"isLeaf": "false",
"expanded": "true"
},
"order": 0,
"text": "sub 1",
"isLeaf": "false",
"negateDevice": null,
"expanded": "true"
},
"order": 0,
"text": "sub sub 1",
"isLeaf": "true",
"expanded": "true"
}
]
}
Earlier when the tree was configured as:
treeReader: {
level_field: "level",
parent_id_field: "parentItemId",
leaf_field: "isLeaf",
expanded_field: "expanded"
},
I was displaying the correct indentation and image icons, however they were not expanded when the json obj always had "expanded":"true" so i tried the below code.
treeReader: {
level_field: "o.level",
parent_id_field: "o.parentItemId",
leaf_field: "o.isLeaf",
expanded_field: "o.expanded"
},
Now I am not getting the Image icons and the tree which was expanded earlier is now flat.
My Json reader just in case i goofed up..
jsonReader: {
root: 'o',
id: 'o.outlineItemId',
parentItemId: 'o.parentItem.outlineItemId',
text: 'o.text',
repeatitems: false,
page: function(obj) { return 1; },
total: function(obj) { return 1; },
records: function(obj) { return obj.o.length; },
},
Any help will be appreciated.
Shah

Got it!
For the reader i had to include cell:'' and remove the o. references. and also loaded:true in the json object.

Related

JPA repository does not return page implementation

Right now I have a repository method annotated with #RestResource(path = "xx") which return a json in the following form
{
"_embedded": {
"myResponse": []
},
"_links": {},
"page": {
"size": 24,
"totalElements": 238,
"totalPages": 10,
"number": 0
}
}
but I would like something with the form :
{
"content": [],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"pageSize": 24,
"pageNumber": 0,
"offset": 0,
"paged": true,
"unpaged": false
},
"last": false,
"totalElements": 238,
"totalPages": 10,
"size": 24,
"number": 0,
"first": true,
"numberOfElements": 24,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"empty": false
}
But when I create a GetMapping in my controller which is simply calling my repo method like so :
repo.findByTitleContaining(searchedWord, PageRequest.of(page, size));
I have the desired form of response..
My question is : is there a way to get it directly from the repo with restresource annotation ?

Algorithm for creating nested structure

I have following structure:
{
"list": [
{ "depth": 0, "data": "lorem1" },
{ "depth": 1, "data": "lorem2" },
{ "depth": 2, "data": "lorem3" },
{ "depth": 2, "data": "lorem4" },
{ "depth": 0, "data": "lorem5" },
{ "depth": 1, "data": "lorem6" },
{ "depth": 1, "data": "lorem7" },
{ "depth": 2, "data": "lorem8" }
]
}
I am looking for an algorithm on how to create from that depth a parent-child-like, nested structure.
{
"list": [{
"depth": 0,
"data": "lorem1",
"children": [{
"depth": 1,
"data": "lorem2",
"children": [{
"depth": 2,
"data": "lorem3",
"children": [],
}, {
"depth": 2,
"data": "lorem4",
"children": [],
}]
}]
}, {
"depth": 0,
"data": "lorem5",
"children": [{
"depth": 1,
"data": "lorem6",
"children": [],
}, {
"depth": 1,
"data": "lorem7",
"children": [{
"depth": 2,
"data": "lorem8",
"children": [],
}]
}]
}
]}
The logic is like this:
Assumption: The first item in the list always starts with depth=0
If depth is larger than the last, it must be child of this last one
I can not get this to work. It should be recursive to have infinite nesting/depth levels.
Thank you guys for the help!
You can use a stack to keep track of the current path in the tree. When depth increases from one to the next, then push the new node also on that stack. If not, pop items from the stack until the right depth is reached.
Then you always know in which children collection you need to add the new node.
Here is an runnable implementation in JavaScript:
function algo(list) {
// Create a dummy node to always stay at the bottom of the stack:
let stack = [
{ "depth": -1, "data": "(root)", "children": [] }
];
for (let node of list) {
let newNode = { ...node, children: [] }; // Copy and add children property
if (newNode.depth >= stack.length || newNode.depth < 0) throw "Invalid depth";
while (newNode.depth < stack.length - 1) stack.pop();
stack[stack.length - 1].children.push(newNode);
stack.push(newNode);
}
return stack[0].children;
}
// Demo
let data = {
"list": [
{ "depth": 0, "data": "lorem1" },
{ "depth": 1, "data": "lorem2" },
{ "depth": 2, "data": "lorem3" },
{ "depth": 2, "data": "lorem4" },
{ "depth": 0, "data": "lorem5" },
{ "depth": 1, "data": "lorem6" },
{ "depth": 1, "data": "lorem7" },
{ "depth": 2, "data": "lorem8" }
]
}
// Create a new structure, and load the transformed list in its list property:
let result = {
"list": algo(data.list)
};
// Show result
console.log(result);
To answer to your request to do this without dummy node:
function algo(list) {
let result = [];
let stack = [];
for (let node of list) {
let newNode = { ...node, children: [] }; // Copy and add children property
if (newNode.depth > stack.length || newNode.depth < 0) throw "Invalid depth";
while (newNode.depth < stack.length) stack.pop();
if (!stack.length) result.push(newNode);
else stack[stack.length - 1].children.push(newNode);
stack.push(newNode);
}
return result;
}
// Demo
let data = {
"list": [
{ "depth": 0, "data": "lorem1" },
{ "depth": 1, "data": "lorem2" },
{ "depth": 2, "data": "lorem3" },
{ "depth": 2, "data": "lorem4" },
{ "depth": 0, "data": "lorem5" },
{ "depth": 1, "data": "lorem6" },
{ "depth": 1, "data": "lorem7" },
{ "depth": 2, "data": "lorem8" }
]
}
// Create a new structure, and load the transformed list in its list property:
let result = {
"list": algo(data.list)
};
// Show result
console.log(result);

ElasticSearch - Combine filters & Composite Query to get unique fields combinations

Well.. I am quite "newb" regarding ES so regarding aggregation... there is no words in the dictionary to describe my level regarding it :p
Today I am facing an issue where I am trying to create a query that should execute something similar to a SQL DISTINCT, but among filters. I have this document given (of course, an abstraction of the real situation):
{
"id": "1",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": true,
"kind": "document",
"classification": {
"id": 1,
"name": "a_name_for_id_1"
},
"structure": {
"material": "cartoon",
"thickness": 5
},
"shared": true,
"objective": "stackoverflow"
}
As all the data of the above document can vary, I however have some values that can be redundant, such as classification.id, kind, structure.material.
So, in order to fullfit my requirements, I would like to "group by" these 3 fields in order to have a unique combination of each. If we go deeper, with the following data, I should get the following possibilities:
[{
"id": "1",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": true,
"kind": "document",
"classification": {
"id": 1,
"name": "a_name_for_id_1"
},
"structure": {
"material": "cartoon",
"thickness": 5
},
"shared": true,
"objective": "stackoverflow"
},
{
"id": "2",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": true,
"kind": "document",
"classification": {
"id": 2,
"name": "a_name_for_id_2"
},
"structure": {
"material": "iron",
"thickness": 3
},
"shared": true,
"objective": "linkedin"
},
{
"id": "3",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": false,
"kind": "document",
"classification": {
"id": 2,
"name": "a_name_for_id_2"
},
"structure": {
"material": "paper",
"thickness": 1
},
"shared": false,
"objective": "tiktok"
},
{
"id": "4",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": true,
"kind": "document",
"classification": {
"id": 3,
"name": "a_name_for_id_3"
},
"structure": {
"material": "cartoon",
"thickness": 5
},
"shared": false,
"objective": "snapchat"
},
{
"id": "5",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": true,
"kind": "document",
"classification": {
"id": 3,
"name": "a_name_for_id_3"
},
"structure": {
"material": "paper",
"thickness": 1
},
"shared": true,
"objective": "twitter"
},
{
"id": "6",
"createdAt": 1626783747,
"updatedAt": 1626783747,
"isAvailable": false,
"kind": "document",
"classification": {
"id": 3,
"name": "a_name_for_id_3"
},
"structure": {
"material": "iron",
"thickness": 3
},
"shared": true,
"objective": "facebook"
}
]
based on the above, I should get the following results in the "buckets":
document 1 cartoon
document 2 iron
document 2 paper
document 3 cartoon
document 3 paper
document 3 iron
Of course, for the sake of this example (and to make it easier, I yet don't have any duplicates)
However, on top of that, I need some "pre-filters" as I only want:
Documents that are available isAvailable=true
Documents'structure's thickness should range between 2 and 4 included: 2 >= structure.thickness >= 4
Document's that are shared shared=true
I should so then get only the following combinations compared to the first set of results:
document 1 cartoon -> not a valid result, thickness > 4
document 2 iron
document 2 paper -> not a valid result, isAvailable != true
document 3 cartoon -> not a valid result, thickness > 4
document 3 cartoon -> not a valid result, thickness < 2
document 3 iron -> not a valid result, isAvailable != true
If you're still reading, well.. thanks! xD
So, as you can see, I need all the possible combination of this field regarding the static pattern kind <> classification_id <> structure_material that are matching the filters regarding isAvailable, thickness, shared.
Regarding the output, the hits doesn't matter to me as I don't need the documents but only the combination kind <> classification_id <> structure_material :)
Thanks for any help :)
Max
You can got with Cardinatily aggregations with your existing filters.Please check this url and let me know if you have any queries.
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-metrics-cardinality-aggregation.html
Thanks to a colleague, I could finally get it working as expected!
QUERY
GET index-latest/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"isAvailable": true
}
},
{
"range": {
"structure.thickness": {
"gte": 2,
"lte": 4
}
}
},
{
"term": {
"shared": true
}
}
]
}
},
"aggs": {
"my_agg_example": {
"composite": {
"size": 10,
"sources": [
{
"kind": {
"terms": {
"field": "kind.keyword",
"order": "asc"
}
}
},
{
"classification_id": {
"terms": {
"field": "classification.id",
"order": "asc"
}
}
},
{
"structure_material": {
"terms": {
"field": "structure.material.keyword",
"order": "asc"
}
}
}
]
}
}
}
}
The given result is then:
{
"took": 11,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"my_agg_example": {
"after_key": {
"kind": "document",
"classification_id": 2,
"structure_material": "iron"
},
"buckets": [
{
"key": {
"kind": "document",
"classification_id": 2,
"structure_material": "iron"
},
"doc_count": 1
}
]
}
}
}
So, as we can see, we get the following bucket:
{
"key": {
"kind": "document",
"classification_id": 2,
"structure_material": "iron"
},
"doc_count": 1
}
Note: Be careful regarding the type of your field.. putting .keyword on classification.id was resulting to no results in the buckets... .keyword should be use only on types such as string (as far as I understood, correct me if I am wrong)
As expected, we have the following result (compared to the initial question):
document 2 iron
Note: Be careful, the order of the elements within the aggs.<name>.composite.sources does play a role in the returned results.
Thanks!

How to get the total page number for pagination

I try to make my pageable data for weeks everything works but I would like to know the total number of pagination pages here are the data of my mongonDB.
{
"content": [
{
"mame": "iPhone X",
"eategory": "High-Tech",
"productId": "aDPXF7Xq",
"details": {
"vating": "00",
"stocks": "20",
"price": "800000",
"tags": [
{
"tagsl": "Apple",
"tags2": "aull",
"tags3": null
}
],
"brand": "Apple",
"description": "Iphone xX",
"picture": [
{
"picturel": "photol",
"picture2": null,
"picture3": null,
"picture4": null,
"picture5": null
}
],
"thumbnails": [
{
"thumbnaill": "thumbails 1",
"thumbnail2": null,
"thumbnail3": null,
"thumbnail4": null,
"thumbnail5": null
}
]
}
},
{
"mame": "iPhone X",
"eategory": "High-Tech",
"productId": "cjjVqOBk",
"details": {
"rating": "10",
"stocks": "20",
"price": "800000",
"tags": [
{
"tagsl": "Apple",
"tags2": "aull",
"tags3": null
}
],
"brand": "Apple",
"description": "Iphone xX",
"picture": [
{
"picturel": "photol",
"picture2": null,
"picture3": null,
"picture4": null,
"picture5": null
}
],
"thumbnails": [
{
"thumbnaill": "thumbails 1",
"thumbnail2": null,
"thumbnail3": null,
"thumbnail4": null,
"thumbnail5": null
}
]
}
},
{
"mame": "iPhone X",
"eategory": "High-Tech",
"productId": "LhKiRGr6",
"details": {
"vating": "10",
"stocks": "20",
"price": "800000",
"tags": [
{
"tagsl": "Apple",
"tags2": "aull",
"tags3": null
}
],
"brand": "Apple",
"description": "Iphone xX",
"picture": [
{
"picturel": "photol",
"picture2": null,
"picture3": null,
"picture4": null,
"picture5": null
}
],
"thumbnails": [
{
"thumbnaill": "thumbails 1",
"thumbnail2": null,
"thumbnail3": null,
"thumbnail4": null,
"thumbnail5": null
}
]
}
},
{
"mame": "iPhone X",
"eategory": "High-Tech",
"productId": "dgCvi8NJ",
"details": {
"vating": "10",
"stocks": "20",
"price": "800000",
"tags": [
{
"tagsl": "Apple",
"tags2": "aull",
"tags3": null
}
],
"brand": "Apple",
"description": "Iphone xX",
"picture": [
{
"picturel": "photol",
"picture2": null,
"picture3": null,
"picture4": null,
"picture5": null
}
],
"thumbnails": [
{
"thumbnaill": "thumbails 1",
"thumbnail2": null,
"thumbnail3": null,
"thumbnail4": null,
"thumbnail5": null
}
]
}
}
],
"pageable": {
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"offset": 0,
"pageNumber": 0,
"pageSize": 20,
"paged": true,
"unpaged": false
},
"totalPages": 1,
"totalElements": 4,
"last": true,
"size": 20,
"sort": {
"sorted": false,
"unsorted": true,
"empty": true
},
"number": 0,
"numberOfElements": 4,
"first": true,
"empty": false
}
Now here is the data paging code
#GetMapping("/engine/search")
public PageImpl<Products> engineSearch(#RequestParam("p") String query, #RequestParam(value = "page", defaultValue = "0") int page, Pageable pageable) {
Criteria criteria = new Criteria();
final Aggregation aggregation = Aggregation.newAggregation(
Aggregation.match( criteria.orOperator(
Criteria.where( "name" ).regex( query, "i" ),
Criteria.where( "details.brand" ).regex( query, "i" ),
Criteria.where( "details.tags.tags1" ).regex( query, "i" ),
Criteria.where( "details.tags.tags2" ).regex( query, "i" ),
Criteria.where( "details.tags.tags3" ).regex( query, "i" )
)),
Aggregation.skip(page * 4),
Aggregation.limit(4)
);
List<Products> filter = mongoTemplate.aggregate(aggregation, "Product", Products.class).getMappedResults();
return new PageImpl<Products>(filter, pageable, filter.size());
}
Mongodb 3.4 has introduced $facet aggregation which processes multiple aggregation pipelines within a single stage on the same set of input documents.
Using $facet and $group you can find documents with $limit and can get total count.
You can use below aggregation in mongodb 3.6
db.collection.aggregate([
{ "$facet": {
"totalData": [
{ "$match": { }},
{ "$skip": 10 },
{ "$limit": 10 }
],
"totalCount": [
{ "$count": "count" }
]
}}
])

How to customize the Label Frequency when zoom in [amChart(serial)]

I am using amChart(serial) for showing graph. I have data of length more than 4000. I managed to show the last label value of category axis through "labelFunction" : formatLabel,. But now the problem is to set the label frequency =10. whenever a user zoom in the graph.
Please help, Thanks in advance.
here is code,
var chart= AmCharts.makeChart("rmChart",
{
"theme": "light",
"autoMargins": true, "chartScrollbar": {},
"type": "serial",
"categoryField": 'x-distance',
"legend": {
"useGraphSettings": false
},
"zoomControl": {
"panControlEnabled": false,
"zoomControlEnabled": false
},
"categoryAxis": {
"autoGridCount":false,
"includeHidden":true,
"dashLength":1,
" axisAlpha":1,
"gridPosition": "start",
"labelFunction" : formatLabel,
"minHorizontalGap":20,
"title": "Distance In Meters [m]"
},
"chartCursor": {
"zoomable":true,
"enabled": true,
},
"chartScrollbar": {
"enabled": false
},
"trendLines": [],
"valueAxes": [{
}],
"graphs": [
{
"balloonText": "Distance:[[x-axis]] dB:[[y-axis-0]]",
"fillAlphas": 0,
"fillToAxis": "x",
"lineAlpha": 1,
"valueField": "x-axis",
"valueField": "y-axis-0",
"lineColor": "#FF6600",
},
],
"guides": [],
"valueAxes": [
{
"id": "ValueAxis-1",
"title": "Strength [dB]",
"titleFontSize": 15,
}
],
"balloon": {},
"legend": {
"enabled": false,
"useGraphSettings": false
},
"titles": [
{
"id": "Title-1",
"size": 15,
"text": data[0]["date"]
}
],
"dataProvider": data,
export: {
enabled: false
},
"export": {
"enabled": true,
"menu": []
},
"chartScrollbar": {
"enabled":false
},
});
function formatLabel(value, valueText, axis) {
if (valueText.category%2==0) {
var lastNumber = (Math.abs(valueText.category) % 10)
if (lastNumber==0) {
return valueText.category;
}
}
if (valueText.category==data.length-1) {
return valueText.category;
}
else{
return "";
}
}
here is link to the jsfiddle
https://jsfiddle.net/8zw9h007/10/

Resources