C# MSChart how to shift Y axis like oscilloscope offset button? - c#

I have a MSChart, that x-axis is t(ms), and y-axis is voltage data.
Now I would like programming the code like oscilloscope function "Offset".
When I adjust numericUpDown to shift the wave and Y-axis.
How to get this function? Just like below 2 picture. Thanks!
No shift wave and Y-axis
Now shift Y-axis and wave shift too

The way I would tackle it is to change the y-axis Minimum and/or Maximum values. You can also play with the IntervalOffset.
See here:
private void numericUpDown5_ValueChanged(object sender, EventArgs e)
{
Axis ay = chart2.ChartAreas[0].AxisY;
int oy = (int)numericUpDown5.Value;
if (radioButton1.Checked) ay.IntervalOffset = oy;
if (radioButton2.Checked) ay.Maximum = oy;
if (radioButton3.Checked) ay.Minimum = oy;
}
private void rbAy_CheckedChanged(object sender, EventArgs e)
{
Axis ay = chart2.ChartAreas[0].AxisY;
if (sender == radioButton1) numericUpDown5.Value = (decimal)ay.IntervalOffset;
if (sender == radioButton2) numericUpDown5.Value = (decimal)ay.Maximum;
if (sender == radioButton3) numericUpDown5.Value = (decimal)ay.Minimum;
}

Related

How to limit panning on the X Axis with ZedGraph?

A lot of people already asked this but I haven't found an answer that works for me. I just want to make the user unable to zoom out/pan outside a certain range (between 0 and "size" in my example below). I managed to limit the zooming by using the ZoomEvent and setting the Max and Min values manually, but I can't figure out how to do the same for panning. Here is a bit of code:
int size = 40000;
graphControl.ZoomEvent += GraphControl_ZoomEvent;
graphControl.Scroll += GraphControl_Scroll;
graphControl.ScrollEvent += GraphControl_Scroll;
private void GraphControl_Scroll(object sender, ScrollEventArgs e)
{
if (graphControl.MasterPane.PaneList[0].XAxis.Scale.Max > size)
graphControl.MasterPane.PaneList[0].XAxis.Scale.Max = size;
if (graphControl.MasterPane.PaneList[0].XAxis.Scale.Min < 0)
graphControl.MasterPane.PaneList[0].XAxis.Scale.Min = 0;
graphControl.MasterPane.AxisChange();
graphControl.Refresh();
}
private void GraphControl_ZoomEvent(ZedGraphControl sender, ZoomState oldState, ZoomState newState)
{
if (sender.MasterPane.PaneList[0].XAxis.Scale.Max > size)
sender.MasterPane.PaneList[0].XAxis.Scale.Max = size;
if (sender.MasterPane.PaneList[0].XAxis.Scale.Min < 0)
sender.MasterPane.PaneList[0].XAxis.Scale.Min = 0;
sender.MasterPane.AxisChange();
sender.Refresh();
}
The code above almost does it, but the Min and Max values update only after I've let go of my panning button, I want to limit it at all times (including during the panning). I also think it's worth mentioning that the Scroll event isn't firing at all.
Thank you in advance!
Subscribe to MouseMoveEvent and use the same code like in ZoomEvent.
Additionally, do this only if pan mouse button (middle) is pressed (or Ctrl and left mouse button). If you limit Min side, you have to set the Max side also to maintain the same axis span if you don't want to change the scale of the XAxis.
In this example below I limited only one side. Return false to allow the execution of other actions (panning).
double limit = 0;
double span;
private bool GraphControl_MouseMoveEvent(ZedGraphControl sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Middle || (e.Button == MouseButtons.Left && (ModifierKeys & Keys.Control) == Keys.Control))
{
span = graphControl.GraphPane.XAxis.Scale.Max - graphControl.GraphPane.XAxis.Scale.Min;
if (graphControl.GraphPane.XAxis.Scale.Min < limit)
{
graphControl.GraphPane.XAxis.Scale.Min = limit;
graphControl.GraphPane.XAxis.Scale.Max = limit + span;
}
}
return false;
}

MS Chart Control: prevent zoom when clicking

I'm using a MS Chart Control that sets a cursor when the chart is clicked and that enables the user to zoom in and out. When the user tries to click into the chart it accidentally happens that he drags a very small zoom rectangle and the chart zooms in instead of handling the click.
What can be done to prevent zooming in when trying to click? Is there something like a minimum rectangle size for zooming?
Here's how I handle the click:
_area = new ChartArea();
private void chart1_MouseClick(object sender, MouseEventArgs e)
{
try
{
_area.CursorX.SetCursorPixelPosition(new Point(e.X, e.Y), true);
}
catch (Exception ex)
{
}
}
And this is how I setup the zoom and cursor settings:
_area.AxisX.ScaleView.Zoomable = true;
_area.CursorX.IsUserSelectionEnabled = true;
_area.CursorX.IntervalType = DateTimeIntervalType.Seconds;
_area.CursorX.Interval = 1D;
_area.CursorY.IsUserSelectionEnabled = true;
_area.CursorY.Interval = 0;
You can manually handle zooming yourself. You can use the MouseDown event to capture the start X and start Y. Then use the MouseUp event to capture the end X and end Y. Once you have your start and end points you can determine if you want to zoom or not. If you want to zoom you can use the helper function below to manually zoom.
private void set_chart_zoom(ChartArea c, double xStart, double xEnd, double yStart, double yEnd)
{
c.AxisX.ScaleView.Zoom(xStart, xEnd);
c.AxisY.ScaleView.Zoom(yStart, yEnd);
}
Based on #Baddack's answer here's a complete solution. The key is to disable the zoom feature of the chart and zoom manually (like Baddack suggested) by using MouseUp/MouseDown events. The user selection feature of the chart is kept enabled to use the selection rectangle for setting the zoom interval.
This sample code checks if the zoom retangle is at least 10 pixels wide and high. Only if that's the case the zoom is initiated:
private ChartArea _area;
private Point _chartMouseDownLocation;
...
private void MainForm_Load(object sender, EventArgs e)
{
...
// Disable zooming by chart control because zoom is initiated by MouseUp event
_area.AxisX.ScaleView.Zoomable = false;
_area.AxisY.ScaleView.Zoomable = false;
// Enable user selection to get the interval/rectangle of the selection for
// determining the interval for zooming
_area.CursorX.IsUserSelectionEnabled = true;
_area.CursorX.IntervalType = DateTimeIntervalType.Seconds;
_area.CursorX.Interval = 1D;
_area.CursorY.IsUserSelectionEnabled = true;
_area.CursorY.Interval = 0;
}
private void chart1_MouseDown(object sender, MouseEventArgs e)
{
_chartMouseDownLocation = e.Location;
}
private void chart1_MouseUp(object sender, MouseEventArgs e)
{
// Check if rectangle has at least 10 pixels with and hright
if (Math.Abs(e.Location.X - _chartMouseDownLocation.X) > 10 &&
Math.Abs(e.Location.Y - _chartMouseDownLocation.Y) > 10)
{
// Zoom to the Selection rectangle
_area.AxisX.ScaleView.Zoom(
Math.Min(_area.CursorX.SelectionStart, _area.CursorX.SelectionEnd),
Math.Max(_area.CursorX.SelectionStart, _area.CursorX.SelectionEnd)
);
_area.AxisY.ScaleView.Zoom(
Math.Min(_area.CursorY.SelectionStart, _area.CursorY.SelectionEnd),
Math.Max(_area.CursorY.SelectionStart, _area.CursorY.SelectionEnd)
);
}
// Reset/hide the selection rectangle
_area.CursorX.SetSelectionPosition(0D, 0D);
_area.CursorY.SetSelectionPosition(0D, 0D);
}

Get MouseWheel Scroll Position in a FlowLayoutPanel

I have a FlowLayoutPanel which can be scrolled by the user on the verticle axis. i have the following event handler which is used to see where the user has scrolled to and provides the position number within blocks of 405px:
private void ChangedParentFlowPanel_Scroll(object sender, ScrollEventArgs e)
{
int NewPos = e.NewValue;
int range = (NewPos - 1) / 405 + 1;
CurrentIndex_Changed = range;
tCounter.Text = CurrentIndex_Changed.ToString();
}
That works just fine and does exactly what i need when the user scrolls using the verticle bar. The problem i have is i need to update tCounter with the same value but this time when the user scrolls using the mouse wheel. I'Ve tried the following but this only ever seems to provide the Y axis value for the location of the mouse when it scrolls and not the location of the scroll itself:
private void ChangedParentFlowPanel_Wheel(object sender, MouseEventArgs e)
{
int NewPos = e.Location.Y;
MessageBox.Show(NewPos.ToString());
int range = (NewPos - 1) / 405 + 1;
CurrentIndex_Changed = range;
tCounter.Text = CurrentIndex_Changed.ToString();
}
The question is...how can i get the scroll position of the scroll in ChangedParentFlowPanel when a mousewheel is used?
Thanks to the comment by Hans Pasant here's the answer:
private void ChangedParentFlowPanel_Wheel(object sender, MouseEventArgs e)
{
int NewPos = Math.Abs(ChangedParentFlowPanel.AutoScrollPosition.Y);
int range = (NewPos - 1) / 405 + 1;
CurrentIndex_Changed = range;
tCounter.Text = CurrentIndex_Changed.ToString();
}
Math.Abs because the returned scroll Y value is minus and i need a positive value.

WinForms, MS chart, adding series from a numericUpDown

I have a numericUpDown control which should ,based on the input, draw a straight line on my chart. The input should be only for the Y axis of my chart.
I can see the Tpoint added to Legend but the line is not drawn. What am I missing? I've already looked at the samples for Microsoft Chart Controls and still didn't figure out what's wrong.
private void numericSeries_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13)
{
int s = (int)numericSeries.Value;
Series series = chart2.Series.Add("Tpoint" + (chart2.Series.Count).ToString());
series.ChartArea = "ChartArea1";
series.ChartType = SeriesChartType.FastLine;
series.BorderWidth = 1;
series.Color = Color.Blue;
series.Points.AddY(s);
}
}
EDIT Unfortunately i cant upload pictures.
http://i58.tinypic.com/25aqe4m.jpg
2.EDIT - the chart in the picture is a real time chart which represents PWM values from a DC motor (Y value) vs Datetime (X value). The line i want to draw should represent the Setpoint (reference) value i'm trying to achive.
My X axis
chart2.ChartAreas[0].AxisX.Minimum = chart2.Series[0].Points[0].XValue;
chart2.ChartAreas[0].AxisX.Maximum = DateTime.FromOADate(chart2.Series[0].Points[0].XValue).AddSeconds(15).ToOADate();

winform move an image inside a picturebox

I've been trying to do this for a few hours now, but for the life of me I can't make it possible.
What I'm trying to do is simply move the image found within a picture box in a winform application. My image is roughly 1000x1000 pixels and my box is something arbitrary like 400x500, so, for example, when I click the mouse I'd want the image to move 50 to the left. But the image box should remain the same size.
For the life of me, however, I can't get this to work. What I have been able to do is the following:
if (kinectController.hands[0].fingertips.Count == 1)
{
pictureBox1.SizeMode = PictureBoxSizeMode.CenterImage;
}
This function is for my kinect finger tracking app. So when the application finds a single finder point visiable on the screen, the image is centered. However, I would eventually like the image to move along with my finger movement, which will come once I work out the basic step of moving the image a few pixels to the side.
Any help with this would be appreciated.
I did a little bit of research and apparently moving an image within a PictureBox is no easy task, at the very least I couldn't find anything that would make this possible (not saying there isn't a way to do it though).
However, I came up with a bit of a "workaround", see if this fits your needs. To accomplish this:
Create a Panel control, and size it to however much of the image you
would like to display
Inside that panel place a PictureBox control with your image in it
and set the SizeMode property to AutoSize.
Now, put this code in your form
private bool Dragging;
private int xPos;
private int yPos;
private void pictureBox1_MouseUp(object sender, MouseEventArgs e) { Dragging = false; }
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
Dragging = true;
xPos = e.X;
yPos = e.Y;
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
Control c = sender as Control;
if (Dragging && c!= null) {
c.Top = e.Y + c.Top - yPos;
c.Left = e.X + c.Left - xPos;
}
}
Now whenever you click and drag on the PictureBox, it won't actually move the image within it, but the PictureBox control within the panel. Again, not exactly what you were looking for and I'm not sure how this would convert over to Kinect, but I hope this gets you on the right track.
Not enough reputation to comment but I wanted to add on Ben Black answer if someone ever need more control over the image moving around so you can't move the image past it's borders :
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
Control c = sender as Control;
if (Dragging && c != null)
{
int maxX = pictureBox1.Size.Width * -1 + panel.Size.Width;
int maxY = pictureBox1.Size.Height * -1 + panel.Size.Height;
int newposLeft = e.X + c.Left - xPos;
int newposTop = e.Y + c.Top - yPos;
if (newposTop > 0)
{
newposTop = 0;
}
if (newposLeft > 0)
{
newposLeft = 0;
}
if (newposLeft < maxX)
{
newposLeft = maxX;
}
if (newposTop < maxY)
{
newposTop = maxY;
}
c.Top = newposTop;
c.Left = newposLeft;
}
}

Categories