private void DrawBarValue(int barValue, long startTime, long endTime, Graphics g, SolidBrush brush, bool print) { XAxes xAxes = this.CurveGroup.XAxes; RectangleF rectBorder = print?this.BorderRectPrint:this.BorderRect; if (barValue >= 0 && endTime > startTime) { float posX1 = (startTime - xAxes.OriginalTime) * ScaleSize * 1f / xAxes.TimeScale; float posX2 = (endTime - xAxes.OriginalTime) * ScaleSize * 1f / xAxes.TimeScale; if (posX1 < rectBorder.Width && posX2 > 0) { if (posX1 < 0) { posX1 = 0; } if (posX2 > rectBorder.Width) { posX2 = rectBorder.Width; } brush.Color = GetColor(barValue); g.FillRectangle(brush, posX1 + rectBorder.X, rectBorder.Y, posX2 - posX1, rectBorder.Height); } } }
public CurveGroup(ChartGraph chart) { base.Chart = chart; this.xAxes = new XAxes(); this.CursorPoint = new Point(0, 0); this.ShowCursor = true; }
private void DrawBar(Graphics g, RectangleF rect, bool print) { RectangleF rectBorder = print?this.BorderRectPrint: this.BorderRect; XAxes xAxes = this.CurveGroup.XAxes; int pCnt = listBarPoint.Count; int barValue = -1; long startTime = 0; long endTime = 0; using (SolidBrush brush = new SolidBrush(Color.Black)) { for (int i = 0; i < pCnt; i++) { BarPoint bp = listBarPoint[i]; if (barValue < 0) //无效点 { barValue = bp.Value; startTime = bp.Time; endTime = startTime; } else if (bp.Time < endTime) { //开始绘制 DrawBarValue(barValue, startTime, endTime, g, brush, print); barValue = bp.Value; startTime = bp.Time; endTime = bp.Time; } else if (bp.Value != barValue) { endTime = bp.Time; //开始绘制 DrawBarValue(barValue, startTime, endTime, g, brush, print); barValue = bp.Value; startTime = bp.Time; } else { endTime = bp.Time; } } DrawBarValue(barValue, startTime, endTime, g, brush, print); } }
private string GetTimeText(long time) { XAxes xAxes = CurveGroup.XAxes; if (xAxes.XAxesMode == XAxesMode.Absolute) { DateTime timeTips = ChartGraph.ChartTime2DateTime(time); //if (xAxes.TimeScale >= TicksPerDay) //{ // return timeTips.ToString("yyyy-MM-dd"); //} //else if (xAxes.TimeScale >= TicksPerHour) //{ // return timeTips.ToString("MM-dd HH:mm"); //} //else { return(timeTips.ToString("HH:mm:ss")); } } else if (xAxes.XAxesMode == XAxesMode.Relative) { double time1 = (double)(time - this.RelativeTime) / 1000000L; if (this.XFreqScale < 0) { if (xAxes.TimeScale >= TicksPerSecond) { return(time1.ToString("0.000") + "秒"); } else if (xAxes.TimeScale >= TicksPerMiliSec) { return((time1 * 1000).ToString("0.") + "毫秒"); } else { return((time1 * 1000000).ToString("0.") + "微秒"); } } else { return((time1 * 1000000 * this.XFreqScale).ToString("0.00") + "HZ"); } } return(""); }
public override void DrawStage2(Graphics g, RectangleF rect) { if (!this.Visible) { return; } if (!this.CurveGroup.ShowCursor) { return; } //绘制光标 RectangleF disRect = this.Rectangle; // RectangleF borderRect = new RectangleF(disRect.X, disRect.Top + CaptionHeight, disRect.Width, disRect.Height - CaptionHeight - XScaleHeight); RectangleF borderRect = disRect; Point pCursor = CurveGroup.CursorPoint; using (Pen pen = new Pen(Color.LightGray, 1)) { pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom; pen.DashPattern = new float[] { 4.5f, 4.5f }; if ((pCursor.X >= borderRect.Left) && (pCursor.X <= borderRect.Right)) { g.DrawLine(pen, pCursor.X, borderRect.Top, pCursor.X, borderRect.Bottom); } if (pCursor.Y >= borderRect.Top && pCursor.Y <= borderRect.Bottom) { g.DrawLine(pen, borderRect.Left, pCursor.Y, borderRect.Right, pCursor.Y); } } if (borderRect.Contains(pCursor)) { XAxes xAxes = CurveGroup.XAxes; List <string> listTipsValue = new List <string>(); List <string> listTipsTime = new List <string>(); List <Color> listColor = new List <Color>(); long cursorTime = 0; if (xAxes.XAxesMode == XAxesMode.Absolute) { long timeAbs = xAxes.OriginalTime + (long)((pCursor.X - borderRect.X) * xAxes.TimeScale / ScaleSize); DateTime timeTips = ChartGraph.ChartTime2DateTime(timeAbs); cursorTime = timeAbs; if (xAxes.TimeScale >= TicksPerDay) { listTipsValue.Add("时间:" + timeTips.ToString("yyyy-MM-dd")); } else if (xAxes.TimeScale >= TicksPerHour) { listTipsValue.Add("时间:" + timeTips.ToString("MM-dd HH:mm")); } else { listTipsValue.Add("时间:" + timeTips.ToString("HH:mm:ss")); } listTipsTime.Add(""); } else if (xAxes.XAxesMode == XAxesMode.Relative) { double time = ((pCursor.X - borderRect.X) * xAxes.TimeScale / ScaleSize - (this.RelativeTime - xAxes.OriginalTime)) / 1000000L; cursorTime = (long)(this.RelativeTime + (pCursor.X - borderRect.X) * xAxes.TimeScale / ScaleSize); if (XFreqScale > 0) { { listTipsValue.Add("频率:" + (time * 1000000 * XFreqScale).ToString("0.00") + "Hz"); } } else { if (xAxes.TimeScale >= LineArea.TicksPerSecond) { listTipsValue.Add("时间:" + time.ToString("0.000") + "秒"); } else if (xAxes.TimeScale >= LineArea.TicksPerMiliSec) { listTipsValue.Add("时间:" + (time * 1000).ToString("0.") + "毫秒"); } else { listTipsValue.Add("时间:" + (time * 1000000).ToString("0.") + "微妙"); } } listTipsTime.Add(""); } listColor.Add(Color.White); for (int i = 0; i < lines.Count; i++) { lines[i].CursorValue = float.NaN; if (lines[i].Visible == false) { continue; } List <LinePoint> cPoints = lines[i].GetCursorPoint(false); StringBuilder sb = new StringBuilder(lines[i].Name + ":"); string timeTxt = ""; if (cPoints.Count == 1) { if (float.IsNaN(cPoints[0].Value) == false) { if (Math.Abs(cursorTime - cPoints[0].Time) < LineArea.TicksPerDay) { sb.Append(cPoints[0].Value.ToString("0.000") + (string.IsNullOrEmpty(this.YAxes.UnitString) ? lines[i].YAxes.UnitString : this.YAxes.UnitString)); timeTxt = (this.XFreqScale > 0 ? "频率" : "时间:") + GetTimeText(cPoints[0].Time); } } } else if (cPoints.Count > 1) { for (int k = 0; k < cPoints.Count; k++) { sb.Append("(" + (k + 1) + "):"); if (float.IsNaN(cPoints[k].Value) == false) { if (Math.Abs(cursorTime - cPoints[k].Time) < LineArea.TicksPerDay) { timeTxt = (this.XFreqScale > 0?"频率": "时间:") + GetTimeText(cPoints[k].Time); sb.Append(cPoints[k].Value.ToString("0.000") + (string.IsNullOrEmpty(this.YAxes.UnitString) ? lines[i].YAxes.UnitString : this.YAxes.UnitString) + "," + timeTxt); timeTxt = ""; } } } } listTipsValue.Add(sb.ToString()); listTipsTime.Add(timeTxt); listColor.Add(lines[i].LineColor); } using (Font font = new Font("雅黑", 8f)) { float txtLineHeight = 20; float txtMaxWidth = 0; float txtDateMaxWidth = 0; float txtValueMaxWidth = 0; for (int i = 0; i < listTipsValue.Count; i++) { SizeF txtSize = g.MeasureString(listTipsValue[i], font); if (txtSize.Width > txtValueMaxWidth) { txtValueMaxWidth = txtSize.Width; } txtSize = g.MeasureString(listTipsTime[i], font); if (txtSize.Width > txtDateMaxWidth) { txtDateMaxWidth = txtSize.Width; } } txtMaxWidth = txtDateMaxWidth + txtValueMaxWidth; txtMaxWidth += 10f; RectangleF rectTxt = new RectangleF(); rectTxt.Width = txtMaxWidth; rectTxt.Height = listTipsValue.Count * txtLineHeight; if ((pCursor.X > rect.Width / 2) && (pCursor.Y > rect.Height / 2)) //第一象限 { rectTxt.X = pCursor.X - txtMaxWidth; rectTxt.Y = pCursor.Y - txtLineHeight * listTipsValue.Count; } else if ((pCursor.X < rect.Width / 2) && (pCursor.Y > rect.Height / 2)) { rectTxt.X = pCursor.X; rectTxt.Y = pCursor.Y - rectTxt.Height; } else if ((pCursor.X < rect.Width / 2) && (pCursor.Y < rect.Height / 2)) { rectTxt.X = pCursor.X + 12; rectTxt.Y = pCursor.Y + 15; } else { rectTxt.X = pCursor.X - rectTxt.Width; rectTxt.Y = pCursor.Y; } using (SolidBrush brush = new SolidBrush(Color.FromArgb(150, 88, 119, 211))) { g.FillRectangle(brush, rectTxt.X, rectTxt.Y, rectTxt.Width, rectTxt.Height); for (int i = 0; i < listTipsValue.Count; i++) { brush.Color = listColor[i]; g.DrawString(listTipsValue[i], font, brush, new PointF(rectTxt.X + 5, rectTxt.Y + i * txtLineHeight)); if (listTipsTime[i] != "") { g.DrawString(listTipsTime[i], font, brush, new PointF(rectTxt.X + 5 + txtValueMaxWidth, rectTxt.Y + i * txtLineHeight)); } } } } } }
private void DrawLine(Graphics g, RectangleF rect, List <LinePoint> points, bool print) { if (this.Visible == false) { return; } RectangleF disRect = print ? this.LineArea.PrintRectangle : this.LineArea.Rectangle; // RectangleF borderRect = new RectangleF(disRect.X, disRect.Top + LineArea.CaptionHeight, disRect.Width, disRect.Height - LineArea.CaptionHeight - LineArea.XScaleHeight); RectangleF borderRect = disRect; float lastValue = float.NaN; bool prevValid = false; long prevTime = -1; long prevX = -1; float prevStart = 0; float prevEnd = 0; float prevMax = float.MinValue; float prevMin = float.MaxValue; XAxes xAxes = this.Chart.XAxes; long timeEnd = xAxes.OriginalTime + (long)((borderRect.Width + CurveGroup.MarginRight) * 1d / CurveGroup.ScaleSize * xAxes.TimeScale); bool lookbackPoint = false; int lookbackNum = 0; using (Pen pen = new Pen(this.LineColor, this.LineWidth)) using (SolidBrush brush = new SolidBrush(this.LineColor)) { if (print) { pen.Color = Color.Lime; brush.Color = Color.Lime; } int pCnt = points.Count; int startIndex = SearchPoint(points, xAxes.OriginalTime); startIndex -= 10; if (startIndex < 0) { startIndex = 0; } for (int i = startIndex; i >= 0; i--) { float val = points[i].Value; if (float.IsInfinity(val) || float.IsNaN(val) || float.IsNegativeInfinity(val) || float.IsPositiveInfinity(val)) { continue; } startIndex = i; break; } for (int i = startIndex; i < pCnt; i++) { lookbackPoint = false; LinePoint pOrig = points[i]; LinePoint p = pOrig; if (this.TimeDayAlign) { p.Time = p.DayAlignTime; } if (i > 1 && i < pCnt) { if ((points[i - 2].Time > timeEnd) && (points[i - 1].Time > timeEnd) && (points[i].Time > timeEnd)) { break; } } if (float.IsNaN(pOrig.Value)) { p = new LinePoint(pOrig.Time, lastValue); } if (float.IsNaN(p.Value) || float.IsInfinity(p.Value) || float.IsNegativeInfinity(p.Value) || float.IsPositiveInfinity(p.Value)) { if (prevValid && (prevX >= 0) && (prevX < borderRect.Width) && (prevMax > prevMin)) { if (prevMax > 0 && prevMin < borderRect.Height) { float max = Math.Min(prevMax, borderRect.Height); float min = Math.Max(prevMin, 0); g.DrawLine(pen, prevX + borderRect.X, borderRect.Bottom - min, prevX + borderRect.X, borderRect.Bottom - max); } } lastValue = float.NaN; prevValid = false; } else { lastValue = p.Value; long posX = (p.Time - xAxes.OriginalTime) * CurveGroup.ScaleSize / xAxes.TimeScale; float posY = 0; if (this.YAxes.Mode == YAxesMode.Auto) { posY = (p.Value - this.LineArea.SharedYAxes.YAxesMin) / (this.LineArea.SharedYAxes.YAxesMax - this.LineArea.SharedYAxes.YAxesMin) * borderRect.Height; } else { posY = (p.Value - this.YAxes.YAxesMin) / (this.YAxes.YAxesMax - this.YAxes.YAxesMin) * borderRect.Height; } if (prevX + borderRect.X <= this.LineArea.CurveGroup.CursorPoint.X) { this.CursorValue = p.Value; } if (prevValid && (posX == prevX)) { prevEnd = posY; if (posY > prevMax) { prevMax = posY; } if (posY < prevMin) { prevMin = posY; } } else { if (posX != prevX) { if (prevValid && (prevX >= 0) && (prevX < borderRect.Width) && (prevMax > prevMin)) { if (prevMax > 0 && prevMin < borderRect.Height) { float max = Math.Min(prevMax, borderRect.Height); float min = Math.Max(prevMin, 0); g.DrawLine(pen, prevX + borderRect.X, borderRect.Bottom - min, prevX + borderRect.X, borderRect.Bottom - max); } } } if (prevValid && (posX > prevX)) { if (i > 0) { PointF p1 = new PointF(prevX + borderRect.X, borderRect.Bottom - prevEnd); PointF p2 = new PointF(posX + borderRect.X, borderRect.Bottom - posY); RectangleF rectBig = new RectangleF(borderRect.X - 1, borderRect.Y - 1, borderRect.Width + 2, borderRect.Height + 2); DrawLine(g, pen, rectBig, p1, p2); } } //if (prevValid && (posX < prevX)) if (prevValid && (prevTime - p.Time) > 10L * 1000000L) { lookbackPoint = true; lookbackNum++; } prevX = posX; prevStart = posY; prevMax = posY; prevMin = posY; prevEnd = posY; prevValid = true; } //绘制点 if (this.LineArea.CurveGroup.DrawPointFlagXAxesScale >= this.LineArea.CurveGroup.XAxes.TimeScale) { PointF pDot = new PointF(borderRect.X + posX, borderRect.Bottom - posY); //把边框扩大1个像素 RectangleF rectBig = new RectangleF(borderRect.X - 1, borderRect.Y - 1, borderRect.Width + 2, borderRect.Height + 2); if (rectBig.Contains(pDot)) { if (lookbackPoint) { g.FillRectangle(brush, pDot.X - 7f, pDot.Y - 7f, 14, 14); using (Font font = new Font("雅黑", 8)) { StringFormat sf = new StringFormat(); sf.Alignment = StringAlignment.Near; sf.LineAlignment = StringAlignment.Center; g.DrawString(lookbackNum.ToString(), font, Brushes.Black, new RectangleF(pDot.X - 7f, pDot.Y - 7f, 14, 14), sf); } } else { DrawLinePointDot(g, brush, ref pOrig, ref pDot); } } } } prevTime = p.Time; } } }