I have a google chart, that generally is very slow (over 5 minutes) and sometimes just crashes depending on the number of series I need to show. If I have one series it takes around 10 seconds, but if I add say 20 series, it will take several minutes any more than that and the browser dies.
Each series has around 8,000 rows from the JSON. I have checked and tested the code and the loop in the chart code is killing it.
My chart code is as follows:
function drawMultiLineChart() {
var section = $('#LocationNameDdl :selected').val();
var uid = '#guid';
var from = $('#dateFrom').val();
var to = $('#dateTo').val();
var parsedData = "";
var dName = "";
var colIndex = "";
var result = "";
var rowIndex = "";
$.ajax({
url: 'ProjectCharts/GetChartDataBySection',
datatype: 'json',
type: 'get',
async: false,
data: { section: section, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
google.charts.load('current', {
packages: ['corechart']
}).then(function () {
parsedData = $.parseJSON(d);
dName = new google.visualization.DataTable();
dName.addColumn('date', 'Date');
$.each(parsedData, function (key, value) {
colIndex = dName.addColumn('number', 'Serial: ' + key);
result = $.parseJSON(value);
$.each(result, function (k, v) {
rowIndex = dName.addRow();
dName.setValue(rowIndex, 0, new Date(v.ReadingDate));
dName.setValue(rowIndex, colIndex, Number(v.ReadingValue));
});
});
var options = multiLineChartOptions();
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(dName, options);
});
},
error: function () {
alert("Error");
}
});
};
I call the JSON from the following code, this is fine and performs very quickly:
public async Task<JsonResult> GetJsonChartData(string serial, string uid, string from, string to)
{
var dateFrom = Convert.ToDateTime(from).ToString("yyyy-MM-dd HH:mm:ss");
var dateTo = Convert.ToDateTime(to).ToString("yyyy-MM-dd HH:mm:ss");
var g = new GetChartData(_configuration);
List<ChartDataModel> items = await Task.Run(() => g.GetChartDataFromSqlServer(serial, uid, dateFrom, dateTo));
return Json(JsonConvert.SerializeObject(items, Formatting.Indented));
}
The JSON:
[{"LoggerId":"1000651443","ReadingDate":"2018-12-05 00:03:03, "ReadingValue":"12.6", "Tooltip":"Someinfo"},
{"LoggerId":"1000651447","ReadingDate":"2018-12-05 00:04:03, "ReadingValue":"12.7", "Tooltip":"Someinfo"}]
[{"LoggerId":"1000651444","ReadingDate":"2018-12-05 00:03:05, "ReadingValue":"12.9", "Tooltip":"Someinfo"},
{"LoggerId":"1000651445","ReadingDate":"2018-12-05 00:03:07, "ReadingValue":"14.9", "Tooltip":"Someinfo"}]
[{"LoggerId":"1000651446","ReadingDate":"2018-12-05 00:03:17, "ReadingValue":"13.6", "Tooltip":"Someinfo"},
{"LoggerId":"1000651446","ReadingDate":"2018-12-05 00:04:17, "ReadingValue":"43.6", "Tooltip":"Someinfo"}]
How can I improve not only the performance but the load time?
Should I be using a different charting tool?
Can I process the data server side that will allow for increased performance?
Related
So, i call trhough Ajax an IActionResult to go to another view and the IActionResult executes entirely except that it doesn't return the view.
Here is the code of the action result, it just take some products and search for their prices on the database and then sums them. And it executes perfectly. I changed the code a little to some lines to show me the values of each variable in the console and it works fine. The only problem is that when it suppose to show the view in the browser, nothing happens
[HttpPost]
public IActionResult Cart(List<int[]> carrito){
var productsToBuy = selectProductsByID(carrito);
var detallesOrden = new List<OrderDetailModel>();
int sumaTotal = 0;
for(int i = 0; i<carrito.Count; i++){
var detalle = new OrderDetailModel{
idProduct = carrito[i][0],
cantidad = carrito[i][1],
subTotal = productsToBuy[i].precio * carrito[i][1]
};
sumaTotal += detalle.subTotal;
}
var orden = new OrderModel{
estado = 0,
sumaTotal = sumaTotal
};
ViewBag.ProductsToBuy = productsToBuy;
ViewBag.DetallesOrden = detallesOrden;
ViewBag.Orden = orden;
return View();
}
This is the function which i use to call the actionresult it sends an array with the products id and their quantities
function goToCart(){
showCart();
var target = '#Url.Action("Cart", "Home")';
$.ajax({
type: 'POST',
data:{
carrito: carrito
},
url: target,
success: function(result){
},
error: function(result){
alert('error');
}
});
}
What am i doing wrong? I'll appreciate any kind of help.
Sorry for the combinnation of english and spanish.
This is my first time using JSON and I'm having a bit of trouble parsing and using it in my controller. I already tried these solutions Unable to successfully receive JSON data to .NET MVC Controller, How to receive JSON as an MVC 5 action method parameter, but none of them made it for me.
I'm retrieving some data from my html and sending the arrays through ajax to the controller in the following code:
JQuery:
var values = $('ul#values li').map(function() {
return this.textContent;
}).get()
var lines = $('ul#lines li').map(function() {
return {
Column: this.textContent,
Table: this.getAttribute("name")
};
}).get();
var columns = $('ul#lines li').map(function() {
return {
Column: this.textContent,
Table: this.getAttribute("name")
};
}).get();
var filters = $('ul#filters li.panel').map(function () {
var n = this.getAttribute("name");
var c = $(this).children()[1].textContent;
var r = $(this).find("li input:checked").map(function() {
return this.parentNode.textContent;
}).get();
if (r.length === 0)
return null;
else
return { table: n, name:c, vals: r };
}).get();
$.ajax({
type: "POST",
url: "/Home/PivotTable",
dataType: "json",
traditional: true,
data: {
indicators: values,
lines: JSON.stringify(lines) ,
columns: JSON.stringify(columns),
filters: JSON.stringify(filters)
},
success: function (data) {
alert(data.s, data.l);
}
});
And this is the form data being posted:
indicators: Taxa Mensal de inflação
lines:[{"Column":" Base","Table":"D_Base"}]
columns:[{"col":" Trimestre","table":"D_Calendario"}]
filters:[{"table":"D_PF_ClasseProdutos","name":" Código","vals":[" 22"," 23"]}]
And receiving the data in the controller where I need to access the data:
public JsonResult PivotTable(string[] indicators, Lines[] lines, object[] columns, object[] filters)
{
string sa = indicators[0];
var l = lines;
var col = columns;
var fil = filters;
var result = new { s = sa, l=l[0].Column};
return Json(result, JsonRequestBehavior.AllowGet);
}
public class Lines
{
public string Column { get; set; }
public string Table { get; set; }
}
I tried binding lines to an object, like the solution in one of the links, but got
NullRefrenceException was unhandled by usercode
While the other parameters receive the appropriate
data, but i can´t access the properties of the object.
What am I doing wrong, and how can i parse the data or bind it to an object?
You can try to use Json.NET library which allows you to serialize and deserialize.
Pass your params as string and do the following:
Lines[] m = JsonConvert.DeserializeObject<Lines>(lines);
I'm writing an ASP.NET 3.5 app and I'm passing values from the web page to the code behind via AJAX.
The object I'm passing:
var queryData = {
'FiltrarPorTexto': false,
'Texto': "",
'FiltrarPorCategorizacion': false,
'FiltrarPorTipo': false,
'Tipo': 0,
'Pagina': 1
};
My AJAX call:
$.ajax({
type: "POST",
url: 'SDI_generararchivosbloomberg.aspx/ObtenerListadoInstrumentosJSON',
data: '{ "datosPeticion": ' + JSON.stringify(queryData) + ' }',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(response) {
// ...
},
error: function(xhr, msg, msg2) {
// ...
}
});
My code-behind:
[WebMethod]
[ScriptMethod]
public static ObjetoRespuesta ObtenerListadoInstrumentosJSON(ObjetoFiltro datosPeticion)
{
if (datosPeticion.Pagina < 0) return new ObjetoRespuesta
{
PaginaActual = 0,
TotalPaginas = 0,
TotalRegistros = 0,
HtmlTabla = "Error: el número de página no puede ser menor a 0"
};
var elementosASaltar = (datosPeticion.Pagina - 1) * ELEMENTOS_POR_PAGINA;
var listado = bdc.GetTable<INSTRUMENTOS_BLOOMBERG>().AsQueryable();
if (datosPeticion.FiltrarPorNombre) listado = listado.Where(i => i.NEMO_INSTRUMENTO.Contains(datosPeticion.Nombre));
if (datosPeticion.FiltrarPorCategorizacion) listado = listado.Where(i => !i.ESTADO_CATEGORIZACION);
if (datosPeticion.FiltrarPorTipo) listado = listado.Where(i => i.TIPO_INSTRUMENTO == (insts.Find(r => r.Id == datosPeticion.Tipo)).Id);
var cantidadTotal = listado.Count();
if (cantidadTotal < 1) return new ObjetoRespuesta
{
PaginaActual = 0,
TotalPaginas = 0,
TotalRegistros = 0,
HtmlTabla = "Error: No se encontraron elementos"
};
if (elementosASaltar > 0) listado = listado.Skip(elementosASaltar);
listado = listado.Take(ELEMENTOS_POR_PAGINA);
return new ObjetoRespuesta
{
PaginaActual = datosPeticion.Pagina,
TotalPaginas = (cantidadTotal / ELEMENTOS_POR_PAGINA),
TotalRegistros = cantidadTotal,
HtmlTabla = GenerarTablaHtml(listado)
};
}
My problem is, some fields are not being correctly replicated in the code-behind. For example, when the queryData object is:
queryData
{...}
FiltrarPorTexto: true
Texto: "PEN"
FiltrarPorCategorizacion: false
FiltrarPorTipo: false
Tipo: 0
Pagina: 1
What gets unserialized in the code-behind is:
datosPeticion
{myNamespace.ObjetoFiltro}
FiltrarPorCategorizacion: false
FiltrarPorNombre: false
FiltrarPorTipo: false
Nombre: null
Pagina: 1
Tipo: 0
and the weird thing is, this only happens with those fields. Sending different values for FiltrarPorCategorizacion or Pagina, for example, yield the correct behavior.
Does anyone know what can I do to find the cause/fix this?
I think your myNamespace.ObjetoFiltro class is missing properties 'FiltrarPorTexto' and 'Texto' while your json object needs a 'Nombre' property.
Nevermind, this was a mistake as dumb as they can get.
For those with the same problem, make sure your JS object and the .NET object's fields have the same name.
This is driving me crazy... as part of another issue I've been working on ajax transfers to my mvc4 web app.
I've been working with this as an example: http://www.codeproject.com/Articles/692793/Introduction-to-Knockout-js-and-CRUD-Operations-in
The model is as follows:
public class ColorList
{
public int? ID;
public string ColorName;
}
The controller function is as follows:
[WebMethod]
public ColorList[] GetAssignedColors(string szUserRecID)
{
int Rec = Convert.ToInt32(szUserRecID);
var query = (from t in db.tblColors
join c in db.tblUser on t.fkColorID equals c.pkColorID
where t.fkRecID == Rec
select new ViewModels.ColorList()
{
ColorName = c.szColorName,
ID = t.ColorID
}).OrderBy(c => c.ColorName);
//var q = query.ToArray(); // if I break and view q, the array exists
return query.ToArray();
}
Not sure this matters but here's my Ajax method:
$.ajax({
type: "POST",
url: '#Url.Action("GetAssignedColors", "EditColors")',
data: { szUserRecID: RecID },
success: function (results) {
var colors = $.map(results.d, function (item) {
return new Color(item)
});
self.CurrentColors(colors);
},
error: function (err) {
alert(err.status + " : " + err.statusText);
}
})
if I watch fiddler the response my code provides is (in text view):
"MyApps.ViewModels.ColorList[]"
Not the array of colors as I am expecting.
Why is the function returning the variable name as an array instead of the array itself?
I've played around with this, but my ajax call doesn't seem to interpret the json response... However, the data shows in this instance but get a 200/ok with seemingly unusable data in my web page.
[HttpPost]
public JsonResult GetAssignedColors(string szUserRecID)
{
int Rec = Convert.ToInt32(szUserRecID);
var query = (from t in db.tblColors
join c in db.tblUser on t.fkColorID equals c.pkColorID
where t.fkRecID == Rec
select new ViewModels.ColorList()
{
ColorName = c.szColorName,
ID = t.ColorID
}).OrderBy(c => c.ColorName);
//var q = query.ToArray(); // if I break and view q, the array exists
return Json(query.ToArray(), JsonRequestBehavior.AllowGet);
}
Since formatting didn't work in the comments this is what worked; results didn't have the data necessary but "data" did.
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
The webpage I was working off of had:
success: function (result) {
var colors = $.map(result.d, function (item) {
return new Color(item)
});
The actual working method was:
success: function (data) {
var colors = $.map(data, function (item) {
return new Color(item)
});
I did not use the [webmethod] per Robert's wisdom and used the json response.
The final / working function was:
[HttpPost]
public JsonResult GetAssignedColors(string szUserRecID)
{
int Rec = Convert.ToInt32(szUserRecID);
var query = (from t in db.tblColors
join c in db.tblUser on t.fkColorID equals c.pkColorID
where t.fkRecID == Rec
select new ViewModels.ColorList()
{
ColorName = c.szColorName,
ID = t.ColorID
}).OrderBy(c => c.ColorName);
//var q = query.ToArray(); // if I break and view q, the array exists
return Json(query.ToArray());
}
Note the removal of JsonRequestBehavior.AllowGet
thanks Robert!
I'm using tableDnD to re-order table rows, and then serialize them using "$.tableDnD.serialize()"
I want to send this to C# for processing, what's the best of doing so?
The below is an example of the serialization
pages[]=&pages[]=21&pages[]=23&pages[]=34&pages[]=37&pages[]=40&pages[]=43&pages[]=46&pages[]=49&pages[]=31&pages[]=50&pages[]=51&pages[]=52&pages[]=53&pages[]=54&pages[]=55&pages[]=56&pages[]=57&pages[]=58&pages[]=61&pages[]=65&pages[]=70&pages[]=74&pages[]=77&pages[]=78&pages[]=79&pages[]=82&pages[]=85&pages[]=88&pages[]=91&pages[]=94&pages[]=97&pages[]=100&pages[]=103&pages[]=106&pages[]=109&pages[]=112&pages[]=115&pages[]=119&pages[]=122&pages[]=123
Important Information
I tagged this as MVC but forgot to mention it. I'm using ASP.NET MVC
You can send that as-is using one of jQuery's ajax methods. I would prefer to turn it into a smaller, neater CSV string before sending it to the server as follows:
var str = 'pages[]=&pages[]=21&pages[]=23&pages[]=34&pages[]=37&pages[]=40&pages[]=43&pages[]=46&pages[]=49&pages[]=31&pages[]=50&pages[]=51&pages[]=52&pages[]=53&pages[]=54&pages[]=55&pages[]=56&pages[]=57&pages[]=58&pages[]=61&pages[]=65&pages[]=70&pages[]=74&pages[]=77&pages[]=78&pages[]=79&pages[]=82&pages[]=85&pages[]=88&pages[]=91&pages[]=94&pages[]=97&pages[]=100&pages[]=103&pages[]=106&pages[]=109&pages[]=112&pages[]=115&pages[]=119&pages[]=122&pages[]=123';
var tmpArr = str.split('&');
var pagesArr = [];
for(var i = 0;i < tmpArr.length; i++) {
var paramArr = tmpArr[i].split('=');
if(paramArr[1] != null && paramArr[1] != '') {
pagesArr.push(paramArr[1]);
}
}
alert(pagesArr); //now much prettier
//turn it into a CSV string
var pagesCsv = pagesArr.join(',');
$.ajax({
type: "POST",
url: "some.aspx",
data: pagesCsv,
success: function(msg){
alert( "Data Saved: " + msg );
}
});
Based on the example of karim79 :
var str = 'pages[]=&pages[]=21&pages[]=23&pages[]=34&pages[]=37&pages[]=40&pages[]=43&pages[]=46&pages[]=49&pages[]=31&pages[]=50&pages[]=51&pages[]=52&pages[]=53&pages[]=54&pages[]=55&pages[]=56&pages[]=57&pages[]=58&pages[]=61&pages[]=65&pages[]=70&pages[]=74&pages[]=77&pages[]=78&pages[]=79&pages[]=82&pages[]=85&pages[]=88&pages[]=91&pages[]=94&pages[]=97&pages[]=100&pages[]=103&pages[]=106&pages[]=109&pages[]=112&pages[]=115&pages[]=119&pages[]=122&pages[]=123';
var pos = null;
var index = 0;
while ((pos=str.indexOf("[]"))>-1)
{
str = str.substr(0, pos-1) + "_" + (index) + str.substr(pos+2);
index++;
}
alert(str);
$.ajax({
type: "POST",
url: "some.aspx",
data: str,
success: function(msg){
alert( "Data Saved: " + msg );
}
});
In C#
string[] keys = Request.QueryString.AllKeys;
Array.Sort(keys);
StringBuilder sb = new StringBuilder();
foreach (string key in keys)
{
if (key.IndexOf("pages_")!=-1)
{
sb.Append(Request.QueryString[key]);
}
}
// sb container the all values
You can also put everything in to one object like this:
var prm = { pages=[...], someOtherPages=[], additionalParam="", integer=1324 }
jQuery.ajax({
url: "someurl.aspx",
type: "POST",
data: {prm: JSON.stringify(prm)},
});
and parse prm on C# side by using this JSON Parser:
JObject json = JObject.Parse(Request.Form["prm"]);
JArray items = json["pages"] as JArray;
foreach (JToken item in items)
{
int i = item["type"].Value<int>(); // take an item as int
string s = item["type"].Value<string>(); // take an item as string
JArray ar = item["complex"] as JArray; // that an item as an array
}
much simplier and flexible