Page 1 of 1

Chart synchronization

Posted: Tue Feb 13, 2007 5:13 pm
by 9639223
Hi, I've got a problem.

I've got a form with two charts. One of them displays current function values (say, f(x)) using FastLine series, and the other displays the history of the function (f(x, t), x is in the same range as in the first chart) using ColorGrid series. So the X axis is of the same range in both charts, and Y is different.

When user zooms one of the charts, the other one should adjust display window to contain the area of the chart with the same range of x values. It was easy to implement this synchronization when user zooms the chart.

Code: Select all

		private void tChart_UndoneZoom(object sender, System.EventArgs e)
		{
			TChart other = (sender != tChart1) ? tChart1 : tChart2;
			other.UndoneZoom -= new EventHandler(tChart_UndoneZoom);
			other.Zoom.Undo();
			other.UndoneZoom += new EventHandler(tChart_UndoneZoom);
		}

		private void tChart_Zoomed(object sender, System.EventArgs e)
		{
			TChart current = (TChart)sender;
			TChart other = (current != tChart1) ? tChart1 : tChart2;
			Zoom zoom = current.Zoom;
			Rectangle chartRect = other.Chart.ChartRect;
			other.Zoomed -= new EventHandler(tChart_Zoomed);
			other.Zoom.ZoomRect(new Rectangle(zoom.x0, chartRect.Y, zoom.x1 - zoom.x0, chartRect.Height));
			other.Zoomed += new EventHandler(tChart_Zoomed);
		}
But I didn't find a way to perform adjustment when user scrolls zoomed or unzoomed chart. I'm able to track scrolling by handling Scroll event, but I've no idea of how to adjust the other chart.

Thanks in advance,
Alexander

Posted: Wed Feb 14, 2007 2:24 pm
by narcis
Hi Alexander,

To achieve what you request you can do something like in the example below. A couple of things that should be considered:

1. Notice that default's chart scrolling has been disabled because we found that scrolling to the left and to the top wasn't working very well and this caused chart's not being synchronized. We will try to fix this ASAP.

2. You'll also notice that the chart where scroll is applied doesn't repaint correctly. We found that when there are 2 charts in the same form and both having to repaint some problems occur. We will also try to fix this issue ASAP.

Code: Select all

        private void Form1_Load(object sender, EventArgs e)
        {
						line1.FillSampleValues();
            line2.FillSampleValues();            

            tChart1.Zoomed+=new EventHandler(tChart1_Zoomed);
            tChart1.UndoneZoom+=new EventHandler(tChart1_UndoneZoom);
						tChart1.MouseDown += new MouseEventHandler(tChart1_MouseDown);
						tChart1.MouseMove += new MouseEventHandler(tChart1_MouseMove);
						tChart1.MouseUp += new MouseEventHandler(tChart1_MouseUp);

						tChart2.Zoomed += new EventHandler(tChart1_Zoomed);
						tChart2.UndoneZoom += new EventHandler(tChart1_UndoneZoom);
						tChart2.MouseDown += new MouseEventHandler(tChart1_MouseDown);
						tChart2.MouseMove += new MouseEventHandler(tChart1_MouseMove);
						tChart2.MouseUp += new MouseEventHandler(tChart1_MouseUp);

						tChart1.Panning.Allow = ScrollModes.None;
						tChart2.Panning.Allow = ScrollModes.None;
        }

        private int X0 = -1;
        private int Y0 = -1;
        
        void tChart1_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                X0 = e.X;
                Y0 = e.Y;
            }
        }

        void tChart1_MouseMove(object sender, MouseEventArgs e)
				{
					if ((X0 != -1) && (Y0 != -1))
					{
				
						TChart current = (TChart)sender;
						TChart other = (sender != tChart1) ? tChart1 : tChart2;

						double cXOffset = current.Axes.Bottom.CalcPosPoint(e.X) - current.Axes.Bottom.CalcPosPoint(X0);
						double cYOffset = current.Axes.Left.CalcPosPoint(e.Y) - current.Axes.Left.CalcPosPoint(Y0);

						double oXOffset = other.Axes.Bottom.CalcPosPoint(e.X) - other.Axes.Bottom.CalcPosPoint(X0);
						double oYOffset = other.Axes.Left.CalcPosPoint(e.Y) - other.Axes.Left.CalcPosPoint(Y0);
						
						current.Axes.Bottom.Automatic = false;
						current.Axes.Bottom.Minimum -= cXOffset;
						current.Axes.Bottom.Maximum -= cXOffset;

						current.Axes.Left.Automatic = false;
						current.Axes.Left.Minimum -= cYOffset;
						current.Axes.Left.Maximum -= cYOffset;
						
						other.Axes.Bottom.Automatic = false;
						other.Axes.Bottom.Minimum -= oXOffset;
						other.Axes.Bottom.Maximum -= oXOffset;

						other.Axes.Left.Automatic = false;
						other.Axes.Left.Minimum -= oYOffset;
						other.Axes.Left.Maximum -= oYOffset;

						X0 = e.X;
						Y0 = e.Y;
					}
        }

        void tChart1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {							
							X0 = -1;
							Y0 = -1;							
            }
        }

        private void tChart1_UndoneZoom(object sender, EventArgs e)
        {
						TChart current = (TChart)sender;
            TChart other = (sender != tChart1) ? tChart1 : tChart2;

						current.Axes.Left.Automatic = true;
						current.Axes.Bottom.Automatic = true;

						other.Axes.Left.Automatic = true;
						other.Axes.Bottom.Automatic = true;
						//other.UndoneZoom -= new EventHandler(tChart1_UndoneZoom);
						//other.Zoom.Undo();
						//other.UndoneZoom += new EventHandler(tChart1_UndoneZoom); 
        }

        private void tChart1_Zoomed(object sender, EventArgs e)
        {
            TChart current = (TChart)sender;
            TChart other = (current != tChart1) ? tChart1 : tChart2;
            Zoom zoom = current.Zoom;
            Rectangle chartRect = other.Chart.ChartRect;
            other.Zoomed -= new EventHandler(tChart1_Zoomed);
            other.Zoom.ZoomRect(new Rectangle(zoom.x0, chartRect.Y, zoom.x1 - zoom.x0, chartRect.Height));
            other.Zoomed += new EventHandler(tChart1_Zoomed); 
        }