Hi,
We are working on a project that has very extensive use of interactive charts. There are lots of functionality in which user interacts with lines and points on graph. We are using "Tee Chart for .Net v2" and having difficulties to implement the following functionality:
1. Selecting a Line or Point and getting its object when there are a number of lines and points on the graph.
2. Dragging the selected Point Series, Point and Line on the graph using mouse.
3. Cloning selected item at some other location on the graph, which means when user presses mouse on some series or line, a copy of that object is created on the screen at the same position and then user drags the copy to some other position on the screen.
4. Mouse pointer must always be on the selected item while dragging.
5. We should be able to get the End Points in case of line and location in case of Points at any instance.
6. Rotation of line along any point on the line using mouse, i.e. user presses mouse at any point on the line and then, when user moves mouse, line rotates along a specific point on the line.
7. All the actions of dragging and rotation must be very smooth.
We have one more query that whether we can use "TeeChart for .Net v2" in a WPF application. If yes then how?
We are looking forward for your reply.
Best Regards
Yatendra
How to add user interaction in charts
Re: How to add user interaction in charts
Hi Amol,
However, using DragPoint tool, you won't be able to clone a series and select the new series directly, the "source" series is already selected so it is going to be dragged.
Furthermore, I'm not sure if you want to drag the whole series when this clone is created or only a point. If you want to drag the whole series, I'm afraid you shouldn't use the DragPoint tool and do all the work manually with Mouse events.
If you want to rotate a single series, tell us how exactly, and we will add the feature request in the wish list to be implemented in future releases.
The following example I think achieves most of the demands on these 3 points.Amol wrote:1. Selecting a Line or Point and getting its object when there are a number of lines and points on the graph.
2. Dragging the selected Point Series, Point and Line on the graph using mouse.
3. Cloning selected item at some other location on the graph, which means when user presses mouse on some series or line, a copy of that object is created on the screen at the same position and then user drags the copy to some other position on the screen.
However, using DragPoint tool, you won't be able to clone a series and select the new series directly, the "source" series is already selected so it is going to be dragged.
Furthermore, I'm not sure if you want to drag the whole series when this clone is created or only a point. If you want to drag the whole series, I'm afraid you shouldn't use the DragPoint tool and do all the work manually with Mouse events.
Code: Select all
public Form1()
{
InitializeComponent();
CreateChart();
InitializeChart();
}
private Steema.TeeChart.TChart tChart1;
private void CreateChart()
{
tChart1 = new Steema.TeeChart.TChart();
this.Controls.Add(tChart1);
tChart1.Dock = DockStyle.Fill;
Steema.TeeChart.Commander chartController1 = new Steema.TeeChart.Commander();
this.Controls.Add(chartController1);
chartController1.Chart = tChart1;
chartController1.Dock = DockStyle.Top;
}
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
for (int i = 0; i < 3; i++)
{
new Steema.TeeChart.Styles.Points(tChart1.Chart);
tChart1[tChart1.Series.Count - 1].FillSampleValues(10);
new Steema.TeeChart.Styles.Line(tChart1.Chart);
tChart1[tChart1.Series.Count - 1].FillSampleValues(10);
((Steema.TeeChart.Styles.Line)(tChart1[tChart1.Series.Count - 1])).Pointer.Visible = true;
}
tChart1.MouseDown += new MouseEventHandler(tChart1_MouseDown);
new Steema.TeeChart.Tools.DragPoint(tChart1.Chart);
}
void tChart1_MouseDown(object sender, MouseEventArgs e)
{
Rectangle rect = tChart1.Chart.ChartRect;
if (rect.Contains(e.X, e.Y))
{
int ValueIndex;
for (int SeriesIndex = 0; SeriesIndex < tChart1.Series.Count; SeriesIndex++)
{
ValueIndex = tChart1[SeriesIndex].Clicked(e.X, e.Y);
if (ValueIndex != -1)
{
tChart1.Header.Text = "SeriesIndex: " + SeriesIndex + ", ValueIndex: " + ValueIndex;
Keys modKey = Control.ModifierKeys;
if (modKey == Keys.Control)
{
Steema.TeeChart.Styles.CustomPoint clone = ((Steema.TeeChart.Styles.CustomPoint)tChart1[SeriesIndex].Clone());
clone.Pointer.Visible = true;
}
}
}
}
}
I'm not sure to understand it. If the code above isn't doing it, could you please give me more details?Amol wrote:4. Mouse pointer must always be on the selected item while dragging.
I'm not sure to understand the either. You can get the last point of a series with tChart1[SeriesIndex].YValue[tChart1[SeriesIndex].count-1] and the same for the XValue.Amol wrote:5. We should be able to get the End Points in case of line and location in case of Points at any instance.
The series are drawn respectively to their axes, and all the axes are all in the same panel. The panel can be rotated (you can use the rotate tool to do that) but then all the series will rotate at the same time.Amol wrote:6. Rotation of line along any point on the line using mouse, i.e. user presses mouse at any point on the line and then, when user moves mouse, line rotates along a specific point on the line.
If you want to rotate a single series, tell us how exactly, and we will add the feature request in the wish list to be implemented in future releases.
Feel free to check the demo above and tell us if it isn't smooth enough. Of course, as much series or points you'll have in your chart, slower will be the repaint process.Amol wrote:7. All the actions of dragging and rotation must be very smooth.
I'm afraid that TeeChart.WPF.dll was introduced in TeeChart for .NET v3 so you should upgrade it.Amol wrote:We have one more query that whether we can use "TeeChart for .Net v2" in a WPF application. If yes then how?
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: How to add user interaction in charts
Hi Yeray,
Thank You very much for your reply. Your suggestions are valuable.
1. You provided the code to drag a single point of series and told that dragging of a series have to be done manually using mouse events. It will be very helpful if you can provide the code for that.
2. As you said that there is no feature for rotating a single series in TeeChart currently. I am wondering whether it can be manually done with mouse events. If yes then, would you please provide a little code snippet to achieve that too.
I have downloaded “TeeChart for .Net v4 evaluation”. I am failing to add the TeeChart control in the Toolbox of Visual Studio 2008, so that I can drag and drop it to a WPF window. I also tried to add TeeChart control to WPF window manually (through xaml as well as C#) but it is not displayed on the window when I run it. Please suggest some way to do that.
For your information I did not forget to add the required assembly to my project.
Thank you once again.
Waiting for your reply….
Thank You very much for your reply. Your suggestions are valuable.
1. You provided the code to drag a single point of series and told that dragging of a series have to be done manually using mouse events. It will be very helpful if you can provide the code for that.
2. As you said that there is no feature for rotating a single series in TeeChart currently. I am wondering whether it can be manually done with mouse events. If yes then, would you please provide a little code snippet to achieve that too.
I have downloaded “TeeChart for .Net v4 evaluation”. I am failing to add the TeeChart control in the Toolbox of Visual Studio 2008, so that I can drag and drop it to a WPF window. I also tried to add TeeChart control to WPF window manually (through xaml as well as C#) but it is not displayed on the window when I run it. Please suggest some way to do that.
For your information I did not forget to add the required assembly to my project.
Thank you once again.
Waiting for your reply….
Re: How to add user interaction in charts
Hi Amol,
Anyway, taking the example above, where I modified all the points for the selected series with the same diffX and diffY values, the rotation you want to do will probably have to calculate a different diffX and diffY for each point in the series.
Here it is an example:Amol wrote:1. You provided the code to drag a single point of series and told that dragging of a series have to be done manually using mouse events. It will be very helpful if you can provide the code for that.
Code: Select all
public Window1()
{
InitializeComponent();
InitializeChart();
}
private Point MouseDwn;
private int draggingSeries;
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
for (int i = 0; i < 4; i++)
{
new Steema.TeeChart.WPF.Styles.FastLine(tChart1.Chart);
tChart1[i].FillSampleValues();
}
MouseDwn = new Point(-1, -1);
draggingSeries = -1;
tChart1.Zoom.Allow = false;
tChart1.MouseDown += new MouseButtonEventHandler(tChart1_MouseDown);
tChart1.MouseMove += new MouseEventHandler(tChart1_MouseMove);
tChart1.MouseUp += new MouseButtonEventHandler(tChart1_MouseUp);
}
void tChart1_MouseDown(object sender, MouseButtonEventArgs e)
{
MouseDwn = e.GetPosition(e.MouseDevice.Target);
int tmp;
for (int i = 0; i < tChart1.Series.Count; i++)
{
tmp = tChart1[i].Clicked(MouseDwn);
if (tmp != -1)
{
draggingSeries = i;
break;
}
}
}
void tChart1_MouseMove(object sender, MouseEventArgs e)
{
Point ActualMouse = e.GetPosition(e.MouseDevice.Target);
if (draggingSeries != -1)
{
if ((ActualMouse.X != MouseDwn.X) || (ActualMouse.Y != MouseDwn.Y))
{
double diffX = tChart1[draggingSeries].XScreenToValue(MouseDwn.X) - tChart1[draggingSeries].XScreenToValue(ActualMouse.X);
double diffY = tChart1[draggingSeries].YScreenToValue(MouseDwn.Y) - tChart1[draggingSeries].YScreenToValue(ActualMouse.Y);
for (int i = 0; i < tChart1[draggingSeries].Count; i++)
{
tChart1[draggingSeries].XValues[i] = tChart1[draggingSeries].XValues[i] - diffX;
tChart1[draggingSeries].YValues[i] = tChart1[draggingSeries].YValues[i] - diffY;
}
}
tChart1.Invalidate();
MouseDwn = ActualMouse;
}
}
void tChart1_MouseUp(object sender, MouseButtonEventArgs e)
{
MouseDwn = new Point(-1, -1);
draggingSeries = -1;
}
I'm not sure on what exact "rotation axis" would you like to use to rotate the selected series.Amol wrote:2. As you said that there is no feature for rotating a single series in TeeChart currently. I am wondering whether it can be manually done with mouse events. If yes then, would you please provide a little code snippet to achieve that too.
Anyway, taking the example above, where I modified all the points for the selected series with the same diffX and diffY values, the rotation you want to do will probably have to calculate a different diffX and diffY for each point in the series.
I'm afraid TeeChart.WPF.dll doesn't support designtime edition. You can't drop it from the toolbox but you can edit your .xaml as follows:Amol wrote:I am failing to add the TeeChart control in the Toolbox of Visual Studio 2008, so that I can drag and drop it to a WPF window. I also tried to add TeeChart control to WPF window manually (through xaml as well as C#) but it is not displayed on the window when I run it. Please suggest some way to do that.
Code: Select all
<Window x:Class="WpfNetTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="358" Width="707"
xmlns:teechart="clr-namespace:Steema.TeeChart.WPF;assembly=TeeChart.WPF">
<Grid>
<teechart:TChart x:Name="tChart1"/>
</Grid>
</Window>
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: How to add user interaction in charts
Hi Yeray,
Thank you for the suggestions.
But I still see that there are few issues that are not resolved yet.
1. As I told you that I am using “TeeChart for .Net v4 evaluation”. I do not see any assembly named “TeeChart.Wpf.dll” in that package. Which version of TeeChart did you use for the xaml example you provided? I am still failing to add chart to the window while using version4. I am using following xaml for adding TeeChart to window-
2. The rotation I required on series is exactly as I am explaining here. There will be exactly two visible pointers on the line. User can drag any of these points, anywhere on the line. To rotate the line user presses the mouse on either of these two points and then when he moves the mouse the line rotates along the other point.
3. So kind of you for providing the code to drag the series but my requirement is slightly different. You are trying to keep the whole line in the view while dragging and changing the properties of grid lines and axes. What I need is that, do not change the maximum and minimum of axes, just crop the portion of the line that goes beyond limits of axes that means we will be seeing only a portion of line if it goes beyond the axes limits and if it is dragged back in the view the whole line will again be visible.
Best Regards.
Waiting for your reply….
Thank you for the suggestions.
But I still see that there are few issues that are not resolved yet.
1. As I told you that I am using “TeeChart for .Net v4 evaluation”. I do not see any assembly named “TeeChart.Wpf.dll” in that package. Which version of TeeChart did you use for the xaml example you provided? I am still failing to add chart to the window while using version4. I am using following xaml for adding TeeChart to window-
Code: Select all
<Window x:Class="TChart2010InWPF.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:t="clr-namespace:Steema.TeeChart;assembly=TeeChart"
Title="Window2" Height="300" Width="300">
<Grid>
<t:TChart x:Name="tChart1">
</Grid>
</Window>
2. The rotation I required on series is exactly as I am explaining here. There will be exactly two visible pointers on the line. User can drag any of these points, anywhere on the line. To rotate the line user presses the mouse on either of these two points and then when he moves the mouse the line rotates along the other point.
3. So kind of you for providing the code to drag the series but my requirement is slightly different. You are trying to keep the whole line in the view while dragging and changing the properties of grid lines and axes. What I need is that, do not change the maximum and minimum of axes, just crop the portion of the line that goes beyond limits of axes that means we will be seeing only a portion of line if it goes beyond the axes limits and if it is dragged back in the view the whole line will again be visible.
Best Regards.
Waiting for your reply….
Re: How to add user interaction in charts
Hi Amol,
The dll should be in the installation folder, by default TeeChart for .NET 2010 EVAL or TeeChart for .NET 2010
What you could do is to force the axes not to be automatic any more, once they have been calculated the first time. So you could add the following at, for example, OnMouseDown event:
The installers that include the TeeChart.WPF.dll are the TeeChart for .NET v3 and up for Visual Studio .NET 2008 and up. Please check that you haven't installed the TeeChart .NET v4 for Visual Studio 2005 or 2003.Amol wrote:1. As I told you that I am using “TeeChart for .Net v4 evaluation”. I do not see any assembly named “TeeChart.Wpf.dll” in that package. Which version of TeeChart did you use for the xaml example you provided?
The dll should be in the installation folder, by default TeeChart for .NET 2010 EVAL or TeeChart for .NET 2010
Then, you should do something similar to what I tried to explain. Knowing the center of rotation point and the mouse position at MouseDown, you can calculate the initial angle. You should also calculate the same angle for the "actual" mouse position at OnMouseMove and this will give you the angle of rotation you have to apply to all the points. Just some trigonometry calculations.Amol wrote:2. The rotation I required on series is exactly as I am explaining here. There will be exactly two visible pointers on the line. User can drag any of these points, anywhere on the line. To rotate the line user presses the mouse on either of these two points and then when he moves the mouse the line rotates along the other point.
I haven't changed the axes properties as you can see in the code above. I just changed the lines values. What happens is that, by default, TeeChart axes are set to scale automatically to fill all the series visible.Amol wrote:3. So kind of you for providing the code to drag the series but my requirement is slightly different. You are trying to keep the whole line in the view while dragging and changing the properties of grid lines and axes. What I need is that, do not change the maximum and minimum of axes, just crop the portion of the line that goes beyond limits of axes that means we will be seeing only a portion of line if it goes beyond the axes limits and if it is dragged back in the view the whole line will again be visible.
What you could do is to force the axes not to be automatic any more, once they have been calculated the first time. So you could add the following at, for example, OnMouseDown event:
Code: Select all
tChart1.Axes.Bottom.Automatic = false;
tChart1.Axes.Left.Automatic = false;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: How to add user interaction in charts
Hi Yeray,
Thank you very much for your ideas and suggestions.
The code you provided for dragging of line works fine now, I am really thankful to you for that, yet there is some optimization needed to make the dragging faster, but I will try to sort it out myself.
The idea you given for the rotation of line is looking like that it will work fine and I will definitely try to implement it. But it will be so kind of you and of course very helpful for me if you can provide a little code example for that.
For your kind information I am using "TeeChart for .NET 2010 EVAL" and I rechecked the installation directory, but I could not find any assembly named"TeeChart.WPF.dll". The only relevant dll I found there is "TeeChart.dll" and I am still failing to use it with WPF.
I really appreciate your quick response on my queries.
Best Regards for you...
Thank you very much for your ideas and suggestions.
The code you provided for dragging of line works fine now, I am really thankful to you for that, yet there is some optimization needed to make the dragging faster, but I will try to sort it out myself.
The idea you given for the rotation of line is looking like that it will work fine and I will definitely try to implement it. But it will be so kind of you and of course very helpful for me if you can provide a little code example for that.
For your kind information I am using "TeeChart for .NET 2010 EVAL" and I rechecked the installation directory, but I could not find any assembly named"TeeChart.WPF.dll". The only relevant dll I found there is "TeeChart.dll" and I am still failing to use it with WPF.
I really appreciate your quick response on my queries.
Best Regards for you...
Re: How to add user interaction in charts
Hi Amol,
Here it is the list of the latest evaluation installers: All them, by default, install the library in the "TeeChart for .NET 2010 EVAL" folder, but only the following contain the TeeChart.WPF.dll:
- TeeChartNET2010VSNET2010Eval_4.1.2010.08047.exe
- TeeChartNET2010VSNET2005WPFEval_4.1.2010.08045.exe
- TeeChartNET2010VSNET2008Eval_4.1.2010.08046.exe
First of all, I said that TeeChart.WPF.dll is included in the installers for Visual Studio .NET 2008 and up, but there is a TeeChart.WPF.dll for Visual Studio .NET 2005 too. But note that it is given in a separate installer because its possible to build WPF projects in Visual Studio .NET 2005 installing the Visual Studio 2005 extensionsYeray wrote:The installers that include the TeeChart.WPF.dll are the TeeChart for .NET v3 and up for Visual Studio .NET 2008 and up
Here it is the list of the latest evaluation installers: All them, by default, install the library in the "TeeChart for .NET 2010 EVAL" folder, but only the following contain the TeeChart.WPF.dll:
- TeeChartNET2010VSNET2010Eval_4.1.2010.08047.exe
- TeeChartNET2010VSNET2005WPFEval_4.1.2010.08045.exe
- TeeChartNET2010VSNET2008Eval_4.1.2010.08046.exe
Here it is:Amol wrote:The idea you given for the rotation of line is looking like that it will work fine and I will definitely try to implement it. But it will be so kind of you and of course very helpful for me if you can provide a little code example for that.
Code: Select all
private Point MouseDwn;
private int draggingSeries;
private int centerRotationPoint;
private class CustomLine : Steema.TeeChart.WPF.Styles.Line
{
public int VisibleIndex1;
public int VisibleIndex2;
public CustomLine(Steema.TeeChart.WPF.Chart c) : base(c)
{
}
}
private void InitializeChart()
{
tChart1.Aspect.View3D = false;
for (int i = 0; i < 4; i++)
{
CustomLine series = new CustomLine(tChart1.Chart);
series.FillSampleValues();
series.Pointer.Visible = true;
series.VisibleIndex1 = 4;
series.VisibleIndex2 = 19;
series.GetPointerStyle += new Steema.TeeChart.WPF.Styles.CustomPoint.GetPointerStyleEventHandler(series_GetPointerStyle);
series.ClickPointer += new Steema.TeeChart.WPF.Styles.CustomPoint.ClickPointerEventHandler(series_ClickPointer);
}
MouseDwn = new Point(-1, -1);
draggingSeries = -1;
centerRotationPoint = -1;
tChart1.Zoom.Allow = false;
tChart1.MouseDown += new MouseButtonEventHandler(tChart1_MouseDown);
tChart1.MouseMove += new MouseEventHandler(tChart1_MouseMove);
tChart1.MouseUp += new MouseButtonEventHandler(tChart1_MouseUp);
}
void series_ClickPointer(Steema.TeeChart.WPF.Styles.CustomPoint series, int valueIndex, double x, double y)
{
CustomLine s = series as CustomLine;
if (valueIndex == s.VisibleIndex1) centerRotationPoint = s.VisibleIndex2;
else if (valueIndex == s.VisibleIndex2) centerRotationPoint = s.VisibleIndex1;
else centerRotationPoint = -1;
}
void series_GetPointerStyle(Steema.TeeChart.WPF.Styles.CustomPoint series, Steema.TeeChart.WPF.Styles.GetPointerStyleEventArgs e)
{
CustomLine s = series as CustomLine;
if ((e.ValueIndex == s.VisibleIndex1) || (e.ValueIndex == s.VisibleIndex2)) e.Style = Steema.TeeChart.WPF.Styles.PointerStyles.Circle;
else e.Style = Steema.TeeChart.WPF.Styles.PointerStyles.Nothing;
}
void tChart1_MouseDown(object sender, MouseButtonEventArgs e)
{
tChart1.Axes.Bottom.Automatic = false;
tChart1.Axes.Left.Automatic = false;
MouseDwn = e.GetPosition(e.MouseDevice.Target);
int tmp;
for (int i = 0; i < tChart1.Series.Count; i++)
{
tmp = tChart1[i].Clicked(MouseDwn);
if (tmp != -1)
{
draggingSeries = i;
break;
}
}
}
void tChart1_MouseMove(object sender, MouseEventArgs e)
{
Point ActualMouse = e.GetPosition(e.MouseDevice.Target);
if (centerRotationPoint != -1)
{
if ((ActualMouse.X != MouseDwn.X) || (ActualMouse.Y != MouseDwn.Y))
{
double X1 = ActualMouse.X - tChart1[draggingSeries].CalcXPos(centerRotationPoint);
double Y1 = ActualMouse.Y - tChart1[draggingSeries].CalcYPos(centerRotationPoint);
double a1 = Math.Atan2(Y1, X1);// *(180.0 / Math.PI);
double X2 = MouseDwn.X - tChart1[draggingSeries].CalcXPos(centerRotationPoint);
double Y2 = MouseDwn.Y - tChart1[draggingSeries].CalcYPos(centerRotationPoint);
double a2 = Math.Atan2(Y2, X2);
for (int i = 0; i < tChart1[draggingSeries].Count; i++)
{
if (i != centerRotationPoint)
{
double diffX = tChart1[draggingSeries].CalcXPos(i) - tChart1[draggingSeries].CalcXPos(centerRotationPoint);
double diffY = tChart1[draggingSeries].CalcYPos(i) - tChart1[draggingSeries].CalcYPos(centerRotationPoint);
double mod = Math.Sqrt(Math.Pow(diffX, 2) + Math.Pow(diffY, 2));
double a3 = Math.Atan2(diffY, diffX);
double diffA = a3 - a2 + a1;
tChart1[draggingSeries].XValues[i] = tChart1[draggingSeries].XScreenToValue(tChart1[draggingSeries].CalcXPos(centerRotationPoint) + Math.Cos(diffA) * mod);
tChart1[draggingSeries].YValues[i] = tChart1[draggingSeries].YScreenToValue(tChart1[draggingSeries].CalcYPos(centerRotationPoint) + Math.Sin(diffA) * mod);
}
}
tChart1.Invalidate();
MouseDwn = ActualMouse;
}
}
else
{
if (draggingSeries != -1)
{
if ((ActualMouse.X != MouseDwn.X) || (ActualMouse.Y != MouseDwn.Y))
{
double diffX = tChart1[draggingSeries].XScreenToValue(MouseDwn.X) - tChart1[draggingSeries].XScreenToValue(ActualMouse.X);
double diffY = tChart1[draggingSeries].YScreenToValue(MouseDwn.Y) - tChart1[draggingSeries].YScreenToValue(ActualMouse.Y);
for (int i = 0; i < tChart1[draggingSeries].Count; i++)
{
tChart1[draggingSeries].XValues[i] = tChart1[draggingSeries].XValues[i] - diffX;
tChart1[draggingSeries].YValues[i] = tChart1[draggingSeries].YValues[i] - diffY;
}
tChart1.Invalidate();
MouseDwn = ActualMouse;
}
}
}
}
void tChart1_MouseUp(object sender, MouseButtonEventArgs e)
{
MouseDwn = new Point(-1, -1);
draggingSeries = -1;
centerRotationPoint = -1;
}
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |