Hi All,
I have a situation where the chart needs to be switched between a log scale and a linear scale. To solve this I created 2 axis (one of each) and collapse one of them while the other is visible. The user can switch between them from a context menu.
I declare them in XAML as:
<s:SciChartSurface.YAxes>
<s:NumericAxis x:Name="LinearAxis" Id="LinearAxisID" AutoRange="Always" AxisAlignment="Left" AxisTitle="Linear" Style="{StaticResource LinearScaleStyle}" Visibility="Visible" GrowBy="0.0, 0.1"/>
<s:LogarithmicNumericAxis x:Name="LogAxis" Id="LogAxisID" AxisAlignment="Left" AxisTitle="Log" Style="{StaticResource LogScaleStyle}" GrowBy="0.0, 0.1" />
</s:SciChartSurface.YAxes>
THE ISSUE:
I’ve noticed that the Major and Minor gridlines are drawn based on the order the Axis are declared in <s:SciChartSurface.YAxes> which isn’t a problem. The problem comes when I collapse one axis and make the other visible (obviously re-assigning the series to the visible axis by ID) – The axis and data change as you might expect but the major and minor gridlines are not redrawn.
In summary, if you start with log gridlines, you always get log gridlines – even on a linear axis.
Is there a way to force the redrawing of the gridlines?
- Stuart McCullough asked 9 years ago
- You must login to post comments
Hi Stuart,
If you want one axis to draw gridlines, and the other not, you need to set AxisBase.IsPrimaryAxis to true (to draw gridlines) or to false (to not draw gridlines). That will solve the problem.
However, I think what you’re looking for is a good way to switch between linear and logarithmic axis. So, here is one way you can do this, with attached behaviours:
SwitchYAxisTypeBehavior
Dynamically Switches an axis instance on a chart depending on a bound boolean property
// Note this could be extended to deal with XAxis quite easily
public class SwitchYAxisTypeBehavior
{
// Define the Default YAxis -- this can be done in XAML
public static readonly DependencyProperty DefaultYAxisProperty = DependencyProperty.RegisterAttached(
"DefaultYAxis", typeof(AxisBase), typeof(SwitchYAxisTypeBehavior), new PropertyMetadata(default(AxisBase), OnPropertyChanged));
public static void SetDefaultYAxis(DependencyObject element, AxisBase value)
{
element.SetValue(DefaultYAxisProperty, value);
}
public static AxisBase GetDefaultYAxis(DependencyObject element)
{
return (AxisBase)element.GetValue(DefaultYAxisProperty);
}
// Define the Alternative YAxis -- this can be done in XAML
public static readonly DependencyProperty AlternativeYAxisProperty = DependencyProperty.RegisterAttached(
"AlternativeYAxis", typeof(AxisBase), typeof(SwitchYAxisTypeBehavior), new PropertyMetadata(default(AxisBase), OnPropertyChanged));
public static void SetAlternativeYAxis(DependencyObject element, AxisBase value)
{
element.SetValue(AlternativeYAxisProperty, value);
}
public static AxisBase GetAlternativeYAxis(DependencyObject element)
{
return (AxisBase)element.GetValue(AlternativeYAxisProperty);
}
// Define a boolean attached property which switches between default and alternative YAxis
public static readonly DependencyProperty UseAlternateYAxisProperty = DependencyProperty.RegisterAttached(
"UseAlternateYAxis", typeof(bool), typeof(SwitchYAxisTypeBehavior), new PropertyMetadata(default(bool), OnPropertyChanged));
public static void SetUseAlternateYAxis(DependencyObject element, bool value)
{
element.SetValue(UseAlternateYAxisProperty, value);
}
public static bool GetUseAlternateYAxis(DependencyObject element)
{
return (bool)element.GetValue(UseAlternateYAxisProperty);
}
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
// This is where we switch the axis type depending on boolean
var scs = d as SciChartSurface;
if (scs == null) return;
bool useAlternateYAxis = GetUseAlternateYAxis(scs);
scs.YAxis = useAlternateYAxis ? GetAlternativeYAxis(scs) : GetDefaultYAxis(scs);
}
}
Usage (XAML):
<s:SciChartSurface x:Name="sciChart" Grid.Row="1" m:SwitchYAxisTypeBehavior.UseAlternateYAxis="{Binding UseLogarithmicAxis}">
<m:SwitchYAxisTypeBehavior.DefaultYAxis>
<s:NumericAxis AxisTitle="Numeric Axis" DrawMajorBands="True" VisibleRange="0, 10" AutoRange="Never"/>
</m:SwitchYAxisTypeBehavior.DefaultYAxis>
<m:SwitchYAxisTypeBehavior.AlternativeYAxis>
<s:LogarithmicNumericAxis AxisTitle="Logarithmic Axis" LogarithmicBase="10" TextFormatting="0.0" CursorTextFormatting="0.0"
DrawMajorBands="True" VisibleRange="0.1, 10000"/>
</m:SwitchYAxisTypeBehavior.AlternativeYAxis>
...
</s:SciChartSurface>
Alternatively, if not using MVVM
Attached properties can be set in code as well. The C# equivalent for setting an attached property is:
var scs = new SciChartSurface();
// ...
SwitchYAxisTypeBehavior.SetDefaultYAxis(scs, new NumericAxis() { ... } );
SwitchYAxisTypeBehavior.SetAlternateYAxis(scs, new LogarithmicNumericAxis() { ... } );
SwitchYAxisTypeBehavior.SetUseAlternateYAxis(scs, true);
Best regards,
Andrew
- Andrew Burnett-Thompson answered 9 years ago
-
Hi Andrew - I do like this answer, it solves my immediate problem and points me in the right direction for a proper MVVM implementation. We're trying to move towards this pattern but we're a bit inexperienced and most of the time an expedient solution wins over a proper one. Thanks again
-
If we had time to create answers like this all the time, we would! As our products mature we are hoping to spend more time on educating our users on general WPF tips/tricks as well as scichart API tips. Best regards, Andrew
- You must login to post comments
I’ve created a better solution than behavior.
I used DataTriggers:
<Style TargetType="s:SciChartSurface">
<Setter Property="YAxis" Value="{StaticResource NumericAxisY}" />
<Style.Triggers>
<DataTrigger Binding="{Binding UseLogarithmicAxisY}" Value="True">
<Setter Property="YAxis" Value="{StaticResource LogarithmicAxisY}" />
</DataTrigger>
</Style.Triggers>
</Style>
In my opinion this solution should be in official Examples Suite.
- Alitec Developer answered 8 years ago
-
It’s a great solution! Thank you for sharing! Please be advised – if you share the LogarithmicAxisY instance on more than one chart, it will break. Ensure the LogarithmicAxisY is declared with x:Shared=”False” to prevent this
-
is really a good solution. Just to make it a complete answer, you also need to: remove YAxis from SciChartSurface define resource like following:
- You must login to post comments
It looks like that I can’t add XAML code to comments. So I have to post it here.
Alitec Developer’s solution is really a good solution. Just to make it a complete answer, you also need to:
remove YAxis from SciChartSurface
define resource like following:
<s:NumericAxis x:Key="NumericAxisY" AxisTitle="Counts" GrowBy="0.1, 0.15" VisibleRangeLimitMode="Min" VisibleRangeLimit="0,0" />
<s:LogarithmicNumericAxis x:Key="LogarithmicAxisY" AxisTitle="Counts (Log)" GrowBy="0.1, 0.15" VisibleRangeLimitMode="Min" VisibleRangeLimit="0,0" />
Hope this will save you a few minutes.
- Hao Zeng answered 5 years ago
- last edited 5 years ago
- You must login to post comments
Please login first to submit.