I am using the jQuery-Plugin Chart.JS to create nice looking diagrams and graphs for my site - it works quite well if i'm using static values.
Now i am trying to create the chart dynamically from values that are stored in a table in a database.
I read quite a lot about how to do it (ajax-call etc.) but i can't just figure out where my fault is.
This is my script for the chart together with the ajax-method:
$(document).ready(function () {
$.ajax({
type: "POST",
url: "/ChartData.asmx/GetChartData",
data: jsonData,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: OnSuccess_,
error: OnErrorCall_
});
// Defining chart.js-function to realize a woundchart with the size of the wound
function OnSuccess_(response) {
var aData = response.d;
var array = [];
$.each(aData, function (inx, val) {
var obj = {};
obj.value = val.value;
array.push(obj);
});
var woundchart = document.getElementById('chartForWound');
var chart = woundchart.getContext('2d');
var colorFade = chart.createLinearGradient(0, 0, 0, 500); // creating linear gradient with: (x0, y0, x1, y1)
// adding colorstops between 0 and 1 in the linear gradient
colorFade.addColorStop(0, "#FF0000");
colorFade.addColorStop(0.5, "#FFFF33");
colorFade.addColorStop(1, "#00FF33");
new Chart(chart, {
type: 'line', // defining type of the chart as linechart
data: {
labels: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], // Labels for x-Axis
datasets: [{
label: "Wundgröße in mm",
fill: false,
pointRadius: 5,
pointHoverRadius: 7,
borderColor: colorFade,
pointBorderColor: colorFade,
pointBackgroundColor: colorFade,
pointHoverBackgroundColor: colorFade,
pointHoverBorderColor: colorFade,
data: array, // TODO: entering values from database (y-values)
}]
},
// Defining further options to style the graph
options: {
responsive: true,
animation: {
duration: 4000, // time while animation is active (4000ms)
easing: 'easeInQuart' // style of the animation
},
scales: {
xAxes: [{
scaleLabel: {
display: true,
labelString: 'Zeit / Tage' // label for x-Axis
}
}],
yAxes: [{
scaleLabel: {
display: true,
labelString: 'Wundgröße / mm' // label for y-Axis
}
}]
}
}
});
}
});
And this is my method in my .asmx-File to get the values from the column in the database:
[WebMethod]
public List<ChartData> GetChartData(List<string> chartdata){
List<ChartData> woundData = new List<ChartData>();
ConnectionStringSettings connectionString = ConfigurationManager.ConnectionStrings["pflegedokumentationConnectionString"];
SqlConnection conn = new SqlConnection(connectionString.ConnectionString);
SqlCommand query = new SqlCommand("SELECT measurement_results FROM epadoc_mod_wound_chart_results", conn);
conn.Open();
SqlDataReader dr = query.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
ChartData data = new ChartData();
data.value = Convert.ToInt32(dr["measurement_results"].ToString());
woundData.Add(data);
}
}
return woundData;
}
I dont get any error when running the code, the chart just isn't be created.
Related
I'm using datatable.js, I have table in view and API returns JSON results. I have lots of rows and i want to bind them by each page.Is there any way that datatable do it for me? I read lots of documentation but I didn't find anything useful for API
API Controller
public IHttpActionResult Get(int id)
{
return Ok(_context.Students.OrderBy(c => c.id).Skip((id - 1) * 10).Take(10).ToList());
}
Here is my table config
<script>$(document).ready(function () {
var pageindex = 1;
var table = $("#staff").DataTable({
"processing": true,
"serverSide": true,
ajax: {
url: "/Api/staffs",
dataSrc: "",
data: {
id: pageindex,
},
},
columns: [
{
data: "stf_FirstName",
},
{
data: "stf_LastName",
},
{
data: "stf_Code",
}
]
});
table.on('page', function () {
Currentpagenum();
});
function Currentpagenum() {
var info = table.page.info();
pageindex = (info.page + 1);
}
});</script>
If there are lots of rows than server side processing should be used
Try this :
HTML :
<table id="tblGrid" class="table display nowrap" style="width:100%">
</table>
JS :
function SetGrid() {
$('#tblGrid').DataTable({
"proccessing": true,
"serverSide": true,
// server side
"ajax": {
url: "/api/YourController/Method",
type: 'POST',
"data": {
Param1: Value1
}
},
// if client side
//data: YourList, // Js Array
columns: [
{ data: 'Id' },
{ data: 'Name', title: "Name" },
...
...
{ title: "Actions"},
],
"columnDefs": [
{ targets: 0, visible: false,},
],
"ordering": false,
"lengthChange": false,
"pageLength": 10,
"bDestroy": true,
"oLanguage": {
"sEmptyTable": "No Record Found"
},
});
}
Sample C# :
public object YourMethod(Param1 Value1)
{
var start = int.Parse(HttpContext.Current.Request.Form["start"]);
var result = new {
draw = HttpContext.Current.Request.Form["draw"],
recordsTotal = YourList.Count,
recordsFiltered = YourList.Count,
data = YourList.Skip(start).Take(10).ToList()
};
return result;
}
Hi tried to load the jqgrid with json by passing javascript object. but the grid is not loading.
Below is my javascript code
oSearchParam = {
InvoiceNo: document.getElementById('txtInvoiceNumber').value,
}
var grid = $("#dataGrid")[0];
//my code
$("#dataGrid").jqGrid({
// setup custom parameter names to pass to server
prmNames: {
rows: "numRows",
page: "page",
sort: "sortField",
order: "sortOrder"
},
// add by default to avoid webmethod parameter conflicts
// postData: { oSearchParam: oSearchParam },
// setup ajax call to webmethod
datatype: function (postdata) {
$(".loading").show(); // make sure we can see loader text
$.ajax({
url: 'InvoiceSearch.aspx/GetSearchResultData',
type: "POST",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(postdata),
dataType: "json",
success: function (data, st) {
if (st == "success") {
var grid = $("#dataGrid")[0];
alert(data.d);
grid.addJSONData(JSON.parse(data.d));
}
},
error: function () {
alert("Error with AJAX callback");
}
});
},
// this is what jqGrid is looking for in json callback
jsonReader: {
root: "rows",
page: "page",
total: "totalpages",
records: "totalrecords",
cell: "cell",
id: "id", //index of the column with the PK in it
repeatitems: true
},
autowidth: true,
shrinkToFit: true,
height: 'auto',
colNames: ['InvoiceNo'],
colModel: [
{ name: 'InvoiceNo', index: 'InvoiceNo', width: 55, search: false }
],
rowNum: 10,
rowList: [10, 20, 30],
pager: jQuery("#pagingGrid"),
sortname: "InvoiceNo",
sortorder: "asc",
viewrecords: true,
caption: "Grid Title Here",
gridComplete: function () {
$(".loading").hide();
}
}).jqGrid('navGrid', '#pagingGrid', { edit: true, add: true, del: true },
{}, // default settings for edit
{}, // add
{}, // delete
{ closeOnEscape: true, closeAfterSearch: true }, //search
{}
)
And below is the webmethod
[WebMethod]
public static string GetSearchResultData(int? numRows, int? page, string sortField, string sortOrder, SearchParam oSearchParam)
{
DataTable dtInvoiceList = Mymethod();
var query = dtInvoiceList.AsEnumerable()
.Select(i => new SearchParam
{
InvoiceNo = i.Field<string>("InvoiceNo"),
// ImageId = i.Field<string>("DocID"),
InvoiceAmount = i.Field<decimal>("Amount"),
// ImageId = i.Field<string>("DocID"),
Status = i.Field<string>("Status"),
CurrentlyWith = i.Field<string>("CurrentlyWith")
}).ToList();
//--- setup calculations
int pageIndex = page ?? 1; //--- current page
int pageSize = numRows ?? 10; //--- number of rows to show per page
int totalRecords = query.Count(); //--- number of total items from query
int totalPages = (int)Math.Ceiling((decimal)totalRecords / (decimal)pageSize); //--- number of pages
var sortedRecords = query
.Skip((pageIndex - 1) * pageSize) //--- page the data
.Take(pageSize).ToList();
//--- format json
var jsonData = new
{
totalpages = totalPages, //--- number of pages
page = pageIndex, //--- current page
totalrecords = totalRecords, //--- total items
rows = (
from row1 in sortedRecords
select new
{
i = row1.ImageId,
cell = new string[] {
row1.InvoiceNo,
row1.Status,
row1.CurrentlyWith,
row1.InvoiceAmount.ToString(),
}
}
).ToArray()
};
string result = Newtonsoft.Json.JsonConvert.SerializeObject(jsonData);
return result;
}
My webmethod is not getting called.
Can anybody help me on this.
I am trying the code of highstocks which is given below
<script type="text/javascript">
$(function () {
Highcharts.setOptions({
global: {
useUTC: false
}
});
// Create the chart
$('#container').highcharts('StockChart', {
chart: {
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = <%=chartData%>
series.addPoint([x, y], true, true);
}, 1000);
}
}
},
rangeSelector: {
buttons: [{
count: 1,
type: 'minute',
text: '1M'
}, {
count: 5,
type: 'minute',
text: '5M'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: false,
selected: 0
},
title: {
text: 'Sensor Data'
},
exporting: {
enabled: false
},
series: [{
name: 'Sensor Value',
data: (function () {
//generate an array of random data
var data = [], time = (new Date()).getTime(), i;
for (i = -999; i <= 0; i++) {
data.push([
time + i * 1000,
<%= chartData%>
]);
}
return data;
})()
}]
});
});
</script>
and displaying it in to the container
<div id="container" style="min-width: 400px; height: 400px; margin: 0 auto; width: 733px;"></div>
The code behind is
public string chartData
{
get;
set;
}
protected void Page_Load(object sender, EventArgs e)
{
GetData();
List<int> _data = new List<int>();
foreach (DataRow row in dt.Rows)
{
_data.Add((int)row["Id"]);
}
JavaScriptSerializer jss = new JavaScriptSerializer();
chartData = jss.Serialize(_data); //this make your list in jSON format like [88,99,10]
Response.Write(chartData);
}
private void GetData()
{
StringBuilder str = new StringBuilder();
SqlConnection con = new SqlConnection("Data Source=INBDQ2WK2LBCD2S\\SQLEXPRESS;Initial Catalog=MCAS;Integrated Security=SSPI");
SqlDataAdapter adp = new SqlDataAdapter("select top 1 Id from Monitoring order by Id desc ", con);
adp.Fill(dt);
}
Here I have created a JSON and I am transferring it to the javascript for highchart.
The problem I am having is that it is showing only one point. The values which are also updated in the database it is not updating in the chart.
What is wrong with it?
In your code I can see this:
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = <%=chartData%>;
series.addPoint([x, y], true, true);
}, 1000);
I guess, that chartData variable is where you have stored new point? At least you expect to have there. However your variable chartData is assigned in HTML once, after page is loaded from server. That you will update value on server, doesn't mean value get updated on client side.
I advice to use AJAX calls, for example: http://www.highcharts.com/studies/live-server.htm (see sources for code example).
Ok. I have several JQuery Ajax posts, which are calling individual WebMethods. I've come across an issue, and i now need to combine the webmethods into one, but then still be able to split out the return values according to the list. So for example, I need something that returns multiple lists, so that my Ajax call, can then render the respective Jquery Datatables like: table 1 = drList[0], table 2 =drList[1] etc.
Webmethod code is below:
[WebMethod]
[ScriptMethod]
public static List<GlobalClasses.ValueDateSummary> GetValueDateSummary()
{
string TSQL = "SELECT * FROM vw_view1 WHERE (SenderBIC ='" + HttpContext.Current.User.Identity.Name + "') ORDER BY ValueDate DESC";
DataTable dtValueDateSummary = null;
GlobalClasses.ValueDateSummary objSummary;
SqlConnection conn = new SqlConnection(WebConfigurationManager.ConnectionStrings["MIReporting"].ConnectionString);
using (conn)
{
conn.Open();
using (SqlDataAdapter sqlAdapter = new SqlDataAdapter(TSQL, conn))
{
dtValueDateSummary = new DataTable();
sqlAdapter.Fill(dtValueDateSummary);
}
}
List<GlobalClasses.ValueDateSummary> drList = new List<GlobalClasses.ValueDateSummary>();
foreach (DataRow row in dtValueDateSummary.Rows)
{
objSummary = new GlobalClasses.ValueDateSummary();
objSummary.fld1= row["1"].ToString();
objSummary.fld2 = row["2"].ToString();
objSummary.fld3 = row["3"].ToString();
objSummary.fld5 = row["4"].ToString();
drList.Add(objSummary);
}
return drList;
}
the only difference between this and the other webmethod call is the view being used.
the Ajax call is :
$.ajax({
type: 'POST',
url: 'Default.aspx/GetValueDateSummary',
data: '{}',
contentType: 'application/json;charset=utf-8',
dataType: 'json',
success: function (response) {
renderMsgSummary(response.d);
},
error: function (errMsg) {
$('#errorMessage').text(errMsg);
}
})
the renderMsgSummary is the Jquery datatable, so this need to be as follows:
renderMsgSummary(response.d[0]);
renderOtherTable(response.d[1]);
OK - almost there, trying to merge the client side script in now.
<script type="text/javascript">
$(document).ready(function () {
function renderMsgVal(result) {
var dtMsgValData = [];
$.each(result, function () {
dtMsgValData.push([
this.SenderBIC,
this.ValueDate,
this.MessageType,
this.Reference
]);
});
function renderMsgSummary(result) {
var dtMsgSumData = [];
$.each(result, function () {
dtMsgSumData.push([
this.SenderBIC,
this.MessageDate,
this.MessageType,
this.Count
]);
});
$('#tblValueDateSummary').dataTable({
"aaData": dtMsgValData,
"aLengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100]]
'asStripClasses': null,
"iDisplayLength": 10,
//"aaSorting": [[0, "asc"]],
"bJQueryUI": true,
"bFilter": true,
"bAutoWidth": false,
"bProcessing": true,
// "sDom": 'RC<"clear">lfrtip',
"sDom": 'RC<"H"lfr>t<"F"ip>',
//Scrolling .......
"sScrollY": "250px",
"sScrollX": "100%",
"sScrollXInner": "100%",
"bScrollCollapse": true,
//Dynamic Language .......
"oLanguage": {
//"sZeroRecords": "There are no messages that match your,
"sLengthMenu": "Display _MENU_ records per,
"sInfo": "Displaying _START_ to _END_ of _TOTAL_ records",
"sInfoEmpty": "Displaying _START_ to _END_ of _TOTAL_m
"sInfoFiltered": "(filtered from _MAX_ total records)",
"sEmptyTable": 'No Rows to display.....!',
"sSearch": "Search all columns:",
"sLoadingRecords": "Please wait - loading..."
},
"oSearch": {
"sSearch": "",
"bRegex": false,
"bSmart": true
}
});
$('#tblMessageDateSummary').dataTable({
"aaData": dtMsgSumData,
"aLengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100]]
"asStripClasses": null,
"iDisplayLength": 10,
"aaSorting": [[0, "asc"]],
"bJQueryUI": true,
"bFilter": true,
"bAutoWidth": true,
"bProcessing": true,
"sDom": 'RC<"clear">lfrtip',
//"sDom": '<"F"ip>l',
//Scrolling .......
"sScrollY": "250px",
"sScrollX": "100%",
"sScrollXInner": "100%",
"bScrollCollapse": true,
//Dynamic Language .......
"oLanguage": {
// "sZeroRecords": "There are no messages that match your,
"sLengthMenu": "Display _MENU_ records per,
"sInfo": "Displaying _START_ to _END_ of _TOTAL_ records",
"sInfoEmpty": "Showing 0 to 0 of 0 records",
"sInfoFiltered": "(filtered from _MAX_ total records)",
"sEmptyTable": 'No Rows to display.....!',
"sSearch": "Search all columns:"
},
"oSearch": {
"sSearch": "",
"bRegex": false,
"bSmart": true
}
});
}
$.ajax({
type: 'POST',
url: 'Default.aspx/GetMessageDetails',
data: '{}',
contentType: 'application/json;charset=utf-8',
dataType: 'json',
success: function (response) {
//console.log(response);
//alert(response.d);
renderMsgVal(response.d[0]);
renderMsgSummary(response.d[1]);
},
error: function (errMsg) {
$('#errorMessage').text(errMsg);
}
});
</script>
not sure if this is possible?
If I understand correctly, you can return a List of Lists.
public static List<List<GlobalClasses.ValueDateSummary>> GetValueDateSummary()
{
var allLists = new List<List<GlobalClasses.ValueDateSummary>>();
foreach (DataRow row in dtValueDateSummary.Rows)
{
objSummary = new GlobalClasses.ValueDateSummary();
objSummary.fld1= row["1"].ToString();
objSummary.fld2 = row["2"].ToString();
objSummary.fld3 = row["3"].ToString();
objSummary.fld5 = row["4"].ToString();
drList.Add(objSummary);
}
allLists.Add(drList);
//add other lists to allLists
//..
return allLists;
}
wrap your various lists into a bigger class i.e.
make a class something like
public class Wrapper
{
public List<GlobalClasses.ValueDateSummary> list1 {get;set;}
public List<GlobalClasses.ValueDateSummary> list2 {get;set;}
public List<SomeOtherClassCollectino> list3{get;set;}
}
and return this wrapper in your webmethod i.e.
[WebMethod]
[ScriptMethod]
public static List<GlobalClasses.ValueDateSummary> GetValueDateSummary()
{
// your db logic
Wrapper wrapper = new Wrapper();
List<GlobalClasses.ValueDateSummary> drList = new List<GlobalClasses.ValueDateSummary>();
foreach (DataRow row in dtValueDateSummary.Rows)
{
objSummary = new GlobalClasses.ValueDateSummary();
objSummary.fld1= row["1"].ToString();
objSummary.fld2 = row["2"].ToString();
objSummary.fld3 = row["3"].ToString();
objSummary.fld5 = row["4"].ToString();
drList.Add(objSummary);
}
wrapper.list1 = drList;
//similarly fetch other lists
//wrapper.list2 = drList2;
return new JavaScriptSerializer().Serialize(wrapper);
}
and on the client side you can access it like:
var jsonData = $.parseJSON(msg.d);
renderMsgSummary(jsonData.list1);
renderMsgSummary(jsonData.list2);
I am working on a MVC application. I have written a jqGrid in my aspx page.
$(document).ready(function () {
jQuery("#jqgajax").jqGrid({
url: 'http://localhost:54136/home/fetchData',
datatype: "json",
colNames: ['ProcessName', 'WorkingSet64'],
colModel: [
{ name: 'ProcessName', index: 'ProcessName', width: 55 },
{ name: 'WorkingSet64', index: 'WorkingSet64', width: 90 }
],
rowNum: 80,
mtype:'Get',
width: 700,
rowList: [10, 20, 30],
sortname:'id',
viewrecords: true,
sortorder: "desc",
caption: "New API Example"
});
});
C# Code at controller:
var jsonData = new
{
total =10,
page = 10,
records = 10,
rows = (
from p in pu
select new
{
id = ++counter,
cell = new
{
ProcessName = p.ProcessName.ToString(),
WorkingSet64 = p.Memory.ToString()
}
}).ToArray()
};
return Json(jsonData,JsonRequestBehavior.AllowGet);
The issue it rows are getting generated in the grid, but there is no data in the rows.
Please let me know what am I doing wrong.
Default jsonReader wait for cell as array of strings. So you should replace the part of the code
cell = new
{
ProcessName = p.ProcessName.ToString(),
WorkingSet64 = p.Memory.ToString()
}
to
cell = new [] { p.ProcessName, p.Memory.ToString() }