I am making a GUI that reads in serial data, and I want to have the option to choose to plot the data on either the left or right Y axis. I can plot the data on the left y axis, but I am unable to plot it on the Left axis. What is wrong with my code?
Here is the relevant Code:
GraphPane myPane2;
PointPairList inst3time = new PointPairList();
myPane2 = zedGraphControl2.GraphPane;
myPane2.Title = "Data vs Time Plots";
myPane2.XAxis.Title = "Elapsed Minutes";
private void UpdateData3(string line)
{
if (this.InvokeRequired)
{
this.BeginInvoke(new UpdateDataDelegate(UpdateData3), new object[] { line });
}
else
{
if (chk_DISPLAY_3.Checked == true)
{
timer3.Interval = (30000);
timer3.Start();
OZ1lastdatatime = DateTime.Now;
count++;
if (count > 7)
{
count = 0;
TextBox_3.Text = "";
TextBox_3.AppendText(line);
}
else
{
TextBox_3.AppendText(line);
}
}
if (chk_SAVE_FILE_3.Checked == true)
{
StoreData3.Write(line);
StoreData3.Flush();
}
if (chk_PLOT_3.Checked == true)
{
string[] blahArray = line.Split(new char[] { ',' });
//string blaharray = Convert.ToDouble(blahArray[2]).ToString("F4");
int column_data = Convert.ToInt32(textBox5.Text);
double inst3 = Convert.ToDouble(blahArray[column_data]);
//TextBox_3.Text = Convert.ToString(oz1);
TimeSpan span = DateTime.UtcNow - startDateTimeOfProgram;
double elapsedMinutes = span.TotalMinutes;
inst3time.Add(elapsedMinutes,inst3);
if (cbo_POSITION_3.Text == "LEFT")
{
myPane2.YAxis.Title = cbo_Instrument_3.Text;
zedGraphControl2.AxisChange();
zedGraphControl2.GraphPane.AddCurve("",inst3time, Color.Blue, SymbolType.Circle);
zedGraphControl2.Refresh();
}
if (cbo_POSITION_3.Text == "RIGHT")
{
myPane2.Y2Axis.Title = cbo_Instrument_3.Text;
zedGraphControl2.AxisChange();
LineItem myCurve = zedGraphControl2.GraphPane.AddCurve("",inst3time, Color.Blue, SymbolType.Circle);
myCurve.IsY2Axis = true;
zedGraphControl2.Refresh();
}
}
}
}
I was able to figure it out: I needed to make sure that the Y2 Axis was visible:
myPane2.Y2Axis.IsVisible = true;
myPane2.Y2Axis.Title = cbo_Instrument_3.Text;
zedGraphControl2.AxisChange();
LineItem myCurve = myPane2.AddCurve("",inst3time, Color.Blue, SymbolType.Circle);
myCurve.IsY2Axis = true;
zedGraphControl2.AxisChange();
zedGraphControl2.Refresh();
Related
I have a route/polygon named "BBB"(figure1,figure2) in my GMap .Net Windows form Application.I am drawing route/polygon from mouse and storing all latitudes and longitudes into List<PointLatLng>.What i want is set of Latitudes and Longitudes between two intersecting points(latitude and longitude).
Note:
I have all Latitudes and Longitudes of route/polygon "BBB"(figure1,figure2) as well as "CCC"(figure1,figure2).
please let me know if something is not clear.Is there any Library or Api ?
Code: Some Code for Idea
List<PointLatLng> ListOfDragLatLang = new List<PointLatLng>();
PointLatLng StartingLatLng = new PointLatLng();
PointLatLng EndingLatLng = new PointLatLng();
// polygons
GMapPolygon polygon;
readonly GMapOverlay top = new GMapOverlay();
internal readonly GMapOverlay objects = new GMapOverlay("objects");//for storing markers
internal readonly GMapOverlay routes = new GMapOverlay("routes");// for storing routes
internal readonly GMapOverlay polygons = new GMapOverlay("polygons");//for storing polygons
public bool IsErasorCursorVisible { get => _IsErasorCursorVisible; set => _IsErasorCursorVisible = value; }
public bool IsPencilCursorVisible { get => _IsPencilCursorVisible; set => _IsPencilCursorVisible = value; }
public bool IsNormalCursorVisible { get => _IsNormalCursorVisible; set => _IsNormalCursorVisible = value; }
private void MainMap_MouseUp(object sender, MouseEventArgs e)
{
PointLatLng OnMouse = MainMap.FromLocalToLatLng(e.X, e.Y);
lblLatitude.Text = OnMouse.Lat.ToString();
lblLongitude.Text = OnMouse.Lng.ToString();
if (IsPencilCursorVisible && IsDrawing)
{
EndingLatLng = MainMap.FromLocalToLatLng(e.X, e.Y);
ListOfDragLatLang.Add(StartingLatLng);
IsDragging = false;
IsDrawing = false;
MainMap.DragButton = MouseButtons.Right;
//polygon = new GMapPolygon(ListOfDragLatLang, txtZoneName.Text);
//polygon.LocalPoints.AddRange(ListOfPoints);
//polygon.Stroke = new Pen(Color.Black, 3);
//polygon.IsHitTestVisible = true;
//polygon.Stroke.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
//polygons.Polygons.Add(polygon);
//MainMap.UpdatePolygonLocalPosition(polygon);
lblTotalPolygonsAdded.Text = polygons.Polygons.Count.ToString();
for (int i = 0; i < ListOfDragLatLang.Count; i++)
{
AddPinPointToPolygon(ListOfDragLatLang[i], i, txtZoneName.Text);
}
RegenerateRoute(txtZoneName.Text);
GMarkerGoogle marker = new GMarkerGoogle(new PointLatLng(ListOfDragLatLang.Sum(c => c.Lat) / ListOfDragLatLang.Count, ListOfDragLatLang.Sum(c => c.Lng) / ListOfDragLatLang.Count), GMarkerGoogleType.orange_dot);
marker.ToolTip = new GMapBaloonToolTip(marker);
marker.ToolTipText = txtZoneName.Text;
marker.ToolTipMode = MarkerTooltipMode.Always;
marker.IsVisible = true;
marker.Tag = txtZoneName.Text;
objects.Markers.Add(marker);
MainMap.UpdateMarkerLocalPosition(marker);
MainMap.UpdatePolygonLocalPosition(polygon);
}
}
private void MainMap_MouseDown(object sender, MouseEventArgs e)
{
PointLatLng OnMouse = MainMap.FromLocalToLatLng(e.X, e.Y);
if (e.Button == MouseButtons.Left)
{
if (IsPencilCursorVisible && IsDrawing)
{
StartingLatLng = OnMouse;
ListOfDragLatLang.Add(StartingLatLng);
ListOfPoints.Add(new GPoint(e.X, e.Y));
IsDragging = true;
MainMap.DragButton = MouseButtons.Middle;
currentRoute = new GMapRoute(txtZoneName.Text);
currentRoute.Stroke = new Pen(Color.Black, 3);
currentRoute.IsHitTestVisible = true;
routes.Routes.Add(currentRoute);
MainMap.UpdateRouteLocalPosition(currentRoute);
//polygon = new GMapPolygon(ListOfDragLatLang,txtZoneName.Text);
//polygon.LocalPoints.AddRange(ListOfPoints);
//polygon.Stroke = new Pen(Color.Black, 3);
//polygon.IsHitTestVisible = true;
//polygon.Stroke.DashStyle = System.Drawing.Drawing2D.DashStyle.Solid;
//polygons.Polygons.Add(polygon);
//MainMap.UpdatePolygonLocalPosition(polygon);
}
}
}
private void MainMap_MouseMove(object sender, MouseEventArgs e)
{
PointLatLng OnMouse = MainMap.FromLocalToLatLng(e.X, e.Y);
lblLatitude.Text = OnMouse.Lat.ToString();
lblLongitude.Text = OnMouse.Lng.ToString();
if (e.Button == MouseButtons.Left)
{
if (IsPencilCursorVisible && IsDrawing)
{
if (MainMap.IsMouseOverPolygon)
{
MainMap.Cursor = MainCursor;
}
else
{
MainMap.Cursor = PencilCursor;
}
IsDragging = true;
ListOfPoints.Add(new GPoint(e.X, e.Y));
ListOfDragLatLang.Add(OnMouse);
lblTotalLatLng.Text = ListOfDragLatLang.Count.ToString();
currentRoute.Points.Add(OnMouse);
MainMap.UpdateRouteLocalPosition(currentRoute);
//polygon.Points.Add(OnMouse);
//MainMap.UpdatePolygonLocalPosition(polygon);
}
else
{
PointLatLng pnew = MainMap.FromLocalToLatLng(e.X, e.Y);
if (CurentRectMarker == null)
{
return;
}
int? pIndex = (int?)CurentRectMarker.Tag;
if (pIndex.HasValue)
{
if (pIndex < currentRoute.Points.Count)
{
currentRoute.Points[pIndex.Value] = pnew;
MainMap.UpdateRouteLocalPosition(currentRoute);
}
//if (pIndex < polygon.Points.Count)
//{
// polygon.Points[pIndex.Value] = pnew;
// MainMap.UpdatePolygonLocalPosition(polygon);
//}
}
if (currentMarker.IsVisible)
{
currentMarker.Position = pnew;
}
CurentRectMarker.Position = pnew;
if (CurentRectMarker.InnerMarker != null)
{
CurentRectMarker.InnerMarker.Position = pnew;
}
}
MainMap.Refresh();
}
}
Figure 1
Figure 2
Question:How to get the Latitudes and Longitudes of yellow color edge in figure 2 between intersecting point "A" and "B"?
Assuming your List is in the correct order
Find the index of the coordinate at point A and B in your List and then create a new list using all points that are between the two indexes.
I want to detect the rectangles in the red zone of the picture below, I defined the picture center and drew a line and compared my center to the rectangles center and that way I am able to find the centres.
My approach didn't take Y into consideration but the left range requires that. So I think Points would be appropriate to use here but I don't know how to do that,
QUESTION How to define this range(demonstrated by the redlines), I just want to know which objects are on the left line,right line,center line(gray lines), So by defining lines,spaces, anything would work for me,
// Rectangles am interested in, have left, right, top, bottom pixel position
var rectangleCenter =(left + right) / 2;
if (rectangleCenter >= (CenterRef - 50) && rectangleCenter <= (CenterRef + 50))
{
}
// assuming 5 is the curve
for(int i=0; i<somelimit; i+5)
{
var rectangleCenter = (left + right) / 2;
// assuming its a 1000 pixel image, Mycenter is 500,
leftRef = MyCenter + 250;
leftRef + i;
if (rectangleCenter >= (leftRef - 50) && rectangleCenter <= (leftRef + 50))
{
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
double[,] allPoints = new double[5, 3]; //Each rectangle is defined by 4 X/Y Points (left-top, left-bottom, right-top and right-bottom)
//The four points of each rectangle have to be inside the given area (inside the given couple of red lines)
int foundInArea = 0;
int areaCount = 0;
do
{
areaCount = areaCount + 1; //There are three areas; what is inside each couple of two red lines
foundInArea = areaCount;
int count1 = 0;
do
{
count1 = count1 + 1;
if (!isInArea(areaCount, new double[] { 0, allPoints[count1, 1], allPoints[count1, 2] }))
{
foundInArea = 0;
break;
}
} while (count1 < 4);
if (foundInArea > 0)
{
break;
}
} while (areaCount < 3);
if (foundInArea > 0)
{
//Rectangle inside are foundInArea
}
}
private bool isInArea(int areaNo, double[] pointToTest)
{
bool isThere = false;
double alpha = returnAngles(areaNo); //Inclination of the red lines
double[] startPoint1 = returnStartEndPoints(areaNo, true, true); //Initial point of the red line on the left
double[] endPoint1 = returnStartEndPoints(areaNo, true, false); //End point of the red line on the left
double[] startPoint2 = returnStartEndPoints(areaNo, false, true); //Initial point of the red line on the right
double[] endPoint2 = returnStartEndPoints(areaNo, false, false); //End point of the red line on the right
return checkPoint(pointToTest, alpha, startPoint1, endPoint1, startPoint2, endPoint2);
}
private bool checkPoint(double[] pointToTest, double alpha, double[] startPoint1, double[] endPoint1, double[] startPoint2, double[] endPoint2)
{
bool isThere = false;
//You have all the information and can perform the required trigonometrical calculculations to determine whether the two lines surround the given point or not
//I think that I have worked more than enough in this code :)
return isThere;
}
//Hardcoded angles for each red line.
//All the angles have to be taken from the same reference point (for example: middle-bottom part)
//Example: area1 (lines on the left): 240 degree, area2: 270 degree...
private double returnAngles(int areaNo)
{
double outVal = 0;
if (areaNo == 1)
{
//outVal = val;
}
else if (areaNo == 2)
{
//outVal = val;
}
else if (areaNo == 3)
{
//outVal = val;
}
return outVal;
}
//Returning the X (index 1) and Y (index 2) values under the given conditions (start/end point for each area)
//These values have to be hardcoded from a rough estimation. For example, by assuming that the start is in the upper part,
//the starting point for the left line can be assumed to be X = max_X/3 and Y = max_Y
private double[] returnStartEndPoints(int areaNo, bool isLeftLine, bool isStartPoint)
{
double[] outPoint = new double[3];
if (areaNo == 1)
{
if (isLeftLine)
{
if (isStartPoint)
{
//outPoint[1] = value; //hardcoded X for start point of line on the left of area1
//outPoint[2] = value; //hardcoded Y for start point of line on the left of area1
}
else
{
//outPoint[1] = value;
//outPoint[2] = value;
}
}
else
{
if (isStartPoint)
{
//outPoint[1] = value;
//outPoint[2] = value;
}
else
{
//outPoint[1] = value;
//outPoint[2] = value;
}
}
}
else if (areaNo == 2)
{
if (isLeftLine)
{
if (isStartPoint)
{
//outPoint[1] = value;
//outPoint[2] = value;
}
else
{
//outPoint[1] = value;
//outPoint[2] = value;
}
}
else
{
if (isStartPoint)
{
//outPoint[1] = value;
//outPoint[2] = value;
}
else
{
//outPoint[1] = value;
//outPoint[2] = value;
}
}
}
else if (areaNo == 3)
{
if (isLeftLine)
{
if (isStartPoint)
{
//outPoint[1] = value;
//outPoint[2] = value;
}
else
{
//outPoint[1] = value;
//outPoint[2] = value;
}
}
else
{
if (isStartPoint)
{
//outPoint[1] = value;
//outPoint[2] = value;
}
else
{
//outPoint[1] = value;
//outPoint[2] = value;
}
}
}
return outPoint;
}
}
How can I use Luxand API to get to work in visual studio 2010? I need to detect points of chin in a given face, can I do it with any other API?
I have tried this sample code:
OpenFileDialog openFileDialog1 = new OpenFileDialog();
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
try
{
FSDK.CImage image = new FSDK.CImage(openFileDialog1.FileName);
// resize image to fit the window width
double ratio = System.Math.Min((pictureBox1.Width + 0.4) / image.Width,
(pictureBox1.Height + 0.4) / image.Height);
image = image.Resize(ratio);
Image frameImage = image.ToCLRImage();
Graphics gr = Graphics.FromImage(frameImage);
FSDK.TFacePosition facePosition = image.DetectFace();
if (0 == facePosition.w)
MessageBox.Show("No faces detected", "Face Detection");
else
{
int left = facePosition.xc - facePosition.w / 2;
int top = facePosition.yc - facePosition.w / 2;
gr.DrawRectangle(Pens.LightGreen, left, top, facePosition.w, facePosition.w);
FSDK.TPoint[] facialFeatures = image.DetectFacialFeaturesInRegion(ref facePosition);
int i = 0;
foreach (FSDK.TPoint point in facialFeatures)
gr.DrawEllipse((++i > 2) ? Pens.LightGreen : Pens.Blue, point.x, point.y, 3, 3);
gr.Flush();
}
// display image
pictureBox1.Image = frameImage;
pictureBox1.Refresh();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Exception");
}
}
I get this error:
Could not load file or assembly 'xquisite.application.exe' or one of its dependencies. This assembly is built by a runtime newer than the currently loaded runtime and cannot be loaded.
what is your settings for your target? Any CPU ? Try x86 for Runtime !
have you add to your app.config <startup useLegacyV2RuntimeActivationPolicy="true"/>
?
These two thinks i forgot, were the reason of my errors which was the same as yours.
here is a piece of my code:
private void DetectFace()
{
var failerCounter = 0;
var cameraHandler = 0;
try
{
const int failerLimit = 2;
int failerLimitFaceDetection = Properties.Settings.Default.NotDetectedLimit;
float similarityMinimum = Properties.Settings.Default.SimilarityLimit;
var r = FSDKCam.OpenVideoCamera(ref CameraName, ref cameraHandler);
if (r != FSDK.FSDKE_OK)
{
MessageBox.Show(StringHelper.ErrorCamera);
}
FSDK.SetFaceDetectionParameters(
Properties.Settings.Default.DetectionHandleArbitaryRotations,
Properties.Settings.Default.DetectionDetermineFaceRotationAngle,
Properties.Settings.Default.DetectionInternalResizeWidth);
FSDK.SetFaceDetectionThreshold(Properties.Settings.Default.DetectionFaceDetectionThreshold);
while (IsFaceDetectionActive)
{
var imageHandle = 0;
if (FSDK.FSDKE_OK != FSDKCam.GrabFrame(cameraHandler, ref imageHandle))
{
Application.Current.Dispatcher.Invoke(delegate { }, DispatcherPriority.Background);
continue;
}
var image = new FSDK.CImage(imageHandle);
var frameImage = image.ToCLRImage();
FaceContent = frameImage;
var gr = Graphics.FromImage(frameImage);
var facePosition = image.DetectFace();
IsFaceDetected = facePosition.w != 0;
if (!IsFaceDetected)
{
if (failerCounter++ > failerLimitFaceDetection)
{
failerCounter = 0;
OnFaceNotDetected();
}
}
// if a face is detected, we detect facial features
if (IsFaceDetected)
{
var facialFeatures = image.DetectFacialFeaturesInRegion(ref facePosition);
SmoothFacialFeatures(ref facialFeatures);
FaceTemplate = image.GetFaceTemplate();
// Similarity = 0.5f -> fin the right value ....
IsFaceRecognized = FaceMetricHandler.LooksLike(FaceTemplate, similarityMinimum).Any();
if (IsFaceRecognized)
{
foreach (var match in FaceMetricHandler.LooksLike(FaceTemplate, similarityMinimum))
{
failerCounter = 0;
GreetingMessage = match.Name;
IsFaceDetectionActive = false;
OnFaceRecognized();
break;
}
}
else
{
if (failerCounter++ > failerLimit)
{
failerCounter = 0;
IsFaceDetectionActive = false;
OnFaceNotRecognized();
}
}
if (IsFaceFrameActive)
{
gr.DrawRectangle(Pens.Red, facePosition.xc - 2*facePosition.w/3,
facePosition.yc - facePosition.w/2,
4*facePosition.w/3, 4*facePosition.w/3);
}
}
else
{
ResetSmoothing();
}
FaceContent = frameImage;
GC.Collect();
Application.Current.Dispatcher.Invoke(delegate { }, DispatcherPriority.Background);
}
}
catch(Exception e)
{
logger.Fatal(e.Message);
InitializeCamera();
}
finally
{
FSDKCam.CloseVideoCamera(cameraHandler);
FSDKCam.FinalizeCapturing();
}
}
BTW, you can use x64 with win64\FaceSDK.NET.dll
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)
So I've made this range bar chart with the MS Chart Control. I have two questions:
How can I implement an event handler for when the user double clicks a series? I can't see one anywhere.
For some reason the scrollbar on my X Axis (which, amusingly, the Chart Control seems to think is the Y Axis...) seems to be partially transparent for some reason...can anyone shed any light as to why that might be?
Here's my code so far, bastardised from a PDF I found somewhere on the net (yeah, I know, it's messy, needs tidying up):
private void PopulateGantt()
{
foreach (Job jobThis in lstJobs)
{
if ((jobThis.HireFrom != null) && (jobThis.HireTo != null))
{
string xlabel = string.Empty;
double xordinal = 0;
double yplot1 = 0;
double yplot2 = 0;
yplot1 = (double)((DateTime)jobThis.HireFrom).ToOADate();
yplot2 = (double)((DateTime)jobThis.HireTo).ToOADate()+1;
// Use a different series for each datapoint
Series seriesInstance = new Series();
// For Gantt charts, we want a RangeBar graph type
seriesInstance.ChartType = SeriesChartType.RangeBar;
// Have a start and end date so plotting 2 points on the y-axis
seriesInstance.YValuesPerPoint = 2;
// We want to draw datapoint side by side (night is day?)
seriesInstance.CustomProperties = "DrawSideBySide=false";
// Add the datapoint to the series, specifying tooltiptext, colorand label
xordinal = lstJobs.IndexOf(jobThis); //(double)itemIndex;
seriesInstance.Points.AddXY(xordinal, yplot1, yplot2);
//seriesInstance.Points[0].Color = resourceColor;
seriesInstance.Points[0].AxisLabel = xlabel;
seriesInstance.Label = jobThis.Number + jobThis.Type + " - " + jobThis.ClientCompanyName;
seriesInstance.Points[0].ToolTip = jobThis.Number + jobThis.Type +
"\r\n\r\n" + jobThis.ClientCompanyName +
"\r\n\r\n" + jobThis.BriefDescription;
seriesList.Add(seriesInstance);
}
chtHC.Series.Clear();
foreach (Series plotSeries in seriesList)
{
chtHC.Series.Add(plotSeries);
}
// Force x-axis to show each task or resource
chtHC.ChartAreas[0].AxisX.Interval = 1;
// Set y-axis to show each day of the month
chtHC.ChartAreas[0].AxisY.Interval = 1;
// Set x-axis to show in reversed order so dates are displayed leftto-right
//chtHC.ChartAreas[0].AxisY.IsReversed = true;
//chtHC.ChartAreas[0].AxisX
// Set other y-axis properties
chtHC.ChartAreas[0].AxisY.IsStartedFromZero = false;
chtHC.ChartAreas[0].AxisY.IsMarginVisible = false;
chtHC.ChartAreas[0].AxisY.IntervalType = DateTimeIntervalType.Days;
// Set the y-axis labels
DateTime? datFirst = null;// = new DateTime();
DateTime? datLast = null; //= new DateTime();
//datFirst = (DateTime)lstJobs[0].HireFrom;
foreach (Job jobFirst in lstJobs)
{
if (jobFirst.HireFrom != null)
{
if (datFirst == null)
{
datFirst = (DateTime)jobFirst.HireFrom;
}
else
{
if (jobFirst.HireFrom < datFirst)
{
datFirst = (DateTime)jobFirst.HireFrom;
}
}
}
if (jobFirst.HireTo != null)
{
if (datLast == null)
{
datLast = (DateTime)jobFirst.HireTo;
}
else
{
if (jobFirst.HireTo > datLast)
{
datLast = (DateTime)jobFirst.HireTo;
}
}
}
}
if ((datFirst != null))
{
//datLast = ((DateTime)datFirst).AddDays(21);
chtHC.ChartAreas[0].AxisY.Minimum = ((DateTime)datFirst).AddDays(-1).ToOADate();
chtHC.ChartAreas[0].AxisY.Maximum = ((DateTime)datLast).AddDays(+1).ToOADate();
}
chtHC.ChartAreas[0].CursorY.AutoScroll = true;
chtHC.ChartAreas[0].AxisY.ScaleView.Zoomable = true;
chtHC.ChartAreas[0].AxisY.ScaleView.SizeType = DateTimeIntervalType.Days;
//chtHC.ChartAreas[0].AxisY.LabelStyle.Format = "MMM dd ddd";
//chtHC.ChartAreas[0].AxisY.LabelStyle.Format = "ddd MMM dd";
chtHC.ChartAreas[0].AxisY.LabelStyle.Format = "ddd dd/MM/yyyy";
//chtHC.ChartAreas[0].AxisX.// Force redraw of chart
chtHC.ChartAreas[0].AxisY.ScaleView.Zoom(chtHC.ChartAreas[0].AxisY.Minimum, chtHC.ChartAreas[0].AxisY.Minimum+21);
chtHC.ChartAreas[0].AxisY.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
chtHC.ChartAreas[0].AxisY.ScaleView.SmallScrollSize = 1;
chtHC.Update();
}
}
There's no specific event able to handle datapoint clicks, but you can use MouseClick event plus HitTest method, e.g.:
void chart1_MouseClick(object sender, MouseEventArgs e)
{
var pos = e.Location;
var results = chart1.HitTest(pos.X, pos.Y,false, ChartElementType.DataPoint);
foreach (var result in results)
{
if (result.ChartElementType == ChartElementType.DataPoint)
{
// use result.Series etc...
}
}
}
the chart has also a double click event
private void chart_MouseDoubleClick(object sender, MouseEventArgs e)