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

RadCartesianChart Series Click to MVVM Command with parameter

4 Answers 258 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Doug
Top achievements
Rank 1
Doug asked on 18 Sep 2014, 10:27 PM
I have a WPF MVVM application with a screen that has a Telerik Chart(RadCartesianChart) on it. The chart can contain more than one series in it. I need to have at least one of the series be clickable and based on the click execute a command in the View Model sending it the point (or at least the X axis) on the line that was clicked.

I believe I need to set the Command and CommandParameter in the codebehind of the page, but not sure how.

In the end I need the click command of the series to execute the PlotChartItemClickedCommand Sending it a parameter containing the X axis data which in my case is the Category.

Below is my code XAML, CodeBehind and VM. Any help would be greatly appreciated

XAML:
<telerik:RadCartesianChart x:Name="RccLineChart"
                              Width="354"
                              Height="300" >
    <telerik:RadCartesianChart.Resources>
        <DataTemplate x:Key="PointTemplate">
            <Ellipse Height="6" Width="6" Fill="red" />
        </DataTemplate>
    </telerik:RadCartesianChart.Resources>
    <telerik:RadCartesianChart.HorizontalAxis>
        <telerik:CategoricalAxis ShowLabels="False" Title="Count" x:Name="LineHorzAxis"/>
    </telerik:RadCartesianChart.HorizontalAxis>
    <telerik:RadCartesianChart.VerticalAxis>
        <telerik:LinearAxis Maximum="{Binding Path=MaxYValue}" Minimum="{Binding Path=MinYValue}" Title="C"/>
    </telerik:RadCartesianChart.VerticalAxis>
    <telerik:RadCartesianChart.Series>
    </telerik:RadCartesianChart.Series>
</telerik:RadCartesianChart>

CodeBehind:
public CodeBehindConstructor()
{
    InitializeComponent();
    InitialIzeLineChart();
}
 
private void InitialIzeLineChart()
{
    foreach (CartesianSeries series in GetSeries())
    {
        RccLineChart.Series.Add(series);
    }
}
 
private IEnumerable<CartesianSeries> GetSeries()
{
    string Line1ItemsSourcePath = string.Empty;
    string PointsItemsSourcePath = string.Empty;
    string referenceLineItemsSourcePath = string.Empty;
    string Line1Resource = string.Empty;
    string PointsResource = string.Empty;
    Line1Resource = "Line1Template";
    PointsResource = "PointTemplate";
 
    CategoricalSeries Line1Series = null;
    CategoricalSeries PointSeries = null;
    CategoricalSeries referenceLineSeries = null;
    Line1Series = new LineSeries();
    PointSeries = new PointSeries();
    referenceLineSeries = new LineSeries();
 
    Line1ItemsSourcePath = "Line1Data";
    PointsItemsSourcePath = "PointsData";
    referenceLineItemsSourcePath = "ReferenceLine";
 
    List<CartesianSeries> generatedSeries = new List<CartesianSeries>();
    Line1Series.CategoryBinding = new PropertyNameDataPointBinding("Category");//this is what we want to send to the VM on the click of the chart
    Line1Series.ValueBinding = new PropertyNameDataPointBinding("Data");
    Line1Series.ShowLabels = false;
    Line1Series.CombineMode = ChartSeriesCombineMode.None;
    Line1Series.IsHitTestVisible = true;
    Line1Series.SetBinding(CategoricalSeries.ItemsSourceProperty, new Binding(Line1ItemsSourcePath));
    Line1Series.PointTemplate = this.Resources[Line1Resource] as DataTemplate;
 
    //CommandBinding lineCB = new CommandBinding();
    //ICommand lineCommand = new ICommand();
     
    generatedSeries.Add(Line1Series);
 
    PointSeries.CategoryBinding = new PropertyNameDataPointBinding("Category");
    PointSeries.ValueBinding = new PropertyNameDataPointBinding("Data");
    PointSeries.ShowLabels = true;
    PointSeries.CombineMode = ChartSeriesCombineMode.None;
    PointSeries.SetBinding(CategoricalSeries.ItemsSourceProperty, new Binding(PointsItemsSourcePath));
    PointSeries.PointTemplate = this.Resources[PointsResource] as DataTemplate;
 
    generatedSeries.Add(PointSeries);
 
    referenceLineSeries.CategoryBinding = new PropertyNameDataPointBinding("Category");
    referenceLineSeries.ValueBinding = new PropertyNameDataPointBinding("Data");
    referenceLineSeries.ShowLabels = false;
    referenceLineSeries.CombineMode = ChartSeriesCombineMode.None;
    referenceLineSeries.IsHitTestVisible = true;
    referenceLineSeries.SetBinding(CategoricalSeries.ItemsSourceProperty, new Binding(referenceLineItemsSourcePath));
    referenceLineSeries.PointTemplate = this.Resources[Line1Resource] as DataTemplate;
 
    generatedSeries.Add(referenceLineSeries);
 
    return generatedSeries;
}

ViewModel:
public RelayCommand<ChartItemClickEventArgs> PlotChartItemClickedCommand
{
    get { return new RelayCommand<ChartItemClickEventArgs>(PlotChartItemClickedExecute, AlwaysTrueCanExecute); }
}
 
private void ProfilePlotChartItemClickedExecute(object e)
{
    int xPointClicked = ?????
 
}



4 Answers, 1 is accepted

Sort by
0
kirk
Top achievements
Rank 1
answered on 22 Sep 2014, 12:53 PM
I'm having the same problem, are there any solutions yet?
0
Petar Marchev
Telerik team
answered on 23 Sep 2014, 08:39 AM
Hello Doug,

Depending on the exact behavior you want to get, you can use different approaches.

From what I understand you have logic that needs to be executed when a Category of the axis is clicked. So perhaps this logic needs to be executed when the reader clicks an axis label and not a data point visual. So do consider executing this code when an axis label gets clicked.

Whether you decide to make the axis label clickable or the data point clickable - you can use a style and an attached behavior to get this. Say that you are using BarSeries - you need to use a DefaultVisualStyle that has a setter for a custom attached property. In the attached property you can attach handlers for the mouse up and down events. In the handlers you can find the DataContext of the visual element (it is a DataPoint) and from the data point you can get the data-item and the parenting series and chart, so you can get the view model and call the method you need. I hope this helps.

Regards,
Petar Marchev
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
0
Doug
Top achievements
Rank 1
answered on 23 Sep 2014, 06:02 PM
Petar,

I do need the click point of the line. In addition, I may have more than one line in the chart, so I will need to execute a different command depending on which line in the chart is clicked. That is the reason why I was thinking that the code I am needing would need to go in the codebehind as the LineSeries is being defined. Am I thinking correctly? In either case do you have a code sample I could see?

Thanks,

Doug
0
Petar Marchev
Telerik team
answered on 25 Sep 2014, 07:24 AM
Hi Doug,

If the line series has a point template - you could make the points clickable. Do you have points or is it just a line?

If you have points - you can use the approach described earlier, a style with a setter for an attached property (you can define the style in code).

If you do not have points - there is nothing to be clicked and you can simply attach a handler to the MouseDown event of the line series and execute the logic per series, not per data point (because there are no data point visuals).

If you need further assistance please send us some snapshots of the current output and explanations where you would like to click the series and what information do you need in the click handler - the data point or the series.

Regards,
Petar Marchev
Telerik
 
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
 
Tags
General Discussions
Asked by
Doug
Top achievements
Rank 1
Answers by
kirk
Top achievements
Rank 1
Petar Marchev
Telerik team
Doug
Top achievements
Rank 1
Share this question
or