If I have a large number of series (or data points in a single pie series), the legend gets cut off. I tried to template the chart to put a ScrollViewer around the LegendPanel, but that didn't work since the XamWebChart.cs code adds the LegendPanel to its RootElement, so I get this:
XamWebChart Warning: Element is already the child of another element
This was my template (which I applied in code behind):
<ControlTemplate TargetType="igChart:XamWebChart"> <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Grid x:Name="RootElement" Background="{TemplateBinding Background}" Margin="{TemplateBinding Padding}" > <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto" MaxWidth="200"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid x:Name="CaptionPanel" Grid.Row="0" Grid.ColumnSpan="2" Grid.Column="0"/> <Grid x:Name="ScenePanel" Grid.Column="0" Grid.Row="1"/> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" Grid.Column="1" Grid.Row="1" > <Grid x:Name="LegendPanel" Grid.Column="1" Grid.Row="1" /> </ScrollViewer> <!--<igChart:Legend x:Name="LegendPanel" Grid.Column="1" Grid.Row="1" MaxWidth="200"/>--> </Grid> </Border></ControlTemplate>
Is there any way to get some sort of scrolling in the legend so I can see all the items in a pie series (even beyond 50 or so gets cut off depending on the control size)?
Thanks,Keith
you can put a ScrollViewer in the Legend Template like this:
<igChart:XamChart.Legend> <igChart:Legend> <igChart:Legend.Style> <Style TargetType="{x:Type igChart:Legend}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type igChart:Legend}"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer Height="50"> <ContentPresenter Height="100"/> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </igChart:Legend.Style> </igChart:Legend> </igChart:XamChart.Legend>
Thanks David, but that doesn't seem to work for me. If I comment the Legend Style below, it shows as expected. With the style, I see the srollviewer, but nothing inside of it.
I'm using Infragistics.Silverlight.DataVisualization.Chart.v9.1 Version: 9.1.20091.1000
<igChart:XamWebChart x:Name="XamWebChart1"> <igChart:XamWebChart.Legend> <igChart:Legend> <igChart:Legend.Style> <Style TargetType="igChart:Legend"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="igChart:Legend"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer Height="200"> <ContentPresenter Height="300"/> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </igChart:Legend.Style> </igChart:Legend> </igChart:XamWebChart.Legend> <igChart:XamWebChart.Series> <igChart:Series ChartType="Column" Label="Series 1"> <igChart:Series.DataPoints> <igChart:DataPoint Value="10" Label="point1" /> <igChart:DataPoint Value="20" Label="point2" /> <igChart:DataPoint Value="30" Label="point3" /> </igChart:Series.DataPoints> </igChart:Series> </igChart:XamWebChart.Series></igChart:XamWebChart>
Am I missing something?Thanks,Keith
Here's another option you can experiment with. It creates uses a canvas control that reformats content that is added to it into a different control instead. This might get you started on other ways to rearrange the content:
The Code:
public class FakeCanvas : Canvas { public FakeCanvas() { this.LayoutUpdated += new EventHandler(FakeCanvas_LayoutUpdated); } private ItemsControl itemsControl; public ItemsControl ItemsControl { get { return itemsControl; } set { itemsControl = value; if (itemsControl != null) { itemsControl.Measure( new Size(Double.PositiveInfinity, Double.PositiveInfinity)); this.Width = itemsControl.DesiredSize.Width; this.Height = itemsControl.DesiredSize.Height; SetTop(itemsControl, 0); SetLeft(itemsControl, 0); this.Children.Add(itemsControl); } } } void FakeCanvas_LayoutUpdated( object sender, EventArgs e) { if (ItemsControl == null) { return; } if (this.Children.Count == 1) { if (this.Children[0] == ItemsControl) { return; } } ItemsControl.Items.Clear(); List<UIElement> move = new List<UIElement>(); foreach (UIElement child in this.Children) { if (child != ItemsControl) { move.Add(child); } } move.Sort( (ele1, ele2) => Canvas.GetTop(ele1).CompareTo( Canvas.GetTop(ele2))); foreach (UIElement child in move) { this.Children.Remove(child); ItemsControl.Items.Add(child); } ItemsControl.Measure( new Size(Double.PositiveInfinity, Double.PositiveInfinity)); this.Width = itemsControl.DesiredSize.Width; this.Height = itemsControl.DesiredSize.Height; SetTop(itemsControl, 0); SetLeft(itemsControl, 0); if (ItemsControl.Parent == null) { this.Children.Add(ItemsControl); } } }
The changes to the legend style:
<igChart:XamWebChart.Legend> <igChart:Legend Width="100"> <igChart:Legend.Style> <Style TargetType="igChart:Legend"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="igChart:Legend"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <local:FakeCanvas x:Name="RootElement" > <local:FakeCanvas.ItemsControl> <ListBox Height="100" Width="100" /> </local:FakeCanvas.ItemsControl> </local:FakeCanvas> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </igChart:Legend.Style> </igChart:Legend> </igChart:XamWebChart.Legend>
-Graham
Hi Graham,
The fake canvas approach that you have suggested introduces the scrollbar successfully in my legend box and works for multiple series also. But if I disable the horizontal scrollbar and the legend item label is very long the entire legend box shifts to the extreme right of the canvas and only partial legend box is seen. In the normal case without scrollbar infragistics legend item gets truncated when the legend item label is too long. I would ideally want this behaviour to continue.
This is one of the default feature I found was failing when I tried using the fake canvas code. Can you please look into this and help me find a solution to introduce a scrollbar in legend box without loosing on any default feature provided with infragistics
quick and easy way would be to update the fake canvas in the control template to look like:
<local:FakeCanvas HorizontalAlignment="Left" x:Name="RootElement" Background="Beige" > <local:FakeCanvas.ItemsControl> <ListBox Height="70" Width="200" ScrollViewer.HorizontalScrollBarVisibility="Hidden" /> </local:FakeCanvas.ItemsControl> </local:FakeCanvas>
You basically need to make sure the listbox width is appropriate to the size that the labels are being truncated to.
Automatically deciding this value would be a bit more infolved, does this work for you?
In my project the legend labels sometimes runs to as many as 30 characters . In such a scenario we cannot assign the width of the listbox to that of the label. Therefore I would want truncation or wrapping of label .
How can I achieve that? If I use default legend provided by infragistics the labels gets truncated. I would want the same functionality to continue.
If you can decide the maximum width that you will allow for the legend, you can set it as the max with of the legend control and the width of the items control and you will get the desired truncation. The max width of the legend control is what drives the truncation of the labels, so just set it to whatever width you are setting for the items control in the fake canvas and you should be fine. Here is a screen shot:
And here is the xaml that produced it:
<igChart:Legend MaxWidth="150"> <igChart:Legend.Style> <Style TargetType="igChart:Legend"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="igChart:Legend"> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <local:FakeCanvas x:Name="RootElement" HorizontalAlignment="Left" > <local:FakeCanvas.ItemsControl> <ListBox ScrollViewer.HorizontalScrollBarVisibility="Hidden" Height="70" Width="150" /> </local:FakeCanvas.ItemsControl> </local:FakeCanvas> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style> </igChart:Legend.Style> </igChart:Legend>
Could you share more detail as to how you are moving between them? Are they in a tab control or are you removing and adding them to the visual tree? If you could provide a small sample that illustrates the issue that would help. You may need to have the fake canvas refresh when the controls loaded event fires also, depending on what you are doing.
I have used this on one of my applications. In my application I am moving from one chart to another with the click of series of buttons. When I land on the chart that I have included the "FakeCanvas" on the first time it works great. However, when I go from that chart to another chart and then come back, the legend items are totally gone. How do I get the items to build each time?
Thanks
ptilwani,
It's come to my attention Developer Support is helping you with this issue, is there any more assistance you need?
Please find the ResourceDictStyle.txt attached which is nothing but a resource dictionary.
In my Page.Xaml I try applying the declared style to the legend in the following way:
<igChart:XamWebChart.Legend>
<igChart:Legend MaxWidth="100" Style="{StaticResource ScrollableLegend}" />
</igChart:XamWebChart.Legend>
Then I get the following error:
Error: Unhandled Error in Silverlight Application Code:2255 Category:Runtime Error Message:AG_E_PARSER_BAD_TYPE MethodName:
If I decalre the style in UserControl.Resources everything works fine. Please tell me if you need any more info.
For starters, make sure you have the same Xaml namespace declarations in your resource dictionary as in the file you originally had the style defined in. Are there any more details about the error than that? Can you provide a sample the reproduces the problem?