Panning and Zooming

Oystein Bjorke 6 лет назад 0
This discussion was imported from CodePlex

JuergenD wrote at 2012-11-07 15:51:

Hi, thanks for this great Plot-Library!

I have a question about panning and zooming charts. I have a time series with data for every day for about ten years. I created a simple line chart with this data and everything looks nice. But I have a problem with the zoom/pan feature. 

Using the Mousewheel or the +/- Key zooms the chart in both directions (x and y axis). But I need the zoom only on the x-axis and the y-axis should scale itself automatically by the new min/max values inside the chart window. 

Also panning the chart left/right with the cursor keys should rescale the y-axis.

Is this possible?

Best Regards

objo wrote at 2012-11-07 16:15:

Sorry, this is not supported 'out of the box'.

You could subscribe to the x-axis change event, then find the minimum and maximum y-values for the visible part of the curve (you have to write this yourself).
Then update the minimum and maximum properties of the y-axis and refresh the plot.

This should work for both mouse and keyboard events.

JuergenD wrote at 2012-11-08 09:31:

Oh wow, that was quick :-) Thanks for your fast response.

I will try to add your suggestions to my code. Thanks for your help.

JuergenD wrote at 2012-11-08 13:22:

Ok, I was playing around with the code but without success. How can I update the min/max Values of the y-axis?

I can access the min/max DateTime Values from the visible range inside the change event like so

void xAxisDateTime_AxisChanged(object sender, AxisChangedEventArgs e) {
    DateTimeAxis axis = sender as DateTimeAxis;
    DateTime dtMax = DateTime.FromOADate(axis.ActualMaximum);
    DateTime dtMin = DateTime.FromOADate(axis.ActualMinimum);

But when I try to update the min/max values of the y-axis with new values I already retrieved from my data:

myYAxis.Minimum = GetMin(dtMin, dtMax);
myYAxis.Maximum = GetMax(dtMin, dtMax);

nothing happens. How can I refresh the chart?
By the way, I am using class variables (myPlot, myYAxis) to access the plot components. Is it possible to get access to the components via the "sender" object? I am in the X-Axis event handler. How can I access the Y-Axis or the series of my plotmodel without using class variables?

Best Regards

JohnnyPP wrote at 2012-11-13 21:15:



what is the status of this thread? I am also very interested in the feature that zooms only the x-axis and the y-axis scales itself automatically by the new min/max values inside the chart window.


Kind regards,


JuergenD wrote at 2012-11-14 09:48:


The status is unchanged. Unfortunately I got no response from the author anymore.

The current implemented zoom/pan feature feels more like a zoom/pan inside a drawing software like Photoshop. In my opinion it makes no sense to zoom/pan a chart this way. It is pretty useless to see areas of my chart without the function graph or data series. Therefore I would prefer an option to force the chart to show always a piece of my function and disable the possibility to pan or zoom to an area where the function or the dataseries does not exist.

I would need an example or information about how I can change the min/max values for the y-axis and then force a redraw of the chart. It does not work with the method I already tested (see my prev. message). 

Another problem is to get access to the y-axis and the series from inside x-axis event handler. I can use "global" class variables, but this is a bit clumsy...

Please let me know when you get any further information. 

Best Regards,

objo wrote at 2012-11-14 18:36:

The Minimum and Maximum properties are overridden by the ViewMaximum and ViewMinimum properties (which are set when you pan/zoom your axes). You can

a) call Reset() then set Minimum and Maximum on the y-axis


b) call Zoom(newMinimum,newMaximum) on the y-axis

Then call RefreshPlot as you do in your code.

JuergenD wrote at 2012-11-15 09:57:


No need to be sorry, the software is free and I am very grateful for your work :-)

Your last hint was the missing puzzle-piece for my code. I am using variant b and now I can pan the chart on the x-axis and the y-axis and the function plot redraws perfectly. I have to fine tune the performance of my seek min/max method for really large data series, but that should be easy...

Many Thanks for your help

and best regards


JohnnyPP wrote at 2012-11-15 20:20:

Hello Juergen,


would it be possible for you to post your solution to the forum? It would help me a lot.

Thanks in advance!



JuergenD wrote at 2012-11-16 10:00:


My program is rather to big to publish it here. But I wrote a small example, with my "solution". It is not perfect, but it works for me.
Create a new Windows Form Solution named SimpleChart, add  an OxyPlot.WindowsForms.Plot control on your form, change the Layout.Doc property from None to Fill and use my code inside form1.cs.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using OxyPlot;

namespace SimpleChart {
    public partial class Form1 : Form {
        //I am using a small helper class for my date/value pairs
        //providing an IComparable Interface for using BinarySearch
        //in the x-axis change event
        class MyValue : IComparable {
            public DateTime Date { get; set; }
            public double Value { get; set; }
            public MyValue(DateTime d) {
                Date = new DateTime(d.Year, d.Month, d.Day);
            public MyValue(DateTime d, double v) {
                Date = new DateTime(d.Year, d.Month, d.Day);
                Value = v;
            int IComparable.CompareTo(object to) {
                return Date.CompareTo(((MyValue)to).Date);
        DateTimeAxis xAxisDateTime;
        LinearAxis yAxisValues;
        List<MyValue> myValues;
        PlotModel plotModel;
        LineSeries lineSeries;

        public Form1() {

            myValues = new List<MyValue>();
            DateTime startDate = new DateTime(2000, 1, 1);
            double startValue = 100;
            Random r = new Random();
            for (int i = 0; i < 1000; i++, startDate = startDate.AddDays(1), startValue += (r.NextDouble() - 0.5)) {
                myValues.Add(new MyValue(startDate, startValue));

            plotModel = new PlotModel("Chart");

            xAxisDateTime = new DateTimeAxis() { 
                IntervalType = DateTimeIntervalType.Auto, 
                MinorIntervalType = DateTimeIntervalType.Days, 
                MajorGridlineStyle = LineStyle.Solid, 
                MinorGridlineStyle = LineStyle.Dot, 
                CalendarWeekRule = System.Globalization.CalendarWeekRule.FirstFourDayWeek, 
                FirstDayOfWeek = DayOfWeek.Monday, 
                Position = AxisPosition.Bottom 
            //Set the min/max values of the x-axis to my min/max date to prevent zoom/pan beyond data series
            xAxisDateTime.AbsoluteMinimum = myValues[0].Date.ToOADate();
            xAxisDateTime.AbsoluteMaximum = myValues[myValues.Count - 1].Date.ToOADate();
            //calling user defined event on change
            xAxisDateTime.AxisChanged += xAxisDateTime_AxisChanged;

            yAxisValues = new LinearAxis() { 
                MajorGridlineStyle = LineStyle.Solid, 
                MinorGridlineStyle = LineStyle.Dot 


            lineSeries = new LineSeries {
                Title = "Values",
                Color = OxyColor.FromArgb(255, 78, 154, 6),
                MarkerType = MarkerType.None,
                StrokeThickness = 1,
                DataFieldX = "Date",
                DataFieldY = "Value",
                ItemsSource = myValues

            plot1.Model = plotModel;


        void xAxisDateTime_AxisChanged(object sender, AxisChangedEventArgs e) {
            DateTimeAxis axis = sender as DateTimeAxis;

            //save the current min/max date values
            DateTime dtMax = DateTime.FromOADate(axis.ActualMaximum);
            DateTime dtMin = DateTime.FromOADate(axis.ActualMinimum);

            double minValue = double.MaxValue;
            double maxValue = double.MinValue;

            //BinarySearch, because the xAxisDateTime is sorted
            int idxMin = myValues.BinarySearch(new MyValue(dtMin));
            int idxMax = myValues.BinarySearch(new MyValue(dtMax));

            //if we can not find an exact location (result is negativ) we can use the complement 
            //see BinarySearch help for further explanation
            if (idxMin < 0) idxMin = ~idxMin;
            if (idxMax < 0) idxMax = ~idxMax;

            //find the corresponding min/max values in the selected intervall
            for (int i = idxMin; i < idxMax; i++) {
                minValue = Math.Min(minValue, myValues[i].Value);
                maxValue = Math.Max(maxValue, myValues[i].Value);

            //set y-axis min/max and redraw the chart
            yAxisValues.Zoom(minValue, maxValue);

When running the program, you have first to zoom (mouse wheel or ctrl-right mouse button) inside the chart to use the x-axis pan feature (drag with right mouse button or use cursor keys), because if it is "unzoomed" you already see the whole chart and cannot pan beyond valid x/y pairs. Ctrl-Double-Click with Right mouse button brings back the whole chart.

Hope that helps
bet regards


endorphing wrote at 2013-10-08 17:18:

I believe there's a property called 'IsZoomEnabled' in the Axis (in the WPF version), that lets you disable zooming in a particular direction.

Gubo wrote at 2014-03-19 10:34:

I think it does not work 100% accurately because instead of DateTime.FromOADate() you should use DateTimeAxis.ToDateTime(). There is a one day difference for some reason.

jackRose wrote at 2014-05-06 13:18:

I think it's very important feature - the zoom only on the x-axis or the y-axis. The best choice +/- for zooming and mouse wheel for panning. I will try to use info from this topic, but I hope it will be supported 'out of the box'. Oxyplot is really fantastic graphic library, but it needs to get this feature.

In any case thank you for great job!

Сервис поддержки клиентов работает на платформе UserEcho