ChartArea Template3D

5 posts, 0 answers
  1. Trystan
    Trystan avatar
    5 posts
    Member since:
    Jul 2013

    Posted 11 Jul 2013 Link to this post

    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)?  



  2. Petar Kirov
    Admin
    Petar Kirov avatar
    425 posts

    Posted 16 Jul 2013 Link to this post

    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 >>
  3. UI for WPF is Visual Studio 2017 Ready
  4. Trystan
    Trystan avatar
    5 posts
    Member since:
    Jul 2013

    Posted 16 Jul 2013 Link to this post

    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.
  5. Petar Kirov
    Admin
    Petar Kirov avatar
    425 posts

    Posted 21 Jul 2013 Link to this post

    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 >>
  6. Trystan
    Trystan avatar
    5 posts
    Member since:
    Jul 2013

    Posted 22 Jul 2013 Link to this post

    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.
Back to Top
UI for WPF is Visual Studio 2017 Ready