Bind X axis label Width to ActualWidth of Bar in Chart

2 posts, 0 answers
  1. Muppet
    Muppet avatar
    1 posts
    Member since:
    Oct 2011

    Posted 07 Oct 2011 Link to this post

    I need to trim the text the item labels of the x axis to the same width as the bars of my chart. Some of the labels could be quite long, so the end of one label could overlap the beginning of the next (Note: I don’t want to rotate these labels). It also needs to be able to resize if the window size changes or if the amount of bars changes.

     

    On my template I have set the texttrimming to use CharacterEllipsis, but obviously this only works if the width is set. So I would like to bind the width of the x axis label to the ActualWidth of the Bar (or Candle).

     

    Using Snoop I can see the ActualWidth of PART_MainContainer and a few other PART_ containers that change size with the size of window. So how do I bind to one of these PART_s? If this can be achieved using just XAML that would be great. I don’t really have code behind skills.

    This is what I have so far;

    >>>> x-axis label style

    <Style x:Key="AxisXLabel2D" TargetType="{x:Type telerik:AxisLabel2D}">
        <Setter Property="ItemLabelStyle">
            <Setter.Value>
                <Style TargetType="TextBlock">
                    <Setter Property="Foreground" Value="DarkGoldenrod" />
                    <Setter Property="FontWeight" Value="Normal" />
                    <Setter Property="TextTrimming" Value="CharacterEllipsis" />
                    <Setter Property="TextAlignment" Value="Center" />
                    <Setter Property="Padding" Value="8,1,8,5" />
                    <Style.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="TextTrimming" Value="None" />
                            <Setter Property="FontWeight" Value="DemiBold" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type telerik:AxisLabel2D}">
                    <Border x:Name="border" BorderThickness="1" BorderBrush="Transparent" CornerRadius="5,2,5,2"
                            Width="{Binding ElementName=PART_MainContainer, Path=ActualWidth}">
                        <TextBlock x:Name="labeltext" Style="{TemplateBinding ItemLabelStyle}">
                        <TextBlock.LayoutTransform>
                            <RotateTransform />
                        </TextBlock.LayoutTransform>
                        <TextBlock.Text>
                            <Binding>
                                <Binding.Converter>
                                    <telerik:LabelFormatConverter />
                                </Binding.Converter>
                            </Binding>
                        </TextBlock.Text>
                        </TextBlock>
                    </Border>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="BorderBrush" Value="LightGray" TargetName="border"  />
                            <Setter Property="Background" Value="White" TargetName="border" />
                            <Setter Property="Panel.ZIndex" Value="99999" />
                            <Setter Property="Padding" Value="8,3,8,3" TargetName="labeltext" />
                            <Setter Property="Width" Value="Auto" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    >>>>> RadChart
    <telerik:RadChart x:Name="radChart">
                <telerik:RadChart.DefaultView>
                    <telerik:ChartDefaultView>
                        <telerik:ChartDefaultView.ChartArea>
                            <telerik:ChartArea SmartLabelsEnabled="True" EnableAnimations="False">
                                <telerik:ChartArea.DataSeries>
                                    <telerik:DataSeries>
                                        <telerik:DataPoint YValue="45" XCategory="Subject 01" />
                                        <telerik:DataPoint YValue="48" XCategory="Subject 02" />
                                        <telerik:DataPoint YValue="53" XCategory="Subject 03" />
                                        <telerik:DataPoint YValue="41" XCategory="Subject 04" />
                                        <telerik:DataPoint YValue="32" XCategory="Subject 05" />
                                        <telerik:DataPoint YValue="28" XCategory="Subject 06" />
                                        <telerik:DataPoint YValue="63" XCategory="Subject 07" />
                                        <telerik:DataPoint YValue="74" XCategory="Subject 08" />
                                        <telerik:DataPoint YValue="77" XCategory="Subject 09" />
                                        <telerik:DataPoint YValue="85" XCategory="Subject 10" />
                                        <telerik:DataPoint YValue="89" XCategory="Subject 11" />
                                        <telerik:DataPoint YValue="80" XCategory="Subject 12" />
                                    </telerik:DataSeries>
                                </telerik:ChartArea.DataSeries>
                            </telerik:ChartArea>
                        </telerik:ChartDefaultView.ChartArea>
                    </telerik:ChartDefaultView>
                </telerik:RadChart.DefaultView>
            </telerik:RadChart>

    >>>>> The code behind that styles the chart
    public MainWindow()
            {
                this.InitializeComponent();
     
                this.radChart.DefaultView.ChartArea.Loaded += ChartArea_Loaded;
     
                // Insert code required on object creation below this point.
                 
            }
            void ChartArea_Loaded(object sender, RoutedEventArgs e)
            {
                ChartArea area = sender as ChartArea;
                HorizontalAxisLabels2D axisLabelsContainer = area.FindChildByType<HorizontalAxisLabels2D>();
                var axisLabels = axisLabelsContainer.ChildrenOfType<AxisLabel2D>();
                System.Windows.Style style = this.Resources["AxisXLabel2D"] as System.Windows.Style;
     
                foreach (var item in axisLabels)
                {
                    item.Style = style;
                }
            }


    Secondly, (not really a problem, but I thought I'd ask as I'm here!) Does anyone know how to make it so the CharacterEllipsis (or whatever ellipsis), could appear in the center of the word, not at the end?

    For example, a full width label "Test Subject 001", trimmed to say "Test Subje..." is ok, but in this case it would be better if it said "Test Su...001".  I know it's probably not the right place to post this, but any help would be great. Does anything in the RadControls do this?

    Thank you in advance.


  2. Evgenia
    Admin
    Evgenia avatar
    1406 posts

    Posted 12 Oct 2011 Link to this post

    Hi Muppet,

    Binding to ActualWidth property is a known Framework issue. The main problem is that ActualWidth isn't a Dependency Property, nor does it implements INotifyPropertyChanged so the Binding has no way of knowing that the ActualWidth has changed. However you may find a good work-around for this here. Unfortunately there is no way that you can implement your scenario without the use of code-behind.

    Greetings,
    Evgenia
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
  3. UI for WPF is Visual Studio 2017 Ready
Back to Top