Move series per drag&drop
Posted: Thu Jan 21, 2010 4:19 pm
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:
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!
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();
}
How can i achieve a better behaviour to move a series per drag&drop without refreshing the chart?
Thanks in advance!