
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 |
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
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.

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.

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

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?
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.

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

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

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) |
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 >>

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
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 >>
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.

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.
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