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

Binding data in RadChartView with LightSwitch

11 Answers 260 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Adrian
Top achievements
Rank 1
Adrian asked on 12 Oct 2012, 10:49 AM
Hello there, I am attempting to learn how to use RadChartView.

Initially I had an application which used RadChart, but upon seeing that RadChartView is a new and improved version of this, I decided it would be best to learn how to use that instead.

However, converting my code has not been easy and I am having no end of trouble trying to bind my data, and I have not been able to find many good resources (forum topics, help pages, etc) to work out what I'm doing wrong (most are for RadChart).

My Visual Studio Solution comprises two projects; A LightSwitch project and a Silverlight project. The Silverlight one contains the code for the RadChartView control, and the LightSwitch project contains the data and references the Silverlight project to use the RadChartView control as a custom control.

Here is the XAML I'm using:
<telerik:ChartDataSource x:Name="chartDataSource" ItemsSource ="{Binding Screen.BusinessDatas}"/>
<telerik:RadCartesianChart x:Name="xRadChartView" Background="Blue" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Right" Height = "600" Width="1500">
<telerik:RadCartesianChart.VerticalAxis>
<telerik:CategoricalAxis />
</telerik:RadCartesianChart.VerticalAxis>
<telerik:RadCartesianChart.HorizontalAxis>
<telerik:LinearAxis />
</telerik:RadCartesianChart.HorizontalAxis>
<telerik:RadCartesianChart.Series>
</telerik:RadCartesianChart.Series>
</telerik:RadCartesianChart>

It's worth noting that I've removed a lot of commented out code, etc (from my attempts to get this working, and from old RadChart code) from this to make it more readable. The reason there is no chart series specified here is because I was setting it via dropdown box, however I have also tried setting it like this:

<telerik:LineSeries CategoryBinding="DTValue"
ValueBinding="ItemValue"
ItemsSource="{Binding Screen.BusinessDatas}">
<telerik:LineSeries.PointTemplates>
</telerik:LineSeries.PointTemplates>
</telerik:LineSeries>

That's it for the code snippets from RadChartViewControl.XAML.

For RadChartViewControl.cs:

public RadChartViewControl()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(RadChartControl_Loaded);
xRadChartView.Series[0].ItemsSource = chartDataSource;
}

void RadChartControl_Loaded(object sender, RoutedEventArgs e)
{
xRadChartView.HorizontalAxis = new Telerik.Windows.Controls.ChartView.CategoricalAxis();
xRadChartView.HorizontalAxis.LabelFormat = "MMM-yyyy";
}


Finally there is ChartScreen.cs where it tries to bind the data there:

partial void ChartScreen_Activated()
{
var chart = this.FindControl("ScreenContent");
chart.DisplayName = "";
chart.SetBinding(RadChartViewControl.ContentProperty, "Value", System.Windows.Data.BindingMode.TwoWay);
}


That last line in particular (chart.SetBinding()) causes this error to appear in the Output window when running and the control to not appear at all.
A first chance exception of type 'System.ArgumentOutOfRangeException' occurred in mscorlib.dll
System.Windows.Data Error: BindingExpression path error: 'Value' property not found on 'Microsoft.LightSwitch.Presentation.Framework.Internal.ErrorControl' 'Microsoft.LightSwitch.Presentation.Framework.Internal.ErrorControl' (HashCode=8281621). BindingExpression: Path='Value' DataItem='Microsoft.LightSwitch.Presentation.Framework.Internal.ErrorControl' (HashCode=8281621); target element is 'Microsoft.LightSwitch.Presentation.Framework.Internal.ErrorControl' (Name=''); target property is 'Content' (type 'System.Windows.UIElement')..


I was originally getting this error until I made some other changes to my XAML and C# but unfortunately I cannot remember exactly what I changed, however I'm pasting it here in case it is of any use in working out what I'm doing wrong:

System.Windows.Data Error: 'MS.Internal.Data.DynamicValueConverter' converter failed to convert value
'Microsoft.LightSwitch.Framework.Client.VisualCollection`1[LightSwitchApplication.BusinessData]'
(type 'Microsoft.LightSwitch.Framework.Client.VisualCollection`1[LightSwitchApplication.BusinessData]');
BindingExpression: Path='Value' DataItem='Microsoft.LightSwitch.Presentation.Implementation.ContentItemFromDefinition' (HashCode=35009555);
target element is 'LightSwitchApplication.RadChartViewControl' (Name='');
target property is 'Content' (type 'System.Windows.UIElement')..


I have tried researching these errors but I'm afraid I do not really understand them.

Any help with this would be greatly appreciated. Thanks in advance.

EDIT: Posted in the wrong forum, sorry, this is meant to be in the RadChartView forum. ><

11 Answers, 1 is accepted

Sort by
0
Yavor
Telerik team
answered on 16 Oct 2012, 10:46 AM
Hi Matt,

One piece of advice I can give you is first to create your application in a normal silverlight app. This will free you of the LightSwitch stuff and errors that bothers you. Next you can find a lot of demo code and explanations in our online help system here that will get you started.

If you have any particular question about RadChartView I will be happy to assist you!

Kind regards,
Yavor
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Adrian
Top achievements
Rank 1
answered on 16 Oct 2012, 01:51 PM
If I define data manually in the Silverlight application's XAML I can see the RadChartView work with this.  My issue is with binding data from LightSwitch to the Telerik RadChartView.
0
Yavor
Telerik team
answered on 17 Oct 2012, 08:30 AM
Hello,

As the code snippets can reveal some of your scenario, a sample project that reproduces the problem can help us a lot in finding out what is wrong. Without some code that we can read and run we can only guess.

Kind regards,
Yavor
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Ade
Top achievements
Rank 1
answered on 17 Oct 2012, 10:03 AM
I'll try to do this, however what I'm really interested in here is an example of how to correctly bind data from LightSwitch to the Telerik RadChartView control.  If you know anywhere I can view an example of this I would greatly appreciate it, thanks.

EDIT:  I took the Silverlight project I had as part of my Solution with the LightSwitch project and made it a separate stand alone Project Solution.

I stripped out all unnecessary code and the following is the complete code used to display a simple bar chart with the data being defined in C# code.  What I want to do though is access data in a LightSwitch project that is in the same solution as the Silverlight project with the Telerik control.

The code for the simple stand-alone project:

MainPage.xaml.cs:
<UserControl x:Class="ChartViewControl.MainPage"
        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
             xmlns:local="clr-namespace:LightSwitchApplication">
    <Grid x:Name="LayoutRoot">
        <local:RadChartViewControl />
    </Grid>
</UserControl>

RadChartViewControl.xaml:

<UserControl x:Class="LightSwitchApplication.RadChartViewControl"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
 
    <Grid x:Name="LayoutRoot" Background="White" ShowGridLines="True" >
         
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
         
        <telerik:RadCartesianChart x:Name="xRadChartView" Background="Blue" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Right" Height = "600" Width="1500"> <!-- telerik:StyleManager.Theme="Metro">-->
             
            <telerik:RadCartesianChart.VerticalAxis>
                <telerik:LinearAxis />
            </telerik:RadCartesianChart.VerticalAxis>
            <telerik:RadCartesianChart.HorizontalAxis>
                <telerik:CategoricalAxis />
            </telerik:RadCartesianChart.HorizontalAxis>
            <telerik:RadCartesianChart.Series>
            </telerik:RadCartesianChart.Series>
        </telerik:RadCartesianChart>       
    </Grid>
</UserControl>

RadChartViewControl.xaml.cs:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
 
namespace LightSwitchApplication
{
    public partial class RadChartViewControl : UserControl
    {
        public int dataValues;
        public RadChartViewControl()
        {
            dataValues = 1;
            InitializeComponent();
 
            xRadChartView.Series.Add(new Telerik.Windows.Controls.ChartView.BarSeries());
            xRadChartView.Series[0].ItemsSource = new double[] { 20, 30, 15, 40 };
             
        }
    }
}


0
Yavor
Telerik team
answered on 22 Oct 2012, 07:49 AM
Hello,

I should mention that the RadChartView can be bound to any IEnumerable as mentioned here. The sample code you shared compiles and runs without issues in a standalone silverlight application.

We have created also a set of hands-on labs that can help you kick start in LightSwitch. The full list is available here. We have created a lab for our older charting solution - the RadChart, but I am sure that still you will find it useful, because the RadChart binds to data very similarly to RadChartView.

Greetings,
Yavor
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Adrian
Top achievements
Rank 1
answered on 22 Oct 2012, 08:24 AM
I've seen your LightSwitch examples before.  It was useful for working out how to make RadChart work with LightSwitch, but I cannot see any similar resources for RadChartView on that page.

My issue is that I do not know how to get the RadChartView to correctly be set to read the LightSwitch data.  I understand that it can be bound to pretty much anything as the page you link says.  What I do not know how to do is bind it to the LightSwitch project specifically.  I don't know how to point the control to the data stored within LightSwitch.
0
Yavor
Telerik team
answered on 25 Oct 2012, 09:08 AM
Hello Adrian,

Indeed, we don't have hands-on lab for RadChartView. I have prepared for you the code needed for RadChartView to bind to the data in the hands-on lab for RadChart.

<telerik:RadCartesianChart>
    <telerik:RadCartesianChart.Behaviors>
        <telerik:ChartPanAndZoomBehavior PanMode="Horizontal" ZoomMode="Horizontal" />
    </telerik:RadCartesianChart.Behaviors>
    <telerik:RadCartesianChart.Grid>
        <telerik:CartesianChartGrid MajorXLineDashArray="5, 5" MajorYLineDashArray="5, 5" MajorLinesVisibility="XY">
            <telerik:CartesianChartGrid.MajorYLineStyle>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="Gray"/>
                </Style>
            </telerik:CartesianChartGrid.MajorYLineStyle>
            <telerik:CartesianChartGrid.MajorXLineStyle>
                <Style TargetType="Line">
                    <Setter Property="Stroke" Value="Gray"/>
                </Style>
            </telerik:CartesianChartGrid.MajorXLineStyle>
        </telerik:CartesianChartGrid>
    </telerik:RadCartesianChart.Grid>
    <telerik:RadCartesianChart.VerticalAxis>
        <telerik:LinearAxis/>
    </telerik:RadCartesianChart.VerticalAxis>
    <telerik:RadCartesianChart.HorizontalAxis>
        <telerik:DateTimeContinuousAxis MajorStepUnit="Week" MajorStep="1" LabelFormat="MMM-yyyy"/>
    </telerik:RadCartesianChart.HorizontalAxis>
    <telerik:LineSeries CategoryBinding="DTValue" ValueBinding="ItemValue" ItemsSource="{Binding Path=Screen.BusinessDatas}" />
</telerik:RadCartesianChart>

Notice the code in yellow. It will create 1 line series that will bind to the DTValue and ItemValue of the BusinessDatas table as shown in the hands-on lab for RadChart.

Hope this helps!

All the best,
Yavor
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Adrian
Top achievements
Rank 1
answered on 12 Nov 2012, 11:44 AM
Very sorry for my late reply.  Your posts have been useful, thanks.  In the end it was a combination of me writing some code that worked and not realising it worked due to the very large amount of random auto-generated data I was using to test it (it made it look like some sort of graphical glitch), and then writing code that didn't work at all.

I have another question that I hope you may be able to help me with though.  Is it possible to bind a RadChartView control directly to a RadGridControl, rather than table or screen data?

As in, directly use the data in the RadGrid control for the RadChartView.

Thanks in advance.

EDIT:  Also, is it possible to change the axis type of a chart dynamically?  I ask because I've been trying to make a chart switch between a LineSeries and a ScatterPointSeries.  The code does not error out, but it does not appear to do what I want it to either.  Initially the Horizontal axis is a Categorical axis.  I'm trying to change it to linear and then change the chart series to display the ScatterPoint chart.  If I have the Horizontal axis initially set to LinearAxis then the ScatterPoint chart will display, but the LineSeries one will not.

These are some of the things I have tried:

xRadChartView_Cartesian.Series[0].HorizontalAxis = new Telerik.Windows.Controls.ChartView.LinearAxis();

And:

xRadChartView_Cartesian.Series[0].ClearValue(Telerik.Windows.Controls.ChartView.CartesianSeries.HorizontalAxisProperty);
 
xRadChartView_Cartesian.Series[0].SetValue(Telerik.Windows.Controls.ChartView.CartesianSeries.HorizontalAxisProperty, new Telerik.Windows.Controls.ChartView.LinearAxis());

Sorry for all the questions. ><
0
Petar Kirov
Telerik team
answered on 15 Nov 2012, 11:55 AM
Hello Adrian,

Let me address your questions one by one.

1. Yes it possible bind a RadChartView to a RadGrid. This help topic shows just that - a chart visualizing the currently selected row(s). However the example uses a RadChart. To give you a jump-start I have modified the RadChart specific references with their ChartView variants. More specifically the things that need to be changed are:
<telerikChart:RadChart x:Name="radChart" Grid.Column="1" Margin="8"/>
to
<telerik:RadCartesianChart x:Name="chartView" Grid.Column="1" Margin="8">                  
    <telerik:RadCartesianChart.VerticalAxis>
        <telerik:LinearAxis />
    </telerik:RadCartesianChart.VerticalAxis>
        <telerik:RadCartesianChart.HorizontalAxis>
        <telerik:CategoricalAxis />
    </telerik:RadCartesianChart.HorizontalAxis>
</telerik:RadCartesianChart>
(in the first code snippet)

Replace these 2 method calls in the radGridView_SelectionChanged(...) method:
CreateSeriesMappings( selectedList );
SetChartItemsSource( selectedList );
with
CreateSeries(selectedList);
And finally the CreateSeries method (which replaces the 2 aforementioned ones): 
private void CreateSeries(Collection<PlotInfo> invoicesList)
{
    chartView.Series.Clear();
 
    //If there is only one row show bar series, else use line series
    CategoricalSeries series1 =
        invoicesList.Count < 2 ?
        (CategoricalSeries)new BarSeries() :
        (CategoricalSeries)new LineSeries();
 
    PropertyNameDataPointBinding valueBinding1 =
        new PropertyNameDataPointBinding("UnitsInStock");
    series1.ValueBinding = valueBinding1;
    series1.ItemsSource = invoicesList;
 
    CategoricalSeries series2 =
        invoicesList.Count < 2 ?
        (CategoricalSeries)new BarSeries() :
        (CategoricalSeries)new LineSeries();
 
    PropertyNameDataPointBinding valueBinding2 =
        new PropertyNameDataPointBinding("UnitPrice");
    series2.ValueBinding = valueBinding2;
    series2.ItemsSource = invoicesList;
 
    chartView.Series.Add(series1);
    chartView.Series.Add(series2);
}

2. I'm not quite sure why your code that switches the series (from ScatterPoint to Line) does not work. I have created a sample project demonstrating this on button click. I have attached it for your convenience.

If you have any further questions, I'll be glad to help.
 
Greetings,
Petar Kirov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

0
Adrian
Top achievements
Rank 1
answered on 20 Nov 2012, 05:10 PM
Thanks for your reply.  From your example with regard to the axis, I was able to notice that you were setting chart.HorizontalAxis rather than chart.Series[0].HorizontalAxis, which is what I was using.  Altering my code to set the value of the former fixed the axis issue for me.

With regard to using data in the gid view as a source for the chart, it looks like the way to do it is to populate a list with data from the grid view and then use that list as the data source?  Am I understanding that correctly?

EDIT:  For this particular part:
foreach ( Products product in radGridView.SelectedItems ) selectedList.Add( ( Products )item );


"The name 'item' does not exist in the current context."

Is the text 'item' meant to in fact be 'product' in your documentation?

EDIT2:

I have found all I actually need to do is something like this:
xRadChartView_Cartesian.Series[0].ItemsSource = radGridView.SelectedItems;

This single line appears to do exactly what I wanted, and it appears it only needs to be set once (I put the line in the MainPage() function after the call to InitializeComponent() ).

Are there any major disadvantages to doing it this way that you can see?  Or is this a good way to do this?

EDIT3:  I do seem to have run in to some sort of issue unfortunately.  If I change the chart series at run-time, and then try to select an item on the Grid to display on the chart, I get the message, "The provided node does exist in this collection."

I suspect the issue may lie in the code I use to create a new series:

xRadChartView_Cartesian.HorizontalAxis = new Telerik.Windows.Controls.ChartView.DateTimeContinuousAxis() { MajorStepUnit = Telerik.Charting.TimeInterval.Week, MajorStep = 1, LabelFormat = "MMM-yyyy" };
 
xRadChartView_Cartesian.VerticalAxis = new Telerik.Windows.Controls.ChartView.LinearAxis();
 
((Telerik.Windows.Controls.ChartView.CategoricalSeries)chartSeries).CategoryBinding = new Telerik.Windows.Controls.ChartView.PropertyNameDataPointBinding("myDate");
((Telerik.Windows.Controls.ChartView.CategoricalSeries)chartSeries).ValueBinding = new Telerik.Windows.Controls.ChartView.PropertyNameDataPointBinding("Id");
 
chartSeries.SetBinding(Telerik.Windows.Controls.ChartView.CategoricalSeries.ItemsSourceProperty, new System.Windows.Data.Binding("MyTable"));
//chartSeries.ItemsSource = radGridView.SelectedItems;
 
chartSeries.SetBinding(Telerik.Windows.Controls.ChartView.CategoricalSeries.ShowLabelsProperty, new System.Windows.Data.Binding("ShowLabels"));
chartSeries.SetBinding(Telerik.Windows.Controls.ChartView.CategoricalSeries.CombineModeProperty, new System.Windows.Data.Binding("SelectedCombineMode"));
 
xRadChartView_Cartesian.Series[0] = (Telerik.Windows.Controls.ChartView.CategoricalSeries)chartSeries;

In the code above I'm setting it to use MyTable as a source rather than the selected items in the grid view to try and find out what precisely is causing the error I'm receiving.

One other thing, after I experience that error, the grid view behaves a little strangely and will no longer allow me to select multiple items (in fact, the item I originally had selected when the error occured will remain selected and will not change).

EDIT4:  It appears I can assign my ItemsSource to radGridView.SelectedItems just fine, BUT I can only do it once.  Trying to do it twice and then trying selecting something on the grid view will break it.

EDIT5:  I have now fixed it, or rather worked around it.  I've ended up going with a list kind of like with the example above.  This is what I now have:
private void radGridView_SelectionChanged(object sender, Telerik.Windows.Controls.SelectionChangeEventArgs e)
{
    List<object> selectedItems = new List<object>();
    foreach(object selectedItem in radGridView.SelectedItems)
    {
        selectedItems.Add(selectedItem);
    }
    xRadChartView_Cartesian.Series[0].ItemsSource = selectedItems;
}

I would obviously prefer to not have to store the currently selected items in a separate list, and would rather have some way of using .SelectedItems, as that feels like it would be a better solution.  For now, however, this will suffice.

It's worth noting that when I change my Chart series, I set the items source as I used to, so that the chart will continue to use the originally selected grid rows as a data source, rather than displaying nothing:
xRadChartView_Cartesian.Series[0].ItemsSource = radGridView.SelectedItems;

EDIT6: The last line above is actually a bad idea if the chart's series is changed more than once without the currently selected rows being changed, as it will trigger the error.  I have resolved this by taking the code in radGridView_SelectionChanged and putting it in to a separate function that I call once I've set the chart series, and when the radGridView_SelectionChanged function is called.
0
Petar Kirov
Telerik team
answered on 22 Nov 2012, 01:24 PM
Hi Adrian,

1. Let me explain in more detail why the chart series have Vertical/HorizontalAxis properties just like the RadCartesianChart has.

The axes properties of the chart are the default axes used by all the chart series (defined in radCartesianChart.Series). However there are situations where you want a series to use different axes then the default (global) chart axes.These non-default axes are defined per series.  Here you can find an example of that.

2. Yes you understood correctly. This particular example shows that. However it is possible to use the grid view and the chart in different ways. For example by clicking on item on the chart, the grid view could be used to display a more detailed information about the data point. If you have a different scenario in mind, we can help you achieve it.

3. That's correct. The "product" variable should be used instead of "item".

4. 
xRadChartView_Cartesian.Series[0].ItemsSource = radGridView.SelectedItems;
this is actually a better way to do this (and less error-prone). Since the RadGridView.SelectedItems collection is ObservableCollection it will notify the chart if it changes, and the chart will refresh its series accordingly.
 
Regards,
Petar Kirov
the Telerik team

Explore the entire Telerik portfolio by downloading Telerik DevCraft Ultimate.

Tags
Chart
Asked by
Adrian
Top achievements
Rank 1
Answers by
Yavor
Telerik team
Adrian
Top achievements
Rank 1
Ade
Top achievements
Rank 1
Petar Kirov
Telerik team
Share this question
or