kendo chart data display with filtering - kendo-ui

I want to use Kendo Chart and created it as:
<div id="chart"></div>
function createChart() {
$("#chart").kendoChart({
dataSource: {
transport: {
read: {
url: '#Url.RouteUrl(new { Area = "SuperAdmin", Controller = "DeviceDataUsage", Action = "DeviceDataUsageChart" })',
type: "POST",
dataType: "json"
}
},
sort: {
field: "Date",
dir: "asc"
}
},
categoryAxis: {
field: "Date"
}
});
}
$(document).ready(function () {
createChart();
});
My ajax call returns the following JSON:
[{"Date":"2022-08-01T00:00:00","Account":"0442047510-00001","ByteUsed":32596822687},{"Date":"2022-08-02T00:00:00","Account":"0442047510-00001","ByteUsed":36612506846},{"Date":"2022-08-03T00:00:00","Account":"0442047510-00001","ByteUsed":33163744510},{"Date":"2022-08-04T00:00:00","Account":"0442047510-00001","ByteUsed":33885441890},{"Date":"2022-08-05T00:00:00","Account":"0442047510-00001","ByteUsed":34242721748},{"Date":"2022-08-06T00:00:00","Account":"0442047510-00001","ByteUsed":27183604932},{"Date":"2022-08-07T00:00:00","Account":"0442047510-00001","ByteUsed":24292004315},{"Date":"2022-08-08T00:00:00","Account":"0442047510-00001","ByteUsed":24229587601},{"Date":"2022-08-09T00:00:00","Account":"0442047510-00001","ByteUsed":32560544972},{"Date":"2022-08-10T00:00:00Z","Account":"0442047510-00001","ByteUsed":29415723282},{"Date":"2022-08-01T00:00:00","Account":"0642341711-00001","ByteUsed":7153376},{"Date":"2022-08-02T00:00:00","Account":"0642341711-00001","ByteUsed":18197239},{"Date":"2022-08-03T00:00:00","Account":"0642341711-00001","ByteUsed":27505657},{"Date":"2022-08-04T00:00:00","Account":"0642341711-00001","ByteUsed":26128919},{"Date":"2022-08-05T00:00:00","Account":"0642341711-00001","ByteUsed":20523014},{"Date":"2022-08-06T00:00:00","Account":"0642341711-00001","ByteUsed":25958925},{"Date":"2022-08-07T00:00:00","Account":"0642341711-00001","ByteUsed":25540890},{"Date":"2022-08-08T00:00:00","Account":"0642341711-00001","ByteUsed":18362064},{"Date":"2022-08-09T00:00:00","Account":"0642341711-00001","ByteUsed":26562369},{"Date":"2022-08-10T00:00:00Z","Account":"0642341711-00001","ByteUsed":25290919}]
so, as we can see, there are data for 2 different accounts (it can be 3 different accounts or more). Data can be exist for the same date for both or not, no matter (if not, we think it ByteUsed as 0).
Now I want to display this data like:
where every bar is account name, X axis is date, Y axis is byteUsed.
How to do it? I don't understand how to set series depends on Account value from my JSON

You can group by Account, for example, and define a series of type "column" to set the rest of the configurations. I've also added a logarithmic scale to this example, just to demonstrate a possible configuration, as the sample data points do not show clearly in a linear scale value axis.

Related

jqgrid data comes as undefined while grouping

I am using free jqgrid.I am using following code as a simple example.Data comes out be correct without grouping but with grouping it is unable to capture data(placeid) not shown in the row.I understand that on grouping, rowObject does not have placeid but how do I go about resolving the issue.
jsfiddle link: http://jsfiddle.net/johnnash03/6jhqgxw8/5/
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}]
var cols = ["place","code"];
$("#grid").jqGrid({
datatype: "local",
height: 250,
colNames: cols,
colModel: [{
name: 'place',
}, {
name: 'code',
formatter: function( cellvalue, options, rowObject ) {
return rowObject['placeid']
}
}]
});
for(var i=0;i<rows.length;i++)
$("#grid").jqGrid('addRowData',i+1,rows[i]);
// Data comes correct on commenting following line.
$("#grid").jqGrid( 'groupingGroupBy', 'place');
The main problem in your demo is the usage of the property placeid, which isn't in any columns of the grid. You fills additionally the grid using addRowData method called in the loop. It's the slowest way to fill the grid, which I know. The most important in your case is that the internal data of the grid will be filled only with place, code and id properties. No placeid property will be saved locally. Thus one don't see it during the later groping the grid.
One can solves the problem by usage additionalProperties option, which specify the names of additional properties of input items, which needed be saved in the local data. Adding
additionalProperties: ["placeid"]
option solves the issue. See the modified demo http://jsfiddle.net/OlegKi/6jhqgxw8/8/
I'd strictly recommend you to modify the code to about the following:
var rows = [{
"place": "Kerala",
"placeid": "61",
"code": "kc10",
}];
$("#grid").jqGrid({
data: rows,
colModel: [
{ name: "place" },
{ name: "code",
formatter: function (cellvalue, options) {
return options.rowData.placeid;
}
}
],
grouping: true,
groupingView : {
groupField : ["place"]
},
localReader: { id: "placeid" }
});
Where one can add optionally additionalProperties: ["placeid"] too. See http://jsfiddle.net/OlegKi/6jhqgxw8/9/.
The above code create, fills and group the data at once. It uses localReader: { id: "placeid" } additionally to inform that placeid property has the rowid information (the unique values used as the values of id property of the rows: <tr> elements) instead of default id property.

Highcharts pie charts served from AJAX call

I am trying different ways of rendering json data from mysql/php to Highcharts. So far I've been successful rendering bar charts using this approach but for some reason, I have not been able to render data in a pie chart.
One js file handles the AJAX call:
$(function () {
var select_program = program_type_php;
var select_year = '2016';
console.log ('pie_chart'+program_type_php);
$.ajax({
url: 'model/job_group_pie_chart.php',
data: {user: 2, select_program:select_program, select_year:select_year},
type: 'GET',
async: true,
dataType: "json",
success: function (year_2016) {
pie_chart_2016(year_2016);
console.log('data 2016 job groups'+year_2016);
}
});
Upon success, I call a function in another js file (in this example, 'pie_chart_2016' and pass it the data object.
Here's the other js file responsible for rendering the data into a Highchart:
function pie_chart_2016 (year_2016) {
console.log('year_2016'+year_2016);
$('#pie-chart1').highcharts({
chart: {
plotBackgroundColor: null,
plotBorderWidth: null,
plotShadow: false,
type: 'pie'
},
title: {
text: ''
},
tooltip: {
pointFormat: '{series.name}: <b>{point.percentage:.1f}%</b>'
},
plotOptions: {
pie: {
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: true,
format: '<b>{point.name}</b>: {point.percentage:.1f} %',
style: {
color: (Highcharts.theme && Highcharts.theme.contrastTextColor) || 'black'
}
},
showInLegend: true
},
series: year_2016
}
});
};
I have checked, and I do get valid json from my php file:
[{name:"Group1",y:829},{name:"Group2",y:9247},{name:"Group3",y:71}]
These are raw counts (829, 9247, 71) but when I was able to get a pie chart to render by inputting values manually, Highcharts calculated the percentages for me - nice!
I've also set up enough console.logs to know that my functions are being called, and that my data object is being processed.
Still, all I get is a blank panel, and 'highcharts.com' in the lower left hand corner, so the html is working too.
The approach I'm using works really well with bar charts, so I am stumped!
Thanks for any help you can provide.
Thanks to Rahul, I moved 'series:' outside of plotOptions, and added these lines. I should have caught this sooner, that pie charts needs the 'data' property while bar charts have that included in their JSON array. Appears to be working well for now. Thanks again Rahul!
series: [{
name: 'Job Group',
colorByPoint: true,
data: year_2016
}]

Setting Value programmatically in KendoUI multiselect

I have my KendoUI MultiSelect widget initialized like this:
$("#" + key).kendoMultiSelect({
placeholder: placeholder,
dataTextField: dataText,
dataValueField: dataValue,
filter: "contains",
autoBind: false,
dataSource: {
type: "jsonp",
transport: {
read: {
url: urlValue
}
},
error: function(e) {
console.log(e);
}
},
value: GetSavedJSONObject(key),
//value: [
//{ Name: "Chang", Id: 2 },
// { Name: "Uncle Bob's Organic Dried Pears", Id: 7 }
//],
select: removeMark,
change: multiselect_checkForChanges,
autoClose: isAutoClose
});
where GetSavedJSONObject(key) is an array of objects like this:
[Object { Id=1, Name="AA"}, Object { Id=2, Name="BB"}]
The issue I'm facing is when the page loads, I can see "AA" and "BB" in the multiselect widget and no call is made to the url. However, when I attempt to add more items to the widget, there are none to be added because the widget thinks the only items available are the items I specified in the "value" field of the widget during initialization.
In the Server Filtering demo, you will see that the example sets the value of the widget just like I did but when you try to add more items to the widget, then a call is made to the url for more data and the widget opens.
I'm sure this is user error but I just need some pointers on what to try next in order to get the widget to display the rest of the data.
EDIT:
When I made GetSavedJSONObject(key) return an array of the Ids so
[1,2,3]
I was able to click on the widget to get the rest of the data. However, the desired outcome is being able to set the values of the widget (because I have the Id/Name pairs) without having to make the call to the datasource and being able to click on the widget to fetch the rest of the data)
Keeping my array of Objects and setting the serverFiltering: true attribute fixed the issue. Hope this saves someone else time. sigh

How to filter kendo grid data using filter specified for computed column

Have a look at this jsfiddle
I have a computed column (NewCol as mentioned in the below code) in the kendo grid - which has filter option enabled. The columns shows True/False based on the data of the other column.
schema: {
model: {
fields: {
OrderID: { type: "number" },
Freight: { type: "number" },
OrderDate: { type: "date" },
ShipCity: { type: "string" },
NewCol: {type: "string"}
}
}
}
The column definition in grid is,
{
field: "NewCol",
title: "Computed",
template: '#= (OrderDate > new Date(1996,6,10) ) ? "False" : "True" #'
}
Now, my issue is, the data are not getting filtered using that column filter i.e. True/False. If I filter with True/False, the grid goes empty.
I have tried defining function in datasource for the column as below, but then its not showing any data for the column.
NewCol: function () {
console.log(this.get('OrderDate'));
if (this.get('OrderDate') > new Date()) return 'False';
else return 'True';
},
Ans shows the js error Uncaught TypeError: undefined is not a function
There are two options. The first is compatible with your version of KendoUI, the second you will have to move to current one.
1st solution, define a schema.parse function that computes the new column on read time:
parse: function (data) {
var tgtDate = new Date(1996,6,10);
$.each(data.d.results, function(idx, elem) {
var d = parseInt(elem.OrderDate.substr(6));
elem.NewCol = (d > tgtDate ) ? "False" : "True";
});
return data;
}
From there, the column is like any other column received from the server so you can use it.
You can see you JSFiddle modified here http://jsfiddle.net/OnaBai/3TsGB/3/
2nd solution is use a new feature that allows to define a options.fields.fieldName.parse function for a field definition in the model and do something similar to what I did in the previous solution.

Kendo UI Grid, restful URL and paging

I have a web service from which I get text which is parsed into JSON using $parseJSON from jquery.
A client can get data from the web service by doing loading http://myserver/myfunction/{pagenumber}/{pagesize}
This will return an object
{
total: <some int> //A number indicating the total number of records
rowsForPage: [......] //An array with just the rows for the requested page
}
How can I use this endpoint as a datasource for a Kendo UI grid which will pass the page number and page size for the selected page.
For the life of me I cannot figure this out, but I would think this should be relatively simple.
$("#grid").kendoGrid({
dataSource: {
serverPaging: true,
schema: {
data: function(data) {
return data.rowsForPage;
},
total: function(data) {
return data.total;
}
},
transport: {
read: "http://myserver/myfunction"
}
}
);
As far as the url goes you have to parse out the url parameters skip and take to identify which records you should be passing back. If your page size is 100 and your page is 3 then it should pass
skip=200&take=100

Resources