I have kendo chart as below. I have to plot the graph which has more than 20k points. The problem i am facing here is the chart is rendering very slow. How to improve the peformance of this. Any help on this is highly appreciated?
#(Html.Kendo().PanelBar()
.Name("linePanelBar")
//.ExpandMode(PanelBarExpandMode.Multiple)
.HtmlAttributes(new { style = "width:100%;height:300px;background-color:transparent;" })
.Items(panelbar =>
{
panelbar.Add().Text("Correlation")
.Expanded(true)
.Content(#<div onclick="onCell3Clicked()">
<div id="loading"></div>
#if (#Model != null && #Model.XValues != null && #Model.YValues != null)
{
#(Html.Kendo().Chart()
.Name("Correlationchart")
.RenderAs(RenderingMode.Canvas)
.Transitions(false)
.Title(Model.YString + " Vs " + Model.XString + " Relationship")
//.Legend(legend => legend
// .Position(ChartLegendPosition.Right).Visible(true)
//)
.SeriesDefaults(seriesDefaults =>
seriesDefaults.ScatterLine().Style(ChartScatterLineStyle.Smooth)
)
.Series(series =>
{
series.Scatter(Model.CorrelationChartData).Fields("xValue", "yValue").NoteTextField("fallback").Notes(notes => notes.Label(label => label.Position(ChartNoteLabelPosition.Outside)).Position(ChartNotePosition.Top));
series.ScatterLine(Model.RegressionChartData).Fields("xValue", "yValue").Name("Regression");
series.ScatterLine(Model.LowessChartData).Fields("xValue", "yValue").Name("Lowess");
}).Events(e=>e.SelectStart("onSelectStart").SelectEnd("onSelectEnd"))
.ChartArea(x => x.Width(600).Height(300))
.XAxis(x => x
.Numeric()
.Title(title => title.Text(Model.XString))
.Crosshair(crosshair => crosshair
.Visible(true)
.Tooltip(tooltip => tooltip
.Visible(true)
)
)
)
.YAxis(y => y
.Numeric()
.Title(title => title.Text(Model.YString))
.AxisCrossingValue(-5)
.Crosshair(crosshair => crosshair
.Visible(true)
.Tooltip(tooltip => tooltip
.Visible(true)
)
)
)
)
}
</div>);
}))
Thanks
Related
I have a kendo line chart which will bind the data from Model as below. Now i would like to show at particular point a call out message saying degradation start at this point dynamically. Can some one help me on this how to acheive this.
<div style="overflow:scroll;width:100%">
#if (#Model != null && #Model.XYAxisData != null)
{
#(Html.Kendo().Chart()
.Name("Predictionchart")
.Transitions(false)
.RenderAs(RenderingMode.Canvas)
//.Title(Model.YString + " Vs " + Model.XString + " Relationship")
.Legend(legend => legend
.Position(ChartLegendPosition.Right).Visible(true)
)
.SeriesDefaults(seriesDefaults =>
seriesDefaults.Line().Style(ChartLineStyle.Smooth)
)
.Series(series =>
{
series.ScatterLine(Model.XYAxisData).Fields("xValue", "yValue");
series.ScatterLine(Model.XYPredictedData).Fields("xValue", "yValue");
})
.ChartArea(x => x.Width(1000).Height(400))
.XAxis(x => x
.Numeric()
.Title(title => title.Text(Model.PredictXString))
.Crosshair(crosshair => crosshair
.Visible(true)
.Tooltip(tooltip => tooltip
.Visible(true)
//.Format("{0:n1}")
)
)
//.Max(35)
)
.YAxis(y => y
.Numeric()
.Title(title => title.Text(""))
.AxisCrossingValue(-5)
.Crosshair(crosshair => crosshair
.Visible(true)
.Tooltip(tooltip => tooltip
.Visible(true)
//.Format("{0:n1}")
)
)
//.Min(-5)
//.Max(25)
)
)
}
</div>
During editing of the grid, I need to validate the data input and if it fails validation, I need to revert the bad data back to an unchanged state so it won't get saved (akin to using the Reset button, but just for the current row being editing...this is a batch editing grid).
Using the javascript code below, I can identify the problem, throw up the alert, but after the user accepts the alert, they could still just click the Save button and it would save that way, with the incorrect data.
To combat this, you'll see I try to set the e.values and e.model to 0, but it is not working (no error is thrown, it just doesn't change the value in the grid).
Maybe I need to identify the DOM element and change it's value directly, but I couldn't find how to retrieve the DOM element from the e object.
function beforeCartonPackUpdates(e) {
if (e.values.QtyToPack > e.model.OrderedQty) {
alert("ERROR! You cannot pack more than was ordered.");
e.model.set("QtyToPack", 0);
e.values.QtyToPack = 0;
return false;
}
if (e.values.QtyToPack > e.model.RemainingToPack) {
alert("Warning! You are packing more than is available.");
return true;
}
}
#(Html.Kendo().Grid<OTIS.AppServ.OrderMgmt.ViewModels.ShipOrderDetailViewModel>()
.Name("ShipOrderDtlsGrid")
.HtmlAttributes(new { style = "width:100%;" })
.Resizable(resize => resize.Columns(true))
.Columns(columns =>
{
columns.Bound(l => l.Id).Hidden();
columns.Bound(l => l.OrderHeaderId).Hidden();
columns.Bound(l => l.StatusId).Hidden();
columns.Bound(l => l.ItemId)
.ClientTemplate("<a href='" +
Url.Action("Edit", "ManageItems", new { area = "InventoryMgmt" }) +
"/#= ItemId #'" +
" target='_blank'>#= ItemDescription #</a>"
)
.ClientFooterTemplate("#=kendo.format('Line Count: {0:n0}', count)#");
columns.Bound(l => l.OrderedQty)
.Title("Ord")
.HeaderHtmlAttributes(new { style = "text-align:right;" })
.HtmlAttributes(new { style = "text-align:right;" })
.FooterHtmlAttributes(new { style = "text-align:right;" })
.ClientFooterTemplate("#=kendo.format('{0:n2}', sum)#");
columns.Bound(l => l.BackorderedQty)
.Title("B/O")
.HeaderHtmlAttributes(new { style = "text-align:right;" })
.HtmlAttributes(new { style = "text-align:right;" })
.FooterHtmlAttributes(new { style = "text-align:right;" })
.ClientFooterTemplate("#=kendo.format('{0:n2}', sum)#");
columns.Bound(l => l.PickedQty)
.Title("Pick")
.HeaderHtmlAttributes(new { style = "text-align:right;" })
.HtmlAttributes(new { style = "text-align:right;" })
.FooterHtmlAttributes(new { style = "text-align:right;" })
.ClientFooterTemplate("#=kendo.format('{0:n2}', sum)#");
columns.Bound(l => l.PackedQty)
.Title("Pack")
.HeaderHtmlAttributes(new { style = "text-align:right;" })
.HtmlAttributes(new { style = "text-align:right;" })
.FooterHtmlAttributes(new { style = "text-align:right;" })
.ClientFooterTemplate("#=kendo.format('{0:n2}', sum)#");
columns.Bound(l => l.RemainingToPack)
.Title("Remain")
.HeaderHtmlAttributes(new { style = "text-align:right;" })
.HtmlAttributes(new { style = "text-align:right;" })
.FooterHtmlAttributes(new { style = "text-align:right;" })
.ClientFooterTemplate("#=kendo.format('{0:n2}', sum)#");
columns.Bound(l => l.QtyToPack)
.HeaderHtmlAttributes(new { style = "text-align:right;" })
.HtmlAttributes(new { #class = "editable", style = "text-align:right;" })
.FooterHtmlAttributes(new { style = "text-align:right;" })
.ClientFooterTemplate("#=kendo.format('{0:n2}', sum)#");
//columns.Command(command =>
// {
// command.Edit();
// command.Destroy();
// }).Width(180);
})
.Editable(editing => editing.Mode(GridEditMode.InCell))
.Events(events =>
{
//events.SaveChanges("afterCartonPackUpdates"); //fires BEFORE saving - good place to do validation
events.Save("beforeCartonPackUpdates"); //fires Before saving, but as soon as cell value changes, better place to do validation
events.SaveChanges("preCartonPackUpdates");//fires AFTER .Save but before calling destroy method
}
)
// Add "Create" command
.ToolBar(toolbar =>
{
//toolbar.Create().Text("Add Work Order Detail");
toolbar.Template(#<text>#RenderOrderDetailsToolBar()</text>);
//toolbar.Custom().Text("<span class='k-icon k-cancel'></span>Cancel</text>").Url("##_").HtmlAttributes(new { #class = "k-grid-cancel-changes" });
//toolbar.Custom().Text("<span class='k-icon k-update'></span>Pack</text>").Url("##_").HtmlAttributes(new { #class = "k-grid-save-changes" });
//toolbar.Save();
})
.DataSource(dataSource => dataSource
.Ajax() // Specify that the data source is of ajax type
.Aggregates(aggregates =>
{
aggregates.Add(x => x.ItemId).Count();
aggregates.Add(x => x.OrderedQty).Sum();
aggregates.Add(x => x.PickedQty).Sum();
aggregates.Add(x => x.RemainingToPack).Sum();
aggregates.Add(x => x.QtyToPack).Sum();
aggregates.Add(x => x.PackedQty).Sum();
aggregates.Add(x => x.BackorderedQty).Sum();
})
.Batch(true)
.Model(model =>
{
model.Id(c => c.Id);
model.Field(c => c.OrderHeaderId).DefaultValue(Model.Id);
model.Field(c => c.UnitCost).Editable(false);
model.Field(c => c.ItemDescription).Editable(false);
model.Field(c => c.OrderedQty).Editable(false);
model.Field(c => c.PickedQty).Editable(false);
model.Field(c => c.PackedQty).Editable(false);
model.Field(c => c.BackorderedQty).Editable(false);
}
)
.Sort(sort =>
{
sort.Add(c => c.ItemDescription);
})
.Events(events =>
{
events.Error("KendoGridErrors");// Specify a handler for the error event
events.RequestEnd("onPackCartonGridComplete");
}
)
// CRUD configuration -->
//.Create(create => create.Action("Grid_SaveOrUpdate", "ManageWorkOrders", new { area = "OrderMgmt" }).Type(HttpVerbs.Post))
.Read(read => read.Action("GetShipOrderDetails", "ManageShipOrders", new { area = "OrderMgmt", intOrderHeaderId = #Model.Id })// Specify the action method and controller name
.Type(HttpVerbs.Get)
)
.Update(update => update.Action("CreateCartonAndPack", "ManageShippingContainers", new { area = "OrderMgmt" }).Type(HttpVerbs.Post))
//.Destroy(destroy => destroy.Action("Grid_Delete", "ManageWorkOrders", new { area = "OrderMgmt" }).Type(HttpVerbs.Post))
// <-- CRUD configuration
)
.Sortable()
)
Figured it out...was simple in the end. Just needed to put in the e.preventDefault();
function shipOrderDtlsGrid_OnSave(e) {
if (e.values.QtyToPack > e.model.RemainingToPack) {
e.preventDefault();
alert("ERROR! You cannot pack more than is Remaining To Pack.");
return;
}
}
I created a Create Action in Controller for saving new product into database. I saved it already but when I click Refresh button, it didn't save on Kendo Grid, either database.
public ActionResult Create([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = "models")]IEnumerable<ProductDTO> products)
{
var results = new List<ProductDTO>();
if (products != null && ModelState.IsValid)
{
foreach (var product in products)
{
var create = db.Products.First(c => c.ProductID == product.ProductID);
results.Add(product);
db.SaveChanges();
}
}
return Json(results.ToDataSourceResult(request, ModelState));
}
EDIT
Kendo View:
#(Html.Kendo().Grid(Model)
.Name("Products")
.Columns(c =>
{
c.Command(p => p.Edit()).Width(170);
c.Bound(p => p.ProductID);
c.Bound(p => p.Name);
c.Bound(p => p.ListPrice);
c.Bound(p => p.ProductNumber);
c.Bound(p => p.Color);
c.Bound(p => p.StandardCost);
c.Command(p => p.Destroy()).Width(100);
}
)
.ToolBar(tb =>
{
tb.Create();
tb.Save();
})
.Pageable(pageable => pageable
.Refresh(true)
.PageSizes(true)
.ButtonCount(5))
.Sortable()
.Editable(e => e.Mode(GridEditMode.InCell))
.DataSource(d => d .Ajax()
.Batch(true)
.Model(model =>
{
model.Id(c => c.ProductID);
})
.Create("Create", "Home")
.Read("GetSub","Home")
.Update("Edit", "Home")
.Destroy("Delete", "Home")
.PageSize(10)
)
.HtmlAttributes(new { style= "width: 800px" })
)
What's a solution could be solve in this case? Thank you for your reply, have a great day!
I have been using inline deletion for Kendo Grid, but I need to check the conditions and then delete the rows.
#(Html.Kendo().Grid<DocumentSearchViewModel>()
.Name("documentListGrid")
.Columns(columns =>
{
columns.Bound(model => model.AgentID).Title("Agent Code").Width("15%");
columns.Bound(model => model.DocumentSecurityID).ClientTemplate("#if(data.AllowToView==1)" +
"{ #<a class='lnkDocument' href='" + Url.Action("Download", "Document", new { fileName = "#=ScanFile#", fileLocation = "#=VC01#", batchTime = "#=BatchTime#", documentNumber = "#=CaseID#" }) + "' target='documentViewer'>#=data.BatchDescription#</a>#" +
" " + " }" +
"else{#<a class='disable-link' onclick='return Response();'>#=data.BatchDescription#</a> #}#").Title("Description").Width("30%");
columns.Bound(model => model.CaseID).Width("10%").Title("Case#");
columns.Bound(model => model.DocumentGroupID).Width("15%").Title("Group ID");
columns.Bound(model => model.BatchNumber).Width("10%").Title("Batch#");
columns.Bound(model => model.CreatedDate).Width("10%").Format(UI.DocumentSearchDateFormat).Title("Created Date");
columns.Command(command => command.Custom("Remove").Click("deleteRow"));
columns.Bound(model => model.DocSystemID).Visible(false);
})
.Pageable()
.Sortable(sortable => sortable.AllowUnsort(false))
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Model(model => model.Id(p => p.CaseID))
.Read(read => read.Action(WorkflowControllers.Document.ActionNames.GetDocumentList, WorkflowControllers.Document.Name, new { caseId = #Model.CaseID }))
.Events(ev => ev.Change("OnGridChange"))
).AutoBind(true).Events(events => events.DataBound("DisplayDocument"))
)
Calling javascript function which will call a Controller method using Ajax Call:
function deleteRow(e) {
e.preventDefault ? e.preventDefault() : e.returnValue = false;
var grid = $("#documentListGrid").data("kendoGrid");
if (confirm("Are you sure you want to delete the selected record(s)?")) {
grid.removeRow($(e.target).closest("tr"));
} else {
// cancel button is clicked
}
}
How do I get the row's value and check the conditions?
$('#Grid').click(function () {
var gview = $(this).data("kendoGrid");
var selectedItem = gview.dataItem(gview.select());
var Guid = selectedItem.YourPropertName;
})
selectedItem will have all the properties of your model
I have master and details kendo grid, when I insert/delete the header everything is working fine, but When i try to insert more than one record in the details grid the create statement will loop for all inserted records (new and old ones) each time I try to add a new record, also when I try to delete a record from the details table, the view will call the create method instead of delete one.
#(Html.Kendo().Grid(Model.ItemSuppliers)
.Name("CreateItem_gridSuppliers")
.Columns(columns =>
{
columns.Bound(p => p.ItemCode).Title(MyResources.GridItemCode).Width(100);
columns.ForeignKey(p => p.SupplierID, Model.Suppliers, "SupplierID", "SupplierID").Title(MyResources.Supplier).Width(200).EditorTemplateName("SupplierForeignkeyEditor");
columns.Bound(p => p.SupplierNameE).Title(MyResources.SupplierNameE).Width(150);
columns.Bound(p => p.CustomDutyPercentage).Title(MyResources.CustomDutyPercentage).Width(200);
columns.Bound(p => p.CustomDutyRate).Title(MyResources.CustomDutyRate).Width(200);
columns.Command(command => { command.Edit().Text(MyResources.EditText).UpdateText(MyResources.UpdateText).CancelText(MyResources.CancelText); command.Destroy().Text(MyResources.Delete); }).Width(170);
})
.ToolBar(toolBar =>
{
toolBar.Create().Text(MyResources.AddNewItem);
})
.Events(e => e.Edit("gridEdit").Cancel("OnCancel").DataBound("CreateItem_gridSuppliers_GridDataBound").Change("ItemSupplierSaved"))
.Editable(editable => editable.Mode(GridEditMode.InLine))
.ClientDetailTemplateId("template")
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.ServerOperation(true)
.Events(events => events.Error("gridErrorHandler"))
.Events(ev => ev.RequestEnd("ItemSupplierSaved"))
.Model(model =>
{
model.Id(p => p.ItemSuppliersID);
model.Field(p => p.ItemSuppliersID).Editable(false);
model.Field(p => p.ItemCode).Editable(false);
})
.Read(read => read.Action("GetItemSuppliers", "Item", new { __cnv = Model.ConversationKey }))
.Update(update => update.Action("ItemSupplier_Update", "Item", new { __cnv = Model.ConversationKey }))
.Create(create => create.Action("ItemSupplier_Create", "Item", new { __cnv = Model.ConversationKey }))
.Destroy(destroy => destroy.Action("ItemSupplier_Delete", "Item", new { __cnv = Model.ConversationKey }))
))
<script id="template" type="text/kendo-tmpl">
#(Html.Kendo().Grid(Model.ItemOrigins)
.Name("ItemOrigin_#=ItemSuppliersID#")
.Columns(columns =>
{
columns.Bound(p => p.ItemCode).Hidden();
columns.Bound(p => p.ItemSuppliersID).Title(MyResources.ItemSuppliersID).Width(120);
columns.Bound(p => p.ItemOriginID).Title(MyResources.ItemOriginID).Width(100);
columns.ForeignKey(p => p.OriginID, Model.Origins, "OriginID", "OriginNameE").Title(MyResources.OriginID).Width(100);
columns.Bound(p => p.ProductBarCode).Title(MyResources.ProductBarCode).Width(200);
columns.Command(command => { command.Edit().Text(MyResources.EditText).UpdateText(MyResources.UpdateText).CancelText(MyResources.CancelText); command.Destroy().Text(MyResources.Delete); }).Width(190);
})
.ToolBar(toolBar =>
{
toolBar.Create().Text(MyResources.AddNewItem);
})
.Events(e => e.Edit("RemoveItemOriginFilter").Cancel("ReloadGrid"))
.Editable(editable => editable.Mode(GridEditMode.InLine).DisplayDeleteConfirmation(true).DisplayDeleteConfirmation(MyResources.ItemOriginDeleteConfirm))
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(5)
.ServerOperation(true)
.Events(events => events.Error("gridErrorHandler"))
.Model(model =>
{
model.Id(p => p.ItemOriginID);
model.Field(p => p.ItemOriginID).Editable(false);
model.Field(p => p.ItemSuppliersID).Editable(false);
model.Field(p => p.Origin);
})
.Read(read => read.Action("GetItemOrigin", "Item", new { itemSupplierID = "#=ItemSuppliersID#", __cnv = Model.ConversationKey }))
.Update(update => update.Action("ItemOrigin_Update", "Item", new { itemSupplierID = "#=ItemSuppliersID#", __cnv = Model.ConversationKey }))
.Create(create => create.Action("ItemOrigin_Create", "Item", new { itemSupplierID = "#=ItemSuppliersID#", __cnv = Model.ConversationKey }))
.Destroy(destroy => destroy.Action("ItemOrigin_Delete", "Item", new { itemSupplierID = "#=ItemSuppliersID#", __cnv = Model.ConversationKey }))
)
.ToClientTemplate()
)
</script>
And here is my controller
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ItemOrigin_Create([DataSourceRequest] DataSourceRequest request, ItemOriginViewModel item, int itemSupplierID, string __cnv)
{
List<ItemOriginViewModel> itemOrigins = new List<ItemOriginViewModel>();
if (Session["ItemOrigin_" + __cnv + itemSupplierID] != null)
{
itemOrigins = (List<ItemOriginViewModel>)Session["ItemOrigin_" + __cnv + itemSupplierID];
if (item.UID == null)
{
item.UID = Guid.NewGuid().ToString();
item.ItemSuppliersID = itemSupplierID;
itemOrigins.Add(item);
}
else
{
int index = itemOrigins.FindIndex(x => x.UID == item.UID);
itemOrigins[index] = item;
}
}
else
{
item.UID = Guid.NewGuid().ToString();
item.ItemSuppliersID = itemSupplierID;
itemOrigins.Add(item);
}
Session["ItemOrigin_" + __cnv + itemSupplierID] = itemOrigins;
return Json(itemOrigins.ToDataSourceResult(request));
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult ItemOrigin_Delete([DataSourceRequest] DataSourceRequest request, ItemOriginViewModel item, string __cnv)
{
List<ItemOriginViewModel> itemOrigins = (List<ItemOriginViewModel>)Session["ItemOrigin_" + __cnv + item.ItemSuppliersID];
int index = itemOrigins.FindIndex(x => x.ItemOriginID == item.ItemOriginID);
itemOrigins.RemoveAt(index);
Session["ItemOrigin_" + __cnv + item.ItemSuppliersID] = itemOrigins;
var result = itemOrigins;
return Json(result.ToDataSourceResult(request));
}
Any suggestion please to solve this issue??
The Kendo DataSource will attempt to send items that are marked as 'new' or 'dirty'. 'New' just means that the item ID (it looks like your ID column is ItemSuppliersID) is undefined or 0. It will keep resending these items as long as that ID is not set.
Normally, your controller should return the item that was just inserted, but with the ID now set to the new value. Then Kendo will copy the ID from the response to the object on the client. Since the ID is then set, the item will no longer be marked 'new' and will stop being sent to the server.
In other words, if you POST:
{
"ItemSuppliersID": 0,
"ItemCode": "ABC"
}
then the controller should return:
{
"ItemSuppliersID": 123, // <-- ID field is now set
"ItemCode": "ABC"
}