SciChart® the market leader in Fast WPF Charts, WPF 3D Charts, iOS Chart, Android Chart and JavaScript Chart Components
What is the recommended way to use the same text formatting for both Axis and Annotation labels?
There are two scenarios.
When zooming DatetimeAxis, it automatically changes the text format in the label. For example if XAxis visible range is few seconds, it changes the format as HH:mm:ss. But still the annotation label shows the date. Please see attachement : DatetimeAxisAnnotationLabel.PNG
<sciChart:SciChartSurface.XAxis> <sciChart:DateTimeAxis Name="XAxisStartTime" AxisTitle="Start Time"/> </sciChart:SciChartSurface.XAxis>
If there is a LabelFormatter, what is the recommended way to apply the same formatting for Annotation Label text?
Please see attachement : LabelFormatterAnnotationLabel.PNG (annotation label shows number of milliseconds)
<sciChart:SciChartSurface.XAxis> <sciChart:NumericAxis Name="XAxisDuration" AxisTitle="Duration" LabelFormatter="{StaticResource TimeDurationAxisFormatter}" AxisMode="Logarithmic" /> </sciChart:SciChartSurface.XAxis>
Thanks!
Hi,
Please, try following code:
<s:HorizontalLineAnnotation HorizontalAlignment="Stretch" IsEditable="True" LabelPlacement="Axis" ShowLabel="True" Stroke="Orange" StrokeThickness="2" Y1="..."> <s:HorizontalLineAnnotation.LabelValue> <MultiBinding Converter="{StaticResource LabelFormatterCoverter}"> <Binding Path="Y1" RelativeSource="{RelativeSource Self}"/> <Binding Path="LabelFormatter" /> </MultiBinding> </s:HorizontalLineAnnotation.LabelValue> </s:HorizontalLineAnnotation>
Value converter:
public class CustomLabelProvider : LabelProviderBase { public override string FormatLabel(IComparable dataValue) { return dataValue.ToString(); // TODO: Implement as you wish } public override string FormatCursorLabel(IComparable dataValue) { return dataValue.ToString();// TODO: Implement as you wish } }
..and LabeProvider in VM:
private ILabelProvider _labelProvider = new CustomLabelProvider(); public ILabelProvider LabelProvider { get { return _labelProvider; } }
You also need to bind LabelProvider to IAxis.LabelProvider:
<s:SciChartSurface ....> ........ <s:SciChartSurface.YAxis> <s:NumericAxis LabelProvider="{Binding LabelProvider}" .... /> </s:SciChartSurface.YAxis> </s:SciChartSurface>
You should modify this code a bit, just replace Horizontal by Vertical annotation, change Y1 on X1 and use DateTimeLabelFormatter instead of DefaultLabelFormatter.
Please, let us know if this works,
Best regards,
Yuriy
Hi,
As far as I am aware annotation’s label must have the same format as the parent axis has by default. Maybe just try setting the TextFormatting property on the YAxis explicitly and see if it is aplied to the label as well.
Do you use any bindings on the annotation label? How do you set it’s value? Maybe you can format it in XAML using the same formatting as on YAxis?
Best regards,
Yuriy
<Style x:Key="HorizontalLineAnnotationStyle" TargetType="s:HorizontalLineAnnotation"> <Setter Property="Stroke" Value="#FFFF6600"/> <Setter Property="StrokeThickness" Value="2"/> <Setter Property="ShowLabel" Value="False"/> <Setter Property="LabelPlacement" Value="Axis"/> <Setter Property="HorizontalAlignment" Value="Stretch"/> </Style> <ControlTemplate x:Key="HorAnnotLabelTemplate" TargetType="s:AnnotationLabel"> <Border Background="Transparent" BorderBrush="{Binding Path=Stroke}" BorderThickness="1.5" Padding="1" CornerRadius="2" HorizontalAlignment="Left"> <StackPanel> <TextBox FontSize="12" Foreground="#FF333333" Background="{Binding Path=Stroke}" BorderBrush="Transparent" BorderThickness="0.2" IsReadOnly="True" IsHitTestVisible="False" Text="{Binding Path=YDif, RelativeSource={RelativeSource FindAncestor, AncestorType=my:MainWindow, AncestorLevel=1}}" /> <TextBox FontSize="12" Foreground="#FF333333" Background="{Binding Path=Stroke}" BorderBrush="Transparent" BorderThickness="0.2" IsReadOnly="True" IsHitTestVisible="False" Text="{Binding Path=Text, RelativeSource={RelativeSource TemplatedParent}}" x:Name="PART_InputTextArea" /> </StackPanel> </Border> </ControlTemplate>And in the chart:
<!-- Create Y Axes on the Left and Right --> <s:SciChartSurface.YAxes> <s:NumericAxis TickTextBrush="Black" BorderBrush="Black" AxisTitle="" AxisAlignment="Left" Id="GenYAxis" GrowBy="{StaticResource GrowBy1}" BorderThickness="0,0,1,0"/> </s:SciChartSurface.YAxes> <s:SciChartSurface.Annotations> <!-- Horizontal Lines --> <pp:CustomHorizontalLineAnnotation x:Name="FHor" YAxisId="GenYAxis" ShowLabel="True" IsEditable="True" IsEnabled="True" Width="600" Y1="2" DragDirections="YDirection" Style="{StaticResource HorizontalLineAnnotationStyle}"/> <pp:CustomHorizontalLineAnnotation x:Name="FHor2" YAxisId="GenYAxis" ShowLabel="False" IsEditable="True" IsEnabled="True" Width="600" Y1="0" DragDirections="YDirection" Style="{StaticResource HorizontalLineAnnotationStyle}"> <s:AnnotationLabel Template="{StaticResource HorAnnotLabelTemplate}" LabelPlacement="Axis"/> </pp:CustomHorizontalLineAnnotation> </s:SciChartSurface.Annotations>
public class CustomHorizontalLineAnnotation : HorizontalLineAnnotation { internal int IntHAnot1; internal int IntHAnot2; protected override void MoveAnnotationTo(AnnotationCoordinates coordinates, double horizOffset, double vertOffset) { base.MoveAnnotationTo(coordinates, horizOffset, vertOffset); var axis = GetYAxis(YAxisId); if (this.ParentSurface.Annotations.Count >= 2) { var et = this.ParentSurface; MainWindow mw = (MainWindow)Application.Current.MainWindow; mw.YDif = (Math.Round((double)mw.chartt.FHor2.Y1 - (double)mw.chartt.FHor.Y1, 1)).ToString(); //StatciChart.YDif = (double)this.ParentSurface.Annotations[0].Y1 - (double)this.ParentSurface.Annotations[1].Y1; } } protected override void PlaceAnnotation(AnnotationCoordinates coordinates) { base.PlaceAnnotation(coordinates); var axis = GetYAxis(YAxisId); if (axis.AxisAlignment == AxisAlignment.Left) { var axisLabels = AnnotationLabels.Where(x => x.LabelPlacement == LabelPlacement.Axis); foreach (var label in axisLabels) { var canvas = label.Parent as Canvas; if (canvas != null) { var width = canvas.ActualWidth - label.DesiredSize.Width; Canvas.SetLeft(label, width); } } } } public static readonly DependencyProperty IsZoProperty = DependencyProperty.Register( "IsZo", typeof(string), typeof(CustomRubberBandXyZoomModifier), new PropertyMetadata("dghd")); public string IsZo { get { return (string)this.GetValue(IsZoProperty); } set { this.SetValue(IsZoProperty, value); } } }If i set the Format of the YAxis then i will not have a different format when i zoom into the chart. Thats why i just want to bind to the format of the YAxis itself. By the way, yesterday i started a clean new test project. The same thing ocurs. Strange part is that the XAxis labelformater works perfectly. Only the YAxis is doing strange.
OK, thanks for the update! Let us investigate the issue. I’ll get back to you soon,
Best regards,
Yuriy
Hi,
Different formats on axis and annotation is the default behavior. This can be worked around by that approach given in the second post. Please, take a look at the attachments for the complete code.
Best regards,
Yuriy
<Style x:Key="HorizontalLineAnnotationStyle" TargetType="s:HorizontalLineAnnotation"> <Setter Property="Stroke" Value="#FFFF6600"/> <Setter Property="StrokeThickness" Value="2"/> <Setter Property="ShowLabel" Value="False"/> <Setter Property="LabelPlacement" Value="Axis"/> <Setter Property="HorizontalAlignment" Value="Stretch"/> </Style> <ControlTemplate x:Key="HorAnnotLabelTemplate" TargetType="s:AnnotationLabel"> <Border Background="Transparent" BorderBrush="{Binding Path=Stroke}" BorderThickness="1.5" Padding="1" CornerRadius="2" HorizontalAlignment="Left"> <StackPanel> <TextBox FontSize="12" Foreground="#FF333333" Background="{Binding Path=Stroke}" BorderBrush="Transparent" BorderThickness="0.2" IsReadOnly="True" IsHitTestVisible="False" Text="{Binding Path=YDif, RelativeSource={RelativeSource FindAncestor, AncestorType=my:MainWindow, AncestorLevel=1}}" /> <TextBox FontSize="12" Foreground="#FF333333" Background="{Binding Path=Stroke}" BorderBrush="Transparent" BorderThickness="0.2" IsReadOnly="True" IsHitTestVisible="False" x:Name="PART_InputTextArea" > <TextBox.Text> <MultiBinding Converter="{StaticResource CustmLabelFormatterCoverter}"> <Binding Path="Text" RelativeSource="{RelativeSource TemplatedParent}" /> <Binding Source="{StaticResource CustmLabelFormatter}" Mode="OneWay" /> </MultiBinding> </TextBox.Text> </TextBox> </StackPanel> </Border> </ControlTemplate>
Hi,
It looks like you should use TemplateBinding or RelativeSource=TemplatedParent instead of plain Bindings. Please, try and let us know if you get it working.
Best regards,
Yuriy
Hi,
I’ll try to take a quick look and compile an example which uses the template you posted above. Get back to you when it’s done. Maybe there really are some issues with annotations allocation in VisualTree.
Best regards,
Yuriy
Hi Bochelie,
Thanks for the example project. The problem with the code is that LabelFormatter obtain a string, which represents already formatted value. To get proper formatting, you need to either change binding to receive actual value from the LabelValue property or parse incoming string inside the LabelFormatter and format it again.
Here is changes required to get it working(the first approach from above):
<TextBox.Text> <MultiBinding Converter="{StaticResource CustmLabelFormatterCoverter}"> <Binding ElementName="FHor2" Path="LabelValue" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/> <Binding Source="{StaticResource CustmLabelFormatter}" Mode="OneWay" /> </MultiBinding> </TextBox.Text>
Please, let us know if it works now,
Best regards,
Yuriy
Please login first to submit.