Search code examples
winformschartsdevexpressxtrachart

Keep different Secondary Axis linked in Devexpress XtraCharts control


My setup is like this: I have multiple panes (16) in a chart control, and each pane has to have its own X axis because each pane can have different strips and strips seem to be linked to the axis itself, not the pane or the series (weird).

This is what it looks like: https://i.sstatic.net/UycPf.png. You can see the strips which represent dropped packets for each channel, and they're by definition different across channels.

Now my problem is that I also need to support zooming and panning (which is done), but my X axis has to keep in sync across all panes. Basically if I zoom in on a certain point in time, every pane has to zoom in there.

How do I achieve that without sharing an X axis? Or how do I achieve per-pane strips while sharing an X axis? Either way would solve my problem.


Solution

  • You can use ChartControl.AxisVisualRangeChanged event to update zoom of each axis. Just set for each axis VisualRange.Auto = false and VisualRange.AutoSideMargins = false.
    Here is example for SwiftPlotDiagram:

    private void chartControl1_AxisVisualRangeChanged(object sender, AxisRangeChangedEventArgs e)
    {
        var axisX = e.Axis as SwiftPlotDiagramAxisXBase;
    
        if (axisX == null)
            return;
    
        var diagram = (SwiftPlotDiagram)chartControl1.Diagram;
    
        UpdateVisualRange(axisX, diagram.AxisX);
    
        foreach (SwiftPlotDiagramAxisXBase secondaryAxisX in diagram.SecondaryAxesX)
            UpdateVisualRange(axisX, secondaryAxisX);
    }
    
    private void UpdateVisualRange(SwiftPlotDiagramAxisXBase axisFrom, SwiftPlotDiagramAxisXBase axisTo)
    {
        if (axisTo != axisFrom)
        {
            var rangeFrom = axisFrom.VisualRange;
            var rangeTo = axisTo.VisualRange;
    
            if (!rangeTo.MinValue.Equals(rangeFrom.MinValue) || !rangeTo.MaxValue.Equals(rangeFrom.MaxValue))
                rangeTo.SetMinMaxValues(rangeFrom.MinValue, rangeFrom.MaxValue);
        }
    }