Jump to content
Software FX Community

Minimize the chart legend space by showing it as a title


JuanC

Recommended Posts

Sometimes the size available to a chart imposes a restriction where the legend just takes too much space. In this post we will discuss a couple of possibilities on how to approach this problem

Style your title to mimic a legend

In Chart FX for WPF titles are fully stylable and although typically titles are just strings, you can in fact use any WPF visuals in the title. The problem with this approach is that you would have to code too much information into the title, for example the number of series, colors, etc. which makes this scenario not practical. Also note that things like highlight would not work.

Show the legend underneath the title

Just removing the legend box border and docking the legend box to the top might be sufficient in many scenarios

[color= blue]  <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.Titles[/color][color= blue]>    <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Title[/color][color= blue]>[/color][color= #a31515]Sales in 1998[/color][color= blue]</[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Title[/color][color= blue]>  </[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.Titles[/color][color= blue]>  <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.LegendBox[/color][color= blue]>    <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendBox [/color][color= red]cfx[/color][color= blue]:[/color][color= red]Chart.DockBorder[/color][color= blue]="None" [/color][color= red]DockPanel.Dock[/color][color= blue]="Top" />  </[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.LegendBox[/color][color= blue]>[/color]

Posted Image

Note that in our default style (Glass) the main title is drawn larger and outside the plotting area space, if you would rather have them both together you can change the target panel of the legend box, note that in older builds we did not support a way to specify the index so you might need an updated build if this does not generate the expected results

  [color= blue]<[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.LegendBox[/color][color= blue]>    <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendBox [/color][color= red]cfx[/color][color= blue]:[/color][color= red]Chart.DockBorder[/color][color= blue]="None" [/color][color= red]DockPanel.Dock[/color][color= blue]="Top"                   [/color][color= red]cfx[/color][color= blue]:[/color][color= red]Chart.TargetPanel[/color][color= blue]="Titles-0" />  </[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.LegendBox[/color][color= blue]>[/color]

Posted Image

Combine the title and legend in one line

If the number of series is small we might be able to combine the title text and legend box in one line. To do this we will have to style the legend box and items so it will be a little more involved, hopefully the result will be worthwhile.

[color= blue]<[/color][color= #a31515]Style [/color][color= red]x[/color][color= blue]:[/color][color= red]Key[/color][color= blue]="LegendTitleStyle" [/color][color= red]TargetType[/color][color= blue]="{[/color][color= #a31515]x[/color][color= blue]:[/color][color= #a31515]Type [/color][color= red]ItemsControl[/color][color= blue]}">  <[/color][color= #a31515]Setter [/color][color= red]Property[/color][color= blue]="Template">    <[/color][color= #a31515]Setter.Value[/color][color= blue]>      <[/color][color= #a31515]ControlTemplate[/color][color= blue]>        <[/color][color= #a31515]StackPanel [/color][color= red]Orientation[/color][color= blue]="Horizontal">          <[/color][color= #a31515]StackPanel [/color][color= red]Orientation[/color][color= blue]="Horizontal" [/color][color= red]IsItemsHost[/color][color= blue]="True"                              [/color][color= red]VerticalAlignment[/color][color= blue]="Top" />          <[/color][color= #a31515]TextBlock [/color][color= red]VerticalAlignment[/color][color= blue]="Top" [/color][color= red]Text[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=Tag}"/>        </[/color][color= #a31515]StackPanel[/color][color= blue]>      </[/color][color= #a31515]ControlTemplate[/color][color= blue]>    </[/color][color= #a31515]Setter.Value[/color][color= blue]>  </[/color][color= #a31515]Setter[/color][color= blue]></[/color][color= #a31515]Style[/color][color= blue]><[/color][color= #a31515]DataTemplate [/color][color= red]x[/color][color= blue]:[/color][color= red]Key[/color][color= blue]="LegendTitleItem">  <[/color][color= #a31515]StackPanel [/color][color= red]Orientation[/color][color= blue]="Horizontal">    <[/color][color= #a31515]StackPanel.Resources[/color][color= blue]>      <[/color][color= #a31515]cfxConverters[/color][color= blue]:[/color][color= #a31515]BoolToVisibilityConverter [/color][color= red]x[/color][color= blue]:[/color][color= red]Key[/color][color= blue]="BoolToVisibility"/>    </[/color][color= #a31515]StackPanel.Resources[/color][color= blue]>    <[/color][color= #a31515]StackPanel [/color][color= red]VerticalAlignment[/color][color= blue]="Top" [/color][color= red]x[/color][color= blue]:[/color][color= red]Name[/color][color= blue]="textAndLine">      <[/color][color= #a31515]Border [/color][color= red]Background[/color][color= blue]="Transparent">        <[/color][color= #a31515]ContentControl [/color][color= red]IsHitTestVisible[/color][color= blue]="false" [/color][color= red]Content[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=Content}"                        [/color][color= red]ContentTemplate[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=ContentTemplate}"                        [/color][color= red]Foreground[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=Foreground}"                        [/color][color= red]FontFamily[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=FontFamily}"                        [/color][color= red]FontSize[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=FontSize}"                        [/color][color= red]FontStyle[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=FontStyle}"                        [/color][color= red]FontWeight[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=FontWeight}"/>      </[/color][color= #a31515]Border[/color][color= blue]>      <[/color][color= #a31515]Rectangle [/color][color= red]Fill[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=Stroke}" [/color][color= red]Height[/color][color= blue]="3"/>    </[/color][color= #a31515]StackPanel[/color][color= blue]>    <[/color][color= #a31515]TextBlock [/color][color= red]Text[/color][color= blue]=" "/>     <[/color][color= #a31515]TextBlock [/color][color= red]Text[/color][color= blue]="Vs " [/color][color= red]IsHitTestVisible[/color][color= blue]="false"               [/color][color= red]Visibility[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=LastInGroup,                            [/color][color= red]Converter[/color][color= blue]={[/color][color= #a31515]StaticResource [/color][color= red]BoolToVisibility[/color][color= blue]},                            [/color][color= red]ConverterParameter[/color][color= blue]=false}"/>  </[/color][color= #a31515]StackPanel[/color][color= blue]>  <[/color][color= #a31515]DataTemplate.Triggers[/color][color= blue]>    <[/color][color= #a31515]DataTrigger [/color][color= red]Binding[/color][color= blue]="{[/color][color= #a31515]Binding [/color][color= red]Path[/color][color= blue]=Dimmed}">      <[/color][color= #a31515]DataTrigger.Value[/color][color= blue]>        <[/color][color= #a31515]sys[/color][color= blue]:[/color][color= #a31515]Boolean[/color][color= blue]>[/color][color= #a31515]True[/color][color= blue]</[/color][color= #a31515]sys[/color][color= blue]:[/color][color= #a31515]Boolean[/color][color= blue]>      </[/color][color= #a31515]DataTrigger.Value[/color][color= blue]>      <[/color][color= #a31515]Setter [/color][color= red]Property[/color][color= blue]="Opacity" [/color][color= red]Value[/color][color= blue]="0.25" [/color][color= red]TargetName[/color][color= blue]="textAndLine" />    </[/color][color= #a31515]DataTrigger[/color][color= blue]>  </[/color][color= #a31515]DataTemplate.Triggers[/color][color= blue]></[/color][color= #a31515]DataTemplate[/color][color= blue]>[/color]
  [color= blue]<[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.LegendBox[/color][color= blue]>    <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendBox [/color][color= red]cfx[/color][color= blue]:[/color][color= red]Chart.DockBorder[/color][color= blue]="None" [/color][color= red]DockPanel.Dock[/color][color= blue]="Top"                   [color= red]Tag[/color][color= blue]="Sales in 1998"                   [/color][/color][color= red]ContainerStyle[/color][color= blue]="{[/color][color= #a31515]StaticResource [/color][color= red]LegendTitleStyle[/color][color= blue]}"[/color][color= blue]>      <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendBox.ItemAttributes[/color][color= blue]>        <[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendItemAttributes [/color][color= red]cfx[/color][color= blue]:[/color][color= red]LegendItemAttributes.LegendItemType[/color][color= blue]="Series"                                  [/color][color= red]Template[/color][color= blue]="{[/color][color= #a31515]StaticResource [/color][color= red]LegendTitleItem[/color][color= blue]}"/>      </[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendBox.ItemAttributes[/color][color= blue]>    </[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]LegendBox[/color][color= blue]>  </[/color][color= #a31515]cfx[/color][color= blue]:[/color][color= #a31515]Chart.LegendBox[/color][color= blue]>[/color]

Posted Image

Key points from the XAML

  • In LegendTitleStyle we set a template that has a horizontal stack panel (legend items) + the legend Tag, this allows to reuse this style as all we have to change is the LegendBox tag property.

  • In LegendTitleItem we are showing the legend content with a line under it that uses the series stroke instead of fill, this makes the line a little darker.

  • To hide the separator text (Vs) we used a ChartFX converter because it allows us to set Visibility to Collapsed when the bool property (LastInGroup) is true by setting ConverterParameter to false. The built-in BooleanToVisibilityConverter only seems to convert True to Visible.

  • By using a ContentControl instead of a TextBlock our template should work even if you use Series.ContentTemplate to a more complex visual.

Please note that the legend box can show much more than just the series as it can display information about conditional attributes, axis sections, axis custom gridlines, etc. but in simple scenarios this approach generates a simpler chart while still providing contextual information to your users.

JuanC

Link to comment
Share on other sites

  • 1 month later...

Hi. I was trying to use your example, but it doesn't compile:

'ItemAttributes' property is read-only and cannot be set from markup.

Any suggestions how to fix it? I need a very simple scenario where I hide one specific item from the legend.

I'm evaluating version 8.0.3422.

Thanks,

Boris.

Link to comment
Share on other sites

  • 3 years later...
  • 2 weeks later...
×
×
  • Create New...