protected int timerPerion; // частота отрисовки графиков в активном режиме #endregion Fields #region Constructors /// <summary> /// Инициализирует новый экземпляр класса /// </summary> /// <param name="GPanel">Панель которую будет обслуживать манеджер</param> public GraphicManager(Panel GPanel) { mutex = new Mutex(); slim = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); mode = DrawMode.Default; if (GPanel != null) { panel = GPanel; //panel.StartTime = DateTime.Now; panel.OnResize += new EventHandler(Sheet_Resize); panel.Sheet.onOrientationChange += new EventHandler(Sheet_onOrientationChange); panel.Sheet.onIntervalInCellChange += new EventHandler(Sheet_onIntervalInCellChange); timerPerion = 500; timer = new Timer(TimerCallback, null, Timeout.Infinite, timerPerion); } else { throw new ArgumentNullException(); } }
/// <summary> /// Пересчитать точки на отрисовку /// </summary> /// <param name="pt">Начало координат для отрисовки</param> /// <param name="size">Размер области в которую осуществляется отрисовка</param> public PointF[] Calculate(PointF pt, SizeF size, Panel panel) { try { GraphicValue[] vals = GetValues(); if (vals != null) { float HK = panel.GridHeight / panel.IntervalInCell.Ticks; float WRK = Range.Max - Range.Min; float WK = size.Width / WRK; PointF[] pts = new PointF[vals.Length]; for (int index = 0; index < vals.Length; index++) { float wX = (vals[index].Value - Range.Min) * WK + pt.X; float tY = (vals[index].Time.Ticks - panel.StartTime.Ticks) * HK + pt.Y; pts[index] = new PointF(wX, tY); } return Array.FindAll(pts, Predicate); } } catch { } return null; }
/// <summary> /// Получить стартовое время отрисовываемой ячейки /// </summary> /// <param name="nowTime">Текущее время</param> /// <returns>Стартовое время</returns> protected int GetStartTime(Panel panel, DateTime nowTime) { try { int number = 0; DateTime startTime = panel.StartTime; do { if (nowTime >= startTime) { DateTime finishTime = startTime + panel.IntervalInCell; if (nowTime <= finishTime) { return number; } } number = number + 1; startTime = startTime + panel.IntervalInCell; } while (startTime < panel.FinishTime); } catch { } return -1; }
/// <summary> /// Пересчитать точки на отрисовку cо сжатием /// </summary> /// <param name="pt">Начало координат для отрисовки</param> /// <param name="size">Размер области в которую осуществляется отрисовка</param> /// <returns>Массив точек графика в координатах экрана</returns> public PointF[] CalculateReduceTimer(PointF pt, SizeF size, Panel panel, DateTime currentTime) { try { if (lastTimeTimer == DateTime.MaxValue) lastTimeTimer = currentTime; DateTime startTime = panel.dateTimeCell(currentTime); DateTime finishTime = startTime + panel.IntervalInCell; if (lastTimeTimer <= startTime) startTime = lastTimeTimer; GraphicValue[] vals = GetValues(startTime, currentTime); if (vals != null) { //lastTimeTimer = currentTime; lastTimeTimer = vals[vals.Length - 1].Time; float HK = panel.GridHeight / panel.IntervalInCell.Ticks; float WRK = Range.Max - Range.Min; float WK = size.Width / WRK; int IndexBeg = -1; // Ищем первую значимую точку for (int index = 0; index < vals.Length; index++) { if (float.IsNaN(vals[index].Value)) continue; IndexBeg = index; break; } if ((IndexBeg == -1) || ((IndexBeg + 1) == vals.Length)) { return null; // Рисовать нечего } // PointF[] tmp = new PointF[10000]; // Динамический Список точек графика, вставляемы в результате прореживания int ind_tmp = 0; float wX = (vals[IndexBeg].Value - Range.Min) * WK + pt.X; float tY = (vals[IndexBeg].Time.Ticks - panel.StartTime.Ticks) * HK + pt.Y; PointF Pnt = new PointF(wX, tY); this.tmpPnts[0] = Pnt; int gridPoint = (int)Math.Ceiling(tY); // ближайшая точка сетки float floatPoint = gridPoint; // Эквивалент в типе float if (floatPoint == tY) floatPoint += 1; int intrv = 0; // Длина найденного интервала bool bNan = false; //Признак того что NaN уже вставлен float val = 0; // Накопленное значение для усреднения // Просмотр массива - выявление интервалов длиной 1 пиксел по времени for (int index = IndexBeg + 1; index < vals.Length; index++) { if (vals[index].Time.Ticks > panel.FinishTime.Ticks) break; wX = vals[index].Value; if (float.IsNaN(wX)) { if (bNan) { continue; } else { if (intrv > 0) { // создаём новую точку в списке val = val / intrv; Pnt.X = (val - Range.Min) * WK + pt.X; Pnt.Y = floatPoint; this.tmpPnts[++ind_tmp] = Pnt; } // Добавляем в список NaN c той же координатой wX = float.NaN; Pnt.X = wX; Pnt.Y = floatPoint; this.tmpPnts[++ind_tmp] = Pnt; intrv = 0; val = 0; bNan = true; continue; } } tY = (vals[index].Time.Ticks - panel.StartTime.Ticks) * HK + pt.Y; // Проверка на выход в новую клетку if (tY <= floatPoint) { if (bNan) { continue; } else { val += wX; intrv++; } } else { if (bNan) { bNan = false; val = wX; intrv = 1; gridPoint = (int)Math.Ceiling(tY); // ближайшая точка сетки floatPoint = gridPoint; // Эквивалент в типе float continue; } else { if (intrv > 0) { // создаём новую точку в списке val = val / intrv; Pnt.X = (val - Range.Min) * WK + pt.X; Pnt.Y = floatPoint; this.tmpPnts[++ind_tmp] = Pnt; } val = wX; intrv = 1; gridPoint = (int)Math.Ceiling(tY); // ближайшая точка сетки floatPoint = gridPoint; // Эквивалент в типе float continue; } } } if (intrv > 0) // Последнюю точку не забыть бы { // создаём новую точку в списке Pnt.X = (wX - Range.Min) * WK + pt.X; Pnt.Y = tY; this.tmpPnts[++ind_tmp] = Pnt; } PointF[] pts = new PointF[ind_tmp + 1]; for (int index = 0; index <= ind_tmp; index++) { pts[index] = this.tmpPnts[index]; } // return Array.FindAll(pts, Predicate); return pts; } } catch { } return null; }