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

Bind X axis label Width to ActualWidth of Bar in Chart

1 Answer 174 Views
Chart
This is a migrated thread and some comments may be shown as answers.
Muppet
Top achievements
Rank 1
Muppet asked on 07 Oct 2011, 06:39 PM

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.


1 Answer, 1 is accepted

Sort by
0
Evgenia
Telerik team
answered on 12 Oct 2011, 02:08 PM
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 >>
Tags
Chart
Asked by
Muppet
Top achievements
Rank 1
Answers by
Evgenia
Telerik team
Share this question
or