Interactive data point selection?
-
- Newbie
- Posts: 64
- Joined: Fri Jun 16, 2006 12:00 am
Interactive data point selection?
Hi,
I'm trying to figure out how to provide the following feature to my users. Let's say I have a scatter plot displayed (a Points series). The user wants to select a number of points by clicking and dragging the mouse. Selected points will then be retrieved and some additional information about them will be provided in a separate window.
How can I achieve this?
Best,
Michal Blazejczyk
I'm trying to figure out how to provide the following feature to my users. Let's say I have a scatter plot displayed (a Points series). The user wants to select a number of points by clicking and dragging the mouse. Selected points will then be retrieved and some additional information about them will be provided in a separate window.
How can I achieve this?
Best,
Michal Blazejczyk
Best,
Michal Blazejczyk
Lead Programmer
Genome Quebec
Michal Blazejczyk
Lead Programmer
Genome Quebec
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi Michal,
Yes, you need to do this manually using chart events, for example:
Yes, you need to do this manually using chart events, for example:
Code: Select all
private void Form1_Load(object sender, EventArgs e)
{
tChart1.Aspect.View3D = false;
points1.FillSampleValues();
tChart1.Panning.MouseButton = MouseButtons.Middle;
ResetCoords();
}
private void ResetCoords()
{
X0 = -1;
Y0 = -1;
}
private int X0, Y0;
private void tChart1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
X0 = e.X;
Y0 = e.Y;
}
}
private void tChart1_MouseUp(object sender, MouseEventArgs e)
{
listBox1.Items.Clear();
if ((X0 != -1) && (Y0 != -1))
{
for (int i = 0; i < points1.Count; i++)
{
if ((points1.CalcXPos(i) >= X0) && (points1.CalcXPos(i) <= e.X) &&
(points1.CalcYPos(i) >= Y0) && (points1.CalcYPos(i) <= e.Y))
{
listBox1.Items.Add("Point " + i.ToString() + ": " + points1.XValues[i].ToString() +
", " + points1.YValues[i].ToString());
}
}
ResetCoords();
}
}
private void tChart1_MouseMove(object sender, MouseEventArgs e)
{
if ((X0 != -1) && (Y0 != -1))
{
tChart1.Graphics3D.Brush.Visible = false;
tChart1.Graphics3D.Pen.Color = Color.Black;
tChart1.Graphics3D.Rectangle(X0, Y0, e.X, e.Y);
}
}
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
-
- Newbie
- Posts: 64
- Joined: Fri Jun 16, 2006 12:00 am
Hi,
I found a way that is easier to program:
It works very well because, as the Help says:
Best,
Michal
I found a way that is easier to program:
Code: Select all
private void OnZoomed( object sender, System.EventArgs e )
{
// Here, _chart.Axes.Bottom.Minimum, _chart.Axes.Bottom.Maximum
// _chart.Axes.Left.Minimum, and _chart.Axes.Left.Maximum
// delimit the selected area.
// Do whatever needs to be done...
_chart.Zoom.Undo();
}
This event gets called BEFORE the Chart class is repainted to show the new Axis scales.
Best,
Michal
Best,
Michal Blazejczyk
Lead Programmer
Genome Quebec
Michal Blazejczyk
Lead Programmer
Genome Quebec
I'm looking for the same kind of behaviour, but I have found some problems with both the above methods. The "simple one" implementing OnZoomed will unzoom any previously zooming. I want my users to be able to zoom AND select lines. So let's say they have zoomed on an area, and then tries to select some lines, Zoom.Undo() will reset the zoom.
The other example (overriding mouseUp/down/move seems to work, but the drawn box disappers as soon as the mousepointer remains on the same spot for a short while. I would like the box to always be shown (like the zoom box).
Has anyone implemented such a solution?
Regards Andreas
The other example (overriding mouseUp/down/move seems to work, but the drawn box disappers as soon as the mousepointer remains on the same spot for a short while. I would like the box to always be shown (like the zoom box).
Has anyone implemented such a solution?
Regards Andreas
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi Andreas,
Yes, this can be achieved using TeeChart's AfterDraw event and something like this:
Yes, this can be achieved using TeeChart's AfterDraw event and something like this:
Code: Select all
private void Form1_Load(object sender, EventArgs e)
{
tChart1.Aspect.View3D = false;
points1.FillSampleValues();
tChart1.Panning.MouseButton = MouseButtons.Middle;
ResetCoords();
}
private void ResetCoords()
{
X0 = -1;
Y0 = -1;
}
private int X0, Y0, X1, Y1;
private void tChart1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
X0 = e.X;
Y0 = e.Y;
}
}
private void tChart1_MouseUp(object sender, MouseEventArgs e)
{
listBox1.Items.Clear();
if ((X0 != -1) && (Y0 != -1))
{
for (int i = 0; i < points1.Count; i++)
{
if ((points1.CalcXPos(i) >= X0) && (points1.CalcXPos(i) <= e.X) &&
(points1.CalcYPos(i) >= Y0) && (points1.CalcYPos(i) <= e.Y))
{
listBox1.Items.Add("Point " + i.ToString() + ": " + points1.XValues[i].ToString() +
", " + points1.YValues[i].ToString());
}
}
ResetCoords();
}
}
private void tChart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
X1 = e.X;
Y1 = e.Y;
}
tChart1.Invalidate();
}
private void tChart1_AfterDraw(object sender, Steema.TeeChart.Drawing.Graphics3D g)
{
if ((X0 != -1) && (Y0 != -1))
{
g.Brush.Visible = false;
g.Pen.Color = Color.Black;
g.Rectangle(X0, Y0, X1, Y1);
}
}
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Oh, great, I came up with something similiar (using the OnPaint) method, but I changed to use After draw. However, tChart1.Invalidate(); should be done inside if(e.Button == MouseButtons.Right), otherwise the zoombox (leftclicking and dragging) will flipp out... (don't ask me why) =)
Well, my problem is solved.
My code for checking if any point/line is selected is this:
foreach (Line line in Series)
{
for (int i = 0; i < line.Count; i++)
{
if ((line.CalcXPos(i) >= X0) && (line.CalcXPos(i) <= e.X) &&
(line.CalcYPos(i) >= Y0) && (line.CalcYPos(i) <= e.Y))
{
// Found a selected point, add it to some collection
break;
}
}
}
I haven't played with a large scale of lines yet, but I guess this method could become timeconsuming... or? Is there a better way? I need to know witch lines my "selection box" includes.
Well, my problem is solved.
My code for checking if any point/line is selected is this:
foreach (Line line in Series)
{
for (int i = 0; i < line.Count; i++)
{
if ((line.CalcXPos(i) >= X0) && (line.CalcXPos(i) <= e.X) &&
(line.CalcYPos(i) >= Y0) && (line.CalcYPos(i) <= e.Y))
{
// Found a selected point, add it to some collection
break;
}
}
}
I haven't played with a large scale of lines yet, but I guess this method could become timeconsuming... or? Is there a better way? I need to know witch lines my "selection box" includes.
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi Wicket,
Thanks in advance.
Yes, you are right. I can't think of a better way to achieve that at the moment.I haven't played with a large scale of lines yet, but I guess this method could become timeconsuming... or? Is there a better way?
Sorry but I don't understand what do you exactly mean. Could you please give us some more information?I need to know witch lines my "selection box" includes.
Thanks in advance.
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |
Lets say I have 10 lines drawn on the chart. Then I make a 'selectionbox'. After releasing the mousebutton I want to find out witch of my 10 lies that passes through the box. As my implementation is made right now, I'm only checking the points of the lines, so if a line is passing through the box, but doesn't have a point inside the box, the line will not be selected.
In fact, individual points are not interested for me at all, it's either the complete line or nothing at all. So if there exist a mote efficient way to tell if some part of a line (serie) passes through a rectangualr box, I'd be glad to hear about it.
Regards Andreas
In fact, individual points are not interested for me at all, it's either the complete line or nothing at all. So if there exist a mote efficient way to tell if some part of a line (serie) passes through a rectangualr box, I'd be glad to hear about it.
Regards Andreas
-
- Site Admin
- Posts: 14730
- Joined: Mon Jun 09, 2003 4:00 am
- Location: Banyoles, Catalonia
- Contact:
Hi Andreas,
To achieve what you request you should implement MouseUp event as shown below. To optimize the implementation you could add an array and mark which series have been already selected and check this before doing redundant processing.
To achieve what you request you should implement MouseUp event as shown below. To optimize the implementation you could add an array and mark which series have been already selected and check this before doing redundant processing.
Code: Select all
private void tChart1_MouseUp(object sender, MouseEventArgs e)
{
listBox1.Items.Clear();
if ((X0 != -1) && (Y0 != -1))
{
for (int x = X0; x <= X1; x++)
for (int y = Y0; y <= Y1; y++)
for (int i = 0; i < tChart1.Series.Count; i++)
if (tChart1[i].Clicked(x, y) != -1)
listBox1.Items.Add(tChart1[i].Title);
ResetCoords();
}
}
Best Regards,
Narcís Calvet / Development & Support Steema Software Avinguda Montilivi 33, 17003 Girona, Catalonia Tel: 34 972 218 797 http://www.steema.com |
Instructions - How to post in this forum |