This is a migrated thread and some comments may be shown as answers.

Updating Pie Chart with AJAX and Exploding Field

6 Answers 319 Views
Chart (Obsolete)
This is a migrated thread and some comments may be shown as answers.
Ben
Top achievements
Rank 1
Ben asked on 12 Feb 2014, 09:48 PM
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).

6 Answers, 1 is accepted

Sort by
0
Ben
Top achievements
Rank 1
answered on 12 Feb 2014, 09:55 PM
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>
0
Stamo Gochev
Telerik team
answered on 17 Feb 2014, 12:51 PM
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.
0
Ben
Top achievements
Rank 1
answered on 20 Feb 2014, 02:40 PM
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
0
Stamo Gochev
Telerik team
answered on 21 Feb 2014, 08:26 AM
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.
0
Ben
Top achievements
Rank 1
answered on 21 Feb 2014, 06:01 PM
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.
0
Danail Vasilev
Telerik team
answered on 26 Feb 2014, 03:19 PM
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.
Tags
Chart (Obsolete)
Asked by
Ben
Top achievements
Rank 1
Answers by
Ben
Top achievements
Rank 1
Stamo Gochev
Telerik team
Danail Vasilev
Telerik team
Share this question
or