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

Graph for each group

15 Answers 1051 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Toni Gomez
Top achievements
Rank 1
Toni Gomez asked on 27 Oct 2009, 09:48 AM
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

15 Answers, 1 is accepted

Sort by
0
Chavdar
Telerik team
answered on 30 Oct 2009, 04:12 PM
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.
0
Toni Gomez
Top achievements
Rank 1
answered on 02 Nov 2009, 11:02 AM
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.







0
Joe
Top achievements
Rank 2
answered on 03 Nov 2009, 06:34 PM
--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
0
Toni Gomez
Top achievements
Rank 1
answered on 04 Nov 2009, 08:41 AM
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?
0
Accepted
Chavdar
Telerik team
answered on 04 Nov 2009, 03:11 PM
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.
0
Toni Gomez
Top achievements
Rank 1
answered on 05 Nov 2009, 08:36 AM
Chavdar,

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

Regards,

Jaap
0
Joe
Top achievements
Rank 2
answered on 11 Nov 2009, 07:11 PM

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

0
Sherwin Vealsco
Top achievements
Rank 1
answered on 29 Apr 2010, 12:39 PM
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
0
Steve
Telerik team
answered on 17 Aug 2011, 04:55 PM
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 >>

0
Roy Halvorsen
Top achievements
Rank 1
answered on 22 Sep 2011, 09:28 AM
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
0
Steve
Telerik team
answered on 04 Oct 2011, 01:57 PM
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 >>

0
Ahmed
Top achievements
Rank 1
answered on 29 Aug 2013, 01:25 PM
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 .

0
Stef
Telerik team
answered on 03 Sep 2013, 10:57 AM
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.

0
Amit
Top achievements
Rank 1
answered on 22 Jul 2015, 02:27 PM

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.

0
Stef
Telerik team
answered on 23 Jul 2015, 01:35 PM
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
Tags
General Discussions
Asked by
Toni Gomez
Top achievements
Rank 1
Answers by
Chavdar
Telerik team
Toni Gomez
Top achievements
Rank 1
Joe
Top achievements
Rank 2
Sherwin Vealsco
Top achievements
Rank 1
Steve
Telerik team
Roy Halvorsen
Top achievements
Rank 1
Ahmed
Top achievements
Rank 1
Stef
Telerik team
Amit
Top achievements
Rank 1
Share this question
or