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

Bind SamplingThreshold

2 Answers 133 Views
ChartView
This is a migrated thread and some comments may be shown as answers.
Johannes
Top achievements
Rank 1
Johannes asked on 08 Mar 2021, 12:50 PM

Hi, 

I have a WPF application in which we have made a trend component which should be able to a display a large amount of log values.

We have not been using Sampling until now. So the SamplingThreshold has always been 200 (as I understand is the default value). This makes some of of the trends misleading, since some of the lowest/highest values wont be displayed because they are clustered with other datapoints.

What we would like to to, is to set the SamplingThreshold depending on how many log values we have, and depending on what kind of screen resolution the user has (some of out customers computers are out in a lab environment and has something like a 1280 x 800 res).

My problem now however, is that I'm not able to bind the SamplingThreshold property. 


I have a generic.xaml which datacontext is a ChartViewViewModel. 

Generic:

<telerik:RadCartesianChart x:Name="PART_Chart" Zoom="{Binding ChartZoom, Mode=TwoWay}" PanOffset="{Binding ChartPanOffset, Mode=TwoWay}">
    <telerik:RadCartesianChart.TrackBallInfoStyle>
        <Style TargetType="telerik:TrackBallInfoControl">
            <Setter Property="Header" Value="{Binding DataContext.TrackBallHeader, RelativeSource={RelativeSource AncestorType=local:ChartView}}" />
        </Style>
    </telerik:RadCartesianChart.TrackBallInfoStyle>
    <telerik:RadCartesianChart.Resources>
        <DataTemplate x:Key="trackBallInfoTemplate">
            <StackPanel>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding DataPoint.Presenter.DataContext.Title}"/>
                    <TextBlock Text=": " />
                    <TextBlock Text="{Binding DataPoint.Value, Converter={StaticResource TrimToTwoDecimalsConverter}}" />
                </StackPanel>
            </StackPanel>
        </DataTemplate>
        <DataTemplate x:Key="PointCustomTemplate">
            <Ellipse Height="3" Width="3" Fill="{Binding DataContext.Color, RelativeSource={RelativeSource AncestorType=telerik:PointSeries}}"/>
        </DataTemplate>
        <Style TargetType="telerik:LinearAxis">
            <Setter Property="LabelTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" Foreground="{telerik:VisualStudio2013Resource ResourceKey=MarkerBrush}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="telerik:DateTimeContinuousAxis">
            <Setter Property="LabelTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <TextBlock Text="{Binding}" Foreground="{telerik:VisualStudio2013Resource ResourceKey=MarkerBrush}"/>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style TargetType="telerik:LineSeries">
            <Setter Property="StrokeThickness" Value="1" />
            <Setter Property="Stroke" Value="{Binding Color}" />
            <Setter Property="TrackBallInfoTemplate" Value="{StaticResource trackBallInfoTemplate}" />
            <Setter Property="VerticalAxis" Value="{Binding Axis}" />
            <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="true">
                    <Setter Property="Opacity" Value="1" />
                </DataTrigger>
                <DataTrigger Binding="{Binding IsSelected}" Value="false">
                    <Setter Property="Opacity" Value="0.2" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="telerik:SplineSeries">
            <Setter Property="StrokeThickness" Value="1" />
            <Setter Property="Stroke" Value="{Binding Color}" />
            <Setter Property="TrackBallInfoTemplate" Value="{StaticResource trackBallInfoTemplate}" />
            <Setter Property="VerticalAxis" Value="{Binding Axis}" />
            <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="true">
                    <Setter Property="Opacity" Value="1" />
                </DataTrigger>
                <DataTrigger Binding="{Binding IsSelected}" Value="false">
                    <Setter Property="Opacity" Value="0.2" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="telerik:StepLineSeries">
            <Setter Property="StrokeThickness" Value="1" />
            <Setter Property="Stroke" Value="{Binding Color}" />
            <Setter Property="TrackBallInfoTemplate" Value="{StaticResource trackBallInfoTemplate}" />
            <Setter Property="VerticalAxis" Value="{Binding Axis}" />
            <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="true">
                    <Setter Property="Opacity" Value="1" />
                </DataTrigger>
                <DataTrigger Binding="{Binding IsSelected}" Value="false">
                    <Setter Property="Opacity" Value="0.2" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
        <Style TargetType="telerik:PointSeries">
            <Setter Property="PointTemplate" Value="{StaticResource PointCustomTemplate}"></Setter>
            <Setter Property="TrackBallInfoTemplate" Value="{StaticResource trackBallInfoTemplate}" />
            <Setter Property="VerticalAxis" Value="{Binding Axis}" />
            <Setter Property="Visibility" Value="{Binding IsVisible, Converter={StaticResource VisibilityConverter}}"/>
            <Style.Triggers>
                <DataTrigger Binding="{Binding IsSelected}" Value="true">
                    <Setter Property="Opacity" Value="1" />
                </DataTrigger>
                <DataTrigger Binding="{Binding IsSelected}" Value="false">
                    <Setter Property="Opacity" Value="0.2" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </telerik:RadCartesianChart.Resources>
    <telerik:RadCartesianChart.TrackBallLineStyle>
        <Style TargetType="Polyline">
            <Setter Property="Stroke" Value="Black" />
            <Setter Property="Opacity" Value="{Binding IsTrackballVisible, Converter={StaticResource BoolToOpacityConverter}}"/>
        </Style>
    </telerik:RadCartesianChart.TrackBallLineStyle>
    <telerik:RadCartesianChart.Grid>
        <telerik:CartesianChartGrid MajorLinesVisibility="XY" />
    </telerik:RadCartesianChart.Grid>
    <telerik:RadCartesianChart.Behaviors>
        <telerik:ChartPanAndZoomBehavior x:Name="PART_PanAndZoomBehavior" ZoomMode="Both" PanMode="Both" />
        <telerik:ChartTrackBallBehavior x:Name="PART_ChartTrackBallBehavior" ShowIntersectionPoints="{Binding IsTrackballVisible}" ShowTrackInfo="{Binding IsTrackballVisible}"  />
    </telerik:RadCartesianChart.Behaviors>
    <telerik:RadCartesianChart.HorizontalAxis>
        <telerik:DateTimeContinuousAxis MajorStepUnit="{Binding MajorStepUnit}" MajorStep="{Binding MajorStep}" LabelFormat="{Binding HorizontalAxisLabelFormat}" LabelFitMode="MultiLine" />
    </telerik:RadCartesianChart.HorizontalAxis>
    <telerik:RadCartesianChart.VerticalAxis>
        <telerik:LinearAxis />
    </telerik:RadCartesianChart.VerticalAxis>
    <telerik:RadCartesianChart.SeriesProvider>
        <telerik:ChartSeriesProvider Source="{Binding Series}">
            <telerik:CategoricalSeriesDescriptor CategoryPath="LoggingTime"
            ValuePath="Value"
            ItemsSourcePath="LogValues"
            TypePath="SeriesType"
            TypeConverter="{StaticResource SeriesTypeConverter}" >
                <telerik:CategoricalSeriesDescriptor.ChartDataSourceStyle>
                    <Style TargetType="telerik:ChartDataSource" >
                        <Setter Property="SamplingThreshold" Value="20"/>
                    </Style>
                </telerik:CategoricalSeriesDescriptor.ChartDataSourceStyle>
            </telerik:CategoricalSeriesDescriptor>
        </telerik:ChartSeriesProvider>
    </telerik:RadCartesianChart.SeriesProvider>
</telerik:RadCartesianChart>

 

The code above works as intended, setting the value to SamplingThreshold 20.

Now I want to bind the SamplingThreshold to the ViewModel like below. ChartView is what works as the code behind where the DataContext is set to the ChartViewViewModel.

<telerik:RadCartesianChart.SeriesProvider>
    <telerik:ChartSeriesProvider Source="{Binding Series}">
        <telerik:CategoricalSeriesDescriptor CategoryPath="LoggingTime"
        ValuePath="Value" 
        ItemsSourcePath="LogValues"
        TypePath="SeriesType"
        TypeConverter="{StaticResource SeriesTypeConverter}" >
            <telerik:CategoricalSeriesDescriptor.ChartDataSourceStyle>
                <Style TargetType="telerik:ChartDataSource" >
                    <Setter Property="SamplingThreshold" Value="{Binding DataContext.SamplingThresholdValue, RelativeSource={RelativeSource AncestorType=local:ChartView}}"/>
                </Style>
            </telerik:CategoricalSeriesDescriptor.ChartDataSourceStyle>
        </telerik:CategoricalSeriesDescriptor>
    </telerik:ChartSeriesProvider>
</telerik:RadCartesianChart.SeriesProvider>
public ChartView()
{
    this.DefaultStyleKey = typeof(ChartView);
    var container = ChartViewContainerFactory.CretateContainer(DesignerProperties.GetIsInDesignMode(this));
    viewModel = container.Resolve<IChartViewViewModel>();
    DataContext = viewModel;
}

 

And in the ViewModel the SamplingThresholdValue is set to 20 in the constructor. 
But if I try to get the SamplingThreshold from the CategoricalSeriesDescriptor Style in code behind after the chart is loaded, the value for SamplingThreshold is always unset when it's binded.
I understand that the SamplingThreshold cant be changed when the trend is loaded. But if the value is set in the ViewModel before its loaded, it should be able to find the correct value.

I have also tried the approach where you create a ChartDatasource:

<telerik:ChartDataSource x:Name="chartDataSource1" ItemsSource="{Binding Series}" SamplingThreshold="20"/>

 

Then bind the Seriesprovider to the DataSource:

<telerik:ChartSeriesProvider Source="{Binding ElementName=chartDataSource1}">

 

But when I try this the SamplingThreshold value of 20 set directly in the ChartDataSource won't even be used. It still is unset and has the default value of 200.
All I want to do is to be able to set the SamplingThreshold dynamicly before the chart itself is loaded.
Do you have any idea what I might do wrong here?

Kind Regards, Johannes

2 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 11 Mar 2021, 08:24 AM

Hello Johannes,

The binding in to the SamplingThreshold in the ChartDataSourceStyle doesn't work because it uses RelativeSource binding. This Style is applied to an element which is not part of the visual tree and therefore the RelativeSource binding which is trying to traverse the visual tree in order to find its source doesn't work.

To achieve your requirement, you can move the SamplingThresholdValue property from the view model of the UserControl that holds the chart (the ChartView UserControl in your case), to the view model of the series. In your setup this should be to model that holds the LogValues property. In this case, each series will hold information about the threshold and you can directly data bind the property to the SamplingThreshold of the data source.

<telerik:CategoricalSeriesDescriptor.ChartDataSourceStyle>
	<Style TargetType="telerik:ChartDataSource" >
		<Setter Property="SamplingThreshold" Value="{Binding SamplingThresholdValue}"/>
	</Style>
</telerik:CategoricalSeriesDescriptor.ChartDataSourceStyle>

I've attached a small sample project showing this approach. I hope it helps.

Regards,
Martin Ivanov
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

0
Johannes
Top achievements
Rank 1
answered on 15 Mar 2021, 03:40 PM

Hi and thank you for the reply.

My bad, should have realized that!

This worked really great, as expected!

Once again, thanks for the answer and for the great support!

Kind Regards, Johannes

Tags
ChartView
Asked by
Johannes
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Johannes
Top achievements
Rank 1
Share this question
or