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

ChartArea Template3D

4 Answers 105 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Trystan
Top achievements
Rank 1
Trystan asked on 11 Jul 2013, 03:06 PM
Hi

We are looking at using Telerik charts to replace an older WinForms charting widget, and we need to maintain backwards compatibility in order to maintain the correct look and feel.  Our previous charting widgets heavily supported 3D charting, but Telerik's 3D charts are not particularly similar in visual style to the ones we are looking to replace.  I have been looking at ChartArea, and have noticed that there is a Template3D that is used to dictate how the 3D charts are set up visually, and this would be perfect to use for what we want to do.  In attempting to create a custom style in order to specify our own Template3D, I have been running into a few problems.  Currently, I have a ChartArea style that specifies our custom Template3D, which I have pulled from looking at the default Template3D normally used:

<Style x:Key="defaultAreaStyle" TargetType="c:ChartArea">
        <Setter Property="Template3D">
            <Setter.Value>
                <ControlTemplate TargetType="c:ChartArea">
                    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
                        <ItemsPresenter/>
                        <Grid x:Name="PART_Container"/>
                        <c:ViewportPanel x:Name="PART_CameraExtensionCanvas">
                            <Viewport3D x:Name="PART_ViewPort3D">
                                <Viewport3D.Camera>
                                    <PerspectiveCamera LookDirection="0.2,-0.23,-1" Position="-40,37.5,195"/>
                                </Viewport3D.Camera>
                                <ModelVisual3D>
                                    <ModelVisual3D.Content>
                                        <Model3DGroup>
                                            <AmbientLight Color="#FF606060"/>
                                            <DirectionalLight Color="#FF989898" Direction="-0.5,-0.4,-1"/>
                                        </Model3DGroup>
                                    </ModelVisual3D.Content>
                                </ModelVisual3D>
                                <ContainerUIElement3D>
                                    <ContainerUIElement3D.Transform>
                                        <Transform3DGroup>
                                            <TranslateTransform3D OffsetX="-50" OffsetY="-37.5"/>
                                        </Transform3DGroup>
                                    </ContainerUIElement3D.Transform>
                                    <c:PlaneZX AdornerLayer="{x:Null}" Height="2" SecondaryTicksSource="{Binding AxisX.TickPoints, RelativeSource={RelativeSource TemplatedParent}}" SecondaryAxis3DPoints="0,0,10.1 100,0,10.1">
                                        <c:PlaneZX.PositionTransform>
                                            <TranslateTransform3D OffsetZ="0" OffsetX="0" OffsetY="-2"/>
                                        </c:PlaneZX.PositionTransform>
                                    </c:PlaneZX>
                                    <c:PlaneXY AdornerLayer="{x:Null}" Depth="2" PrimaryTicksSource="{Binding AxisX.TickPoints, RelativeSource={RelativeSource TemplatedParent}}" SecondaryTicksSource="{Binding AxisY.TickPoints, RelativeSource={RelativeSource TemplatedParent}}">
                                        <c:PlaneXY.PositionTransform>
                                            <TranslateTransform3D OffsetZ="-2" OffsetX="0" OffsetY="0"/>
                                        </c:PlaneXY.PositionTransform>
                                    </c:PlaneXY>
                                    <c:PlaneYZ AdornerLayer="{x:Null}" PrimaryTicksSource="{Binding AxisY.TickPoints, RelativeSource={RelativeSource TemplatedParent}}" PrimaryAxis3DPoints="0,0,10.1 0,75,10.1" Width="2">
                                        <c:PlaneYZ.PositionTransform>
                                            <TranslateTransform3D OffsetZ="0" OffsetX="-2" OffsetY="0"/>
                                        </c:PlaneYZ.PositionTransform>
                                    </c:PlaneYZ>
                                    <c:ItemsPresenter3D/>
                                </ContainerUIElement3D>
                            </Viewport3D>
                            <c:LabelsControl x:Name="PART_LabelsControl" ClipToBounds="True">
                                <c:LabelsControl.ItemsPanel>
                                    <ItemsPanelTemplate/>
                                </c:LabelsControl.ItemsPanel>
                                <c:LabelsControl.ItemTemplate>
                                    <DataTemplate>
                                        <c:LabelLayer>
                                            <c:LabelLayer.ItemsPanel>
                                                <ItemsPanelTemplate>
                                                    <c:LabelLayerItemsPanel IsItemsHost="True"/>
                                                </ItemsPanelTemplate>
                                            </c:LabelLayer.ItemsPanel>
                                            <c:LabelLayer.ItemTemplate>
                                                <DataTemplate>
                                                    <Border BorderBrush="#FF5C5C5C" BorderThickness="1" CornerRadius="3" LayoutTransform="{Binding Transform}">
                                                        <Border.Background>
                                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                                <GradientStop Color="#FFCCCCCC" Offset="1"/>
                                                                <GradientStop Color="White"/>
                                                            </LinearGradientBrush>
                                                        </Border.Background>
                                                        <TextBlock Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Margin="4,0">
                                                            <TextBlock.Text>
                                                                <Binding>
                                                                    <Binding.Converter>
                                                                        <c:LabelFormatConverter/>
                                                                    </Binding.Converter>
                                                                </Binding>
                                                            </TextBlock.Text>
                                                        </TextBlock>
                                                    </Border>
                                                </DataTemplate>
                                            </c:LabelLayer.ItemTemplate>
                                        </c:LabelLayer>
                                    </DataTemplate>
                                </c:LabelsControl.ItemTemplate>
                            </c:LabelsControl>
                        </c:ViewportPanel>
                        <c:NoDataControl x:Name="PART_NoData" Style="{TemplateBinding NoDataControlStyle}"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

However, when I try to assign this style to the ChartArea of any 3D chart, I get a null reference exception in RadChart.  The call stack gives the last few calls as:
 
Telerik.Windows.Controls.Charting.dll!Telerik.Windows.Controls.Charting.Series3D.ChartArea.get()
Telerik.Windows.Controls.Charting.dll!Telerik.Windows.Controls.Charting.Series3D.LabelsControl.get()
Telerik.Windows.Controls.Charting.dll!Telerik.Windows.Controls.Charting.Series3D.RemoveLabelLayer()

So my question is how do I properly set Template3D (if it even possible)?  



4 Answers, 1 is accepted

Sort by
0
Petar Kirov
Telerik team
answered on 16 Jul 2013, 01:51 PM
Hi Trystan,

I am afraid that customization of the control when it is in 3D mode is not supported. Additionally we do not recommend using RadChart for new projects because it is no longer in active development since our focus moved to our newer charting solution - RadChartView (represented by the classes RadCartesianChart, RadPieChart and RadPolarChart).
The new control addresses many of the limitations and deficiencies that we have identified in the RadChart implementation over the years. Its architecture was built from the ground-up to offer vastly improved performance (especially in live data scenarios), straight-forward ways of customizing almost every aspect of its appearance and easy to use API.

Regards,
Petar Kirov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Trystan
Top achievements
Rank 1
answered on 16 Jul 2013, 02:51 PM
I did expect a response of this type, but was hoping to avoid it in the first round.  Though I wish I could use ChartView instead of Chart, at this point it is not an option.  The requirements for having good 3D charting are too important (we also need bubble charts as well, which have yet to be supported by ChartView), and for that reason, we have to stick with RadChart (I would suggest that you incorporate 3D charting into ChartView, as in my opinion it is an important feature, and some chart types are much better with 3D).  Also, I know that RadChart is in fact completely customizable (otherwise, why even expose the Template properties on all of the 3D charting classes) as I have found ways to customize the appearances and animations of nearly every 3D chart type, including Bar and Pie/Donut charts.  In fact, it looks like I can customize the 3D viewport entirely through Template3D in ChartArea, but as I have stated above, I do get a null reference error using the template I provided above.  If you could at least take a look at the code above and see if there is something missing that would cause the null reference, that would be a big help.  Since it is a null reference, I am inclined to believe that it is merely a problem of missing an object somewhere in the template that RadChart needs, but as I cannot find any reference to how Template3D looks by default, it is a game of guessing.  I would really appreciate if you could take the time to help with this problem instead of giving a boilerplate answer without even reading my problem.  Also, as I have seen from similar responses on this forum and know that this will come up, I am working in WPF, not Silverlight, so if you do provide a solution, please ensure that it works in WPF, and not just Silverlight.
0
Petar Kirov
Telerik team
answered on 22 Jul 2013, 12:38 AM
Hi Trystan,

What you were missing from your ControlTemplate definition was actually to set the x:Name attribute on the parts of the template that the control relies on. More specifically you need to set the name of the ContainerUIElement3D to PART_PlotArea, the name of PlaneZX to PART_PlaneZX, the name of PlaneXY to PART_PlaneXY, the name of PlaneXY to PART_PlaneXY and finally the name of ItemsPresenter3D to PART_ItemsPresenter3D. Additionally you may want to specify LabelLayer's ItemsSource, because otherwise the control will not display any labels. I have I highlighted the changes that you need to make to your code, in order for control to be able to resolve its template:

<ControlTemplate TargetType="c:ChartArea" x:Key="asd">
    <Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <ItemsPresenter/>
        <Grid x:Name="PART_Container"/>
        <c:ViewportPanel x:Name="PART_CameraExtensionCanvas">
            <Viewport3D x:Name="PART_ViewPort3D">
                <Viewport3D.Camera>
                    <PerspectiveCamera LookDirection="0.2,-0.23,-1" Position="-40,37.5,195"/>
                </Viewport3D.Camera>
                <ModelVisual3D>
                    <ModelVisual3D.Content>
                        <Model3DGroup>
                            <AmbientLight Color="#FF606060"/>
                            <DirectionalLight Color="#FF989898" Direction="-0.5,-0.4,-1"/>
                        </Model3DGroup>
                    </ModelVisual3D.Content>
                </ModelVisual3D>
                <ContainerUIElement3D x:Name="PART_PlotArea">
                    <ContainerUIElement3D.Transform>
                        <Transform3DGroup>
                            <TranslateTransform3D OffsetX="-50" OffsetY="-37.5"/>
                        </Transform3DGroup>
                    </ContainerUIElement3D.Transform>
                    <c:PlaneZX x:Name="PART_PlaneZX" AdornerLayer="{x:Null}" Height="2" SecondaryTicksSource="{Binding AxisX.TickPoints, RelativeSource={RelativeSource TemplatedParent}}" SecondaryAxis3DPoints="0,0,10.1 100,0,10.1">
                        <c:PlaneZX.PositionTransform>
                            <TranslateTransform3D OffsetZ="0" OffsetX="0" OffsetY="-2"/>
                        </c:PlaneZX.PositionTransform>
                    </c:PlaneZX>
                    <c:PlaneXY x:Name="PART_PlaneXY" AdornerLayer="{x:Null}" Depth="2" PrimaryTicksSource="{Binding AxisX.TickPoints, RelativeSource={RelativeSource TemplatedParent}}" SecondaryTicksSource="{Binding AxisY.TickPoints, RelativeSource={RelativeSource TemplatedParent}}">
                        <c:PlaneXY.PositionTransform>
                            <TranslateTransform3D OffsetZ="-2" OffsetX="0" OffsetY="0"/>
                        </c:PlaneXY.PositionTransform>
                    </c:PlaneXY>
                    <c:PlaneYZ x:Name="PART_PlaneYZ" AdornerLayer="{x:Null}" PrimaryTicksSource="{Binding AxisY.TickPoints, RelativeSource={RelativeSource TemplatedParent}}" PrimaryAxis3DPoints="0,0,10.1 0,75,10.1" Width="2">
                        <c:PlaneYZ.PositionTransform>
                            <TranslateTransform3D OffsetZ="0" OffsetX="-2" OffsetY="0"/>
                        </c:PlaneYZ.PositionTransform>
                    </c:PlaneYZ>
                    <c:ItemsPresenter3D x:Name="PART_ItemsPresenter3D"/>
                </ContainerUIElement3D>
            </Viewport3D>
            <c:LabelsControl x:Name="PART_LabelsControl" ClipToBounds="True">
                <c:LabelsControl.ItemsPanel>
                    <ItemsPanelTemplate/>
                </c:LabelsControl.ItemsPanel>
                <c:LabelsControl.ItemTemplate>
                    <DataTemplate>
                        <c:LabelLayer ItemsSource="{Binding}">
                            <c:LabelLayer.ItemsPanel>
                                <ItemsPanelTemplate>
                                    <c:LabelLayerItemsPanel IsItemsHost="True"/>
                                </ItemsPanelTemplate>
                            </c:LabelLayer.ItemsPanel>
                            <c:LabelLayer.ItemTemplate>
                                <DataTemplate>
                                    <Border BorderBrush="#FF5C5C5C" BorderThickness="1" CornerRadius="3" LayoutTransform="{Binding Transform}">
                                        <Border.Background>
                                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                                <GradientStop Color="#FFCCCCCC" Offset="1"/>
                                                <GradientStop Color="White"/>
                                            </LinearGradientBrush>
                                        </Border.Background>
                                        <TextBlock Foreground="Black" FontWeight="Bold" HorizontalAlignment="Center" Margin="4,0">
                                            <TextBlock.Text>
                                                <Binding>
                                                    <Binding.Converter>
                                                        <c:LabelFormatConverter/>
                                                    </Binding.Converter>
                                                </Binding>
                                            </TextBlock.Text>
                                        </TextBlock>
                                    </Border>
                                </DataTemplate>
                            </c:LabelLayer.ItemTemplate>
                        </c:LabelLayer>
                    </DataTemplate>
                </c:LabelsControl.ItemTemplate>
            </c:LabelsControl>
        </c:ViewportPanel>
        <c:NoDataControl x:Name="PART_NoData" Style="{TemplateBinding NoDataControlStyle}"/>
    </Grid>
</ControlTemplate>

I have additionally attached the default Template3D-s for each theme for reference.

I hope this helps.

Regards,
Petar Kirov
Telerik
TRY TELERIK'S NEWEST PRODUCT - EQATEC APPLICATION ANALYTICS for WPF.
Learn what features your users use (or don't use) in your application. Know your audience. Target it better. Develop wisely.
Sign up for Free application insights >>
0
Trystan
Top achievements
Rank 1
answered on 22 Jul 2013, 02:32 PM
Thanks a lot.  I had figured out the ItemsPresenter3D issue, it was what was causing the null reference exception, but I did not consider the ItemsSource binding for the labels, which will certainly help.
Tags
Chart
Asked by
Trystan
Top achievements
Rank 1
Answers by
Petar Kirov
Telerik team
Trystan
Top achievements
Rank 1
Share this question
or