My current program allows the user to click a point, then click another point (at least 20 pixels away) and draws a line between the 2 points. I've used a Polyline so that this can be done multiple times. Though the set of all the lines only appear after all the click are done.
void DrawingCanvas_MouseUp(object sender, MouseButtonEventArgs e) {
Point position = e.GetPosition(this);
if (leftList == null) {
//starting a new set
leftList.Add(position);
lastPoint = position;
return;
}
//calculate distance, i.e. end click
double a = lastPoint.X - position.X;
double b = lastPoint.Y - position.Y;
double distance = Math.Sqrt(a * a + b * b);
if (distance > 20) {
//continue to add to list
leftList.Add(position);
lastPoint = position;
} else {
//end of the line
paint();
leftList = new PointCollection();
}
}
private void paint() {
Polyline line = new Polyline();
line.Visibility = System.Windows.Visibility.Visible;
line.StrokeThickness = 2;
line.Stroke = System.Windows.Media.Brushes.Black;
line.Points = leftList;
myCanvas.Children.Add(line);
}
So my question is two-fold:
A) How do I make it so that after each click the new line is immediately added.
B) How do I render a line between the last point and where the mouse cursor is currently at (i.e. just before you choose your next point)
The following simple example starts drawing a new polyline when the left mouse button is pressed and the mouse is moved by the minimum point distance of 20, with the button kept pressed. It draws the last polyline segment (to the current mouse position) in either red or green, depending on its length. If the mouse button is released and the length of the new segment is >= 20, a new point is appended to the polyline. Otherwise the polyline is terminated, and a new polyline can be created.
private Polyline polyline;
private Polyline segment = new Polyline { StrokeThickness = 2 };
private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (polyline == null)
{
var canvas = (Canvas)sender;
var point = e.GetPosition(canvas);
// create new polyline
polyline = new Polyline { Stroke = Brushes.Black, StrokeThickness = 2 };
polyline.Points.Add(point);
canvas.Children.Add(polyline);
// initialize current polyline segment
segment.Stroke = Brushes.Red;
segment.Points.Add(point);
segment.Points.Add(point);
canvas.Children.Add(segment);
}
}
private void Canvas_MouseMove(object sender, MouseEventArgs e)
{
if (polyline != null)
{
// update current polyline segment
var canvas = (Canvas)sender;
segment.Points[1] = e.GetPosition(canvas);
var distance = (segment.Points[0] - segment.Points[1]).Length;
segment.Stroke = distance >= 20 ? Brushes.Green : Brushes.Red;
}
}
private void Canvas_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (polyline != null)
{
var canvas = (Canvas)sender;
segment.Points[1] = e.GetPosition(canvas);
var distance = (segment.Points[0] - segment.Points[1]).Length;
if (distance >= 20)
{
polyline.Points.Add(segment.Points[1]);
segment.Points[0] = segment.Points[1];
}
else
{
if (polyline.Points.Count < 2)
{
canvas.Children.Remove(polyline);
}
polyline = null;
segment.Points.Clear();
canvas.Children.Remove(segment);
}
}
}
please maintain a collection of points on every click. in collection you can add one class which will have two properties like StartPoint and EndPoint.
when the mouse is clicked first time just add one class object to collection having start point only.
and when you click the mouse next time, ad end point to the last object of the class and meanwhile create a new object and assign this point as its start point and add it to collection, after that call the paint function.
Related
I try to move multiple object open on Helix viewport 3D. so curtly mutiple object are open succesfuly. but problem in when i try to move any specific model at that time object move mouse opposit position like when i move on Right side at time object is goes to left side same as all axis. so i past here mouse move click event hrer, please provide a solution.
Number of query -
multiple object open at time i need to select particular object and move it. curntly all model are move in oposite axix.
Mouse move time object move opposite direction.
Object load Event :
private void loadbtn_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
dlg.DefaultExt = ".stl";
dlg.Filter = "STL Files|*.stl;";
Nullable<bool> result = dlg.ShowDialog();
if (result == true)
{
string filename = dlg.FileName;
openfile = filename;
// txt1.Text = dlg.FileName;
}
ModelVisual3D device3D = new ModelVisual3D();
device3D.Content = Display3d(openfile);
// viewPort3d.Children.Add(device3D);
var reader = new StLReader();
_modelGroup = reader.Read(openfile);
var modelVisual = new ModelVisual3D();
modelVisual.Content = _modelGroup;
// Apply the TranslateTransform3D to your STL object
_modelGroup.Transform = _translate;
// Add the ModelVisual3D to the Children property of the HelixViewport3D
viewPort3d.Children.Add(modelVisual);
}
Mouse Down event is as per below.
private void viewPort3d_MouseDown(object sender, MouseButtonEventArgs e)
{
//*** MOVE ***
var position = e.GetPosition(viewPort3d);
var origin = new Point3D(position.X, position.Y, 0);
Point originPoint = new Point(origin.X, origin.Y);
var transformedOrigin = Viewport3DHelper.UnProject(ConvertToViewport3D(viewPort3d), originPoint);
_lastPosition = position;
viewPort3d.MouseMove += viewPort3d_MouseMove;
viewPort3d.MouseUp += viewPort3d_MouseUp;
}
private Viewport3D ConvertToViewport3D(HelixViewport3D helixViewport)
{
Viewport3D viewport = new Viewport3D();
viewport.Camera = helixViewport.Camera;
foreach (var child in helixViewport.Children)
{
if (child is ModelVisual3D modelVisual)
{
if (modelVisual.Content is Model3D model)
{
ModelVisual3D newChild = new ModelVisual3D();
newChild.Content = model;
viewport.Children.Add(newChild);
}
else
{
// handle other types of modelVisual.Content if necessary
}
}
else
{
// handle other types of Visual3D objects if necessary
}
}
return viewport;
}
Mouse Move event is as per below.
private void viewPort3d_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
System.Windows.Point position = e.GetPosition(this); // this = viewPort3D
double pX = position.X;
double pY = position.Y;
_translate.OffsetX -=pX;
_translate.OffsetY += pY;
_lastPosition = position;
}
Mouse Up event is as per below.
private void viewPort3d_MouseUp(object sender, MouseButtonEventArgs e)
{
//_isDragging = false;
viewPort3d.MouseMove -= viewPort3d_MouseMove;
viewPort3d.MouseUp -= viewPort3d_MouseUp;
//ReleaseMouseCapture();
}
I have a WPF application that suppresses all the mouse inputs so I want to create my own inputs using xaml/behavior for MapSui 3.02. I've added the following method into my ViewModel to allow the user to zoom.
public void MapControlOnMouseWheel(object sender, MouseWheelEventArgs e)
{
Easing easing = default;
if (e.Delta > 0)
{
MapControl.Navigator.ZoomIn(mousePosition, 200, easing);
}
if (e.Delta < 0)
{
MapControl.Navigator.ZoomOut(mousePosition, 200, easing);
}
}
This Zoom method works ok, but it's not as good as the out of the box MapSui Zoom. It's not as smooth, and if you zoom a little too fast it ignores inputs until it has finished the last zoom event.
The out of the box MapSui zoom will zoom faster if you scroll the mouse button faster.
How is this achieved?
For completeness, here is the panning Method which explains where mousePosition comes from in the above zooming Method.
public void MapControlOnMouseMove(object sender, MouseEventArgs e)
{
var screenPosition = e.GetPosition(MapControl);
mousePosition = new Point(screenPosition.X, screenPosition.Y);
Point worldPosition = MapControl.Viewport.ScreenToWorld(screenPosition.X, screenPosition.Y);
if (mouseMiddledown)
{
var panX = lastPosition.X - worldPosition.X;
var panY = lastPosition.Y - worldPosition.Y;
Point newCenter = new Point(lastCentre.X + panX, lastCentre.Y + panY);
MapControl.Navigator?.NavigateTo(newCenter, MapControl.Viewport.Resolution, 0);
lastPosition = new Point(worldPosition.X + panX, worldPosition.Y + panY);
lastCentre = newCenter;
}
else
{
lastPosition = worldPosition;
lastCentre = MapControl.Viewport.Center;
}
CoordsText = $"{worldPosition.X:F0}, {worldPosition.Y:F0}";
}
I want to be able to grab a datapoint drawn in a chart and to move it and change its position by dragging it over the chart control.
How can I ..
..grab the specific series point (series name ="My Series")
When released the series point should change its position/ values
It's like making series points movable with drag event.
Here the color dots (points) should be able to move:
There are some charts like devExpress chart which perform this task but I want to do it in normal MS chart.
Moving a DataPoint is not a built-in feature of the Chart control. We need to code it..
The problem with interacting with a Chart by mouse is that there are not one but three coordinate systems at work in a Chart:
The chart elements, like a Legend or an Annotation are measured in percentages of the respective containers. Those data make up an ElementPosition and usually go from 0-100%.
The Mouse coordinates and all graphics drawn in one of the three Paint events, all work in pixels; they go from 0-Chart.ClientSize.Width/Height.
The DataPoints have an x-value and one (or more) y-values(s). Those are doubles and they can go from and to anywhere you set them to.
For our task we need to convert between mouse pixels and data values.
DO see the Update below!
There are several ways to do this, but I think this is the cleanest:
First we create a few class level variables that hold references to the targets:
// variables holding moveable parts:
ChartArea ca_ = null;
Series s_ = null;
DataPoint dp_ = null;
bool synched = false;
When we set up the chart we fill some of them:
ca_ = chart1.ChartAreas[0];
s_ = chart1.Series[0];
Next we need two helper functions. They do the 1st conversion between pixels and data values:
// two helper functions:
void SyncAllPoints(ChartArea ca, Series s)
{
foreach (DataPoint dp in s.Points) SyncAPoint(ca, s, dp);
synched = true;
}
void SyncAPoint(ChartArea ca, Series s, DataPoint dp)
{
float mh = dp.MarkerSize / 2f;
float px = (float)ca.AxisX.ValueToPixelPosition(dp.XValue);
float py = (float)ca.AxisY.ValueToPixelPosition(dp.YValues[0]);
dp.Tag = (new RectangleF(px - mh, py - mh, dp.MarkerSize, dp.MarkerSize));
}
Note that I chose to use the Tag of each DataPoints to hold a RectangleF that has the clientRectangle of the DataPoint's Marker.
These rectangles will change whenever the chart is resized or other changes in the Layout, like sizing of a Legend etc.. have happend, so we need to re-synch them each time! And, of course you need to initially set them whenever you add a DataPoint!
Here is the Resize event:
private void chart1_Resize(object sender, EventArgs e)
{
synched = false;
}
The actual refreshing of the rectangles is being triggered from the PrePaint event:
private void chart1_PrePaint(object sender, ChartPaintEventArgs e)
{
if ( !synched) SyncAllPoints(ca_, s_);
}
Note that calling the ValueToPixelPosition is not always valid! If you call it at the wrong time it will return null.. We are calling it from the PrePaint event, which is fine. The flag will help keeping things efficient.
Now for the actual moving of a point: As usual we need to code the three mouse events:
In the MouseDown we loop over the Points collection until we find one with a Tag that contains the mouse position. Then we store it and change its Color..:
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
foreach (DataPoint dp in s_.Points)
if (((RectangleF)dp.Tag).Contains(e.Location))
{
dp.Color = Color.Orange;
dp_ = dp;
break;
}
}
In the MouseMove we do the reverse calculation and set the values of our point; note that we also synch its new position and trigger the Chart to refresh the display:
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left) && dp_ != null)
{
float mh = dp_.MarkerSize / 2f;
double vx = ca_.AxisX.PixelPositionToValue(e.Location.X);
double vy = ca_.AxisY.PixelPositionToValue(e.Location.Y);
dp_.SetValueXY(vx, vy);
SyncAPoint(ca_, s_, dp_);
chart1.Invalidate();
}
else
{
Cursor = Cursors.Default;
foreach (DataPoint dp in s_.Points)
if (((RectangleF)dp.Tag).Contains(e.Location))
{
Cursor = Cursors.Hand; break;
}
}
}
Finally we clean up in the MouseUp event:
private void chart1_MouseUp(object sender, MouseEventArgs e)
{
if (dp_ != null)
{
dp_.Color = s_.Color;
dp_ = null;
}
}
Here is how I have set up my chart:
Series S1 = chart1.Series[0];
ChartArea CA = chart1.ChartAreas[0];
S1.ChartType = SeriesChartType.Point;
S1.MarkerSize = 8;
S1.Points.AddXY(1, 1);
S1.Points.AddXY(2, 7);
S1.Points.AddXY(3, 2);
S1.Points.AddXY(4, 9);
S1.Points.AddXY(5, 19);
S1.Points.AddXY(6, 9);
S1.ToolTip = "(#VALX{0.##} / #VALY{0.##})";
S1.Color = Color.SeaGreen;
CA.AxisX.Minimum = S1.Points.Select(x => x.XValue).Min();
CA.AxisX.Maximum = S1.Points.Select(x => x.XValue).Max() + 1;
CA.AxisY.Minimum = S1.Points.Select(x => x.YValues[0]).Min();
CA.AxisY.Maximum = S1.Points.Select(x => x.YValues[0]).Max() + 1;
CA.AxisX.Interval = 1;
CA.AxisY.Interval = 1;
ca_ = chart1.ChartAreas[0];
s_ = chart1.Series[0];
Note that I have set both the Minima and Maxima as well as the Intervals for both Axes. This stops the Chart from running wild with its automatic display of Labels, GridLines, TickMarks etc..
Also note that this will work with any DataType for X- and YValues. Only the Tooltip formatting will have to be adapted..
Final note: To prevent the users from moving a DataPoint off the ChartArea you can add this check into the if-clause of the MouseMove event:
RectangleF ippRect = InnerPlotPositionClientRectangle(chart1, ca_);
if (!ippRect.Contains(e.Location) ) return;
For the InnerPlotPositionClientRectangle function see here!
Update:
On revisiting the code I wonder why I didn't choose a simpler way:
DataPoint curPoint = null;
private void chart1_MouseUp(object sender, MouseEventArgs e)
{
curPoint = null;
}
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button.HasFlag(MouseButtons.Left))
{
ChartArea ca = chart1.ChartAreas[0];
Axis ax = ca.AxisX;
Axis ay = ca.AxisY;
HitTestResult hit = chart1.HitTest(e.X, e.Y);
if (hit.PointIndex >= 0) curPoint = hit.Series.Points[hit.PointIndex];
if (curPoint != null)
{
Series s = hit.Series;
double dx = ax.PixelPositionToValue(e.X);
double dy = ay.PixelPositionToValue(e.Y);
curPoint.XValue = dx;
curPoint.YValues[0] = dy;
}
}
download Samples Environments for Microsoft Chart Controls
https://code.msdn.microsoft.com/Samples-Environments-for-b01e9c61
Check this:
Chart Features -> Interactive Charting -> Selection -> Changing Values by dragging
I'm trying to rotate a rectangle when scrolling slider
there are 2 steps: Click on a rectangle - Scroll the slider.
If I draw only one rectangle, everything is ok.
But when I draw 2 rectangles or more and start rotating, all of my rectangle are rotated together with same angle.
I have no idea about this.
Can anyone help me?
Thanks in advance!
Here is my code: (I found the code for rotating at another post in this page)
Shape _shape;
RotateTransform rt = new RotateTransform();
private void MyCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs)
{
/////////////////////////////////////////////////////
//for know which rectangle has been clicked
if (MyTransform_type == TRANSFORM_TYPE.ROTATE)
{
_shape = e.OriginalSource as Shape;
if (_shape != null)
{
_shape = (Shape)e.OriginalSource;
}
}
}
private void MyCanvas_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
if (MyTransform_type != TRANSFORM_TYPE.NONE && MyTransform_type != TRANSFORM_TYPE.ROTATE)
{
if (_shape == null)
return;
//_shape.ReleaseMouseCapture();
Cursor = Cursors.Arrow;
}
}
private void sldRotate_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (_shape != null)
{
_shape.RenderTransform = rt;
_shape.RenderTransformOrigin = new Point(0.5, 0.5);
var da = new DoubleAnimation(rt.Angle, sldRotate.Value, new Duration(TimeSpan.FromSeconds(0.001)));
rt.BeginAnimation(RotateTransform.AngleProperty, da);
rt.Angle = sldRotate.Value;
}
}
Your mistake is that you create a single RotateTransform object and assign it to the different shapes. So after clicking on several rectangles, every rectangle has the same rotatetransform instance. If you now change the value of the rotatetransform, every rectangle will rotate...
In order to fix that you should change your sldRotate_ValueChanged method. Check if the current shape has already a rotatetransform. If not then create one, if yes adjust the rotatetransform...
Additionally, if you have such a small animation time, you can just leave it out:
private void sldRotate_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
if (_shape != null)
{
var rt = new RotateTransform();
rt.Angle = sldRotate.Value;
_shape.RenderTransform = rt;
_shape.RenderTransformOrigin = new Point(0.5, 0.5);
}
}
It looks like you are using the same RotateTransform named "rt" for all of your rectangles. The simpliest solution will be:
private void MyCanvas_MouseRightButtonDown(object sender, MouseButtonEventArgs)
{
if (MyTransform_type == TRANSFORM_TYPE.ROTATE)
{
_shape = e.OriginalSource as Shape;
//creating new RotateTransform
rt=new RotateTransform();
if (_shape != null)
{
_shape = (Shape)e.OriginalSource;
}
}
}
also you could do
_shape.RenderTransform = rt;
in MyCanvas_MouseRightButtonDown after
_shape = e.OriginalSource as Shape;
instead of doing it each time, when sldRotate_ValueChanged executes to avoid unneeded assignments.
Ok, this could be a little tough to explain. I have a method that computes X and Y values that I want to plot. This method is purely backend and runs inside a backgroundworker called from my main GUI thread.
Separate from my main form I have a form that contains only a zedgraph and a ticker. I use the combination to display the rolling X,Y spit out from my background thread. This works fine, everything goes great here.
When I click a button on my main GUI the backgroundworker is closed, and zedgraph stops updating. Here's where my problem starts
When I click the stop button the graph needs to stay up. It does this just fine... iff it's the very first time it was run. On all future graphs this happens: (Top image is the first graph, second image is the second graph.)
The first graph keeps updating when it isn't supposed to. How do I keep this from happening? Is there a way to "shut down" the first zedgraph and keep it from listening for new data?
Below is my zedgraph code, I'm pretty sure the problem is in here somewhere and not my main GUI code.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ZedGraph;
namespace RTHERM
{
public partial class Readout : Form
{
// Starting time in milliseconds
public static float Time_old = 0.0f;
public static float Tsurf_old;
public static float Tmidr_old;
public static float Tcent_old;
public static float Tenvi_old;
// Every "redrawInterval" secods plot a new point (if one is available)
public static int redrawInterval;
public int plotRange = 15; // Plot will span "plotRange" minutes
int tickStart = 0;
public Readout()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//timer1.Equals(0);
GUI gui = new GUI();
GraphPane graph = zedGraph.GraphPane;
graph.Title.Text = GUI.plotTitle;
graph.XAxis.Title.Text = "Time [min]";
graph.YAxis.Title.Text = "Temperature [F]";
graph.Legend.Position = ZedGraph.LegendPos.BottomCenter;
// Save 1200 points. At 50 ms sample rate, this is one minute
// The RollingPointPairList is an efficient storage class that always
// keeps a rolling set of point data without needing to shift any data values
RollingPointPairList surfList = new RollingPointPairList(1200);
//surfList.Clear();
RollingPointPairList midrList = new RollingPointPairList(1200);
//midrList.Clear();
RollingPointPairList centList = new RollingPointPairList(1200);
//centList.Clear();
RollingPointPairList furnList = new RollingPointPairList(1200);
//furnList.Clear();
// Initially, a curve is added with no data points (list is empty)
// Color is blue, and there will be no symbols
LineItem surf = graph.AddCurve("Surface", surfList, Color.DarkBlue, SymbolType.None);
LineItem midr = graph.AddCurve("Mid-Radius", midrList, Color.DarkOliveGreen, SymbolType.None);
LineItem cent = graph.AddCurve("Center", centList, Color.DarkOrange, SymbolType.None);
LineItem furn = graph.AddCurve("Ambient", furnList, Color.Red, SymbolType.None);
surf.Line.Width = 2;
midr.Line.Width = 2;
cent.Line.Width = 2;
furn.Line.Width = 2;
// Check for new data points
timer1.Interval = redrawInterval;
timer1.Enabled = true;
//timer1.Start();
// Just manually control the X axis range so it scrolls continuously
// instead of discrete step-sized jumps
graph.XAxis.Scale.Min = 0;
graph.XAxis.Scale.Max = plotRange;
graph.XAxis.Scale.MinorStep = 1;
graph.XAxis.Scale.MajorStep = 5;
// Scale the axes
zedGraph.AxisChange();
// Save the beginning time for reference
tickStart = Environment.TickCount;
}
// USING A TIMER OBJECT TO UPDATE EVERY FEW MILISECONDS
private void timer1_Tick(object sender, EventArgs e)
{
// Only redraw if we have new information
if (Transfer.TTIME != Time_old)
{
GraphPane graph = this.zedGraph.GraphPane;
// Make sure that the curvelist has at least one curve
if (zedGraph.GraphPane.CurveList.Count <= 0)
return;
// Grab the three lineitems
LineItem surf = this.zedGraph.GraphPane.CurveList[0] as LineItem;
LineItem midr = this.zedGraph.GraphPane.CurveList[1] as LineItem;
LineItem cent = this.zedGraph.GraphPane.CurveList[2] as LineItem;
LineItem furn = this.zedGraph.GraphPane.CurveList[3] as LineItem;
if (surf == null)
return;
// Get the PointPairList
IPointListEdit surfList = surf.Points as IPointListEdit;
IPointListEdit midrList = midr.Points as IPointListEdit;
IPointListEdit centList = cent.Points as IPointListEdit;
IPointListEdit enviList = furn.Points as IPointListEdit;
// If these are null, it means the reference at .Points does not
// support IPointListEdit, so we won't be able to modify it
if (surfList == null || midrList == null || centList == null || enviList == null)
return;
// Time is measured in seconds
double time = (Environment.TickCount - tickStart) / 1000.0;
// ADDING THE NEW DATA POINTS
// format is List.Add(X,Y) Finally something that makes sense!
surfList.Add(Transfer.TTIME, Transfer.TSURF);
midrList.Add(Transfer.TTIME, Transfer.TMIDR);
centList.Add(Transfer.TTIME, Transfer.TCENT);
enviList.Add(Transfer.TTIME, Transfer.TENVI);
// Keep the X scale at a rolling 10 minute interval, with one
// major step between the max X value and the end of the axis
if (GUI.isRunning)
{
Scale xScale = zedGraph.GraphPane.XAxis.Scale;
if (Transfer.TTIME > xScale.Max - xScale.MajorStep)
{
xScale.Max = Transfer.TTIME + xScale.MajorStep;
xScale.Min = xScale.Max - plotRange;
}
}
// Make sure the Y axis is rescaled to accommodate actual data
zedGraph.AxisChange();
// Force a redraw
zedGraph.Invalidate();
}
else return;
}
public void reset()
{
Time_old = 0.0f;
Tsurf_old = 0.0f;
Tmidr_old = 0.0f;
Tcent_old = 0.0f;
Tenvi_old = 0.0f;
}
private void Form1_Resize(object sender, EventArgs e)
{
if (GUI.isRunning)
{
SetSize();
}
}
// Set the size and location of the ZedGraphControl
private void SetSize()
{
// Control is always 10 pixels inset from the client rectangle of the form
Rectangle formRect = this.ClientRectangle;
formRect.Inflate(-10, -10);
if (zedGraph.Size != formRect.Size)
{
zedGraph.Location = formRect.Location;
zedGraph.Size = formRect.Size;
}
}
private void saveGraph_Click(object sender, EventArgs e)
{
GUI.Pause();
zedGraph.DoPrint();
//SaveFileDialog saveDialog = new SaveFileDialog();
//saveDialog.ShowDialog();
}
private void savePlotDialog_FileOk(object sender, CancelEventArgs e)
{
// Get file name.
string name = savePlotDialog.FileName;
zedGraph.MasterPane.GetImage().Save(name);
GUI.Resume();
}
private bool zedGraphControl1_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e)
{
// Save the mouse location
PointF mousePt = new PointF(e.X, e.Y);
// Find the Chart rect that contains the current mouse location
GraphPane pane = sender.MasterPane.FindChartRect(mousePt);
// If pane is non-null, we have a valid location. Otherwise, the mouse is not
// within any chart rect.
if (pane != null)
{
double x, y;
// Convert the mouse location to X, and Y scale values
pane.ReverseTransform(mousePt, out x, out y);
// Format the status label text
toolStripStatusXY.Text = "(" + x.ToString("f2") + ", " + y.ToString("f2") + ")";
}
else
// If there is no valid data, then clear the status label text
toolStripStatusXY.Text = string.Empty;
// Return false to indicate we have not processed the MouseMoveEvent
// ZedGraphControl should still go ahead and handle it
return false;
}
private void Readout_FormClosed(object sender, FormClosedEventArgs e)
{
}
private void Readout_FormClosing(object sender, FormClosingEventArgs e)
{
//e.Cancel = true;
//WindowState = FormWindowState.Minimized;
}
}
}
The last point is connected to the first point in the graph. I suspect, because all your RollingPointPairList contains the data multiple times. Verify this using a breakpoint in your timer1_Tickfunction.
On private void Form1_Load you will add the complete list to the LineItem.
graph.CurveList.Clear();
LineItem surf = graph.AddCurve("Surface", surfList, Color.DarkBlue, SymbolType.None);
LineItem midr = graph.AddCurve("Mid-Radius", midrList, Color.DarkOliveGreen, SymbolType.None);
LineItem cent = graph.AddCurve("Center", centList, Color.DarkOrange, SymbolType.None);
LineItem furn = graph.AddCurve("Ambient", furnList, Color.Red, SymbolType.None);