Telerik Forums
UI for WPF Forum
1 answer
30 views

Hi,

I am trying to implement a RadCartesianChart3D, but am missing the SeriesProvider Property to be able to bind view models and dynamically create series.. The Telerik package reference is Telerik.UI.for.WPF.NetCore.Xaml (2021.2.615). Was this property not implemented at that time? If so, how do I overcome this?

Example of what Id like to implement:


<telerik:RadCartesianChart3D x:Name="chart">        
        <!--...-->
        <telerik:RadCartesianChart3D.SeriesProvider>
            <telerik:ChartSeriesProvider3D Source="{Binding SeriesData}">
                <telerik:XyzSeries3DDescriptor XValuePath="Year" YValuePath="Industry" ZValuePath="Revenue" ItemsSourcePath="Data">
                    <telerik:XyzSeries3DDescriptor.Style>
                        <Style TargetType="telerik:BarSeries3D" BasedOn="{StaticResource BarSeries3DStyle}" />
                    </telerik:XyzSeries3DDescriptor.Style>
                </telerik:XyzSeries3DDescriptor>
            </telerik:ChartSeriesProvider3D>
        </telerik:RadCartesianChart3D.SeriesProvider>
    </telerik:RadCartesianChart3D>

 

Edit: This feature seems to have been implemented in WPF R2 2022 and I do not have the option to upgrade the Telerik package. Is there a workaround for this?

 

Thanks in advance,

Chris

Chris
Top achievements
Rank 1
Iron
 updated question on 17 Jul 2023
1 answer
39 views
A while back, I was looking to implement a pan feature for my ChartView3D, Telerik directed me to this feature request.  It says you aren't implementing the feature but it does contain sample code to allow me to manually pan the view myself.  I have attached a copy of the sample to this post.

It all mostly works. but I've noticed that the horizontal panning is not true horizontal panning.  If you hit the left or right arrow button just a few times sure it looks that way.  But as you keep moving it left or right and the chart approaches the edge of the windows, it begins to move downward also, as if it were the edge of a large, rotating wheel.

What I need is true XY panning. So that if I hit the left button the scene moves left ONLY, not up or down, no matter how far I move it.

Is there some way to adjust the code in the sample to achieve this?  I'll admit that this sort of math is not at all my strong suit.

Martin Ivanov
Telerik team
 answered on 23 Aug 2022
1 answer
66 views

In my WPF application using c#, I need a count of DataPoints of a series of particular RadCartesianChart using c# (code behind). How can I achieve it?

I have used the following line:

int a = ((Telerik.Windows.Controls.ChartView.CategoricalSeries)new System.Collections.Generic.Mscorlib_CollectionDebugView<CartesianSeries>(((Telerik.Windows.Controls.RadCartesianChart)my SelectedChart).Series).Items[0]).DataPoints.Count;

But it gives the following error:

Error	CS0122	'Mscorlib_CollectionDebugView<T>' is inaccessible due to its protection level

Dinesh
Top achievements
Rank 1
Iron
 answered on 30 Nov 2021
1 answer
44 views

Hi,

I'm working with ChartView3D and Telerik UI for a project. I am using the XAML tags for the graph. I can build and compile the graph. During runtime, when I change the view angles of the graph and rotate, zoom it frequently the axes gets updated with the graph by a small delay. Sometime the axes get stuck. I have attached the screenshot for reference.

The code below is used to create the 3D graph,

 

<telerik:RadCartesianChart3D x:Name="E3DChart" Visibility="Collapsed">
                                            <telerik:RadCartesianChart3D.XAxis>
                                                <telerik:CategoricalAxis3D Title="Position">
                                                    <telerik:CategoricalAxis3D.TitleTemplate>
                                                        <DataTemplate>
                                                            <TextBlock Text="{Binding}" Foreground="White" Padding="3" FontSize="20" />
                                                        </DataTemplate>
                                                    </telerik:CategoricalAxis3D.TitleTemplate>
                                                    <telerik:CategoricalAxis3D.LabelStyle>
                                                        <Style TargetType="TextBlock">
                                                            <Setter Property="Foreground" Value="#FFD4D4D4" />
                                                        </Style>
                                                    </telerik:CategoricalAxis3D.LabelStyle>
                                                </telerik:CategoricalAxis3D>
                                            </telerik:RadCartesianChart3D.XAxis>
                                            <telerik:RadCartesianChart3D.YAxis>
                                                <telerik:CategoricalAxis3D Title="Tube">
                                                    <telerik:CategoricalAxis3D.TitleTemplate>
                                                        <DataTemplate>
                                                            <TextBlock Text="{Binding}" Foreground="White" Padding="3" FontSize="20"/>
                                                        </DataTemplate>
                                                    </telerik:CategoricalAxis3D.TitleTemplate>
                                                    <telerik:CategoricalAxis3D.LabelStyle>
                                                        <Style TargetType="TextBlock">
                                                            <Setter Property="Foreground" Value="#FFD4D4D4" />
                                                        </Style>
                                                    </telerik:CategoricalAxis3D.LabelStyle>
                                                </telerik:CategoricalAxis3D>
                                            </telerik:RadCartesianChart3D.YAxis>
                                            <telerik:RadCartesianChart3D.ZAxis>
                                                <telerik:LinearAxis3D Title="Count">
                                                    <telerik:LinearAxis3D.TitleTemplate>
                                                        <DataTemplate>
                                                            <TextBlock Text="{Binding}" Foreground="White" Padding="3" FontSize="20"/>
                                                        </DataTemplate>
                                                    </telerik:LinearAxis3D.TitleTemplate>
                                                    <telerik:LinearAxis3D.LabelStyle>
                                                        <Style TargetType="TextBlock">
                                                            <Setter Property="Foreground" Value="#FFD4D4D4" />
                                                        </Style>
                                                    </telerik:LinearAxis3D.LabelStyle>
                                                </telerik:LinearAxis3D>
                                            </telerik:RadCartesianChart3D.ZAxis>
                                            <telerik:RadCartesianChart3D.Behaviors>
                                                <telerik:Chart3DCameraBehavior Distance="2500"
                                               FirstAngle="225"
                                               SecondAngle="85"/>
                                                <telerik:Chart3DTooltipBehavior ShowDuration="10000"/>
                                            </telerik:RadCartesianChart3D.Behaviors>
                                            <telerik:RadCartesianChart3D.Grid>
                                                <telerik:CartesianChart3DGrid GridLineThickness="3"/>
                                            </telerik:RadCartesianChart3D.Grid>
                                        </telerik:RadCartesianChart3D>

Martin Ivanov
Telerik team
 answered on 17 Dec 2020
8 answers
76 views

I was surprised to find that assigning a foreground color to a LinearAxis3D does not automatically make the axis line, title or labels take on that color.  That was the behavior I would expect.  But it does not. 

Ok, no problem, I figured I would get around it by defining a style resource for LinearAxis3D that individually binds the color to its logical children to the parent LinearAxis3D.    So I did that and it works just fine for the text title and labels.  But it does not work for the axis line

Are a LinearAxis3D object's axis lines not logical children of that axis?  And if not, is there any way to generically find the LinearAxis3D object for (binding purposes) from within the style?

To illustrate, here's a the Z axis on my chart.  (I've nested the style here for simplicity but in my app it needs to be a separate static resource for re-use.)

<tk:RadCartesianChart3D.ZAxis>
    <tk:LinearAxis3D
        x:Name="ZAxis"
        LabelFormat="0.00"
        SmartLabelsMode="SmartStep"
        Minimum="{Binding ZAxisMin}"
        Maximum="{Binding ZAxisMax}"
        Foreground="Yellow"
        >
        <tk:LinearAxis3D.Style>
            <Style TargetType="{x:Type tk:LinearAxis3D}">
                <Setter Property="LabelStyle">
                    <Setter.Value>
                        <Style TargetType="{x:Type TextBlock}">
                            <Setter Property="Foreground" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:LinearAxis3D}}, Path=Foreground}"/>
                        </Style>
                    </Setter.Value>
                </Setter>
                <Setter Property="LineStyle">
                    <Setter.Value>
                        <Style TargetType="{x:Type Path}">
                            <Setter Property="Stroke" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type tk:LinearAxis3D}}, Path=Foreground}"/>
                            <Setter Property="StrokeThickness" Value="2"/>
                        </Style>
                    </Setter.Value>
                </Setter>
            </Style>
        </tk:LinearAxis3D.Style>
    </tk:LinearAxis3D>
</tk:RadCartesianChart3D.ZAxis>

Since I assigned "Yellow" to the LinearAxis3D.Foreground, my label text blocks manage to find the parent LinearAxis3D and bind to this property to show the correct label color.  But the axis lines never show up.  That binding never finds the LinearAxis3D and so never gets any color. 

If I change this setter to just use a hard coded color then it setter works fine.  But obviously, that's not going to work for me.

Surprisingly, when I tried -- just as a test -- to bind by ElementName to "ZAxis", that didn't work either.  It's not an option for me if I want this Style to be a StaticResource but still I was surprised it did not work.

So do I have any other option here?  Is the Path object used to draw the axis line a logical child of the LinearAxis3D?  And if not, is there any way to achieve what I want?  Or do I need to just  individually nest the line style for each axis?


 

Martin Ivanov
Telerik team
 answered on 26 Nov 2019
1 answer
54 views
I want to set the line style in my chart but I don't know what type to target in the style.  The documentation does not not say.  Line?  Path?  Something else?
Joe
Top achievements
Rank 2
Iron
Iron
Veteran
 answered on 14 Nov 2019
1 answer
69 views

I've got a RadCartesianChart3D chart that looks and works great.   (You fine folks have helped me out with it quite a bit on some recent threads here).  I use the Chart3DCameraBehavior upon it to zoom and rotate.  Although that is great, I now have a customer request for my user to be able to have their mouse moves (or touch moves) pan the chart instead of rotating it.  How may I do this?

I was thinking that I could make this into some sort of mode, but the Chart3DCameraBehavior does not seem to have any facility for panning at all that I can.  Is there another behavior that might do this for me? 

I would not be averse to writing my own code to adjust some sort of TranslateTransform when in some specific "mode", but the problem is that if I were to do that to the whole chart, the axes would pan with the surface and that wouldn't help me at all.

 

-Joe

Martin Ivanov
Telerik team
 answered on 08 Oct 2019
9 answers
314 views

When I create a PointSeries chart, the point's color is determined at moment the chart is showing. But I want the point's color changed with the datasource's some content after the chart was  shown.

So I make a new PlotInfo class shown as below, and  I set DefaultVisualMaterialSelector bind to PlotInfo's ColorFlag, with a Converter.
Finally, the project doesn't work, the point's color didn't change when I modify the ColorFlag.
So does ChartView3D support this kind of abbility? And how can I get what I want?

public class PlotInfo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public double XValue { get; set; }
    public double YValue { get; set; }
    public string ZValue { get; set; }
    private string m_sColorFlag;
    public string ColorFlag
    {
        get { return m_sColorFlag;}
        set
        {
            m_sColorFlag = value;
            if(this.PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, new PropertyChangedEventArgs("ColorFlag"));
            }
        }
    }
}

MainWindow.xaml

<Window x:Class="VariableMaterial.MainWindow"
        xmlns:local="clr-namespace:VariableMaterial"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <local:ColorConvert x:Key="myColorConvert" />
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition />
        </Grid.RowDefinitions>
        <ToolBar Grid.Row="0" Height="auto">
            <Button Content="SetColorFlag=A" Click="ButtonA_Click" Margin="10,0,0,0"/>
            <Button Content="SetColorFlag=B" Click="ButtonB_Click" Margin="10,0,0,0"/>
        </ToolBar>       
        <telerik:RadCartesianChart3D Grid.Row="1">
            <telerik:RadCartesianChart3D.XAxis>
                <telerik:LinearAxis3D />
            </telerik:RadCartesianChart3D.XAxis>
            <telerik:RadCartesianChart3D.YAxis>
                <telerik:LinearAxis3D />
            </telerik:RadCartesianChart3D.YAxis>
            <telerik:RadCartesianChart3D.ZAxis>
                <telerik:CategoricalAxis3D />
            </telerik:RadCartesianChart3D.ZAxis>
            <telerik:RadCartesianChart3D.Series>
                <telerik:PointSeries3D PointSize="100"
                                       DefaultVisualMaterialSelector="{Binding ColorFlag, Converter={StaticResource myColorConvert}}"
                                       XValueBinding="XValue"
                                       YValueBinding="YValue"
                                       ZValueBinding="ZValue"
                                       ItemsSource="{Binding}"/>
            </telerik:RadCartesianChart3D.Series>
            <telerik:RadCartesianChart3D.Grid>
                <telerik:CartesianChart3DGrid />
            </telerik:RadCartesianChart3D.Grid>
            <telerik:RadCartesianChart3D.Behaviors>
                <telerik:Chart3DCameraBehavior />
            </telerik:RadCartesianChart3D.Behaviors>
        </telerik:RadCartesianChart3D>
    </Grid>
</Window>

 

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Media.Media3D;
 
 
namespace VariableMaterial
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<PlotInfo> source = new ObservableCollection<PlotInfo>();
        public MainWindow()
        {
            InitializeComponent();
 
            PlotInfo info1 = new PlotInfo()
            {
                XValue = 1,
                YValue = 1,
                ZValue = "A",
                ColorFlag = "A",
            };
 
            PlotInfo info2 = new PlotInfo()
            {
                XValue = 2,
                YValue = 2,
                ZValue = "B",
                ColorFlag = "B",
            };
 
            source.Add(info1);
            source.Add(info2);
 
            this.DataContext = source;
        }
 
        private void ButtonA_Click(object sender, RoutedEventArgs e)
        {
            source[0].ColorFlag = "B";
        }
 
        private void ButtonB_Click(object sender, RoutedEventArgs e)
        {
            source[1].ColorFlag = "A";
        }
    }
 
    public class ColorConvert : IValueConverter
    {
        private Dictionary<Color, Material> colorToMaterialDict = new Dictionary<Color, Material>();
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            string colorFlag = (string)value;
            Color color;
 
            if (colorFlag == "A")
            {
                color = (Color)ColorConverter.ConvertFromString("#007ACC");
            }
            else
            {
                color = (Color)ColorConverter.ConvertFromString("#68217A");
            }
 
            Material material;
            if (!this.colorToMaterialDict.TryGetValue(color, out material))
            {
                material = new DiffuseMaterial(new SolidColorBrush(color));
                colorToMaterialDict[color] = material;
            }
                 
            return material;
        }
 
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

 

Star
Top achievements
Rank 1
 answered on 23 Jul 2019
8 answers
92 views

I'm using RadCartesianChart3d to show a surface.  I've written some background code to intelligently choose the Maximum and Minimum values for my Z axis to be on nice even numbers which exceed the boundaries of the data.  I then bind the LinearAxis3D for Z to these values.

The chart honors my Minimum value.  Unfortunately, it sometimes ignores my Maximum value and chooses its own.  

To be sure I wasn't wasting your time, before I posted this report, I tried to reproduce the problem using the sample application that Martin Ivanov attached in a reply in this other forum thread from just 2 weeks ago.  It's the attachment "WpfApp17"

https://www.telerik.com/forums/dynamic-colorizer-for-surfaceseries3d

What I did was change the Z axis  in the sample to use some arbitrary Minimum and Maximum values:

<telerik:RadCartesianChart3D.ZAxis>
    <telerik:LinearAxis3D Minimum="-800"  Maximum="900"/>
</telerik:RadCartesianChart3D.ZAxis>

At first, I could not reproduce the problem.  But then I tried updating the sample to use the very latest version of UI for WPF that I have on my machine.  It is R2 2019 SP1 which was literally released today, June 19, 2019.   

Once I changed the assembly references to use the this new version of UI for WPF, the problem did occur.  When I run the sample app with the changes above, my maximum axis value only shows 700, not 900.  

(I realize the data does not go that high but I still want the chart to show the maximum I give to it.)

That's not all.  It gets even stranger.  If you then change the Maximum value from 900 to 1200, suddenly, it *is* honored.


The forum software does not seem to want to let me attach my modified version of the sample to this thread, even though it's a ZIP file and it's only 350k so you'll need to make the changes on your own version to reproduce this.




Martin Ivanov
Telerik team
 answered on 10 Jul 2019
6 answers
178 views

I've got a RadCartesianChart3D that uses a SurfaceSeries3D to show a colorized surface I've attached a sample image to show how it looks now ("Current_Surface.png")

  1. I colorize this surface using  a SurfaceSeries3dValueGradientColorizer.
  2. I build the colorizer in code-behind one single time.  It consists of 64 hard-coded color values that I use to colorize the my surface.
  3. The gradient stops are evenly distributed throughout the 0.0 to 1.0 range.  I just manually set each GradientStop's "Offset" value to be (1.0 / 64.0) apart

This all works very well and looks great.  It produces the image I referred to above.

Here is the XAML I use. 

<tk:RadCartesianChart3D.Series>
     <tk:SurfaceSeries3D ItemsSource="{Binding Points}"
                         XValueBinding="X"
                         YValueBinding="Y"
                         ZValueBinding="Z"
                         x:Name="Series"                                   
                         >
 
         <tk:SurfaceSeries3D.Colorizer>
             <tk:SurfaceSeries3DValueGradientColorizer x:Name="Colorizer" IsAbsolute="False" />
         </tk:SurfaceSeries3D.Colorizer>
     </tk:SurfaceSeries3D>
</tk:RadCartesianChart3D.Series>

And here is how my XAML builds the GradientStops

// "Colors" is an array of 64 custom colors.
// Return an evenly distributed array of them for gradient stops.
 
 var step = 1.0 / Colors.Length;
 var stops = Colors.Select((color, index) => new GradientStop(color, index * step));
 return new GradientStopCollection(stops);

 

But now I have a new requirement.  I need to add a RadSlider that allows the user to dynamically change the colors instantaneously.  The slider sets "cut-off" values distribution of the colors, limiting the range to a subset of 1.0.  The visual effect is to highlight certain values.  Basically I am emulating something that is already done  a different application of ours (that app uses OpenGL).  

To illustrate, I have also attached an image ("Desired_Surface.png") of this alternate application (the one that already has this slider) and the same surface showing.     You can see the the user has adjusted the bottom slider upwards and this has totally compressed the color distribution.  (You can even see the compressed distribution in the slider itself, though I don't need that). 

My problem is that I cannot see how to emulate this with SurfaceSeries3D without using Deferred Dragging .   The user needs to see the colors change immediately as he/she adjusted either of the sliders indicators;  But the only way I can see to implement this is far too slow for anything but deferred dragging.

First I tried binding the Colorizer's GradientStop property.  As you no doubt already know, that is not allowed by WPF

 

<tk:SurfaceSeries3D.Colorizer>
    <tk:SurfaceSeries3DValueGradientColorizer IsAbsolute="False" GradientStops="{Binding GradientStops}"/>

 

Then I tried declaring all 64 gradient stops directly in XAML and binding each one's GradientStop.Offset to a backing view-model property but that is also not allowed (because Gradient stops must be Freezable and always sorted)

<tk:SurfaceSeries3D.Colorizer>
    <tk:SurfaceSeries3DValueGradientColorizer IsAbsolute="False">
 
        <tk:SurfaceSeries3DValueGradientColorizer.GradientStops>
            <GradientStopCollection>
                <GradientStop Color="sc# 1.0,    0.0,    0.0, 0.5625" Offset="{Binding Offset_0}"/>
                <GradientStop Color="sc# 1.0,    0.0,    0.0, 0.6250" Offset="{Binding Offset_1}"/>

So the only way I could get this working was to completely rebuild the entire Colorizer every single time the user adjusts the slider.  I construct 64 new Gradient stops with the new Offset values and put them into a new GradientStop collection.  Unfortunately, this is far, far too laggy and slow.  It's too much work to do for a slider drag.  So I am left with using deferred dragging.  But that's not what my boss wants.

Is there any other approach I might take to speed up the adjustment of the colors? 

 


Martin Ivanov
Telerik team
 answered on 12 Jun 2019
Narrow your results
Selected tags
Tags
+? more
Top users last month
horváth
Top achievements
Rank 2
Iron
Iron
Steve
Top achievements
Rank 2
Iron
Erkki
Top achievements
Rank 1
Iron
Mark
Top achievements
Rank 2
Iron
Iron
Veteran
Jakub
Top achievements
Rank 1
Iron
Want to show your ninja superpower to fellow developers?
Top users last month
horváth
Top achievements
Rank 2
Iron
Iron
Steve
Top achievements
Rank 2
Iron
Erkki
Top achievements
Rank 1
Iron
Mark
Top achievements
Rank 2
Iron
Iron
Veteran
Jakub
Top achievements
Rank 1
Iron
Want to show your ninja superpower to fellow developers?
Want to show your ninja superpower to fellow developers?