/* F H I T T E S T */ /*---------------------------------------------------------------------------- * %%Function: FHitTest * %%Qualified: bg.SBGE.FHitTest * %%Contact: rlittle * * ----------------------------------------------------------------------------*/ public bool FHitTest(Point ptClient, out object oHit, out RectangleF rectfHit) { rectfHit = new RectangleF();; PTFI ptfiHit; // figure out what we hit. // convert the pt into a raw point compatible with our array PointF ptfArray = new PointF(((float)ptClient.X) + m_dxAdjust, (float)ptClient.Y); ptfiHit = new PTFI(); bool fHit = false; // now we can go searching for a point this corresponds to foreach (PTFI ptfi in m_plptfi) { rectfHit = new RectangleF(ptfi.ptf.X - 4.0F, ptfi.ptf.Y - 4.0F, 8.0F, 8.0F); if (!rectfHit.Contains(ptfArray)) { continue; } fHit = true; ptfiHit = ptfi; break; } oHit = ptfiHit; return(fHit); }
/* H O V E R G R A P H */ /*---------------------------------------------------------------------------- * %%Function: HoverGraph * %%Qualified: bg.BgGraph.HoverGraph * %%Contact: rlittle * * ----------------------------------------------------------------------------*/ private void HoverGraph(object sender, System.EventArgs e) { PictureBox pb = (PictureBox)sender; if (BvFromPb(pb) != BoxView.Graph) { return; } Grapher grph = (Grapher)pb.Tag; Point ptRaw = Cursor.Position; Point pt = pb.PointToClient(ptRaw); PTFI ptfiHit = new PTFI(); bool fHit = false; RectangleF rectfHit; object oHit; fHit = grph.FHitTest(pt, out oHit, out rectfHit); ptfiHit = (PTFI)oHit; if (fHit) { if (m_ch == null) { m_ch = new Hover(); } m_ch.ShowTip(ptRaw, ptfiHit.bge); this.Focus(); m_fTipShowing = true; m_rectfTipHitRegion = rectfHit; } this.Focus(); // now lets register for this again user32.TRACKMOUSEEVENT tme = new user32.TRACKMOUSEEVENT(); tme.cbSize = Marshal.SizeOf(tme); tme.dwFlags = 1; tme.dwHoverTime = -1; tme.hwndTrack = pb.Handle; user32.TrackMouseEvent(ref tme); }
void ShadeRanges2(Graphics gr, int dxAdjust, DateTime dttmFirst, SolidBrush hBrushTrans, int nPctSlop, int nPctAbove) { // ok // shade the regions float yMin = YFromReading(80, m_dyPerBgUnit); float yMax = YFromReading(120, m_dyPerBgUnit); // ok, there are 7 days, starting at dttmFirst int iDay = 0; DateTime dttmCur; dttmCur = dttmFirst.AddMinutes(m_iFirstQuarter * 15.0); dttmCur = new DateTime(dttmCur.Year, dttmCur.Month, dttmCur.Day); ArrayList plptf = new ArrayList(); double [] dMeals = { 8.0, 12.0, 18.0 }; double dHours = 0.0; int iplptfi = 0; while (iplptfi < m_plptfi.Count) { PTFI ptfi = (PTFI)m_plptfi[iplptfi]; if (ptfi.bge.Date >= dttmCur) { break; } iplptfi++; } AddCurvePoint(24.0, 0, ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0, 130, 0, nPctAbove); for (; iDay < m_cgp.nHalfDays / 2 + 2; iDay++) { // now, first analyze the day and determine when the meals are...otherwise, use the default meal times dMeals[0] = 8.0; dMeals[1] = 12.0; dMeals[2] = 18.0; // now, see if we can find meals in our day DateTime dttmNext = dttmCur.AddDays(1); while (iplptfi < m_plptfi.Count) { PTFI ptfi = (PTFI)m_plptfi[iplptfi]; if (ptfi.bge.Date >= dttmNext) { break; } if (ptfi.bge.Type == BGE.ReadingType.Dinner) { dMeals[2] = ptfi.bge.Date.Hour; } else if (ptfi.bge.Type == BGE.ReadingType.Breakfast) { dMeals[0] = ptfi.bge.Date.Hour; } else if (ptfi.bge.Type == BGE.ReadingType.Lunch) { dMeals[1] = ptfi.bge.Date.Hour; } iplptfi++; } dHours = 0; AddCurvePoint(dMeals[0], 0.0, ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, dMeals[0], 120, -nPctSlop, nPctAbove); // 0800 dHours = 0; AddCurvePoint(dMeals[1], dMeals[0], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0.5, 180, -nPctSlop, nPctAbove); // 0830 AddCurvePoint(dMeals[1], dMeals[0], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 1.0, 180, 0, nPctAbove); // 0930 AddCurvePoint(dMeals[1], dMeals[0], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0.5, 160, nPctSlop, nPctAbove); // 1000 AddCurvePoint(dMeals[1], dMeals[0], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 1.5, 120, nPctSlop, nPctAbove); // 1130 AddCurvePoint(dMeals[1], dMeals[0], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, dMeals[1] - dMeals[0] - dHours, 120, 0, nPctAbove); // 1200 dHours = 0; AddCurvePoint(dMeals[2], dMeals[1], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0.5, 180, -nPctSlop, nPctAbove); // 1230 AddCurvePoint(dMeals[2], dMeals[1], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 1.0, 180, 0, nPctAbove); // 1330 AddCurvePoint(dMeals[2], dMeals[1], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0.5, 160, nPctSlop, nPctAbove); // 1400 AddCurvePoint(dMeals[2], dMeals[1], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 1.5, 120, nPctSlop, nPctAbove); // 1530 AddCurvePoint(dMeals[2], dMeals[1], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, dMeals[2] - dMeals[1] - dHours, 120, 0, nPctAbove); // 1800 dHours = 0; AddCurvePoint(24.00, dMeals[2], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0.5, 180, -nPctSlop, nPctAbove); // 1830 AddCurvePoint(24.00, dMeals[2], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 1.0, 180, 0, nPctAbove); // 1930 AddCurvePoint(24.00, dMeals[2], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 0.5, 160, nPctSlop, nPctAbove); // 2000 AddCurvePoint(24.00, dMeals[2], ref dHours, ref plptf, dxAdjust, dttmFirst, ref dttmCur, 24.0 - dMeals[2] - dHours, 140, nPctSlop, nPctAbove); // 2400 // repeat for 7 days worth } // ok, now just fill a line back to the beginning while (iDay >= 0) { float x = XFromDate(dttmFirst, dttmCur, m_dxQuarter) - dxAdjust; float y = YFromReading(80 - (80 * nPctAbove) / 100, m_dyPerBgUnit); PointF ptf = new PointF(x, y); plptf.Add(ptf); dttmCur = dttmCur.AddDays(-1); iDay--; } PointF[] points; points = new PointF[plptf.Count]; int iptf = 0; foreach (PointF ptf in plptf) { points[iptf] = ptf; iptf++; } FillMode fm = FillMode.Winding; gr.FillClosedCurve(hBrushTrans, points, fm, 0.2F); }
public void PaintGraph(Graphics gr) { int i, iLast; int dxAdjust = (int)(m_iFirstQuarter * m_dxQuarter); // how much should 0 based x-coordinates be adjusted? Pen penMeal = new Pen(Color.Green, m_dzaLineWidth); Pen penBlueThin = new Pen(Color.LightBlue, (float)0.5); Pen penBlue = new Pen(Color.Blue, (float)1); Pen penGrid = new Pen(Color.DarkGray, (float)1); Pen penLightGrid = new Pen(Color.LightGray, (float)1); SolidBrush brushBlue = new SolidBrush(Color.Blue); if (m_fWgtAvg) { brushBlue = new SolidBrush(Color.Red); penBlue = new Pen(Color.Red, (float)1); } double dxFirstQuarter = m_iFirstQuarter * m_dxQuarter + (m_dxOffset + m_rcfDrawing.Left /*m_dxLeftMargin*/); double dxLastQuarter = dxFirstQuarter + (m_cgp.nHalfDays * 12 * 4) * m_dxQuarter; RectangleF rectfGraphBodyClip = new RectangleF(m_dxOffset + m_rcfDrawing.Left, m_rcfDrawing.Top, // m_dyOffset + m_rcfDrawing.Width - m_dxOffset, m_rcfDrawing.Height - m_dyOffset); gr.SetClip(rectfGraphBodyClip); // ------------------------------ // THIRD: Graph the points // ------------------------------ PTFI ptfiLastMeal = new PTFI(); PTFI ptfi; ptfiLastMeal.bge = null; for (i = 0, iLast = m_plptfi.Count; i < iLast; i++) { PointF ptf; ptfi = ((PTFI)m_plptfi[i]); ptf = ptfi.ptf; // if its before our first point, skip it if (ptf.X < dxFirstQuarter) { continue; } if (ptf.Y == -1.0F && ptfi.bge.Reading == 0) { // lets get a real Y value for this by plotting a line on the curve if (i > 0) { ptf.Y = ((PTFI)m_plptfi[i - 1]).ptf.Y; } else if (i < iLast) { ptf.Y = ((PTFI)m_plptfi[i + 1]).ptf.Y; } else { ptf.Y = 0; } ptfi.ptf = ptf; m_plptfi[i] = ptfi; } if (ptfiLastMeal.bge != null && m_cgp.fShowMeals) { if (ptfiLastMeal.bge.Date.AddMinutes(90.0) <= ptfi.bge.Date && ptfiLastMeal.bge.Date.AddMinutes(150.0) >= ptfi.bge.Date) { float yAdjust; float xLast = ptfiLastMeal.ptf.X - dxAdjust; float yLast = ptfiLastMeal.ptf.Y; yAdjust = ptf.Y - yLast; if (yAdjust < 0.0F) { yAdjust -= 15.0F; } else { yAdjust += 15.0F; } // we have a match gr.DrawLine(penMeal, xLast + m_dzaLineWidth, yLast, xLast + m_dzaLineWidth, yLast + yAdjust); gr.DrawLine(penMeal, xLast + m_dzaLineWidth, yLast + yAdjust, ptf.X + m_dzaLineWidth - dxAdjust, yLast + yAdjust); gr.DrawLine(penMeal, ptf.X + m_dzaLineWidth - dxAdjust, yLast + yAdjust, ptf.X + m_dzaLineWidth - dxAdjust, ptf.Y + m_dzaLineWidth); ptfiLastMeal.bge = null; } else if (ptfiLastMeal.bge.Date.AddHours(150.0) < ptfi.bge.Date) { ptfiLastMeal.bge = null; } } if (ptfi.bge.Type != BGE.ReadingType.SpotTest) { ptfiLastMeal = ptfi; } if (ptf.X > dxLastQuarter) { break; } if (ptfi.bge.InterpReading) { gr.DrawEllipse(penBlueThin, ptf.X - m_dzaLineWidth - dxAdjust, ptf.Y - m_dzaLineWidth, m_dzaLineWidth * 4.0f, m_dzaLineWidth * 4.0f); } else { gr.FillEllipse(brushBlue, ptf.X - m_dzaLineWidth - dxAdjust, ptf.Y - m_dzaLineWidth, m_dzaLineWidth * 4.0f, m_dzaLineWidth * 4.0f); } if (i > 0) { PointF ptfLast = ((PTFI)m_plptfi[i - 1]).ptf; if (ptfLast.X >= dxFirstQuarter) { gr.DrawLine(penBlue, ptfLast.X + 1 - dxAdjust, ptfLast.Y + 1, ptf.X + 1 - dxAdjust, ptf.Y + 1); } } } // if we were doing the translucent range shading, we'd do it here. // ShadeRanges(pb, gr); gr.ResetClip(); m_dxAdjust = dxAdjust; }
public void PaintGraphGridlines(Graphics gr) { // ------------------------------ // FIRST: Draw the shaded ranges // ------------------------------ // how much should 0 based x-coordinates be adjusted? int dxAdjust = (int)(m_iFirstQuarter * m_dxQuarter); PTFI ptfi = (PTFI)m_plptfi[0]; DateTime dttmFirst = new DateTime(ptfi.bge.Date.Year, ptfi.bge.Date.Month, ptfi.bge.Date.Day); RectangleF rectfGraphBodyClip = new RectangleF(m_dxOffset + m_rcfDrawing.Left, m_rcfDrawing.Top, m_rcfDrawing.Width - m_dxOffset, m_rcfDrawing.Height - m_dyOffset); RectangleF rectfGraphFullClip = m_rcfDrawing; gr.SetClip(rectfGraphBodyClip); if (m_fNoCurves) { ShadeRanges(gr); } else { ShadeCurvedRanges(gr, dxAdjust, dttmFirst); } gr.ResetClip(); // ----------------------------------------- // SECOND: Draw the gridlines and the legend // ----------------------------------------- gr.SetClip(rectfGraphFullClip); SolidBrush brushBlue = new SolidBrush(Color.Blue); SolidBrush brushAvg = new SolidBrush(Color.Red); Pen penAvg = new Pen(Color.Red, (float)1); Pen penBlue = new Pen(Color.Blue, (float)1); Pen penGrid = new Pen(Color.DarkGray, (float)1); Pen penLightGrid = new Pen(Color.LightGray, (float)1); Pen penLight2Grid = new Pen(Color.LightBlue, (float)1); gr.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; // now we've found the first index we're going to draw DateTime dttm = DateTime.Parse(dttmFirst.ToString("d")); // figure out the number of quarters in the first date we want // to display int nDayFirst = (m_iFirstQuarter) / (4 * 24) - 1; Font font = new Font("Tahoma", 8); // now we know (rounded up), what the first day will be // as a delta from the first day dttm = dttm.AddDays(nDayFirst); float dyOffsetRegion = m_dyOffset / 4; float yDateLegend = m_rcfDrawing.Bottom - m_dyOffset + dyOffsetRegion * 1.3F; // m_rcfDrawing.Height - m_dyBottomMargin - m_dyOffset + dyOffsetRegion * 1.3F; float xMacLastDrawn = 0.0F; float xMacNoonLastDrawn = 0.0F; Font fontSmall = new Font("Tahoma", 6); // figure out how many other gridlines we should draw // secondary gridlines must be at least wide enough to accommodate // the legend on every other gridline. float dxGrid2Legend = gr.MeasureString("23:59", fontSmall).Width; int nQuartersGrid2 = (int)(dxGrid2Legend / m_dxQuarter); // make sure its evenly divisble into 48 (12 * 4) if (nQuartersGrid2 > 48) { nQuartersGrid2 = 48; } while (48 % nQuartersGrid2 != 0) { nQuartersGrid2++; } for (int nDay = nDayFirst; nDay <= nDayFirst + m_cgp.nHalfDays / 2; nDay++) { dttm = dttm.AddDays(1); string s = dttm.ToString("MM/dd"); SizeF szf = gr.MeasureString(s, font); float x = XFromDate(dttmFirst, dttm, m_dxQuarter) - dxAdjust; if (x > m_rcfDrawing.Left + m_dxOffset) { gr.DrawLine(penLightGrid, x, yDateLegend + dyOffsetRegion, x, 0); } if (x + (float)m_dxQuarter * (4.0F * 12.0F) > m_rcfDrawing.Left + m_dxOffset) { gr.DrawLine(penGrid, x + (float)m_dxQuarter * (4.0F * 12.0F), yDateLegend + dyOffsetRegion, x + (float)m_dxQuarter * (4.0F * 12.0F), 0); } float dxNoon = gr.MeasureString("12:00", fontSmall).Width; if (xMacNoonLastDrawn < x + (float)m_dxQuarter * (4.0F * 12.0F) - dxNoon / 2.0F) { gr.DrawString("12:00", fontSmall, brushBlue, x + (float)m_dxQuarter * (4.0F * 12.0F) - dxNoon / 2.0F, yDateLegend + dyOffsetRegion / 1.5F); xMacNoonLastDrawn = x + (float)m_dxQuarter * (4.0F * 12.0F) + dxNoon / 2.0F; } x -= (szf.Width / 2.0F); if (xMacLastDrawn < x) { gr.DrawString(s, font, brushBlue, x, yDateLegend + dyOffsetRegion); xMacLastDrawn = x + gr.MeasureString(s, font).Width; } bool fText = false; for (int nGrid2 = 0; nGrid2 < 24 * 4; nGrid2 += nQuartersGrid2) { if (nGrid2 != 12 * 4) { x = XFromDate(dttmFirst, dttm.AddMinutes(nGrid2 * 15), m_dxQuarter) - dxAdjust; if (x > m_rcfDrawing.Left + m_dxOffset) { gr.DrawLine(penLight2Grid, x, yDateLegend + dyOffsetRegion, x, 0); if (fText) { int nHour = nGrid2 / 4; int nMinute = (nGrid2 % 4) * 15; string sText = nHour.ToString() + ":" + nMinute.ToString("0#"); float dxText = gr.MeasureString(sText, fontSmall).Width; x -= dxText / 2.0F; gr.DrawString(sText, fontSmall, brushBlue, x, yDateLegend + dyOffsetRegion / 4.0f); } } } fText = !fText; } } // put legend up int n; int dn = ((int)m_cgp.dBgHigh - (int)m_cgp.dBgLow) / m_cgp.nIntervals; gr.DrawLine(penBlue, m_dxOffset + (m_rcfDrawing.Left) - 1.0F, m_rcfDrawing.Top, m_dxOffset + (m_rcfDrawing.Left) - 1.0F, yDateLegend); gr.DrawLine(penBlue, m_dxOffset + (m_rcfDrawing.Left) - 1.0F, yDateLegend, m_rcfDrawing.Width + (m_rcfDrawing.Left) - 1.0F + m_dxOffset, yDateLegend); bool fLine = false; for (n = (int)m_cgp.dBgLow; n <= (int)m_cgp.dBgHigh; n += dn) { float x = m_rcfDrawing.Left /*m_dxLeftMargin*/ + 2.0F; float y = YFromReading(n, m_dyPerBgUnit); if (fLine) { gr.DrawLine(penGrid, (m_dxOffset + m_rcfDrawing.Left) - 4.0F, y, (m_dxOffset + m_rcfDrawing.Left) + m_rcfDrawing.Width, y); } fLine = !fLine; y -= (gr.MeasureString(n.ToString(), font).Height / 2.0F); x = (m_dxOffset + m_rcfDrawing.Left) - 4.0F - gr.MeasureString(n.ToString(), font).Width; gr.DrawString(n.ToString(), font, brushBlue, x, y); } gr.ResetClip(); m_dxAdjust = dxAdjust; }
/* G E T F I R S T D A T E T I M E */ /*---------------------------------------------------------------------------- * %%Function: GetFirstDateTime * %%Qualified: bg.SBGE.GetFirstDateTime * %%Contact: rlittle * * ----------------------------------------------------------------------------*/ public DateTime GetFirstDateTime() { PTFI ptfi = (PTFI)m_plptfi[0]; return(new DateTime(ptfi.bge.Date.Year, ptfi.bge.Date.Month, ptfi.bge.Date.Day)); }