in
Forums
Blogs
Files
Devexpress.Com
ClientCenter
Support Center
DevExpress Channel

Alan's place

  • The XtraCharts Suite: Saving Layouts and State (Feature Preview)

    I want to spend a few minutes describing the ways in which the XtraChart's layout and state can be saved in our forthcoming release v2006.2. Note: As always, all API and feature implementations discussed herein are subject to change, but I expect no changes to this API and you should look forward to using it once the next update is issued.

    Saving the layout of a ChartControl

    The XtraCharts Suite v2006.2 introduces four new methods for the ChartControl. They are declared as follows:

    public void SaveLayoutToStream(Stream stream);
    public void SaveLayoutToFile(string path);
    public void RestoreLayoutFromStream(Stream stream);
    public void RestoreLayoutFromFile(string path);
    

    The code listed below demonstrates the use of these methods.

    using DevExpress.XtraCharts;
    using DevExpress.XtraCharts.Design;
    // …
    
    string filePath = Application.StartupPath + @"\..\..\Charts\myChart.xml";
    
    private void btnCreateChart_Click(object sender, EventArgs e) {
        ChartControl myChart = new ChartControl();
        ChartWizard.Run(myChart, null);
        myChart.SaveLayoutToFile(filePath);
    }
    

    Once saved, this layout can be restored for use at a later time and shown within a form, printed, or exported to one of the available formats.

    private void btnShowChart_Click(object sender, EventArgs e) {
        ChartControl chart1 = new ChartControl();
        chart1.RestoreLayoutFromFile(filePath);
    
        Form form1 = new Form();
        form1.Controls.Add(chart1);
        chart1.Dock = DockStyle.Fill;
    
        form1.Show();
    }
    
    private void btnPrintChart_Click(object sender, EventArgs e) {
        ChartControl chart1 = new ChartControl();
        chart1.RestoreLayoutFromFile(filePath);
        chart1.ShowPrintPreview();
    }
    
    private void btnExportChart_Click(object sender, EventArgs e) {
        ChartControl chart1 = new ChartControl();
        chart1.RestoreLayoutFromFile(filePath);
        chart1.ExportToPdf("Chart.pdf");   
    }
    

    That's about all you'll need to do to implement this new capability in your application once v2006.2 is released.

    ViewState for the WebChartControl

    With XtraCharts v2006.2 you're able to activate save/restore for the WebChartControl's ViewState. I think that most of you who are developing projects in ASP .NET are familiar with the EnableViewState property. For those that are not, the following information from MSDN may be of use to you for familiarization purposes:

    "Control.EnableViewState property
    Gets or sets a value indicating whether the server control persists its view state, and the view state of any child controls it contains, to the requesting client."

    Hence, this feature enables you to save the chart's state between round trips to a client. This means that the state of a WebChartControl is persisted to a string variable and sent to the client and back as a hidden variable. Upon postback, the page framework parses the input string from the hidden variable and populates the ViewState property of a WebChartControl. To help clarify the benefits of ViewState, let's review the following simple example:

    A web page contains a WebChartControl and a Button. Initially, the chart is empty, and every time an end-user clicks the button, a random series point is added to the chart's series. Note that after a point has been added, a page is reloaded, hence it's necessary to enable the ViewState for the WebChartControl, so as to persist all points which were added previously.

    This code enables the ViewState for the WebChartControl:

    protected void Page_Load(object sender, EventArgs e) {
        WebChartControl1.EnableViewState = true;
    }
    

    And the following demonstrates how a series point with the current time as an argument and a random value (1; 10) can be added to a web chart.

    protected void Button1_Click(object sender, EventArgs e) {
        Random random = new Random();
        double value = Math.Round(random.NextDouble() * 10, 1);
    
        SeriesPoint point = new SeriesPoint(DateTime.Now, new double[] { value });
    
        WebChartControl1.Series[0].Points.Add(point);
    }
    

    Note that this code can be different in a real-life application in that you can add any point or make any other changes to the chart on the Button.Click event. The main idea is that after a chart has been changed, the page is reloaded and the last change is applied to the chart along with all the previous changes.

    That's how saving/restoring a chart will work in XtraCharts v2006.2.

    Comments are welcome!

  • XtraReports: Improving performance in ASP .NET

    Ok, what's interesting today? Reporting. Web reporting...

    Note: Those who are not entirely familiar with XtraReports and its Web based reporting engine can read about the basic concepts behind it here: Getting Started - Creating a Web Report. In general, there are two basic controls which can be used for web reporting: the ReportViewer and ReportToolbar. They are dropped onto a Web page, linked together, and can be used to represent and maintain an XtraReport assigned to the ReportViewer.Report property.

    I think that everyone who has ever tried to create a web report should be aware of some hidden pitfalls. For instance, performance problems. Web reporting imposes different constraints and solutions to this problem can sometimes be rather difficult. Some time ago I found a nice KB article which Plato recently submitted to our Knowledge Base. I think that this article will be very useful for those who want to greatly improve the performance of their web reports!

    Look at How to cache a report object in a web application.

    What is the problem then? In particular, the problem is that the ReportViewer disposes of its report on every postback. So, to be able to show the report again, the server has to recreate it. In general, the problem is that for now the XtraReport's document (which is a sequence of bricks for all generated data) can't be saved to a file. We already have this request in our "To Do" list (www.devexpress.com/issue=AS3465), but unfortunately this list is still very long. So, in ASP .NET the report is recreated every time on the server when any of the ReportToolbar's buttons are clicked or a postback occurs. If a report is very complex the obvious need is to prevent this lengthy recreation process.

    Luckily, we are able to workaround this problem, and Plato's article nicely describes how. Just store the created report to a page's cache (or a Session), and then restore it again, if necessary.

    First, you need to disconnect the ReportViewer from the Report at design time and use the page's OnInit method to set the ReportViewer.Report property.

    override protected void OnInit(EventArgs e) {
        InitializeComponent();
        base.OnInit(e);
    
        if (Cached)
            ReportViewer.Report = RestoreReport();
        else
            ReportViewer.Report = CreateReport();
    }
    

    Note: I've slightly modified the code from that article so that it will be easier to understand in the context of this blog entry.

    Here, Cached is the property that indicates whether a report has already been cached or not.

    private bool Cached {
        get {
            if(Session["ReportIndex"] != null) {
                return true;
            }
            else {
                return false;
            }
        }
    }
    

    If a report has already been saved to a Session, then it can be easily restored as follows:

    private XtraReport RestoreReport() {
        return Session["ReportIndex"] as XtraReport;
    }
    

    Creating a report object at runtime is also a very obvious. Interestingly here a created report should be saved to a Session, from which it will be restored:

    private XtraReport CreateReport() {
        XtraReport report = new XtraReport1();
        report.CreateDocument();
        StoreReport(report);
    
        return report;
    }   
    
    private void StoreReport(XtraReport report) {
        Session["ReportIndex"] = report;
    }
    

    But all this will be in vain  if you forget one important thing. Every time a ReportViewer is unloaded, it disposes of the report assigned to its Report property. To avoid this you should handle the ReportViewer.ReportUnload event and set the ReportViewer.Report property to null.

    private void InitializeComponent() {
        this.ReportViewer.Unload += new System.EventHandler(this.ReportViewer_Unload);
    }
    
    private void ReportViewer_Unload(object sender, System.EventArgs e) {
        ReportViewer.Report = null;
    }
    

    That's all you need to do... The first time a report is loaded will take a while, but then an end-user can easily navigate through its pages without needing to wait so long.

    I hope this approach will be useful to all those who use XtraReports for Web reporting, and make your life a bit easier.

    PS. If you have any comments on this, or have any ideas on how web performance can be improved, please, add your comments to this post.

  • Welcome to Alan's Place!

    Hi, Community!

    Well, I've finally decided to start blogging and join the company of such fabulous DX bloogers as Oliver and Julian.

    Most of my work is devoted to four of our .Net products- XtraReports, XtraPrinting, XtraScheduler and XtraCharts (and a couple of other babies that I need to keep secret until official announcements :-) ) - and therefore, my blog entries will mostly focus on these tools.

    I promise to try and discuss "interesting things" here and if you notice that Im not keeping my word, please write to me and remind me of my promise ;-)

Copyright © 1998-2008 Developer Express Inc.
ALL RIGHTS RESERVED