Page 1 of 1

Move series per drag&drop

Posted: Thu Jan 21, 2010 4:19 pm
by 13049497
Hello,

i have a chart with some fastline series and a lot of data in some cases (>10.000 each series). Now i want to give the user the opportunity to move a series with the mouse in the chart per drag&drop. During the move, the series should follow the mouse and at the end the original series, x and y values, should be refreshed with the new offset. I have found a solution in this thread to implement this feature. Problem is, that in this solution the chart is refreshed on every mousevove. With many series and a lot of data this doesn't look fine and is to slow. I want to use a solution, where the chart isn`t refreshed and only the series is following the mouse like in the cursortool with fastcursor = true.
My current code looks like that:

Code: Select all

Steema.TeeChart.TChart tChart1 = new Steema.TeeChart.TChart();
        Steema.TeeChart.Styles.FastLine line1 = new Steema.TeeChart.Styles.FastLine();
        Steema.TeeChart.Styles.FastLine line2 = new Steema.TeeChart.Styles.FastLine();
        private bool clicked;
        private int origX, origY, X, Y, Index;
        Bitmap bitmap;

        public Form1()
        {
            InitializeComponent();
            this.Controls.Add(tChart1);
            tChart1.Dock = DockStyle.Fill;
            tChart1.Aspect.View3D = false;
            tChart1.Zoom.Allow = false;
            tChart1.Series.Add(line1);
            tChart1.Series.Add(line2);
            tChart1.MouseMove +=new MouseEventHandler(tChart1_MouseMove);
            tChart1.MouseUp +=new MouseEventHandler(tChart1_MouseUp);

            line1.FillSampleValues(600000);
            line2.FillSampleValues(600000);

            for (int i = 0; i < tChart1.Series.Count; i++)
            {
                tChart1[i].Click += new MouseEventHandler(Series_Click);
            }
        }

        // user clickes on a series
        void Series_Click(object sender, MouseEventArgs e)
        {
            SetClicked(e.X, e.Y, tChart1.Series.IndexOf(sender as Steema.TeeChart.Styles.Series));
        }

        // create thread to create a bitmap of this series
        private void SetClicked(int X, int Y, int i)
        {
            clicked = true;
            origX = X;
            origY = Y;
            if (i != Index)
            {
                bitmap = null;
                Index = i;
            }
            if (bitmap == null)
            {
                System.Threading.Thread ta = new System.Threading.Thread(delegate()
                            {
                                CreateBitmap();
                            });

                ta.IsBackground = true;
                ta.Start();
            }
        }

        // create a bitmap of the current selected series
        private void CreateBitmap()
        {
            Bitmap tempBitmap = new Bitmap((int)(tChart1.Width - tChart1.Panel.MarginLeft - tChart1.Panel.MarginRight), (int)(tChart1.Height - tChart1.Panel.MarginTop - tChart1.Panel.MarginBottom));
            Graphics g = Graphics.FromImage(tempBitmap);

            Steema.TeeChart.Styles.Series s = tChart1[Index];
            Pen pen = new Pen(s.Color);
            for (int j = 0; j < s.Count - 1; j++)
            {
                Point p0 = new Point(s.CalcXPos(j), s.CalcYPos(j));
                Point p1 = new Point(s.CalcXPos(j + 1), s.CalcYPos(j + 1));
                g.DrawLine(pen, p0, p1);
            }

            bitmap = tempBitmap;            
        }

        private void tChart1_MouseMove(object sender, MouseEventArgs e)
        {
            if (clicked)
            {
                X = e.X;
                Y = e.Y;
                if (bitmap != null)
                {
                    tChart1.Graphics3D.BackBuffer.Render(); // draw the chart without the dragged and moved series (bitmap)
                    tChart1.Graphics3D.Draw(X - origX, Y - origY, bitmap); // draw the bitmap of the selected series                    
                }
            }
        }

        // user drops a series
        private void tChart1_MouseUp(object sender, MouseEventArgs e)
        {
            clicked = false;
            if (X != origX || Y != origY)
            {
                System.Threading.Thread ta = new System.Threading.Thread(delegate()
                               {
                                   MoveChart();
                               });

                ta.IsBackground = true;
                ta.Start();
            }
        }

        // move each point with the new offset
        private void MoveChart()
        {
            double xDiff = tChart1.Axes.Bottom.CalcPosPoint(X) - tChart1.Axes.Bottom.CalcPosPoint(origX);
            double yDiff = tChart1[Index].GetVertAxis.CalcPosPoint(Y) - tChart1[Index].GetVertAxis.CalcPosPoint(origY);

            tChart1.AutoRepaint = false;
            tChart1.SuspendLayout();
            tChart1[Index].BeginUpdate();
            for (int i = 0; i < tChart1[Index].XValues.Count; i++)
            {
                tChart1[Index].XValues[i] += xDiff;
                tChart1[Index].YValues[i] += yDiff;
            }

            tChart1[Index].EndUpdate();
            tChart1.ResumeLayout();
            tChart1.AutoRepaint = true;
            tChart1.Invalidate();
        }
The soltuion is not realy good, because the series which follows the mouse flickers a little bit :(
How can i achieve a better behaviour to move a series per drag&drop without refreshing the chart?

Thanks in advance!

Re: Move series per drag&drop

Posted: Fri Jan 22, 2010 11:14 am
by narcis
Hi AIS,

In that case you can try repainting only a portion of the chart as explained in this thread.

Hope this helps!

Re: Move series per drag&drop

Posted: Fri Jan 22, 2010 1:18 pm
by 13049497
Hello NarcĂ­s,

i dont use v4 of TChart, i use v3.5 and i try the postet solution of the linked thread. The region which is automatic redrawn (only the annotation) through invalidate, causes also a high delay of the cursorttool (fastcursor true/false), that doesn't look good. I think this can not be a solution for me, but i don't know what the BufferStyle can do, because in v3.5 this memeber doesn't exist. Are there any other ways to get a better behaviour?

Thanks in advance.

Re: Move series per drag&drop

Posted: Mon Jan 25, 2010 10:11 am
by 10050769
Hello AIS,


I checked BufferStyle property using last version3 of TeeChart.Newt and, I find it. I recommend updating version3 with last version and retry to do that Narcis commented in last post. If problem still appears please let know and we try to find a solution for the problem.

Thanks,

Re: Move series per drag&drop

Posted: Mon Jan 25, 2010 12:21 pm
by 13049497
Hello Sandra,

i could not update to v4 yet, because a lot of testing must be done after that to ensure the same functionality. Thanks anyway, i will try it next time ;)

Re: Move series per drag&drop

Posted: Mon Jan 25, 2010 12:27 pm
by narcis
Hi AIS,

I think Sandra meant that you could try using latest TeeChart for .NET v3 build available at the client area. It includes BufferStyle property but not all functionality described in the thread I pointed.