Updating Pie Chart with AJAX and Exploding Field

Thread is closed for posting
7 posts, 0 answers
  1. Ben
    Ben avatar
    4 posts
    Member since:
    Mar 2013

    Posted 12 Feb 2014 Link to this post

    I have two pie charts and am trying to have one update the other through the RadAjaxManager with the OnClientSeriesClicked event, as outlined here. Basically, when a series is clicked in PieChart1, an AjaxRequest changes the DataSource on PieChart2. This all works as expected.

    A problem arises when I try to also make the series that was clicked in PieChart1 be exploded, using the example given here. The problem is that the field never becomes exploded in the pie chart. It seems as if the ajax request returning overwrites the changes I have made to "IsExploded". I believe this to be the case because I have another pie chart that is never updated by an ajax request, so is therefore not declared as an updated control in the ajax manager, and setting the field IsExploded to true works just fine in that case. I also inserted a line that just calls alert() to tell me when it is setting IsExploded to true, and I see that alert box, so I know it is getting set, it just doesn't seem to stick.

    Code sample:

            <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" OnAjaxRequest="RadAjaxManager1_AjaxRequest">
              <AjaxSettings>
                   <telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
                        <UpdatedControls>
                            <telerik:AjaxUpdatedControl ControlID="PieChart1" LoadingPanelID="LoadingPanel1"/>
                            <telerik:AjaxUpdatedControl ControlID="PieChart2" LoadingPanelID="LoadingPanel1"/>
                        </UpdatedControls>
                   </telerik:AjaxSetting>
              </AjaxSettings>
            </telerik:RadAjaxManager>

            <telerik:RadCodeBlock ID="codeBlock" runat="server">
              <script type="text/javascript">
                  function OnClientSeriesClicked_PieChart1(sender, args) {
                      $find("<%= RadAjaxManager1.ClientID %>").ajaxRequest("OverallUsageBreakdown;" + args.get_category());

                      args.get_seriesData().map(function(item) {
                          if (item.Prefix === args.get_category()) {
                              item.IsExploded = true;
                              alert("condition true");
                          } else
                              item.IsExploded = false;
                      });

                      sender.set_transitions(false);
                      sender.repaint();
                      sender.set_transitions(true);
                  }
              </script>
            </telerik:RadCodeBlock>

    My question is, does anyone have any suggestions as to how I can get the IsExploded property to stay set to true? It seems as if no matter what I do (I have tried updating IsExploded in an OnResponseEnd script and by using a ResponseScript to call a script that updates the IsExploded field; I have confirmed both of those get called and set the field correctly (using alert boxes to check field values), but have the same problem in the end).
  2. Ben
    Ben avatar
    4 posts
    Member since:
    Mar 2013

    Posted 12 Feb 2014 in reply to Ben Link to this post

    Re posting code block because the formatting got lost somehow (sorry about that):

    01.<telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" OnAjaxRequest="RadAjaxManager1_AjaxRequest">
    02.  <AjaxSettings>
    03.       <telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
    04.            <UpdatedControls>
    05.                <telerik:AjaxUpdatedControl ControlID="PieChart1" LoadingPanelID="LoadingPanel1"/>
    06.                <telerik:AjaxUpdatedControl ControlID="PieChart2" LoadingPanelID="LoadingPanel1"/>
    07.            </UpdatedControls>
    08.       </telerik:AjaxSetting>
    09.  </AjaxSettings>
    10.</telerik:RadAjaxManager>
    11. 
    12.<telerik:RadCodeBlock ID="codeBlock" runat="server">
    13.  <script type="text/javascript">
    14.      function OnClientSeriesClicked_PieChart1(sender, args) {
    15.          $find("<%= RadAjaxManager1.ClientID %>").ajaxRequest("OverallUsageBreakdown;" + args.get_category());
    16.           args.get_seriesData().map(function(item) {
    17.              if (item.Prefix === args.get_category()) {
    18.                  item.IsExploded = true;
    19.                  alert("condition true");
    20.              } else
    21.                  item.IsExploded = false;
    22.          });
    23.          sender.set_transitions(false);
    24.          sender.repaint();
    25.          sender.set_transitions(true);
    26.      }
    27.  </script>
    28.</telerik:RadCodeBlock>
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Stamo Gochev
    Admin
    Stamo Gochev avatar
    157 posts

    Posted 17 Feb 2014 Link to this post

    Hello Ben,

    Thanks to your detailed code snippet, I was able to investigate the issue and it turned out that it is not connected with the AjaxManager. In order to modify the Exploded state of a series item, you can follow these steps:
    1. Find the pie series item that is clicked. One way to do this is to assign a name to every item (you can use the NameField property if the chart is databound or the Name property if your series items are created programmatically) and then use this name as a marker, indicating which item was clicked.
    2. Toggle the Exploded state of the item.
    3. Repaint the chart to apply the changes.
    You can find a full working example in the attached file with detailed comments on the main steps. Could you have a look at it and try to apply it in your configuration?

    Regards,
    Stamo Gochev
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
  5. Ben
    Ben avatar
    4 posts
    Member since:
    Mar 2013

    Posted 20 Feb 2014 in reply to Stamo Gochev Link to this post

    Hi Stamo,

    Thanks for getting back to me so quickly. I am trying to implement your suggestion now, but am wondering if your steps should be implemented in the code behind file (in the method that responds to AjaxRequests) or in the javascript function?

    Also I apologize but I cannot see or find a file attached to your post, are you sure a file as attached or am I missing something here?

    Thanks again!
    Ben
  6. Stamo Gochev
    Admin
    Stamo Gochev avatar
    157 posts

    Posted 21 Feb 2014 Link to this post

    Hello Ben,

    The suggested approach should be done in your markup definition using JavaScript code. As there was a problem with attaching the file, I am pasting the example here:
    JavaScript code:
    <script type="text/javascript">
        function changeExplodedItem(sender,args) {
            var chart=$find("Chart");
                //get the name of the item that you clicked on
                selectedItemName = args.get_category(),
                itemIndex = -1,
                //get a reference to the pie series
                series = chart._chartObject.options.series[0],
                dataLength = series.data.length;
            for (var i = 0; i < dataLength; i++) {
                //note that the "name" property is defined as a column name in the datasource
                //if your original column name is "pieSegmentName", then you should retrieve the value
                //with series.data[i].pieSegmentName
                var currentItemName = series.data[i].name;
                if (currentItemName === selectedItemName) {
                    itemIndex = i;
                }
            }
     
            if (itemIndex != -1) {
                //find if the item is currently exploded or not
                //again, as the property is defined as "isExploded" in the datasource
                //we should use the same name
                var isExploded = series.data[itemIndex].isExploded;
                //change the exploded state
                series.data[itemIndex].isExploded = !isExploded;
                //repaint the chart to apply the changes
                chart.repaint();
            }
     
        }
    </script>
    Markup:
    <telerik:RadHtmlChart runat="server" ID="Chart" Skin="Black" OnClientSeriesClicked="changeExplodedItem">
    </telerik:RadHtmlChart>
    Code-behind:
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            PieSeries pie = new PieSeries();
            pie.DataFieldY = "value";
            pie.NameField = "name";
            pie.ExplodeField = "isExploded";
            Chart.PlotArea.Series.Add(pie);
            Chart.DataSource = GetData();
            Chart.DataBind();
        }
    }
     
    private DataTable GetData()
    {
        DataTable table = new DataTable();
        table.Columns.Add(new DataColumn("value", typeof(int)));
        table.Columns.Add(new DataColumn("name", typeof(string)));
        table.Columns.Add(new DataColumn("isExploded", typeof(bool)));
        table.Rows.Add(new object[] { 200, "name 1", true });
        table.Rows.Add(new object[] { 250, "name 2", false });
        table.Rows.Add(new object[] { 100, "name 3", true });
        table.Rows.Add(new object[] { 200, "name 4", false });
        return table;
    }

    Regards,
    Stamo Gochev
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
  7. Ben
    Ben avatar
    4 posts
    Member since:
    Mar 2013

    Posted 21 Feb 2014 in reply to Stamo Gochev Link to this post

    Hi Stamo, thanks for your reply.

    I tried this but run into the same problem that I had from the start. This code works and will explode the item in the pie series if the chart is not declared as an updated control in the RadAjaxManager, but if the PieChart is declared as an updated control in the RadAjaxManager, and I make an ajaxRequest in the OnClientSeriesClicked function, the pie item is not exploded when the control refreshes.

    If you look at the code I provided in my initial post, you will see that I declare both PieChart1 and PieChart2 as updated controls in the RadAjaxManager. PieChart2 needs to be declared as an updated control because when I select an item in PieChart1 I want to change the DataSource of PieChart2 from the code-behind, as I explained. PieChart1 is declared as an updated control because it also has its datasource updated by another control's OnClientSeriesClicked event. You can see this effect by adding a RadAjaxManager to the sample you provided, adding the Chart as an updated control, and then sending an ajax request in the OnClientSeriesClickedEvent handler.

    Would it be possible to perhaps update which controls are declared as updated controls in the RadAjaxManager during PieChart1's OnClientSeriesClicked event? That way I can only add the controls that are being modified by that ajaxRequest. Alternatively, using ajaxRequestWithTarget would allow me to specify more specific lists of affected controls.
  8. Danail Vasilev
    Admin
    Danail Vasilev avatar
    1490 posts

    Posted 26 Feb 2014 Link to this post

    Hi Ben,

    You can execute JavaScript after the ajax request is executed, where the clicked chart's item can be exploded. For example:
    JavaScript:
    <telerik:RadCodeBlock ID="RadCodeBlock1" runat="server">
        <script type="text/javascript">
            function OnClientSeriesClicked(sender, args) {
                $find("<%= RadAjaxManager1.ClientID %>").ajaxRequest(sender.get_id() + "|" + args.get_category());
            }
     
            function explodeItem(chart, category) {
                var chart = $find(chart);
                //get the name of the item that you clicked on
                selectedItemName = category,
                itemIndex = -1,
                //get a reference to the pie series
                series = chart._chartObject.options.series[0],
                dataLength = series.data.length;
                for (var i = 0; i < dataLength; i++) {
                    //note that the "name" property is defined as a column name in the datasource
                    //if your original column name is "pieSegmentName", then you should retrieve the value
                    //with series.data[i].pieSegmentName
                    var currentItemName = series.data[i].name;
                    if (currentItemName === selectedItemName) {
                        itemIndex = i;
                    }
                }
                if (itemIndex != -1) {
                    //find if the item is currently exploded or not
                    //again, as the property is defined as "isExploded" in the datasource
                    //we should use the same name
                    var isExploded = series.data[itemIndex].isExploded;
                    //change the exploded state
                    series.data[itemIndex].isExploded = !isExploded;
                    //repaint the chart to apply the changes
                    chart.repaint();
                }
            }
        </script>
    </telerik:RadCodeBlock>
    ASPX:
    <telerik:RadAjaxManager ID="RadAjaxManager1" runat="server" OnAjaxRequest="RadAjaxManager1_AjaxRequest">
        <AjaxSettings>
            <telerik:AjaxSetting AjaxControlID="RadAjaxManager1">
                <UpdatedControls>
                    <telerik:AjaxUpdatedControl ControlID="PieChart1" LoadingPanelID="LoadingPanel1" />
                </UpdatedControls>
            </telerik:AjaxSetting>
        </AjaxSettings>
    </telerik:RadAjaxManager>
     
    <telerik:RadHtmlChart runat="server" ID="PieChart1" Skin="Black" OnClientSeriesClicked="OnClientSeriesClicked">
    </telerik:RadHtmlChart>
    C#:
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            PieSeries pie = new PieSeries();
            pie.DataFieldY = "value";
            pie.NameField = "name";
            pie.ExplodeField = "isExploded";
            PieChart1.PlotArea.Series.Add(pie);
            PieChart1.DataSource = GetData();
            PieChart1.DataBind();
        }
    }
    private DataTable GetData()
    {
        DataTable table = new DataTable();
        table.Columns.Add(new DataColumn("value", typeof(int)));
        table.Columns.Add(new DataColumn("name", typeof(string)));
        table.Columns.Add(new DataColumn("isExploded", typeof(bool)));
        table.Rows.Add(new object[] { 200, "name 1", true });
        table.Rows.Add(new object[] { 250, "name 2", false });
        table.Rows.Add(new object[] { 100, "name 3", true });
        table.Rows.Add(new object[] { 200, "name 4", false });
        return table;
    }
    protected void RadAjaxManager1_AjaxRequest(object sender, AjaxRequestEventArgs e)
    {
        string[] arguments = e.Argument.Split('|');
        RadAjaxManager1.ResponseScripts.Add("explodeItem(" + "'" + arguments[0] + "' ," + "'" + arguments[1] + "'" + ")");
    }

    You can find useful Executing Custom Javascript Code after AJAX Update help article.

    I have also attached the full VS example to this post.

    Regards,
    Danail Vasilev
    Telerik
    If you want to get updates on new releases, tips and tricks and sneak peeks at our product labs directly from the developers working on the UI for ASP.NET AJAX, subscribe to the blog feed now.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017