Search code examples
zoomingaxisvisiblox

Binding secondary YAxis to range and zoom from primary YAxis in Visiblox Chart


i am trying to have a simple chart with both YAxis and SecondaryYAxis having the same Range and Zoom. There i have two problems:

1) the binding of Range and Zoom seems not to work as expected:

<charts:Chart.YAxis>
  <charts:LinearAxis LabelsPosition="Inside" x:Name="PrimaryAxis"/>
</charts:Chart.YAxis>

<charts:Chart.SecondaryYAxis>
  <charts:LinearAxis LabelsPosition="Inside" 
         Range="{Binding ElementName=PrimaryAxis, Path=ActualRange}"
         Zoom="{Binding ElementName=PrimaryAxis, Path=Zoom}" 
         AutoScaleToVisibleData="False"/>
</charts:Chart.SecondaryYAxis>

if i have one series displayed on YAxis and another series displayed on SecondaryYAxis both have different scales or ranges.

2) If i have no series displayed on the SecondaryYAxis (since i want to have both axis showing the same data, there is no point in using the SecondaryYAxis), the "unused" SecondaryYAxis does not show Lables nor Ticks at all.

To put my question short: How can i let the chart show the same YAxis on the left and right side?

======= EDIT =======

OK, as @NielW pointed out, i didn't do anything wrong. The problem was that i have the chart in a TabControl which caused the chart to not set the binding as specified in XAML. Don't ask me why, but here is the fix:

Instead of setting the binding in XAML, i do it manually from code behind:

var primary = ResultChart.YAxis as LinearAxis;
var secondary = ResultChart.SecondaryYAxis as LinearAxis;

var rangeBinding = new Binding("ActualRange")
    {
        Source = primary
    };
secondary.SetBinding(LinearAxis.RangeProperty, rangeBinding);

var zoomBinding = new Binding("Zoom")
    {
        Source = primary
    };
secondary.SetBinding(LinearAxis.ZoomProperty, zoomBinding);

I have no idea why binding in xaml doesn't work when the chart is placed in a TabControl. Perhaps somebody can elaborate on that?!


Solution

  • I got your code to work without any problems. I changed "LabelsPosition" to LabelPosition so it would compile. I would guess the problem has something to do with the code you're not showing, like how you're adding the series to your chart.

    Here's all of my code. Hopefully you can use this to get yours working properly.

    <Window x:Class="Graphs.VBGraph"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:charts="clr-namespace:Visiblox.Charts;assembly=Visiblox.Charts"
        Title="Visiblox" Height="350" Width="525" Loaded="Window_Loaded" SizeChanged="Window_SizeChanged">
    <Grid>
    
        <charts:Chart x:Name="Chart" >
            <charts:Chart.Series>
                <charts:RasterLineSeries AntiAliasingEnabled="True" ShowLine="False" ShowPoints="True"> 
                    <charts:RasterLineSeries.DefaultStyle>
                        <charts:LineSeriesStyle  PointFill="Transparent" PointSize="3" PointStroke="Blue"/>
                    </charts:RasterLineSeries.DefaultStyle>
                </charts:RasterLineSeries>                
            </charts:Chart.Series>
    
            <charts:Chart.YAxis>
                <charts:LinearAxis x:Name="PrimaryAxis" LabelPosition="Inside"/>
            </charts:Chart.YAxis>
            <charts:Chart.SecondaryYAxis>
                <charts:LinearAxis LabelPosition="Inside" 
                     Range="{Binding ElementName=PrimaryAxis, Path=ActualRange}"
                     Zoom="{Binding ElementName=PrimaryAxis, Path=Zoom}" 
                     AutoScaleToVisibleData="False"/>
            </charts:Chart.SecondaryYAxis>
        </charts:Chart>
    </Grid>
    

    And the code file:

    using System;
    using System.Windows;
    using Visiblox.Charts;
    
    namespace Graphs
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class VBGraph : Window
        {
            public VBGraph()
            {
                InitializeComponent();
            }
    
            private void draw()
            {
                if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
                    return;
                Random r = new Random();
                DataSeries<double, double> xData = new DataSeries<double, double>();
                for (int i = 0; i < 500; i++)
                {
                    xData.Add(new DataPoint<double, double>() { X = (double)r.Next((int)ActualWidth), Y = (double)r.Next((int)ActualHeight) });
                }
                Chart.Series[0].DataSeries = xData;
            }
    
            private void Window_Loaded(object sender, RoutedEventArgs e)
            {
                draw();
            }
    
            private void Window_SizeChanged(object sender, SizeChangedEventArgs e)
            {
                draw();
            }
        }
    }