I am using a RadCartesianChart3D in a WPF application, where the label along the y-axis on the horiziontal plane denotes a "Flow direction" displayed using an Arrow symbol.
When/if the user rotates the chart around the vertical z-axis, so that the chart is seen from the backside, the values of the Y-axsis are reversed, which in my case translated to the "flow direction" should be swapped, as in: I need to change the arrow symbol in the y-axis label from "Pointing Right" to "Pointing Left" (or the opposite).
I notice, that the RadCartesianChart3D is actually already "flipping" the text label as the chart is rotated.
Is there any way I can intercept this behaviour, eg. as a ChartRotated or LabelPositionUpdated event, as the user rotates the chart, so that I can change the Label text as needed?
Two images attached to illustrate what I try to accomplish
/Thanx
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
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
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>
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?
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
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:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
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();
}
}
}
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.