Link a particular form with a drawn line? - c#

I am developing a GIS application. I want to open a particular form with drawn lines. The form which will open contains a textbox which is showing the length of the line. I am able to select the line. I am able to get the length of the line.
I want to link the form with each line. and the same form should be displayed whenever that line is selected. How can i do it?
should i go for serialization? or is there any good solution?
I know this is GIS related thing, but its more like a C# problem.
Code:
private bool amDigitizing = false;
//Coordiant
private List<DotSpatial.Topology.Coordinate> myDigitizedPoints = new List<DotSpatial.Topology.Coordinate>();
private List<DotSpatial.Topology.Coordinate> myExtractedPoints = new List<DotSpatial.Topology.Coordinate>();
// DEM Layer
private DotSpatial.Controls.MapRasterLayer demLyr;
// Line Layer
private DotSpatial.Controls.MapLineLayer LineLyr;
FormTableEditor ft = new FormTableEditor();
public Form1()
{
InitializeComponent();
appManager1.LoadExtensions();
appManager1.CompositionContainer.ComposeParts(toolManager1);
}
private void map1_MouseMove(object sender, MouseEventArgs e)
{
Coordinate c_mouse = map1.PixelToProj(new System.Drawing.Point(e.X, e.Y));
Xstrip.Text = "X:" + Convert.ToString(c_mouse.X);
Ystrip.Text = "Y:" + Convert.ToString(c_mouse.Y);
}
private void btnDraw_Click(object sender, EventArgs e)
{
try
{
//map1.Layers.Remove(LineLyr);
}
catch
{
// do nothing
}
// Start a Drawing
MessageBox.Show(" Click on the map to draw, double click to stop drawing");
amDigitizing = true;
myDigitizedPoints = new List<DotSpatial.Topology.Coordinate>();
map1.FunctionMode = DotSpatial.Controls.FunctionMode.None;
}
private void map1_MouseClick_1(object sender, MouseEventArgs e)
{
// digitizing
if (amDigitizing == true)
{
DotSpatial.Topology.Coordinate c = new DotSpatial.Topology.Coordinate();
System.Drawing.Point p = new System.Drawing.Point();
p.X = e.X;
p.Y = e.Y;
c = map1.PixelToProj(p);
//double[] s = c.ToArray();
//StartX = s[0];
//StartY = s[1];
myDigitizedPoints.Add(c);
}
}
int NoOfMines = 0;
private void map1_MouseDoubleClick_1(object sender, MouseEventArgs e)
{
// Double click ends digitizing
if (amDigitizing == true)
{
DotSpatial.Topology.Coordinate c = new DotSpatial.Topology.Coordinate();
System.Drawing.Point p = new System.Drawing.Point();
p.X = e.X;
p.Y = e.Y;
c = map1.PixelToProj(p);
myDigitizedPoints.Add(c);
//double[] s = c.ToArray();
//EndX = s[0];
//EndY = s[1];
amDigitizing = false;
DotSpatial.Data.Feature f = new DotSpatial.Data.Feature(DotSpatial.Topology.FeatureType.Line, myDigitizedPoints);
DotSpatial.Data.FeatureSet fs = new DotSpatial.Data.FeatureSet();
fs.AddFeature(f);
NoOfMines = NoOfMines +1 ;
fs.Projection = map1.Projection;
for (int i = 0; i < NoOfMines; i++)
{
fs.Name = "Mine Field" + NoOfMines.ToString();
}
//fs.SaveAs(GraphicsPathExt, true);
//LineLyr = (DotSpatial.Controls.MapLineLayer)map1.AddLayer(GraphicsPathExt);
LineLyr = (MapLineLayer)map1.Layers.Add(fs);
}
}
// Length of the line
private void mnuThin_Click(object sender, EventArgs e)
{
LineLyr.Symbolizer.SetFillColor(Color.Red);
LineLyr.Symbolizer.SetWidth(5.0);
LineLyr.Symbolizer.SetOutline(Color.White, 1.0);
map1.Refresh();
IRaster r = (IRaster)map1.Layers[0].DataSet;
IFeatureSet fs = LineLyr.DataSet;
int np = 0;
try
{
foreach (IFeature f in fs.Features)
{
np += f.Coordinates.Count * 100;
}
}
catch
{
}
double[] plotX = new double[np - 99];
double[] plotY = new double[np - 99];
double x1= 0, y1 = 0, x2 = 0 , y2 = 0 , dx = 0 , dy = 0, newx = 0, newy = 0;
double z = 0;
double TotalLength = 0.0;
int i = 0;
double[] Slope = new double[np / 100];
foreach (IFeature f in fs.Features)
{
foreach (DotSpatial.Topology.Coordinate c in f.Coordinates)
{
x2 = c.X;
y2 = c.Y;
if (i > 0)
{
dx = (x2 - x1) / 100;
dy = (y2 - y1) / 100;
newx = x1;
newy = y1;
for (int j = 0; j < 100; j++)
{
TotalLength += Math.Sqrt(Math.Pow(dx, 2) + Math.Pow(dy, 2));
z = demLyr.DataSet.GetNearestValue(newx, newy);
i += 1;
}
}
x1 = x2;
y1 = y2;
if (i == 0)
{
z = demLyr.DataSet.GetNearestValue(newx, newy);
i += 1;
x1 = x2;
y1 = y2;
}
}
}
//Length of the line
ft.textBox1.Text = TotalLength.ToString();
}
//Selection of layer
private void customizeToolStripMenuItem_Click(object sender, EventArgs e)
{
IMapLayer layerSelect = appManager1.Map.Layers.SelectedLayer;
if (layerSelect == LineLyr)
{
ft.Show();
}
}

As Peter duniho mentioned in the comments of selection change event.
i used that approach to link the form.
DrawObject o = new DrawObject;
Form1 f = new Form1(o);
LegendItem li = new LegendItem();
if (li.IsSelected == true)
{
f.Textbox1.Text = frontage.ToString();
f.show();
}

Related

Caling Class from for loop

I´m working with a Visual studio c# form
I have a class with the following properties:
string Name;
int NumberOfHitBoxes;
Point Hit1;
Point Hit2;
Point Hit3;
I have a mouseMove event that detects if the mouse is in the "hitbox" it works fine like this: ( in the else part ( p.Hit1.X ))
picture.MouseMove += (sender, e) =>
{
var c = sender as PictureBox;
bool h=false;
if (null == c) return;
if (_dragging)
{
c.Top = e.Y + c.Top - _yPos;
c.Left = e.X + c.Left - _xPos;
}
else
{
if ((e.X>p.Hit1.X)&&(e.X<p.Hit1.X+hitw)&&(e.Y>p.Hit1.Y)&&(e.Y<p.Hit1.Y+hitw)){hitbox(c,p.Hit1.X,p.Hit1.Y,8);h=true;tb.Text = p.Type;hitok = p.Input1Point;}
if ((e.X>p.Hit2.X)&&(e.X<p.Hit2.X+hitw)&&(e.Y>p.Hit2.Y)&&(e.Y<p.Hit2.Y+hitw)){hitbox(c,p.Hit2.X,p.Hit2.Y,8);h=true;tb.Text = p.Type;hitok = p.Input2Point;}
if ((e.X>p.Hit3.X)&&(e.X<p.Hit3.X+hitw)&&(e.Y>p.Hit3.Y)&&(e.Y<p.Hit3.Y+hitw)){hitbox(c,p.Hit3.X,p.Hit3.Y,8);h=true;tb.Text = p.Type;hitok = p.Output1Point;}
}
if (!h){picture.Refresh();h=false;hitok = new Point(0,0);}
};
The number of hitboxex warry, so i want to do somthing like this:
picture.MouseMove += (sender, e) =>
{
var c = sender as PictureBox;
bool h=false;
if (null == c) return;
if (_dragging)
{
c.Top = e.Y + c.Top - _yPos;
c.Left = e.X + c.Left - _xPos;
}
else
{
for (int x =1;x<g.NumberOfHitBoxes;x++)
{
if ((e.X>p["Hit"+x.ToString();].X)&&(e.X<p["Hit"+x.ToString();].X+hitw)&&(e.Y>p["Hit"+x.ToString();].Y)&&(e.Y<p["Hit"+x.ToString();].Y+hitw)){hitbox(c,p["Hit"+x.ToString();].X,p["Hit"+x.ToString();].Y,8);h=true;tb.Text = p.Type;hitok = p["Input"+x.ToString()+"Point"];}
}
}
if (!h){picture.Refresh();h=false;hitok = new Point(0,0);}
};
Simplified:
int x = 1;
int whatever = p["Hit"+x.ToString()].X;
Instead of this:
int whatever = p.Hit1.X;
Some bright intelligent person could maybe teach a dumbass like me a litle trick ??
Your class
public class Phit
{
public List<Point> HitBoxes { get; private set; }
public Phit(List<Point> hitboxes)
{
HitBoxes = hitboxes;
}
}
Initialize your class with the hitboxes.
List<Point> hitboxes = new List<Point>
{
new Point(1.2, 1.5),
new Point(1.2, 3.0),
new Point(1.2, 4.5)
};
Phit phit = new Phit(hitboxes);
The loop inside your MouseMove method.
foreach(Point p in phit.HitBoxes)
{
if (e.X > p.X && e.X < p.X + hitw && e.Y > p.Y && e.Y < p.Y + hitw)
{
hitbox(c, p.X, p.Y, 8);
h = true;
tb.Text = $"X: {p.X} / Y: {p.Y}";
hitok = p;
}
}

Resizing and positioning panels in another panel

I'm giving my panels inside another panel (this panel is in a usercontrol) a fixed location and a maximum size that changes with the size of the panel there in. Neither the resize or location works properly. The resize does happen but its to quickly. The location is fine if you only have 1 pinpanel for output and input. When you have more then 1 the locations are fixed but you need to resize the panel to resize to see the other panels. Could you point me in the right direction if you see the problem?
I have a panel drawPanel in this case that i use as a sort of background for the usercontrol. Inside this drawPanel i'm placing pinpanels. I want these pinpanels to resize with the usercontrol and give them a fixed location
private void OnClickPinPanel(object source, EventArgs e)
{
if (source is PinPanel p)
{
int index;
if ((index = Array.IndexOf(inputPins, p)) >= 0)
{
ClickedPinPanel?.Invoke(index, true);
}
else
{
ClickedPinPanel?.Invoke(Array.IndexOf(outputPins, p), false);
}
}
//else log here
}
private void CreatePinPanels(bool isInput)
{
int x = 0;
int y = -(int)(this.Width * 0.05)/2;
if (isInput)
{
for (int i = 0; i < inputPins.Length; i++)
{
y += (i + 1) * (this.Height / inputPins.Length + 1);
inputPins[i] = new PinPanel()
{
Location = new Point(x, y),
Size = new Size((int)(this.Width * 0.05), (int)(this.Width * 0.05)),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right,
};
inputPins[i].Click += OnClickPinPanel;
}
}
else
{
x += this.Width - (int)(this.Width * 0.1);
for (int i = 0; i < outputPins.Length; i++)
{
y += (i + 1) * (this.Height / inputPins.Length+1);
outputPins[i] = new PinPanel()
{
Size = new Size((int)(this.Width * 0.1), (int)(this.Width * 0.1)),
Location = new Point(x, y),
Anchor = AnchorStyles.Left | AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Right
};
outputPins[i].Click += OnClickPinPanel;
}
}
}
The result i get now is that the pinpanels get a fixed location but when you have more then 1 pinpanel, the location is wrong its like if he thinks that the usercontrol is bigger then it is Reality. In order to see all the pins i have to resize and get this After resize
I want it to look like this
expectations
Try something like this out.
Here is my test rig:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
numericUpDown1.Value = someChip1.NumberInputPins;
numericUpDown2.Value = someChip1.NumberOutputPins;
}
private void numericUpDown1_ValueChanged(object sender, EventArgs e)
{
someChip1.NumberInputPins = (int)numericUpDown1.Value;
}
private void numericUpDown2_ValueChanged(object sender, EventArgs e)
{
someChip1.NumberOutputPins = (int)numericUpDown2.Value;
}
}
Sample chip with 5 inputs and 3 outputs:
Here is my PinPanel UserControl (just draws an ellipse/pin the size of the control):
public partial class PinPanel : UserControl
{
public PinPanel()
{
InitializeComponent();
}
private void PinPanel_Paint(object sender, PaintEventArgs e)
{
Rectangle rc = new Rectangle(new Point(0, 0), new Size(this.ClientRectangle.Width - 1, this.ClientRectangle.Height - 1));
e.Graphics.DrawEllipse(Pens.Black, rc);
}
private void PinPanel_SizeChanged(object sender, EventArgs e)
{
this.Refresh();
}
}
And finally, my SomeChip UserControl:
public partial class SomeChip : UserControl
{
public event PinPanelClick ClickedPinPanel;
public delegate void PinPanelClick(int index, bool input);
private PinPanel[] inputPins;
private PinPanel[] outputPins;
private int _NumberInputPins = 2;
public int NumberInputPins
{
get {
return _NumberInputPins;
}
set
{
if (value > 0 && value != _NumberInputPins)
{
_NumberInputPins = value;
CreatePinPanels();
this.Refresh();
}
}
}
private int _NumberOutputPins = 1;
public int NumberOutputPins
{
get
{
return _NumberOutputPins;
}
set
{
if (value > 0 && value != _NumberOutputPins)
{
_NumberOutputPins = value;
CreatePinPanels();
this.Refresh();
}
}
}
public SomeChip()
{
InitializeComponent();
}
private void SomeChip_Load(object sender, EventArgs e)
{
CreatePinPanels();
RepositionPins();
}
private void SomeChip_SizeChanged(object sender, EventArgs e)
{
this.Refresh();
}
private void SomeChip_Paint(object sender, PaintEventArgs e)
{
int PinHeight;
// draw the input pin runs
if (inputPins != null)
{
PinHeight = (int)((double)this.Height / (double)_NumberInputPins);
for (int i = 0; i < NumberInputPins; i++)
{
int Y = (i * PinHeight) + (PinHeight / 2);
e.Graphics.DrawLine(Pens.Black, 0, Y, this.Width / 4, Y);
}
}
// draw the output pin runs
if (outputPins != null)
{
PinHeight = (int)((double)this.Height / (double)_NumberOutputPins);
for (int i = 0; i < NumberOutputPins; i++)
{
int Y = (i * PinHeight) + (PinHeight / 2);
e.Graphics.DrawLine(Pens.Black, this.Width - this.Width / 4, Y, this.Width, Y);
}
}
//draw the chip itself (takes up 50% of the width of the UserControl)
Rectangle rc = new Rectangle(new Point(this.Width / 4, 0), new Size(this.Width / 2, this.Height - 1));
using (SolidBrush sb = new SolidBrush(this.BackColor))
{
e.Graphics.FillRectangle(sb, rc);
}
e.Graphics.DrawRectangle(Pens.Black, rc);
RepositionPins();
}
private void CreatePinPanels()
{
if (inputPins != null)
{
for (int i = 0; i < inputPins.Length; i++)
{
if (inputPins[i] != null && !inputPins[i].IsDisposed)
{
inputPins[i].Dispose();
}
}
}
inputPins = new PinPanel[_NumberInputPins];
for (int i = 0; i < inputPins.Length; i++)
{
inputPins[i] = new PinPanel();
inputPins[i].Click += OnClickPinPanel;
this.Controls.Add(inputPins[i]);
}
if (outputPins != null)
{
for (int i = 0; i < outputPins.Length; i++)
{
if (outputPins[i] != null && !outputPins[i].IsDisposed)
{
outputPins[i].Dispose();
}
}
}
outputPins = new PinPanel[_NumberOutputPins];
for (int i = 0; i < outputPins.Length; i++)
{
outputPins[i] = new PinPanel();
outputPins[i].Click += OnClickPinPanel;
this.Controls.Add(outputPins[i]);
}
}
private void OnClickPinPanel(object sender, EventArgs e)
{
PinPanel p = (PinPanel)sender;
if (inputPins.Contains(p))
{
ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), true);
}
else if (outputPins.Contains(p))
{
ClickedPinPanel?.Invoke(Array.IndexOf(inputPins, p), false);
}
}
private void RepositionPins()
{
int PinRowHeight, PinHeight;
if (inputPins != null)
{
PinRowHeight = (int)((double)this.Height / (double)_NumberInputPins);
PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
for (int i = 0; i < inputPins.Length; i++)
{
if (inputPins[i] != null && !inputPins[i].IsDisposed)
{
inputPins[i].SetBounds(0, (int)((i * PinRowHeight) + (PinRowHeight /2 ) - (PinHeight / 2)), PinHeight, PinHeight);
}
}
}
if (outputPins != null)
{
PinRowHeight = (int)((double)this.Height / (double)_NumberOutputPins);
PinHeight = (int)Math.Min((double)(PinRowHeight / 2), (double)this.Height * 0.05);
for (int i = 0; i < outputPins.Length; i++)
{
if (outputPins[i] != null && !outputPins[i].IsDisposed)
{
outputPins[i].SetBounds(this.Width - PinHeight, (int)((i * PinRowHeight) + (PinRowHeight / 2) - (PinHeight / 2)), PinHeight, PinHeight);
}
}
}
}
}

Design an algorithm for guessing a card number

I am making a card guessing game.there are 100 cards place in 10rows and 10 columns each card with a number and user have to find a number he is thinking of. i want to devise an algorithm to determine whether a given number is written on one of the cards by turning up less than 20 cards.I hav created the buttons dynamically, now im having hard time making a logic to search through them.This is my code.
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
int rememberlast = 0, move = 0;
object savelastobject;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
int sizee = 50, where = 0;
this.Height = 0;
this.Width = 0;
var generatedNum = new List<int>();
var random = new Random();
while (generatedNum.Count < 100)
{
var tempo = random.Next(0, 100);
if (generatedNum.Contains(tempo)) continue;
generatedNum.Add(tempo);
}
char[] text2 = text.ToCharArray();
for (int x = 0; x < 10; x++)
{
for (int y = 0; y < 10; y++)
{
Button ta = new Button();
ta.Name = x.ToString()+y.ToString();
ta.Width = sizee;
ta.Height = sizee;
ta.Tag = generatedNum[where];
where++;
ta.BackColor = Color.Red;
ta.Location = new Point(70 * y, 70 * x);
Controls.Add(ta);
ta.Click += new System.EventHandler(this.button_Click);
this.Width += 90 * x / 13;
this.Height += 90 * x / 8;
}
}
}
private void button_Click(object sender, EventArgs e)
{
Control me = (Control)sender;
rememberlast = int.Parse(me.Tag.ToString());
savelastobject = me;
me.Text = me.Tag.ToString();
me.Enabled = true;
me.BackColor = Color.Gray;
move++;
label2.Text = move.ToString();
me.Enabled = true;
me.Text = me.Tag.ToString();
me.BackColor = Color.Gray;
me.Refresh();
Thread.Sleep(1000);
if (move == 20)
{
MessageBox.Show("Total Moves Consumed");
Application.Restart();
}
if (me.Tag.ToString() == textBox1.Text)
{
//Control him = (Control)savelastobject;
//him.BackColor = Color.LightBlue;
me.BackColor = Color.LightBlue;
MessageBox.Show("You Win");
Application.Restart();
}
}
}
}

Getting values from mouse hover on a class object C#

I've a txt file with a 360 numbers, I must read all of these and draw a kind of Disc made of FillPie eachone colored in scale of grey due to the value of the list. Until here everything is quite simple.I made a class with the data(value in the txt and degree) of one single fillpie with a Paint method that draw it of the correct color.
this is the code of the class:
class DatoDisco
{
int valoreSpicchio;
int gradi;
public DatoDisco(int valoreTastatore, int gradiLettura)
{
valoreSpicchio = valoreTastatore;
gradi = gradiLettura;
}
public void Clear()
{
valoreSpicchio = 0;
gradi = 0;
}
private int ScalaGrigi()
{
int grigio = 0;
if (valoreSpicchio <= 0)
{
grigio = 125 + (valoreSpicchio / 10);
if (grigio < 0)
grigio = 0;
}
if (valoreSpicchio > 0)
{
grigio = 125 + (valoreSpicchio / 10);
if (grigio > 230)
grigio = 230;
}
return grigio;
}
public void Paint (Graphics grafica)
{
try
{
Brush penna = new SolidBrush(Color.FromArgb(255, ScalaGrigi(), ScalaGrigi(), ScalaGrigi()));
grafica.FillPie(penna, 0, 0, 400, 400, gradi, 1.0f);
}
catch
{
}
}
public int ValoreSpicchio
{
get
{
return valoreSpicchio;
}
}
public int Gradi
{
get
{
return gradi;
}
}
}
here is where I draw everything:
public partial class Samac : Form
{
libnodave.daveOSserialType fds;
libnodave.daveInterface di;
libnodave.daveConnection dc;
int rack = 0;
int slot = 2;
int scalaGrigi = 0;
int angolatura = 0;
List<int> valoriY = new List<int>();
//Disco disco = new Disco();
List<DatoDisco> disco = new List<DatoDisco>();
float[] valoriTastatore = new float[360];
public Samac()
{
InitializeComponent();
StreamReader dataStream = new StreamReader("save.txt");
textBox1.Text = dataStream.ReadLine();
dataStream.Dispose();
for (int i = 0; i <= 360; i++ )
chart1.Series["Series2"].Points.Add(0);
//AggiornaGrafico(textBox1.Text, chart1);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
string indirizzoIpPlc
{
get
{
FileIniDataParser parser = new FileIniDataParser();
IniData settings = parser.LoadFile("config.ini");
return settings["PLC_CONNECTION"]["PLC_IP"];
}
}
private void AggiornaGrafico(string nomeFile, Chart grafico, bool online)
{
int max = 0;
int min = 0;
grafico.Series["Series1"].Points.Clear();
grafico.Series["Series2"].Points.Clear();
grafico.Series["Series3"].Points.Clear();
grafico.Series["Series4"].Points.Clear();
grafico.ChartAreas[0].AxisX.Maximum = 360;
grafico.ChartAreas[0].AxisX.Minimum = 0;
grafico.ChartAreas[0].AxisY.Maximum = 500;
grafico.ChartAreas[0].AxisY.Minimum = -500;
String file = nomeFile;
valoriY.Clear();
disco.Clear();
if (online == false)
{
System.IO.File.WriteAllText("save.txt", nomeFile);
}
StreamReader dataStreamGrafico = new StreamReader(file);
StreamReader dataStreamScheda = new StreamReader("Scheda.sch");
string datasample;
string[] scheda = new string[56];
for (int i = 0; i < 56; i++)
{
scheda[i] = dataStreamScheda.ReadLine();
}
dataStreamScheda.Close();
int gradi = 1;
while ((datasample = dataStreamGrafico.ReadLine()) != null)
{
grafico.Series["Series2"].Points.Add(0);
grafico.Series["Series2"].Color = Color.Red;
grafico.Series["Series2"].BorderWidth = 3;
grafico.Series["Series3"].Points.Add(Convert.ToInt32(float.Parse(scheda[5])));
grafico.Series["Series3"].Color = Color.Green;
grafico.Series["Series3"].BorderWidth = 3;
grafico.Series["Series4"].Points.Add(Convert.ToInt32(-float.Parse(scheda[5])));
grafico.Series["Series4"].Color = Color.Green;
grafico.Series["Series4"].BorderWidth = 3;
grafico.Series["Series1"].Points.Add(int.Parse(datasample));
grafico.Series["Series1"].BorderWidth = 5;
valoriY.Add(int.Parse(datasample));
//disco.Add(int.Parse(datasample));
disco.Add(new DatoDisco(int.Parse(datasample), gradi));
gradi++;
}
dataStreamGrafico.Close();
max = Convert.ToInt32(chart1.Series["Series1"].Points.FindMaxByValue().YValues[0]);
min = Convert.ToInt32(chart1.Series["Series1"].Points.FindMinByValue().YValues[0]);
lblCampanatura.Text = (((float)max + min) / 2000.0).ToString();
lblSbandieramento.Text = (((float)max - min) / 1000.0).ToString();
if ((Math.Abs(max) > 800) || (Math.Abs(min) > 800))
{
if (Math.Abs(max) >= Math.Abs(min))
{
chart1.ChartAreas[0].AxisY.Maximum = max + 200;
chart1.ChartAreas[0].AxisY.Minimum = -(max + 200);
}
else
{
chart1.ChartAreas[0].AxisY.Maximum = min + 200;
chart1.ChartAreas[0].AxisY.Minimum = -(min + 200);
}
}
else
{
chart1.ChartAreas[0].AxisY.Maximum = 800;
chart1.ChartAreas[0].AxisY.Minimum = -800;
}
boxGraficaDisco.Refresh();
}
private void button1_Click(object sender, EventArgs e)
{
DialogResult result = openFileDialog1.ShowDialog();
textBox1.Text = openFileDialog1.FileName;
if (result == DialogResult.OK)
{
AggiornaGrafico(textBox1.Text, chart1, timer1.Enabled);
}
}
ToolTip tooltip = new ToolTip();
private int lastX;
private int lastY;
private void chart1_MouseMove(object sender, MouseEventArgs e)
{
if (e.X != this.lastX || e.Y != this.lastY)
{
try
{
int cursorX = Convert.ToInt32(chart1.ChartAreas[0].AxisX.PixelPositionToValue(e.Location.X));
tooltip.Show("X:" + cursorX.ToString("0.00") + "Y:" + Convert.ToInt32(chart1.Series[0].Points[cursorX].YValues[0]).ToString(), this.chart1, e.Location.X + 20, e.Location.Y + 20);
}
catch { }
}
this.lastX = e.X;
this.lastY = e.Y;
}
private void button1_Click_1(object sender, EventArgs e)
{
int indice = ((int)Char.GetNumericValue(textBox1.Text[textBox1.Text.Length - 5]))+1;
if (File.Exists(textBox1.Text.Substring(0, textBox1.Text.Length - 5) + indice + ".txt"))
{
textBox1.Text = textBox1.Text.Substring(0, textBox1.Text.Length - 5) + indice + ".txt";
try
{
AggiornaGrafico(textBox1.Text, chart1, timer1.Enabled);
}
catch
{
MessageBox.Show("Il File non esiste");
}
}
else
{
MessageBox.Show("Il File non esiste");
}
}
private void btnGrafMeno_Click(object sender, EventArgs e)
{
int indice = ((int)Char.GetNumericValue(textBox1.Text[textBox1.Text.Length - 5])) - 1;
if (indice >= 0)
{
textBox1.Text = textBox1.Text.Substring(0, textBox1.Text.Length - 5) + indice + ".txt";
try
{
AggiornaGrafico(textBox1.Text, chart1, timer1.Enabled);
}
catch
{
MessageBox.Show("Il File non esiste");
}
}
else
{
MessageBox.Show("Prima lettura disco");
}
}
private void btnConnetti_Click(object sender, EventArgs e)
{
fds.rfd = libnodave.openSocket(102, indirizzoIpPlc);
fds.wfd = fds.rfd;
if (fds.rfd > 0)
{
di = new libnodave.daveInterface(fds, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k);
di.setTimeout(1000000);
dc = new libnodave.daveConnection(di, 0, rack, slot);
int res = dc.connectPLC();
timer1.Start();
// AggiornaGrafico("Disco.csv", chart1, timer1.Enabled);
}
else
{
MessageBox.Show("Impossibile connettersi");
}
}
private void timer1_Tick(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
int res;
res = dc.readBytes(libnodave.daveDB, 21, 40, 1, null);
if (res == 0)
{
var letturaDati = (dc.getS8At(0) & (1 << 0)) != 0;
if (letturaDati == true)
{
int puntatore = 30;
StreamWriter datiDisco = new StreamWriter("DatiDaPlc.csv");
datiDisco.WriteLine("X;" + "C;" + "Z;");
while (puntatore <= 10838)
{
res = dc.readBytes(libnodave.daveDB, 3, puntatore, 192, null);
if (res == 0)
{
for (int i = 0; dc.getU32At(i) != 0; i = i + 12)
{
datiDisco.Write(dc.getU32At(i).ToString() + ";");
datiDisco.Write(dc.getU32At(i + 4).ToString() + ";");
datiDisco.WriteLine(dc.getFloatAt(i + 8).ToString() + ";");
}
}
puntatore = puntatore + 192;
}
datiDisco.Close();
StreamReader lettura = new StreamReader("DatiDaPlc.csv");
StreamWriter scritt = new StreamWriter("Disco.csv");
var titolo = lettura.ReadLine();
var posizioneLettura = lettura.ReadLine();
var posX = posizioneLettura.Split(';');
int minX = Convert.ToInt32(posX[0]) - 5;
int maxX = Convert.ToInt32(posX[0]) + 5;
int contatore = 0;
while (!lettura.EndOfStream)
{
var line = lettura.ReadLine();
var values = line.Split(';');
if ((Convert.ToInt32(values[1]) >= contatore && Convert.ToInt32(values[1]) < contatore + 1000) && (Convert.ToInt32(values[0]) > minX && Convert.ToInt32(values[0]) <= maxX))
{
scritt.WriteLine(Convert.ToInt32(float.Parse(values[2]) * 1000).ToString());
contatore += 1000;
}
}
lettura.Close();
scritt.Close();
AggiornaGrafico("Disco.csv", chart1, timer1.Enabled);
}
}
else
{
timer1.Stop();
MessageBox.Show("Disconnesso");
dc.disconnectPLC();
di.disconnectAdapter();
fds.rfd = libnodave.closeSocket(102);
fds.wfd = fds.rfd;
}
}
}
private void btnDisconnetti_Click(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
dc.disconnectPLC();
di.disconnectAdapter();
fds.rfd = libnodave.closeSocket(102);
fds.wfd = fds.rfd;
timer1.Stop();
AggiornaGrafico(textBox1.Text, chart1, timer1.Enabled);
}
}
private void Samac_FormClosing(object sender, FormClosingEventArgs e)
{
if (timer1.Enabled == true)
{
dc.disconnectPLC();
di.disconnectAdapter();
libnodave.closeSocket(102);
timer1.Stop();
}
}
private void button1_Click_2(object sender, EventArgs e)
{
if (timer1.Enabled == true)
{
AggiornaGrafico("Disco.csv", chart1, timer1.Enabled);
}
else
{
AggiornaGrafico(textBox1.Text, chart1, timer1.Enabled);
}
}
private void chart2_MouseMove(object sender, MouseEventArgs e)
{
if (e.X != this.lastX || e.Y != this.lastY)
{
try
{
int cursorX = Convert.ToInt32(chart2.ChartAreas[0].AxisX.PixelPositionToValue(e.Location.X));
int cursorY = Convert.ToInt32(chart2.ChartAreas[0].AxisY.PixelPositionToValue(e.Location.Y));
//tooltip.Show("X:" + chart2.Series[0].Points[cursorX].XValue.ToString() + "Y:" + chart2.Series[0].Points[cursorX].YValues[0].ToString(), this.chart2, e.Location.X + 20, e.Location.Y + 20);
tooltip.Show("X:" + cursorX.ToString() + "Y:#VALY" , this.chart2, e.Location.X + 20, e.Location.Y + 20);
//chart2.Series[0].ToolTip="#VALY";
}
catch { }
}
this.lastX = e.X;
this.lastY = e.Y;
}
private void boxGraficaDisco_Paint(object sender, PaintEventArgs e)
{
Graphics grafica = e.Graphics;
//disco.Paint(grafica);
foreach (DatoDisco d in disco)
{
d.Paint(grafica);
}
}
private void boxGraficaDisco_MouseMove(object sender, MouseEventArgs e)
{
if (e.X != this.lastX || e.Y != this.lastY)
{
try
{
foreach (DatoDisco d in disco)
{
}
}
catch { }
}
this.lastX = e.X;
this.lastY = e.Y;
}
}
Now I need that when i go with the mouse over the drawn disc, a tooltip show me the data of the fillPie(degree and value of txt) but i can't figure out how.
Anyone can help me?
this is an image of the disc
Eventually it looks as if all you want is a function to get the angle between the mouse position and the center of the disc..
Here is a function to calculate an angle given two points:
double AngleFromPoints(Point pt1, Point pt2)
{
Point P = new Point(pt1.X - pt2.X, pt1.Y - pt2.Y);
double alpha = 0d;
if (P.Y == 0) alpha = P.X > 0 ? 0d : 180d;
else
{
double f = 1d * P.X / (Math.Sqrt(P.X * P.X + P.Y * P.Y));
alpha = Math.Acos(f) * 180d / Math.PI;
if (P.Y > 0) alpha = 360d - alpha;
}
return alpha;
}

Min and max values of an array

I am editing a program made by who knows, a teacher. Anyway, It is to display stock values that are stored in an array shown in a graph. The teacher has noted that the graph Y axis isn't correct, but we don't have to change that. What we have to change is the radio buttons to checkboxes so we can display multiple stock values on a graph.
So to draw the new graph we have to get the minimum and maximum Y values of the stocks selected. I decided to go with:
if (checkBox1.Checked == true)
{
GetStockValues(0);
maxVal[0] = StockArray.Max();
}
int maxValue = Convert.ToInt16(maxVal.Min());
return maxValue;
The same goes for minValue. The problem is I am not getting any correct numbers. Here is the whole program:
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;
namespace VC2008_StockMktGraphics
{
public partial class frmMaster : Form
{
// let's make the stock values array be public so we don't have to pass
// them back and forth.
public double[] StockArray = new double[ 30 ] ;
public double[] minVal = new double [ 4 ];
public double[] maxVal = new double[4];
public frmMaster()
{
InitializeComponent();
}
private void frmMaster_Resize(object sender, EventArgs e)
{
this.Invalidate() ;
}
protected override void OnPaint(PaintEventArgs e)
{
int h = this.Bounds.Height ;
int w = this.Bounds.Width ;
Rectangle r = new Rectangle();
// Create the graphics context to draw into
Graphics gc = this.CreateGraphics() ;
Pen pBl = new Pen( Color.Black , 2) ;
SolidBrush sB = new SolidBrush(Color.Honeydew ) ;
// if the window is too small, force it to a size
if ( ( h < 200 ) || ( w < 200 ) )
{
this.Width = 200 ;
this.Height = 200 ;
}
// Set dynamic location of graphics box
r.X=Convert.ToInt32( Convert.ToDouble( w ) * 0.2 ) ;
r.Y=Convert.ToInt32( Convert.ToDouble( w ) * 0.2 ) ;
r.Width=Convert.ToInt32( Convert.ToDouble( w ) * 0.8 ) -r.X ;
r.Height=Convert.ToInt32( Convert.ToDouble( h ) * 0.8 -r.Y );
// draw the outer rectangle and fill with a light color
gc.DrawRectangle(pBl, r);
gc.FillRectangle(sB, r);
// set the location of the buttons
btnExit.Left = r.X + r.Width + 10;
btnExit.Top = 10;
chkStartAtZero.Left = r.X + r.Width + 10;
chkStartAtZero.Top = btnExit.Top + 25;
checkBox1.Left = r.X + r.Width + 10;
checkBox1.Top = chkStartAtZero.Top + 25;
checkBox2.Left = checkBox1.Left;
checkBox2.Top = checkBox1.Top + 25;
checkBox3.Left = checkBox2.Left;
checkBox3.Top = checkBox2.Top + 25;
checkBox4.Left = checkBox3.Left;
checkBox4.Top = checkBox3.Top + 25;
if (checkBox1.Checked == true)
DrawStock(0, gc, r);
if (checkBox2.Checked == true)
DrawStock(1, gc, r);
if (checkBox3.Checked == true)
DrawStock(2, gc, r);
if (checkBox4.Checked == true)
DrawStock(3, gc, r);
// dispose of object memories we've allocated
pBl.Dispose() ;
sB.Dispose();
gc.Dispose() ;
}
public void DrawStock( int iWhichStock , Graphics gc , Rectangle r )
{
int i ;
int iLabelX;
int iMinY = 999999;
int iMaxY = 0;
int iCnt;
double dxIncrement;
double dyIncrement;
string strAxisLabel;
Point pLineStart = new Point();
Point pLineEnd = new Point();
Pen pB2 = new Pen(Color.Red, 2);
Font f = new Font("Ariel", (float)10.0);
Brush b = new SolidBrush(Color.Blue);
// Normally, we'd get stock from a database, I'm just going to go
// get it from a function with hard-coded values for demonstration
// purposes.
iMinY = Convert.ToInt16(GetMin());
iMaxY = Convert.ToInt16(GetMax());
// Take the min and max to the next increment of 5 outside them.
iMinY = Convert.ToInt16( iMinY / 5 ) * 5 ;
iMaxY = ( Convert.ToInt16(iMaxY / 5 ) + 1 ) * 5 ;
// Find the number of x-coordinate values
iCnt = 0;
foreach (double d in StockArray)
{
if (d > 0)
iCnt++;
}
// so now we know how many x values there are to spread on the x-axis
dxIncrement = Convert.ToDouble(r.Width / iCnt);
// if the zero checkbox is checked, then we'll set the minimums to zero
if (chkStartAtZero.Checked == true)
{
iMinY = 0;
dMinStockValue = 0.0;
}
// so each y-axis pixel must contain this many dollars of actual stock price
dyIncrement = Convert.ToDouble(r.Height / (iMaxY - iMinY));
// set the starting point of the stock line
pLineStart.X = r.X;
pLineStart.Y = r.Top + r.Height -
Convert.ToInt16(dyIncrement * (StockArray[ 0 ] - Convert.ToDouble(iMinY) ) ) ;
// now graph them
for( i = 1 ; i < StockArray.Length ; i++ )
{
if( StockArray[i] == 0 )
continue ;
pLineEnd.X = pLineStart.X + Convert.ToInt16(dxIncrement);
pLineEnd.Y = r.Top + r.Height -
Convert.ToInt16(dyIncrement * (StockArray[i] - Convert.ToDouble(iMinY)));
gc.DrawLine(pB2,pLineStart, pLineEnd ) ;
pLineStart = pLineEnd ;
}
// now draw the y-axis labels
i = iMinY;
pLineStart.X = r.X;
pLineStart.Y = r.Top + r.Height - Convert.ToInt16(0);
pLineEnd.X = r.X - 8;
while( i <= iMaxY )
{
pLineStart.Y = r.Top + r.Height -
Convert.ToInt16( Convert.ToDouble(i-iMinY ) * dyIncrement ) ;
pLineEnd.Y = pLineStart.Y;
gc.DrawLine(pB2, pLineStart, pLineEnd);
strAxisLabel = Convert.ToString(i);
iLabelX = pLineEnd.X - 18;
if (i < 10)
iLabelX = pLineEnd.X - 8;
else
if (i < 100)
iLabelX = pLineEnd.X - 18;
else
if (i < 1000)
iLabelX = pLineEnd.X - 28;
gc.DrawString(strAxisLabel, f, b, iLabelX, pLineEnd.Y - 8);
i += 10;
}
}
public double GetMin()
{
if (checkBox1.Checked == true)
{
GetStockValues(0);
minVal[0] = StockArray.Min();
}
if (checkBox2.Checked == true)
{
GetStockValues(1);
minVal[1] = StockArray.Min();
}
if (checkBox3.Checked == true)
{
GetStockValues(2);
minVal[2] = StockArray.Min();
}
if (checkBox4.Checked == true)
{
GetStockValues(3);
minVal[3] = StockArray.Min();
}
int minValue = Convert.ToInt16(minVal.Min());
label1.Text = Convert.ToString(minValue);
return minValue;
}
public double GetMax()
{
if (checkBox1.Checked == true)
{
GetStockValues(0);
maxVal[0] = StockArray.Max();
}
if (checkBox2.Checked == true)
{
GetStockValues(1);
maxVal[1] = StockArray.Max();
}
if (checkBox3.Checked == true)
{
GetStockValues(2);
maxVal[2] = StockArray.Max();
}
if (checkBox4.Checked == true)
{
GetStockValues(3);
maxVal[3] = StockArray.Max();
}
int maxValue = Convert.ToInt16(maxVal.Min());
label2.Text = Convert.ToString(maxValue);
return maxValue;
}
public void GetStockValues(int iWhichStock)
{
if (iWhichStock == 0)
{
// IBM
StockArray[0] = 147.64; // 1-10-11
StockArray[1] = 147.28;
StockArray[2] = 149.10;
StockArray[3] = 148.82;
StockArray[4] = 150.00;
StockArray[5] = 150.65;
StockArray[6] = 155.69;
StockArray[7] = 155.80;
StockArray[8] = 155.50;
StockArray[9] = 159.63;
StockArray[10] = 161.44;
StockArray[11] = 161.04;
StockArray[12] = 161.07;
StockArray[13] = 159.21;
StockArray[14] = 162.00;
StockArray[15] = 163.56;
StockArray[16] = 163.30;
StockArray[17] = 163.53;
StockArray[18] = 164.00;
StockArray[19] = 164.83;
}
if (iWhichStock == 1)
{
// BA (The Boeing Company)
StockArray[0] = 69.09; // 1-10-11
StockArray[1] = 68.96;
StockArray[2] = 70.15;
StockArray[3] = 69.63;
StockArray[4] = 70.07;
StockArray[5] = 72.47;
StockArray[6] = 71.73;
StockArray[7] = 71.12;
StockArray[8] = 71.68;
StockArray[9] = 72.73;
StockArray[10] = 72.24;
StockArray[11] = 70.02;
StockArray[12] = 70.56;
StockArray[13] = 69.23;
StockArray[14] = 69.48;
StockArray[15] = 70.29;
StockArray[16] = 71.00;
StockArray[17] = 70.98;
StockArray[18] = 71.38;
StockArray[19] = 71.93;
}
if (iWhichStock == 2)
{
// CAP (CAI International
StockArray[0] = 19.44; // 1-10-11
StockArray[1] = 19.66;
StockArray[2] = 19.68;
StockArray[3] = 19.45;
StockArray[4] = 19.79;
StockArray[5] = 19.90;
StockArray[6] = 19.53;
StockArray[7] = 19.06;
StockArray[8] = 19.05;
StockArray[9] = 19.14;
StockArray[10] = 19.28;
StockArray[11] = 20.11;
StockArray[12] = 19.74;
StockArray[13] = 19.06;
StockArray[14] = 19.04;
StockArray[15] = 20.03;
StockArray[16] = 19.69;
StockArray[17] = 19.56;
StockArray[18] = 19.61;
StockArray[19] = 19.63;
}
if (iWhichStock == 3)
{
// TOT (Total Societe Anonyme)
StockArray[0] = 53.00; // 1-10-11
StockArray[1] = 53.32;
StockArray[2] = 55.00;
StockArray[3] = 56.03;
StockArray[4] = 57.11;
StockArray[5] = 57.10;
StockArray[6] = 56.95;
StockArray[7] = 57.12;
StockArray[8] = 57.12;
StockArray[9] = 58.04;
StockArray[10] = 58.79;
StockArray[11] = 58.69;
StockArray[12] = 59.00;
StockArray[13] = 59.50;
StockArray[14] = 57.80;
StockArray[15] = 58.77;
StockArray[16] = 61.03;
StockArray[17] = 60.70;
StockArray[18] = 59.76;
StockArray[19] = 59.25;
}
}
private void btnExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
private void chkStartAtZero_CheckedChanged(object sender, EventArgs e)
{
this.Invalidate();
}
private void checkBox1_CheckedChanged(object sender, EventArgs e)
{
this.Invalidate();
}
private void checkBox2_CheckedChanged(object sender, EventArgs e)
{
this.Invalidate();
}
private void checkBox3_CheckedChanged(object sender, EventArgs e)
{
this.Invalidate();
}
private void checkBox4_CheckedChanged(object sender, EventArgs e)
{
this.Invalidate();
}
private void frmMaster_Load(object sender, EventArgs e)
{
}
}
}
A couple problems.
Your main issue is you call int maxValue = Convert.ToInt16(maxVal.Min()); in GetMax(), I think you wanted int maxValue = Convert.ToInt16(maxVal.Max());.
However once you fix that you are going to run in to the fact that you are comparing uninitialized/old values of the maxVal array.
Say I only have checkbox 1 and 3 checked, then later I un-check 3, What will be the value of maxVal[2] the seccond time GetMax or GetMin is run, (here's a hint, it's not 0)

Categories