Graph for each group

16 posts, 1 answers
  1. Jaime Diaz
    Jaime Diaz avatar
    12 posts
    Member since:
    Jun 2009

    Posted 27 Oct 2009 Link to this post

    Hi,

    I'm trying to create a report that groups data by a certain field and will then show a grap for each group. In my report I'm trying to use a datasource that contains the following data:
    ID,X,Y,Group (<== column names)
    0,0,1,1
    1,1,1,1
    2,0,2,2
    3,2,2,2
    4,0,3,3
    5,3,3,3

    This is what I have done so far:
    - I've added a group to this report with the Grouping property set to '= Fields.Group'
    - In the group header section I've added a textbox that prints the value for the 'current' Group
    - In the detail section I've added textboxes that print the values for X and Y

    This works as I would expect it to, but now I want to add a graph (Type = Point) to the group header section that will show the two points for each group with the above coordinates. So what I want to achieve is that three headers are generated and that each one has a graph that shows two points.

    I'm trying to use the needdatasource event that gets thrown three times in this case. In my attempt to get the above working, I used the following code:
    Private Sub Chart1_NeedDataSource(ByVal sender As Object, ByVal e As System.EventArgs) Handles Chart1.NeedDataSource 
            Dim myChart As Telerik.Reporting.Processing.Chart = DirectCast(sender, Telerik.Reporting.Processing.Chart) 
            If Chart1.Series.Count = 0 Then 
     
                Chart1.Series.Add(New Charting.ChartSeries("Test", Charting.ChartSeriesType.Point)) 
                Chart1.Series(0).DataXColumn = "Fields.X" 
                Chart1.Series(0).DataYColumn = "Fields.Y" 
     
     
            End If 
     
            If myChart.DataSource Is Nothing Then myChart.DataSource = Me.DataSource 
     
     
        End Sub 
    Unfortunately this does not work. I can see that a graph is generated three times, but each one has the same four points: 0,0 and 1,1 and 2,2 and 3,3.
    What am I doing wrong and how do I get this to work for each group header section so that I have three different graphs with the following points:
    Graph 1: 0,1 and 1,1
    Graph 2: 0,2 and 2,2
    Graph 3: 0,3 and 3,3
  2. Chavdar
    Admin
    Chavdar avatar
    898 posts

    Posted 30 Oct 2009 Link to this post

    Hello Jaap de Wit,

    Currently this scenario can be achieved only with code. Here is a sample code snippet:

    Private Sub Chart1_NeedDataSource(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Chart1.NeedDataSource
            Dim dataTable = New DataTable()
            dataTable.Columns.Add("ID", GetType(Integer))
            dataTable.Columns.Add("X", GetType(Integer))
            dataTable.Columns.Add("Y", GetType(Integer))
            dataTable.Columns.Add("Group", GetType(Integer))
            dataTable.Rows.Add(New Object() {0, 0, 1, 1})
            dataTable.Rows.Add(New Object() {1, 1, 1, 1})
            dataTable.Rows.Add(New Object() {2, 0, 2, 2})
            dataTable.Rows.Add(New Object() {3, 2, 2, 2})
            dataTable.Rows.Add(New Object() {4, 0, 3, 3})
            dataTable.Rows.Add(New Object() {5, 3, 3, 3})
            Dim chart = CType(sender, Telerik.Reporting.Processing.Chart)
            Dim chartDef = CType(chart.ItemDefinition, Telerik.Reporting.Chart)
     
            chartDef.Series.Clear()
            Dim xIndexesList = New List(Of Double)
            For Each row In dataTable.DefaultView
                Dim chartSeries As Telerik.Reporting.Charting.ChartSeries
                Dim seriesName = row("Group").ToString()
                chartSeries = chartDef.Series.GetByName(seriesName)
                If chartSeries Is Nothing Then
                    chartSeries = New Telerik.Reporting.Charting.ChartSeries(seriesName)
                    chartDef.Series.Add(chartSeries)
                End If
                Dim seriesItem = New Telerik.Reporting.Charting.ChartSeriesItem
     
                Dim xValue = CType(row("X"), Double)
                If Not xIndexesList.Contains(xValue) Then
                    xIndexesList.Add(xValue)
                End If
     
                seriesItem.XValue = xIndexesList.IndexOf(xValue)
                seriesItem.YValue = CType(row("Y"), Double)
                 
                chartSeries.Items.Add(seriesItem)
            Next
     
            chartDef.PlotArea.XAxis.Items.Clear()
            chartDef.PlotArea.XAxis.AutoShrink = False
            chartDef.PlotArea.XAxis.AutoScale = False
            chartDef.PlotArea.XAxis.AddRange(0, xIndexesList.Count - 1, 1)
        End Sub

    Hope it helps.

    All the best,
    Chavdar
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  3. DevCraft banner
  4. Jaime Diaz
    Jaime Diaz avatar
    12 posts
    Member since:
    Jun 2009

    Posted 02 Nov 2009 Link to this post

    Thanks for your input. However, when I use this code in a report that groups data on the value 'group' and shows the graph on the groupheadersection, it does not produce the required result. In this example three graphs appear, but each graph looks exactly the same and therefore shows data that doesn't belong to the current group. What I'd like to achieve is that each groupheadersection shows a graph with data that only belongs to that particular group.
    Is there a 'best-practice' way in which I can achieve this?

    What I've done so far, is to dynamically add items to the graph each time when the 'needdatasource' event is raised. I then only add the items that belong to the current group by selecting them from my datasource. It's not the most spectacular looking code, because at run-time I don't have a clue what the current grouping value is that Telerik uses. Therefore I store each grouping value in a list and each time when the needdatasource event is raised, I collect the (n+1)th item of that list. I hope you can provide me a nicer looking solution for this.







  5. Joe
    Joe avatar
    48 posts
    Member since:
    Dec 2007

    Posted 03 Nov 2009 Link to this post

    --What I've done so far, is to dynamically add items to the graph each time when the 'needdatasource' event is raised. I then only add --the items that belong to the current group by selecting them from my datasource. It's not the most spectacular looking code, because --at run-

    How did you get the value of the current group? I have been struggling with the same issue.

    Thanks,
    Joe
  6. Jaime Diaz
    Jaime Diaz avatar
    12 posts
    Member since:
    Jun 2009

    Posted 04 Nov 2009 Link to this post

    I have the same issue as you: I can't be sure at run-time what the current 'grouping value' is. So right now I'm going by the following assumptions:
    1. I supply a datasource which needs to be grouped by only one value
    2. The values in this datasource are sorted by this grouping value
    3. I assume that Telerik will then throw the needdatasource event for each 'grouping value' in the way that I have sorted them

    So at run-time I keep track of how many times the needdatasource event is raised. When it is raised the first time, I assume that this is the first grouping value in my datasource. I then make a selection on my datasource and add the values that belong to this 'grouping value'. When the event is raised the second time, I get the second 'grouping value', etc, etc...

    So far this has produced the result that I was looking for, but as you can see, I have made a few assumptions along the way and I can't be 100% sure that Telerik will really always group my datasource in the way I want it to.

    May be someone from Telerik can shed some light on this issue?
  7. Answer
    Chavdar
    Admin
    Chavdar avatar
    898 posts

    Posted 04 Nov 2009 Link to this post

    Hello,

    Currently the chart's data source is different from the report's data source so you cannot reuse its grouping, sorting or filtering automatically. This also means that the data for the chart should be prepared manually to reflect the desired result.

    Here is an example which can be extended to fit the actual scenario with a few modifications. The key steps are as follows:
        1. Get the current grouping value from the group header section's DataObject.(handle [GroupHeaderSection].ItemDataBinding event).
        2. Create a filtering expression based on this value
        3. Apply filtering
        4. Get the result and fill the chart with data.
    Partial Public Class Report1
        Inherits Telerik.Reporting.Report
        Public Sub New()
            InitializeComponent()
     
            'One time chart configuration settings
            Me.Chart1.PlotArea.XAxis.AutoScale = False
            Me.Chart1.PlotArea.XAxis.AutoShrink = False
            Me.Chart1.PlotArea.XAxis.AddRange(0, 5, 1)
     
            'Dummy data source
            Dim dataTable = New DataTable()
            dataTable.Columns.Add("ID", GetType(Integer))
            dataTable.Columns.Add("X", GetType(Integer))
            dataTable.Columns.Add("Y", GetType(Integer))
            dataTable.Columns.Add("Group", GetType(Integer))
            dataTable.Rows.Add(New Object() {0, 0, 1, 1})
            dataTable.Rows.Add(New Object() {1, 1, 1, 1})
            dataTable.Rows.Add(New Object() {2, 0, 2, 2})
            dataTable.Rows.Add(New Object() {3, 2, 2, 2})
            dataTable.Rows.Add(New Object() {4, 0, 3, 3})
            dataTable.Rows.Add(New Object() {5, 3, 3, 3})
            Me.DataSource = dataTable
        End Sub
     
        Private Sub GroupHeaderSection1_ItemDataBinding(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles GroupHeaderSection1.ItemDataBinding
            Dim groupHeaderSection As Telerik.Reporting.Processing.GroupSection = CType(sender, Telerik.Reporting.Processing.GroupSection)
            Dim report As Telerik.Reporting.Processing.Report = groupHeaderSection.Report
     
            Dim group = groupHeaderSection.DataObject.Item("Group")
            Dim table As DataTable = CType(report.DataSource, DataTable)
            Dim rows() As DataRow = table.Select(String.Format(CultureInfo.InvariantCulture, "Group={0}", group))
     
            Dim chart As Telerik.Reporting.Processing.Chart = groupHeaderSection.ChildElements.Find("Chart1", True)(0)
            Dim chartDef As Telerik.Reporting.Chart = chart.ItemDefinition
            chartDef.Series.Clear()
            Dim chartSeries As New Telerik.Reporting.Charting.ChartSeries()
            Dim row As DataRow
            For Each row In rows
                Dim seriesItem As Telerik.Reporting.Charting.ChartSeriesItem = New Telerik.Reporting.Charting.ChartSeriesItem()
                seriesItem.XValue = CType(row("X"), Double)
                seriesItem.YValue = CType(row("Y"), Double)
                chartSeries.Items.Add(seriesItem)
            Next
            chartDef.Series.Add(chartSeries)
        End Sub
    End Class

    Hope this helps.

    Greetings,
    Chavdar
    the Telerik team

    Instantly find answers to your questions on the new Telerik Support Portal.
    Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
  8. Jaime Diaz
    Jaime Diaz avatar
    12 posts
    Member since:
    Jun 2009

    Posted 05 Nov 2009 Link to this post

    Chavdar,

    You are my hero. This is exactly what I was looking for.

    Regards,

    Jaap
  9. Joe
    Joe avatar
    48 posts
    Member since:
    Dec 2007

    Posted 11 Nov 2009 Link to this post

    Jaap,

     

    Did you ever get this to work? I'm afraid I was forced to go with an alternate solution based on time constraints.

     

    Thanks,

    Joe

  10. Sherwin Vealsco
    Sherwin Vealsco avatar
    1 posts
    Member since:
    Feb 2010

    Posted 29 Apr 2010 Link to this post

    Dim group = groupHeaderSection.DataObject.Item("Group") 
            Dim table As DataTable = CType(report.DataSource, DataTable) 
            Dim rows() As DataRow = table.Select(String.Format(CultureInfo.InvariantCulture, "Group={0}", group)) 
      
            Dim chart As Telerik.Reporting.Processing.Chart = groupHeaderSection.ChildElements.Find("Chart1", True)(0) 
            Dim chartDef As Telerik.Reporting.Chart = chart.ItemDefinition 
            chartDef.Series.Clear() 
            Dim chartSeries As New Telerik.Reporting.Charting.ChartSeries() 
            Dim row As DataRow 
            For Each row In rows 
                Dim seriesItem As Telerik.Reporting.Charting.ChartSeriesItem = New Telerik.Reporting.Charting.ChartSeriesItem() 
                seriesItem.XValue = CType(row("X"), Double) 
                seriesItem.YValue = CType(row("Y"), Double) 
                chartSeries.Items.Add(seriesItem) 
            Next 
            chartDef.Series.Add(chartSeries) 

    How can I implement this in C#. I can't seem to extract the group variable in C#.

    Thanks
  11. Steve
    Admin
    Steve avatar
    10941 posts

    Posted 17 Aug 2011 Link to this post

    Hi Sherwin,

    I'm posting the C# code for the example my colleague provided:

    public partial class Report2 : Telerik.Reporting.Report
      {
          public Report2()
          {
              //
              // Required for telerik Reporting designer support
              //
              InitializeComponent();
              this.chart1.PlotArea.XAxis.AutoScale = false;
              this.chart1.PlotArea.XAxis.AutoShrink = false;
              this.chart1.PlotArea.XAxis.AddRange(0, 5, 1);
     
              //Dummy data source
              DataTable dataTable = new DataTable();
              dataTable.Columns.Add("ID", typeof(int));
              dataTable.Columns.Add("X", typeof(int));
              dataTable.Columns.Add("Y", typeof(int));
              dataTable.Columns.Add("Group", typeof(int));
              dataTable.Rows.Add(new object[] {0, 0, 1, 1});
              dataTable.Rows.Add(new object[] {1, 1, 1, 1});
              dataTable.Rows.Add(new object[] {2, 0, 2, 2});
              dataTable.Rows.Add(new object[] {3, 2, 2, 2});
              dataTable.Rows.Add(new object[] {4, 0, 3, 3});
              dataTable.Rows.Add(new object[] {5, 3, 3, 3});
              this.DataSource = dataTable;
     
              //
              // TODO: Add any constructor code after InitializeComponent call
              //
          }
     
          private void groupHeaderSection1_ItemDataBinding(object sender, EventArgs e)
          {
              Telerik.Reporting.Processing.GroupSection groupHeaderSection = (Telerik.Reporting.Processing.GroupSection)sender;
              Telerik.Reporting.Processing.Report report = groupHeaderSection.Report;
              var group = groupHeaderSection.DataObject["Group"];
              DataTable table = (DataTable)report.DataSource;
              DataRow[] rows = table.Select(string.Format(CultureInfo.InvariantCulture, "Group={0}", group));
     
              Telerik.Reporting.Processing.Chart chart = (Telerik.Reporting.Processing.Chart)groupHeaderSection.ChildElements.Find("Chart1", true)[0];
              Telerik.Reporting.Chart chartDef = (Telerik.Reporting.Chart)chart.ItemDefinition;
              chartDef.Series.Clear();
              Telerik.Reporting.Charting.ChartSeries chartSeries = new Telerik.Reporting.Charting.ChartSeries();
               
              foreach (var row in rows)
              {
                  Telerik.Reporting.Charting.ChartSeriesItem seriesItem = new Telerik.Reporting.Charting.ChartSeriesItem();
                  seriesItem.XValue = Convert.ToDouble(row["X"]);
                  seriesItem.YValue = Convert.ToDouble(row["Y"]);
                  chartSeries.Items.Add(seriesItem);
              }
              chartDef.Series.Add(chartSeries);
          }
      }

    where do note that Group is a column from the sample datasource we bind the report to in the report constructor and not the name of a report group.

    All the best,
    Steve
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get now >>

  12. Roy Halvorsen
    Roy Halvorsen avatar
    83 posts
    Member since:
    Oct 2008

    Posted 22 Sep 2011 Link to this post

    Hi. I'm using the method described in this thread to show correct values in my reporting chart.

    My report has a table and a chart. The table gets it data from a Telerik.Reporting.ObjectDataSource set in the designer window. The chart gets it data from the code behind method below inside chart_NeedDataSource.

    System.Collections.ObjectModel.Collection<ReportCommonMatrixDataContract> reportCollection =
                    ReportCommonMatrixCollection.GetSmokingStatusReport((DateTime)Report.ReportParameters[0].Value,
                                                         (DateTime)Report.ReportParameters[1].Value,
                                                         (string)Report.ReportParameters[2].Value,
                                                         (int?)Report.ReportParameters[3].Value,
                                                         (int?)Report.ReportParameters[4].Value);

    Since the table and chart shows the same data I want to use the reports Telerik.Reporting.ObjectDataSource to provide the data like this:

    System.Collections.ObjectModel.Collection<ReportCommonMatrixDataContract> reportCollection = (System.Collections.ObjectModel.Collection<ReportCommonMatrixDataContract>)objectDataSource1.DataSource;

    This causes an error "An error has occurred while processing Chart 'chart1':
    Unable to cast object of type 'System.RuntimeType' to type 'System.Collections.ObjectModel.Collection`1[Hemit.Mqr.Common.DataContract.ReportCommonMatrixDataContract]'."

    Why doesn't his work?

    Regards, Roy
  13. Steve
    Admin
    Steve avatar
    10941 posts

    Posted 04 Oct 2011 Link to this post

    Hi Roy,

    The declarative data source components are intended to specify declaratively how to retrieve the data for the report. They do not contain any data at all, they only specify the means how to obtain it (e.g. in the case of SqlDataSource - by executing a SQL query against a database, or in the case of ObjectDataSource - by invoking a method/property of a custom business object, etc.). So you see the cast you have is really incorrect.
    In order to achieve your requirement our suggestion is to use a new approach the involves bindings. For more information refer to this forum thread.

    Kind regards,
    Steve
    the Telerik team

    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

  14. Ahmed
    Ahmed avatar
    9 posts
    Member since:
    Jun 2013

    Posted 29 Aug 2013 Link to this post

    Thanks  Steve for your effort ,
    but i have a problem when i run report one graph show to me .
    i make group and fire event   groupHeaderSection_ItemDataBinding .

  15. Stef
    Admin
    Stef avatar
    3052 posts

    Posted 03 Sep 2013 Link to this post

    Hello Ahmed,

    From your screenshot it is not clear what is the data structure and report definition. In my colleagues example, the group is not static, thus it has DataObject containing the current group's data.

    Notice the Chart item is now obsolete. Please consider switching to the new Graph item, which provides greater design time support for expressions, styling and interactivity.

    If you need further help, please open a support thread and send us the report definition with some sample data.

    Regards,
    Stef
    Telerik

    Have you tried the new visualization options in Telerik Reporting Q2 2013? You can get them from your account.

  16. Amit
    Amit avatar
    8 posts
    Member since:
    Jul 2015

    Posted 22 Jul 2015 Link to this post

    Hi ,
    We are facing one Issue and could not able to resolve. We are working with Telerik Graph Control and using Chart type "Line with Marker". Issue is once will prepare the graph on PDF, ​Data Point Marker and ​Data point Label are overlapping with each other (See attached Screenshot). Please let me know if any property available in Telerik to resolve this Issue. I am using 2013 Q3 License ​version of Telerik.

    Thanks for the help in advance.

  17. Stef
    Admin
    Stef avatar
    3052 posts

    Posted 23 Jul 2015 Link to this post

    Hello Amit,

    Please test if setting the YAxis - Scale - Maximum to 110 (based on the data from the screenshot) causes the data point labels to be displayed as expected. Note that you wil have to provide value for the YAxis - Scale - Minimum as well.

    If yes, the issue is that the labels are pushed down to be gathered in the visible plot area. To avoid the issue you can check the maximum displayed value by analyzing the data in code, and then set the number as axis - Scale - Maximum in the report constructor.

    In the latest Telerik Reporting Q2 2015 version there is an option to use a binding to set the minimum and maximum of the scale - How to: Use Bindings to Control the Coordinate System Properties.

    Regards,
    Stef
    Telerik
    Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
Back to Top
DevCraft banner