ASP.NET AJAX MultiHandleSliderExtender - Slide by Year and Month
page 4 of 5
by Bryian Tan
Feedback
Average Rating: This article has not yet been rated.
Views (Total / Last 10 Days): 26473/ 35

Chart Control

Make sure to download the Microsoft Chart Controls for Microsoft .NET Framework 3.5 because the Chart controls required System.Web.DataVisualization.Design.dll and System.Web.DataVisualization.dll. I also included both the dlls in the sample code. Some of the codes in this section are from Samples Environment for Chart Controls. First, let create a method to bind the data source to the Column Chart.  This method accepts two parameters, start and end range values. Then use LINQ to query the CarsList.xml data source and find all the records where YearMonth between start and end range values. Group the result by car brands, stores it in lstCarsnTotal and bind it to the chart. See listing 7.

Listing 7

void PopulateChart(int start, int end)
    {
        List<CarsList> lstCarsnTotal = new List<CarsList>();
 
        XDocument xmlDoc = XDocument.Load(Server.MapPath(Utilities.Instance.CarsListXMLPath));
        lstCarsnTotal = (from c in xmlDoc.Descendants("Car")
                         where (int)c.Attribute("YearMonth") >= GetRange(start) 
            && (int)c.Attribute("YearMonth") <= GetRange(end)
                         group c by (string)c.Attribute("CarBrand") into g
 
                         select new CarsList
                         {
                             CarCount = g.Sum(c => (int)c.Attribute("Count")),
                             CarBrand = g.Key
                         }).ToList();
        Chart1.Series["Default"].ChartType = SeriesChartType.Column;
        Chart1.Series["Default"].Points.DataBindXY(lstCarsnTotal, "CarBrand",             
            lstCarsnTotal, "CarCount"); 
}
 
//return YearMonth
    protected static int GetRange(int rn)
    {
        IEnumerable<Range> rangeText;
 
        rangeText = lstSliderRange.Where(r => r.RowNumber == rn)
            .Select(r => new Range
            {
                Year = r.Year,
                Month = r.Month
            });
 
        return int.Parse(rangeText.First().Year + rangeText.First().Month);
    }

Now, when the user click on the column chart, a GridView will appears next to it. The PopulateGrid method takes the car brand as an argument. Then use LINQ to query the SliderRange.xml data source where YearMonth between the selected range values and CarBrand equal to the selected car brand. See listing 8.

Listing 8

protected void Chart1_Click(object sender, ImageMapEventArgs e)
    {
        if (!GridView1.Visible)
        {
            GridView1.Visible = true;
        }
        //kept track of selected car type
        ChartPostBackValue.Value = e.PostBackValue;
        lblCarBrand.Text = "Car Brand: " + e.PostBackValue;
 
        PopulateGrid(e.PostBackValue);
        PopulateChart(int.Parse(rangeStart.Value), int.Parse(rangeEnd.Value));
    }
 
    void PopulateGrid(string strPostBavkVal)
    {
        List<CarsList> lstCarsnTotal = new List<CarsList>();
 
        XDocument xmlDoc = XDocument.Load(Server.MapPath(Utilities.Instance.CarsListXMLPath));
        lstCarsnTotal = (from c in xmlDoc.Descendants("Car")
                         where (int)c.Attribute("YearMonth") >= 
                              GetRange(int.Parse(rangeStart.Value))
                         && (int)c.Attribute("YearMonth") <= 
GetRange(int.Parse(rangeEnd.Value)) && (string)c.Attribute("CarBrand") == strPostBavkVal
                         select new CarsList
                         {
                             CarCount = (int)c.Attribute("Count"),
                             CarBrand = (string)c.Attribute("CarBrand"),
                             Date = (string)c.Attribute("Date")
                         }).ToList();
 
        GridView1.DataSource = lstCarsnTotal;
        GridView1.DataBind();
    }

Known Issue

On design time, we will see the error "MultiHandleSliderExtender could not be set on property MultiHandleSliderTargets" but code work fine at run time. I have downloaded the example and latest version of Ajax Control Toolkit from CodePlex but didn't solve the problem. A workaround is adding the TagPrefix next to the MultiHandleSliderTargets tag during design time and remove it at run time. Hopefully someone can shed some light on this.

Point of Interest

The Default2.aspx in the sample code includes a master page. If you use a master page, make sure to use the Control.ClientID. For some reason the client __doPostBack function do not work with master page, the work around was to call the button click event. See listing 9. Hopefully someone can shed some light on this too.

Listing 9

<script type="text/javascript">
    var isDragging = false;
    function Drag(sender, args) {
        GetSliderRange($get("<%= rangeStart.ClientID %>").value, 
$get("<%= rangeEnd.ClientID%>").value);
    }
    function DragEnd(sender, args) {
        //prevent postback on slider click
        if ($get("<%= hdfTrackRangeStart.ClientID %>").value !== 
$get("<%= rangeStart.ClientID %>").value) {
            $get("<%= btnLoadChart.ClientID %>").click();
            //__doPostBack("<%= btnLoadChart.ClientID %>", "");
        }
        if ($get("<%= hdfTrackRangeEnd.ClientID %>").value !== 
$get("<%= rangeEnd.ClientID %>").value && 
$get("<%= hdfTrackRangeEnd.ClientID %>").value !== '0') {
            $get("<%= btnLoadChart.ClientID %>").click();
            //__doPostBack("<%= btnLoadChart.ClientID %>", "");
        }
    }
 
    function GetSliderRange(startV, endV) {
        PageMethods.SliderRange(startV, endV, this.callback);
    }
 
    function callback(result) {
 
        var arrResult = result.split("--");
 
        $get("<%= lblStartRange.ClientID %>").innerHTML = arrResult[0];
        $get("<%= lblEndRange.ClientID %>").innerHTML = arrResult[1];
 
    }
    </script>

I have noticed that, clicking on the handle will trigger the DragEnd function and cause unnecessary post back. To remedy this problem, compare the old selected range value and the current selected range value, if they are not equal then permit the call of client-side __doPostBack function. See listing 10.

Listing 10

function DragEnd(sender, args) {
        //prevent postback on slider click
        if ($get("hdfTrackRangeStart").value !== $get("rangeStart").value) {
             __doPostBack("btnLoadChart""");
        }
        if ($get("hdfTrackRangeEnd").value !== $get("rangeEnd").value && 
$get("hdfTrackRangeEnd").value !== '0') {
             __doPostBack("btnLoadChart""");
        }
    }

The chart displayed correctly on my local machine but it displayed a sequence of strange characters in the hosting environment. After doing some research, I discovered that I didn't set appropriate permissions on the storage folder and EnableSessionState on the page directive was set to false. The list of ASP.NET Charts storage mode is available here.


View Entire Article

User Comments

No comments posted yet.






Community Advice: ASP | SQL | XML | Regular Expressions | Windows


©Copyright 1998-2024 ASPAlliance.com  |  Page Processed at 2024-03-28 10:18:40 AM  AspAlliance Recent Articles RSS Feed
About ASPAlliance | Newsgroups | Advertise | Authors | Email Lists | Feedback | Link To Us | Privacy | Search