I am struggling with google visualization api. I have defined following Spring controller that returns json representation of com.google.visualization.datasource.datatable.DataTable.
#RequestMapping(value = "/magento", method = RequestMethod.GET, headers = { "Accept=application/json" }, params = { "table" }, produces = "application/json; charset=utf-8")
public #ResponseBody
DataTable getMagentoCustomersTable() {
DataTable data = new DataTable();
ArrayList<ColumnDescription> cd = new ArrayList<ColumnDescription>();
cd.add(new ColumnDescription("customerId", ValueType.TEXT,
"Customer Id"));
cd.add(new ColumnDescription("email", ValueType.TEXT, "Email"));
cd.add(new ColumnDescription("firstName", ValueType.TEXT, "First Name"));
cd.add(new ColumnDescription("lastName", ValueType.TEXT, "Last Name"));
data.addColumns(cd);
// Fill the data table.
try {
for (CustomerInterface customer : magentoService.getCustomers()
.getCustomers()) {
data.addRowFromValues(customer.getCustomerId(),
customer.getEmail(), customer.getFirstName(),
customer.getLastName());
}
} catch (TypeMismatchException e) {
System.out.println("Invalid type!");
}
return data;
}
Then I am using following ajax call to produce Table output
$.ajax({
url : "${pageContext.request.contextPath}/customer/magento.json",
data : {
table : null
},
dataType : 'json'
}).success(
function(response) {
// Create the data table.
var data = new google.visualization.DataTable(response);
// Set chart options
var options = {
'title' : 'Magento Customers',
'width' : 400,
'height' : 300
};
// Instantiate and draw our table, passing in some options.
var table = new google.visualization.Table(document
.getElementById('chart_div'));
table.draw(data, options);
});
Ajax call return valid json object with data. Table is created with expected number of rows, there is no error in processing js but all table rows are empty as well as column headers.
So my question is am I missing something? What could went wrong?
==EDIT==
Below you can see sample json returned from ajax call to client. When this json is passed to DataTable constructor it is created but I noticed that no columns are created in DataTable object whereas rows are.
{
"warnings": [],
"rows": [{
"customProperties": {},
"cells": [{
"value": {
"value": "1",
"type": "TEXT",
"null": false,
"objectToFormat": "1"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}, {
"value": {
"value": "lname1#gmail.com",
"type": "TEXT",
"null": false,
"objectToFormat": "lname1#gmail.com"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}, {
"value": {
"value": "fname1",
"type": "TEXT",
"null": false,
"objectToFormat": "fname1"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}, {
"value": {
"value": "lname1",
"type": "TEXT",
"null": false,
"objectToFormat": "lname1"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}]
}, {
"customProperties": {},
"cells": [{
"value": {
"value": "2",
"type": "TEXT",
"null": false,
"objectToFormat": "2"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}, {
"value": {
"value": "lname2#gmail.com",
"type": "TEXT",
"null": false,
"objectToFormat": "lname2#gmail.com"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}, {
"value": {
"value": "fname1",
"type": "TEXT",
"null": false,
"objectToFormat": "fname1"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}, {
"value": {
"value": "lname2",
"type": "TEXT",
"null": false,
"objectToFormat": "lname2"
},
"type": "TEXT",
"null": false,
"customProperties": {},
"formattedValue": null
}]
}],
"numberOfRows": 2,
"numberOfColumns": 4,
"columnDescriptions": [{
"id": "customerId",
"type": "TEXT",
"pattern": "",
"customProperties": {},
"label": "Customer Id"
}, {
"id": "email",
"type": "TEXT",
"pattern": "",
"customProperties": {},
"label": "Email"
}, {
"id": "firstName",
"type": "TEXT",
"pattern": "",
"customProperties": {},
"label": "First Name"
}, {
"id": "lastName",
"type": "TEXT",
"pattern": "",
"customProperties": {},
"label": "Last Name"
}],
"customProperties": {},
"localeForUserMessages": null
}
Related
I am using Spring to build sample rest web service.
This is my RequestMapping:
#RequestMapping(value ="/employees", method = RequestMethod.GET)
public Response getAllEmployees(#Context HttpServletRequest request) {
List<Employee> employees = null;
try {
employees = repository.findAll();
}catch(Throwable e) {
RestServiceException rsException = new RestServiceException();
rsException.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
throw rsException;
}
return Response.ok(employees, MediaType.APPLICATION_JSON).build();
}
When I am using this, response is populated as below:
{
"context": {
"headers": {
"Content-Type": [
{
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
}
]
},
"configuration": null,
"entity": [
{
"id": 1,
"name": "Bilbo Baggins",
"role": "burglar"
},
{
"id": 2,
"name": "Frodo Baggins",
"role": "thief"
}
],
"entityType": "java.util.ArrayList",
"entityAnnotations": [],
"entityStream": {
"closed": false,
"committed": false
},
"length": -1,
"language": null,
"location": null,
"date": null,
"lastModified": null,
"mediaType": {
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
},
"entityClass": "java.util.ArrayList",
"lengthLong": -1,
"allowedMethods": [],
"acceptableMediaTypes": [
{
"type": "*",
"subtype": "*",
"parameters": {},
"quality": 1000,
"wildcardType": true,
"wildcardSubtype": true
}
],
"committed": false,
"requestCookies": {},
"acceptableLanguages": [
"*"
],
"responseCookies": {},
"stringHeaders": {
"Content-Type": [
"application/json"
]
},
"entityTag": null,
"links": []
},
"status": 200,
"length": -1,
"language": null,
"location": null,
"date": null,
"lastModified": null,
"mediaType": {
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
},
"metadata": {
"Content-Type": [
{
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
}
]
},
"allowedMethods": [],
"statusInfo": "OK",
"cookies": {},
"stringHeaders": {
"Content-Type": [
"application/json"
]
},
"entityTag": null,
"entity": [
{
"id": 1,
"name": "Bilbo Baggins",
"role": "burglar"
},
{
"id": 2,
"name": "Frodo Baggins",
"role": "thief"
}
],
"links": [],
"headers": {
"Content-Type": [
{
"type": "application",
"subtype": "json",
"parameters": {},
"wildcardType": false,
"wildcardSubtype": false
}
]
}
}
But I want response to be populated as below:
[
{
"id": 1,
"name": "Bilbo Baggins",
"role": "burglar"
},
{
"id": 2,
"name": "Frodo Baggins",
"role": "thief"
}
]
Note : I don't want to change the return type of the method to List.(I want the return type as Response(javax.ws.rs.core.Response) object only).
Is there anyway to populate only the Employee_List in the response.
You are trying to use both JAX-RS and Spring MVC, I guess. With the Response, Spring MVC doesn't recognize the response entity and it serializes the object similar to other objects. If you are using Spring MVC, you want to be using ResponseEntity. You can refer to the below code snippet.
Change the method to return ResponseEntity rather.
#RequestMapping(value ="/employees", method = RequestMethod.GET)
public ResponseEntity getAllEmployees(#Context HttpServletRequest request) {
List<Employee> employees = null;
try {
employees = repository.findAll();
}catch(Throwable e) {
RestServiceException rsException = new RestServiceException();
rsException.setStatus(HttpStatus.INTERNAL_SERVER_ERROR);
throw rsException;
}
return ResponseEntity.ok(employees);
}
A kendo grid has been having a problem with the drag-and-drop functionality, where it has a copy of all the data essentially stuck to the left side of the grid, in-line with the cursor.
The grid that I attach it to is set to editable, however, that appears to have no impact on this. Disabling editing does not fix the problem. It is also worth noting that the grid is bound to the dynamic type, which may have some impact, but I didn't find anything looking into that.
Sortable block is below
#(Html.Kendo().Sortable()
.For("#QuestionGridEditable")
.Filter("table > tbody > tr")
.Cursor("move")
.Axis(SortableAxis.Y)
.PlaceholderHandler("placeholder")
.ContainerSelector("#QuestionGridEditable tbody")
.Events(e => {
e.Change("onDrag");
e.Move("startDrag");
})
Image of the problem
Generated javascript
<script>
kendo.syncReady(function() {
jQuery("#QuestionGridEditable").kendoGrid({
"dataBound": onNewRow,
"columns": [{
"title": "#",
"attributes": {
"style": "width: 2em"
},
"headerAttributes": {
"data-field": "number",
"data-title": "#"
},
"field": "number",
"encoded": true,
"editor": "\u003cinput id=\"number\" max=\"2147483647\" min=\"-2147483648\" name=\"number\" style=\"width:100%\" type=\"text\" /\u003e\u003cscript\u003e\r\n\tkendo.syncReady(function(){jQuery(\"#number\").kendoNumericTextBox({\"format\":\"n0\",\"decimals\":0});});\r\n\u003c/script\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"number\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e",
"editable": funcFalse
}, {
"title": "Visibility",
"attributes": {
"style": "width: 30%"
},
"headerAttributes": {
"data-field": "viewableby",
"data-title": "Visibility"
},
"template": "#=ArrayToString(viewableby)#",
"field": "viewableby",
"encoded": true,
"editor": "\u003cselect id=\"viewableby\" multiple=\"multiple\" name=\"viewableby\"\u003e\u003c/select\u003e\u003cscript\u003e\r\n\tkendo.syncReady(function(){jQuery(\"#viewableby\").kendoMultiSelect({\"dataSource\":[\"Everyone\",\"Faculty\",\"Students\",\"Self\"],\"value\":\"#=ViewersCompactToList(data)#\"});});\r\n\u003c/script\u003e\r\n\r\n\r\n\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"viewableby\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e"
}, {
"title": "Radio button",
"headerAttributes": {
"data-field": "cells[0].Text.text",
"data-title": "Radio button"
},
"field": "cells[0].Text.text",
"encoded": true,
"editor": "\u003cbutton id=\"buttonAddRadio\" class=\"k-button k-button-icontext\" onclick=\"addRB\"\u003e+\u003c/button\u003e\r\n\u003cinput class=\"k-textbox\" id=\"cells_0__Text_text\" name=\"cells[0].Text.text\" /\u003e\r\n \r\n\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"cells[0].Text.text\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e",
"editable": funcTrue
}, {
"title": "Basic text entry static",
"headerAttributes": {
"data-field": "cells[1].Text.text",
"data-title": "Basic text entry static"
},
"field": "cells[1].Text.text",
"encoded": true,
"editor": "\u003cinput class=\"k-textbox\" id=\"cells_1__Text_text\" name=\"cells[1].Text.text\" /\u003e\u003cspan class=\"field-validation-valid\" data-valmsg-for=\"cells[1].Text.text\" data-valmsg-replace=\"true\"\u003e\u003c/span\u003e",
"editable": funcTrue
}, {
"attributes": {
"style": "width: 2em"
},
"command": [{
"name": "destroy",
"buttonType": "ImageAndText",
"text": "Delete"
}]
}],
"scrollable": false,
"editable": {
"confirmation": "Are you sure you want to delete this record?",
"confirmDelete": "Delete",
"cancelDelete": "Cancel",
"mode": "incell",
"template": null,
"createAt": "bottom",
"create": true,
"update": true,
"destroy": true
},
"toolbar": {
"command": [{
"name": null,
"buttonType": "ImageAndText",
"text": "Add new record"
}, {
"name": null,
"buttonType": "ImageAndText"
}]
},
"messages": {
"noRecords": "No records available."
},
"dataSource": {
"type": (function() {
if (kendo.data.transports['aspnetmvc-ajax']) {
return 'aspnetmvc-ajax';
} else {
throw new Error('The kendo.aspnetmvc.min.js script is not included.');
}
}
)(),
"transport": {
"read": {
"url": "/FeedbackForm/ReadQuestionGrid/57"
},
"prefix": "",
"update": {
"url": "/FeedbackForm/UpdateQuestionGrid"
},
"create": {
"url": "/FeedbackForm/CreateQuestionGrid/57"
},
"destroy": {
"url": "/FeedbackForm/DestroyQuestionGrid"
}
},
"serverPaging": true,
"serverSorting": true,
"serverFiltering": true,
"serverGrouping": true,
"serverAggregates": true,
"filter": [],
"schema": {
"data": "Data",
"total": "Total",
"errors": "Errors",
"model": {
"id": "id",
"fields": {
"id": {
"editable": false,
"type": "number",
"defaultValue": -1
},
"number": {
"type": "number"
},
"viewableby": {
"type": "object",
"defaultValue": []
},
"cells": {
"type": "object",
"defaultValue": [{
"Location": {
"id": 0,
"question_id": 0,
"column_id": 14
},
"Text": {
"id": 0,
"location_id": 0,
"viewableby": null,
"text": null
}
}, {
"Location": {
"id": 0,
"question_id": 0,
"column_id": 9
},
"Text": {
"id": 0,
"location_id": 0,
"viewableby": null,
"text": null
}
}]
}
}
}
},
"batch": true
},
"navigatable": true
});
});
<script>
kendo.syncReady(function() {
jQuery("#QuestionGridEditable").kendoSortable({
"change": onDrag,
"filter": "table \u003e tbody \u003e tr",
"container": "#QuestionGridEditable tbody",
"axis": "y",
"cursor": "move",
"placeholder": placeholder
});
});
The problem came down to the HintHandler. Setting the sortable item's HintHandler to a JavaScript function that returned false fixed the issue with the ghost image.
I have create a kendo pivot grid like the example. I have this options
$scope.options = {
"dataSource": {
"type": "xmla",
"columns": [],
"rows": [{
"name": ["[Date].[Hierarchy - QM]"],
"expand": false
}],
"measures": [],
"transport": {
"connection": {
"catalog": "EDI",
"cube": "EDI"
},
"read": {
"url": "..../msmdpump.dll",
"type": "POST",
"dataType": "text",
"contentType": "text/xml"
}
},
"filter": {
"field": "[Date].[Hierarchy - QM]",
"operator": "eq",
"value": "new Date(2016, 1, 1)"
},
"schema": {
"type": "xmla"
}
}
}
and all works perfect. BUT, when i change the filter operator from 'eq' to 'gte' i get the following error
Cannot read property 'replace' of undefined
I have a grid which would have many columns typed date. These all grids is generated from a generic function, so that I cannot know whether the column type is date or not. There is one rule validates through all columns. It is that all columns name end with "Date" suffix. For instance, createDate, editDate, visitedDate, etc...
So that, I can understand that it can be date and I parse it like you can see at the dataSource parse function
I have trouble when I update the cell. It does not reflect its own value to Model. The date column proto function returns "Invalid Date" error. I do not understand what it happen
var dataSource = new kendo.data.DataSource({
"data": [
{
"hidden_gridColumns": "",
"id": "21632",
"projectId": "146",
"customerTypeId": "4",
"district": "0",
"fieldSize": "12",
"fieldType": "0",
"floorCoveringType": "12",
"lastChangeDate": null,
"estimatedModificationDate": null,
"latestCompany": ""
}
],
"schema": {
"model": {
"id": "id",
"fields": {
"gridColumns": {
"type": "string"
},
"id": {
"type": "string"
},
"projectId": {
"type": "string"
},
"customerTypeId": {
"type": "string"
},
"district": {
"type": "string"
},
"fieldSize": {
"type": "string"
},
"fieldType": {
"type": "string"
},
"floorCoveringType": {
"type": "string"
},
"lastChangeDate": {
"type": "date"
},
"estimatedModificationDate": {
"type": "string"
},
"latestCompany": {
"type": "string"
}
}
},
parse: function(data){
$.each(data,
function(rowNo,
row){
$.each(row,
function(colName,
column){
if(colName.indexOf("Date")>=0){
console.log(colName + " taranıyor");
row[colName] = kendo.parseDate(row[colName], "dd-MM-yyyy");
}
});
});
return data;
}
},
"batch": true
})
And this is my columns structure:
var columns = [
{
"title": "gridColumns",
"field": "gridColumns",
"hidden": true
},
{
"title": "id",
"field": "id",
"hidden": true
},
{
"title": "projectId",
"field": "projectId",
"hidden": true
},
{
"title": "Müşteri Tipi",
"field": "customerTypeId",
"hidden": false,
"width": "91",
"values": [
{
"value": "1",
"text": "Yurtiçi "
},
{
"value": "2",
"text": "Yurtdışı"
},
{
"value": "3",
"text": "Spor Kulübü"
},
{
"value": "4",
"text": "Diğer"
},
{
"value": "5",
"text": "Üniversite"
},
{
"value": "6",
"text": ""
}
]
},
{
"title": "district",
"field": "district",
"hidden": true,
"width": "132"
},
{
"title": "Saha Ölçüsü",
"field": "fieldSize",
"hidden": false,
"width": "85"
},
{
"title": "Saha Türü",
"field": "fieldType",
"hidden": false,
"values": [
{
"value": "1",
"text": "Açık"
},
{
"value": "0",
"text": "Kapalı"
}
]
},
{
"title": "Halı Cinsi",
"field": "floorCoveringType",
"hidden": false,
"width": "76"
},
{
"title": "Son Halı değişim Tarih",
"field": "lastChangeDate",
"hidden": false,
"format": "{0:dd-MM-yyyy}"
},
{
"title": "Tahmini Yenileme Tarihih",
"field": "estimatedModificationDate",
"hidden": false
},
{
"title": "Son Çalıştığı Halı Firması",
"field": "latestCompany",
"hidden": false
}
]
I solved this problem by the code below:
parse: function(response) {
var tmpData=[];
for (var i = 0; i < response.length; i++) {
var tmpRow = response[i];
$.each(tmpRow, function(colNo, colValue){
if(colNo.indexOf("Date")>-1){
tmpRow[colNo]=kendo.parseDate(new Date(tmpRow[colNo]));
}
});
tmpData.push(tmpRow);
}
return tmpData;
}
I'm in the process of trying to setup a Kibana dashboard. This dashboard is hitting an ElasticSearch index. My index has the following mappings:
"myindex": {
"mappings": {
"animals": {
"properties": {
"#timestamp": {
"type": "date",
"format": "dateOptionalTime"
},
"#version": {
"type": "string"
},
"Class": {
"type": "string"
},
"Order": {
"type": "string"
},
"Family": {
"type": "string"
},
"Genus": {
"type": "string"
},
"Species": {
"type": "string"
}
}
},
"elements" : {
"properties": {
"#timestamp": {
"type": "date",
"format": "dateOptionalTime"
},
"#version": {
"type": "string"
},
"Symbol": {
"type": "string"
},
"Name": {
"type": "string"
},
"Group": {
"type": "string"
},
"Period": {
"type": "string"
}
}
}
}
}
As the mappings show, my index has two different types of information. My challenge is, I don't know how to setup my kibana dashboard to just list the information for each type. I've confirmed that the data in my elasticsearch instance is the correct data.
In my dashboard, I'm trying to show two tables. One table will show all of the documents associated with "animals". The other table will show all of the documents associated with "elements". Unfortunately, I can't figure out how to focus the results of a table down to a specific type. I'm basically trying to figure out how to setup either a query or a filter (not sure the difference between the two in the kibana world) for a specific panel. Currently, my dashboard looks like this:
{
"title": "Research",
"services": {
"query": {
"list": {
"0": {
"query": "*",
"alias": "",
"color": "#7EB26D",
"id": 0,
"pin": false,
"type": "lucene"
}
},
"ids": [
0
]
},
"filter": {
"list": {
"0": {
"type": "time",
"field": "#timestamp",
"from": "now-{{ARGS.from || '24h'}}",
"to": "now",
"mandate": "must",
"active": true,
"alias": "",
"id": 0
}
},
"ids": [
0
]
}
},
"rows": [
{
"title": "Animals",
"height": "350px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"title": "Animals",
"error": false,
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "table",
"size": 100,
"pages": 5,
"offset": 0,
"sort": [
"#timestamp",
"desc"
],
"style": {
"font-size": "9pt"
},
"overflow": "min-height",
"fields": [
"Class",
"Order",
"Family",
"Genus",
"Species"
],
"localTime": true,
"timeField": "#timestamp",
"highlight": [],
"sortable": true,
"header": true,
"paging": true,
"spyable": true,
"queries": {
"mode": "all",
"ids": [
0
]
},
"field_list": true,
"status": "Stable",
"trimFactor": 300,
"normTimes": true
}
],
"notice": false
},
{
"title": "",
"height": "350px",
"editable": true,
"collapse": false,
"collapsable": true,
"panels": [
{
"title": "Elements",
"error": false,
"span": 12,
"editable": true,
"group": [
"default"
],
"type": "table",
"size": 100,
"pages": 5,
"offset": 0,
"sort": [
"#timestamp",
"desc"
],
"style": {
"font-size": "9pt"
},
"overflow": "min-height",
"fields": [
"Symbol",
"Name",
"Group",
"Period"
],
"localTime": true,
"timeField": "#timestamp",
"highlight": [],
"sortable": true,
"header": true,
"paging": true,
"spyable": true,
"queries": {
"mode": "all",
"ids": [
0
]
},
"field_list": true,
"trimFactor": 300,
"normTimes": true
}
],
"notice": false
}
],
"editable": true,
"failover": false,
"index": {
"interval": "none",
"default": "myindex"
},
"style": "dark",
"panel_hints": true,
"pulldowns": [
{
"type": "query",
"collapse": false,
"notice": false,
"query": "*",
"pinned": true,
"history": [],
"remember": 10
},
{
"type": "filtering",
"collapse": true,
"notice": false
}
],
"loader": {
"save_gist": false,
"save_elasticsearch": true,
"save_local": true,
"save_default": true,
"save_temp": true,
"save_temp_ttl_enable": true,
"save_temp_ttl": "30d",
"load_gist": true,
"load_elasticsearch": true,
"load_elasticsearch_size": 20,
"load_local": true,
"hide": false
},
"refresh": "30s"
}
Can someone tell me how to show two different types of documents in Kibana? I see a queries object on the table panel. Yet, I have no idea how to use it.
Thank you so much
You can use the _type field to narrow the result to a specific elastic search type (e.g. animals).
So when you define the query (or filter) for your table, just make sure to specify the relevant _type (i.e. _type: animals)
You can use scripted fields to have value of type as separate field which will be indexed.
or you can add _type field to search field it will be available.
In case of scripted fields add as doc['_type'].value and give it any name you want.
https://github.com/elastic/kibana/issues/5684