[CLOSED] Async loading and re-loading of panels in a reporting portal - Suggestions?

Hybrid View

Previous Post Previous Post   Next Post Next Post
  1. #1

    [CLOSED] Async loading and re-loading of panels in a reporting portal - Suggestions?

    Hi,

    I'm creating a reporting portal/dashboard which has 4 quadrants each containing a chart (I'm using telerik ASP.NET for the charting component), so the quadrants are made up of user controls which contain NON Ext.Net controls.

    When this page loads I want each of the quadrants to load as and when they are finished quering for the data which makes up the chart. I want them to load asynchronously. I also want to be able to re-load a particular chart on request without having to reload the entire dashboard, i.e. from a directmethod call off of a button for example.

    Do you have any suggestions as to the best way to accomplish this using Ext.NET?

    I'm thinking along the lines of panels with AutoLoad properties pointing to a page which generates the chart...
    or...
    ... possibly using XRender to generate the contents of the quadrant dynamically from a user control...

    What do you think? I know this isn't really a support question, I just wanted some advice from the experts ;-)
    Last edited by Daniil; Jan 27, 2012 at 6:08 PM. Reason: [CLOSED]
  2. #2
    Hi,

    My colleague has participated in the development of a similar application, though with Dundas Charts.

    He asked the assistance of the Ext.NET team and we advised to place a chart into a user control, then place that user control into any Ext.NET container.

    To update a content of that Ext.NET container during a DirectEvent/DirectMethod, use its UpdateContent method.

    It will look something like this:
    https://examples1.ext.net/#/XRender/...UpdateContent/

    There are the following things:
    X.Js.Call("destroyFromCache", new JRawValue(Panel1.ClientID));
    ...
    X.Js.Call("putToCache", new JRawValue(Panel1.ClientID), uc1.ControlsToDestroy);
    They are only required for Ext.NET widgets.

    I think you should not have any Ext.NET widgets in your user control, just Telerik charts. So, this part can be missed.

    I'm not sure that a Telerik chart requires client side destroying, but if it requires, you should care about it by a similar way that we destroy Ext.NET widgets.

    What do you think? I know this isn't really a support question, I just wanted some advice from the experts ;-)
    I think it's 100% a support question and it's good what you've asked.

    It's easier for us to push a developer to a right direction (certainly, if we can), then trying to return him from a wrong direction:)


    By the way, the ExtJS Charts have been included into Ext.NET v2.
    https://examples2.ext.net/#/Chart/Dashboard/Basic/

    More details about the current state of Ext.NET v2 are here:
    http://forums.ext.net/showthread.php?16883
  3. #3
    We have accomplished the same thing using the Portal plugins and Dundas Charts. Dundas charts can return an image. So each portlet contains one image with url set to a httphandler that generates the image/chart to return to client. This is great because the images/charts load async and a tool on the portlet can refresh each image/chart individually.
  4. #4
    Thanks for your replies guys...

    Jchau - The image streaming method is exactly how another product of our company works! We had considered this, however wasn't ideal for this new product because we wanted to keep the 'drill down' functionality and any interaction with the chart which hosting it as an actual control provides. We also will possibly have other things than charts in the quadrants of the dashboard in the future.

    Danill - Yesterday I started experimenting with the AutoLoad/IFrame method which I'd thought of, and I have managed to get things working quite well. If my telerik charts are hosted in a user control, and that control is within a simple container aspx page I can host them in each of the quadrants and use the IFrame mode to load them. The benefit of this that I can see is that if one of the charts takes 10 seconds to load because of a complex query then the other pieces of the dashboard will load immediately and this one piece will drop in async when it is finished. This is what I wanted to accomplish. I've also managed to get a button click in any one of the quadrants reloading itself or any other quadrant using the 'Iframe communication' example and just calling Container.LoadContent() again to refresh the content of the IFrame.
    This isn't quite the same as your suggestion using the XRender example, but is provides the async loading of the charts which I wanted and easily gives me the 'Loading....' mask whilst the chart is loading. Can you do this with the UpdateContent() method?
    Can you see any problems with going this way? Or is your way also able to do this and I'm just not understanding something?
  5. #5
    The main and big IFrame disadvantage is low performance.

    IFrame is too heavy-weight thing for a browser, especially for IE. You can consider each iframe as a separate browser tab.

    We always recommend to avoid iframes if possible.

    Regarding to the questions about the solution I suggest.

    I've prepared a simple example, hope it will clarify what I meant.

    Example Page
    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <%@ Import Namespace="Work" %>
    
    <script runat="server">
        [DirectMethod]
        public void LoadChart(string panelId, string chartId)
        {
            Ext.Net.Panel p = Ext.Net.Utilities.ControlUtils.FindControl<Ext.Net.Panel>(this.Form, panelId);
            BaseUserControl uc = this.LoadControl(string.Format("TestUC{0}.ascx", chartId)) as BaseUserControl;
            uc.PanelID = panelId;
    
            p.ContentControls.Add(uc);
            p.UpdateContent();
        }
    </script>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
        <title>Ext.NET Example</title>
    
        <script type="text/javascript">
            var load = function (panel) {
                panel.body.mask('Loading...', 'x-mask-loading');
                Ext.net.DirectMethods.LoadChart(panel.id, panel.chartId);
            };
        </script>
    </head>
    <body>
        <form runat="server">
            <ext:ResourceManager runat="server" />
            <ext:Panel 
                ID="Panel1" 
                runat="server" 
                Width="200" 
                Height="200">
                <CustomConfig>
                    <ext:ConfigItem Name="chartId" Value="1" Mode="Raw" />
                </CustomConfig>
                <Tools>
                    <ext:Tool Type="Refresh" Handler="load(panel);" />
                </Tools>
                <Listeners>
                    <AfterRender Handler="load(this);" />
                </Listeners>
            </ext:Panel>
            <ext:Panel 
                ID="Panel2" 
                runat="server" 
                Width="200" 
                Height="200">
                <CustomConfig>
                    <ext:ConfigItem Name="chartId" Value="2" Mode="Raw" />
                </CustomConfig>
                <Tools>
                    <ext:Tool Type="Refresh" Handler="load(panel);" />
                </Tools>
                <Listeners>
                    <AfterRender Handler="load(this);" />
                </Listeners>
            </ext:Panel>
        </form>
    </body>
    </html>
    BaseUserControl.cs
    using System;
    using System.Web.UI;
    using Ext.Net;
    
    namespace Work
    {
        public class BaseUserControl : UserControl
        {
            public string PanelID { get; set; }
    
            protected void Page_PreRender(object sender, EventArgs e)
            {
                X.Js.AddScript(string.Format("{0}.body.unmask();", this.PanelID));
            }
        }
    }
    Example TestUC1.ascx
    <%@ Control Language="C#" Inherits="Work.BaseUserControl" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(10000);
        }
    </script>
    
    I am the chart #1
    Example TestUC2.ascx
    <%@ Control Language="C#" Inherits="Work.BaseUserControl" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    
    <script runat="server">
        protected void Page_Load(object sender, EventArgs e)
        {
            System.Threading.Thread.Sleep(10000);
        }
    </script>
    
    I am the chart #2
  6. #6
    Hi Daniil,

    Let's expand your example to fit my scenario.

    ExtXREnderSample.aspx
    <%@ Page Language="C#" %>
    
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <script runat="server">
        [DirectMethod]
        public void LoadChart(string panelId, string chartId)
        {
            Ext.Net.Panel p = Ext.Net.Utilities.ControlUtils.FindControl<Ext.Net.Panel>(this.Form, panelId);
    
            X.Js.Call("destroyFromCache", new JRawValue(p.ClientID));
            DevTest.ExtXRenderControl uc = this.LoadControl("ExtXRenderControl.ascx") as DevTest.ExtXRenderControl;
            uc.PanelID = panelId;
    
            p.ContentControls.Add(uc);
            X.Js.Call("putToCache", new JRawValue(p.ClientID), uc.ControlsToDestroy);
            p.UpdateContent();
        }
    
        protected void Page_Load(object sender, EventArgs e)
        {
        }
    </script>
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head id="Head1" runat="server">
        <title>Ext.NET Example</title>
        <script type="text/javascript">
            var destroyFromCache = function (container) {
                container.controlsCache = container.controlsCache || [];
                Ext.each(container.controlsCache, function (controlId) {
                    var control = Ext.getCmp(controlId);
                    if (control && control.destroy) {
                        control.destroy();
                    }
                });
            };
    
            var putToCache = function (container, controls) {
                container.controlsCache = controls;
            };
    
            var load = function (panel) {
                panel.body.mask('Loading...', 'x-mask-loading');
                Ext.net.DirectMethods.LoadChart(panel.id, panel.chartId);
            };
        </script>
    </head>
    <body>
        <form id="Form1" runat="server">
        <ext:ResourceManager ID="ResourceManager1" runat="server" />
        <ext:Viewport ID="ViewPortMain" runat="server" Layout="border">
            <Items>
                <ext:Panel ID="mainPanel" runat="server" Border="false" Region="Center" BodyStyle="background-color : #e4edfe;">
                    <Content>
                        <ext:BorderLayout ID="BorderLayout1" runat="server">
                            <West MinWidth="175" MaxWidth="400" Split="true" Collapsible="true">
                                <ext:Panel ID="Panel3" Width="175" runat="server" Title="Menu">
                                </ext:Panel>
                            </West>
                            <Center>
                                <ext:Container ID="Container1" runat="server" Region="Center" Layout="VBoxLayout">
                                    <LayoutConfig>
                                        <ext:VBoxLayoutConfig Align="Stretch" />
                                    </LayoutConfig>
                                    <Items>
                                        <ext:Container ID="Container2" runat="server" Layout="HBoxLayout" Flex="1">
                                            <LayoutConfig>
                                                <ext:HBoxLayoutConfig Align="Stretch" />
                                            </LayoutConfig>
                                            <Items>
                                                <ext:Panel ID="Panel1" runat="server" Flex="1">
                                                    <CustomConfig>
                                                        <ext:ConfigItem Name="chartId" Value="1" Mode="Raw" />
                                                    </CustomConfig>
                                                    <Tools>
                                                        <ext:Tool Type="Refresh" Handler="load(panel);" />
                                                    </Tools>
                                                    <Listeners>
                                                        <AfterRender Handler="load(this);" />
                                                    </Listeners>
                                                </ext:Panel>
                                                <ext:Panel ID="Panel4" runat="server" Flex="1">
                                                    <CustomConfig>
                                                        <ext:ConfigItem Name="chartId" Value="2" Mode="Raw" />
                                                    </CustomConfig>
                                                    <Tools>
                                                        <ext:Tool Type="Refresh" Handler="load(panel);" />
                                                    </Tools>
                                                    <Listeners>
                                                        <AfterRender Handler="load(this);" />
                                                    </Listeners>
                                                </ext:Panel>
                                            </Items>
                                        </ext:Container>
                                    </Items>
                                </ext:Container>
                            </Center>
                        </ext:BorderLayout>
                    </Content>
                </ext:Panel>
            </Items>
        </ext:Viewport>
        </form>
    </body>
    </html>
    ExtXRenderControl.ascx
    <%@ Control Language="C#" Inherits="DevTest.ExtXRenderControl" CodeBehind="ExtXRenderControl.ascx.cs" %>
    <%@ Register Assembly="Ext.Net" Namespace="Ext.Net" TagPrefix="ext" %>
    <%@ Import Namespace="System.Collections.Generic"%>
    <ext:Label runat="server" ID="txtMyPanelID" />
    ExtXRenderControl.ascx
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Ext.Net;
    
    namespace DevTest
    {
        public partial class ExtXRenderControl : System.Web.UI.UserControl
        {
            public string PanelID { get; set; }
    
            public virtual List<string> ControlsToDestroy
            {
                get
                {
                    return new List<string>
                           {
                                txtMyPanelID.ClientID
                           };
                }
            }
    
            protected void Page_PreRender(object sender, EventArgs e)
            {
                X.Js.AddScript(string.Format("{0}.body.unmask();", this.PanelID));
            }
    
            protected void Page_Load(object sender, EventArgs e)
            {
                this.txtMyPanelID.Text = PanelID;
                System.Threading.Thread.Sleep(3000);
            }
        }
    }
    There are 3 issues I have with this at the moment.

    Firstly when the page loads, the panels should simply display their PanelID in the ext:Label, these labels seem to get mixed up and panel1 displays panel1panel2 and panel2 displays nothing! I don't understand how this happens.... when you refresh a panel it seems to be random as to which ext:Label gets updated with what!!

    Secondly the 'Loading' mask is not centered on the panels any more on initial page load (it seems to work for a refresh).

    Thirdly, how could I initiate a panel load from server side, i.e. from inside a directmethod? (because load is now client side?).
    I must initiate a panel load server side because the code to determine which panel needs to re-load and with what parameters is not stuff I want to write in javascript.

    Many thanks for your help so far...

Similar Threads

  1. Replies: 4
    Last Post: Nov 03, 2011, 7:46 PM
  2. [CLOSED] Height Issues when auto loading panels
    By craig2005 in forum 1.x Legacy Premium Help
    Replies: 19
    Last Post: Mar 21, 2011, 8:04 PM
  3. Replies: 7
    Last Post: Jul 16, 2010, 12:02 AM
  4. Replies: 6
    Last Post: Mar 12, 2010, 1:34 AM
  5. Replies: 0
    Last Post: Oct 07, 2009, 4:10 AM

Tags for this Thread

Posting Permissions