/// <summary> /// Virtual to Screen XY /// </summary> public static LongPoint TranslateToScreen(LongPoint virtualpoint, DataTimeRange xrange, DataRange yrange, LongRectangle rectangle) { if (xrange.Delta == 0 || yrange.Delta == 0) { // have seen this happen when we try to render graphs after the host failed to install a vm // doesn't matter too much what we return as the VM entry is going to get removed. Just don't crash. log.ErrorFormat("Tried to translate datapoint through range of zero. xrange.Delta: {0}, yrange.Delta: {1}", xrange.Delta, yrange.Delta); return new LongPoint(0, 0); } // work out x, assume origin is bottom right double x = rectangle.Right - ((rectangle.Width * (virtualpoint.X - xrange.Min)) / xrange.Delta); // work out y double y = rectangle.Bottom - ((rectangle.Height * (virtualpoint.Y - yrange.Min)) / yrange.Delta); y = y > rectangle.Bottom ? rectangle.Bottom : y < rectangle.Y ? rectangle.Y : y; if (x >= ARBITRARY_MICROSOFT_LINE_MAX_LENGTH && y >= ARBITRARY_MICROSOFT_LINE_MAX_LENGTH) { log.DebugFormat("Point translated to more than max line length: x={0} y={1} vx={2} vy={3} xrange_min={4} xrange_max={5} yrange_min={6} yrange_max={7} rectangle_x={8} rectangle_y={9} rectangle_w={10} rectangle_h={11}", x, y, virtualpoint.X, virtualpoint.Y, xrange.Min, xrange.Max, yrange.Min, yrange.Max, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); // draw a random line as this is better than crashing return new LongPoint(0, 0); } return new LongPoint((long)x, (long)y); }
public MouseActionArgs(Point p, Rectangle r, DataTimeRange xrange, DataRange yrange) { Point = p; Rectangle = r; XRange = xrange; YRange = yrange; }
public static void Render(Graphics g, Rectangle r, DataTimeRange xrange, DataRange yrange, Pen pen, Brush graphShadow, List<DataPoint> points, bool showselections) { if (points.Count == 0) return; int index = points.FindIndex(dataPoint => dataPoint.Y < 0); if (index >= 0) { //CA-38898: when there are no data from the server we do not want //to show anything; leave gaps instead of making up data (zeros or inf) DoRender(g, r, xrange, yrange, pen, graphShadow, points.Where((val, idx) => idx < index).ToList(), showselections); Render(g, r, xrange, yrange, pen, graphShadow, points.Where((val, idx) => idx > index).ToList(), showselections); } else { DoRender(g, r, xrange, yrange, pen, graphShadow, points, showselections); } }
public bool OnMouseClick(MouseActionArgs args) { DataRange yrange = this.CustomYRange ?? args.YRange; List <DataPoint> range = BinaryChop(Points, args.XRange); if (range.Count == 0) { return(false); } List <LongPoint> polypoints = new List <LongPoint>(); foreach (DataPoint p in range) { LongPoint lp = LongPoint.TranslateToScreen(p.Point, args.XRange, yrange, new LongRectangle(args.Rectangle)); polypoints.Add(new LongPoint(lp.X, lp.Y + 10)); polypoints.Insert(0, new LongPoint(lp.X, lp.Y - 10)); } Polygon poly = new Polygon(polypoints); return(poly.Contains(new LongPoint(args.Point))); }
public static void Render(Graphics g, Rectangle r, DataTimeRange xrange, DataRange yrange, Pen pen, Brush graphShadow, List <DataPoint> points, bool showselections) { if (points.Count == 0) { return; } int index = points.FindIndex(dataPoint => dataPoint.Y < 0); if (index >= 0) { //CA-38898: when there are no data from the server we do not want //to show anything; leave gaps instead of making up data (zeros or inf) DoRender(g, r, xrange, yrange, pen, graphShadow, points.Where((val, idx) => idx < index).ToList(), showselections); Render(g, r, xrange, yrange, pen, graphShadow, points.Where((val, idx) => idx > index).ToList(), showselections); } else { DoRender(g, r, xrange, yrange, pen, graphShadow, points, showselections); } }
/// <summary> /// Screen XY to Virtual /// </summary> public static LongPoint DeTranslateFromScreen(LongPoint screenpoint, DataTimeRange xrange, DataRange yrange, LongRectangle rectangle) { // work out x, assume origin is bottom right double x = xrange.Min + (xrange.Delta * (rectangle.Right - screenpoint.X)) / (double)rectangle.Width; // work out y double y = yrange.Min + (yrange.Delta * (rectangle.Bottom - screenpoint.Y)) / (double)rectangle.Height; return new LongPoint((long)x, (long)y); }
private static void DoRender(Graphics g, Rectangle r, DataTimeRange xrange, DataRange yrange, Pen pen, Brush graphShadow, List<DataPoint> points, bool showselections) { if (points.Count == 0) return; // draw line 'tween points LongPoint locbase = LongPoint.TranslateToScreen(points[0].Point, xrange, yrange, new LongRectangle(r)); List<Point> PointsToDraw = new List<Point>(); for (int i = 1; i < points.Count; i++) { LongPoint loc = LongPoint.TranslateToScreen(points[i].Point, xrange, yrange, new LongRectangle(r)); if (locbase.X == loc.X) continue; if (locbase.X > r.Right && loc.X < r.Left) { // trim it to the Y axis double delta = (double)(locbase.Y - loc.Y) / (locbase.X - loc.X); int dxl = r.Left - (int)locbase.X; int dxr = r.Right - (int)loc.X; int newyr = (int)(delta * dxr); int newyl = (int)(delta * dxl); PointsToDraw.Add(new Point(r.Right, newyr + (int)loc.Y)); PointsToDraw.Add(new Point(r.Left, newyl + (int)locbase.Y)); break; } else if (locbase.X > r.Right) { // trim it to the Y axis double delta = (double)(locbase.Y - loc.Y) / (locbase.X - loc.X); int dx = r.Right - (int)loc.X; int newy = (int)(delta * dx); PointsToDraw.Add(new Point(r.Right, newy + (int)loc.Y)); } else if (loc.X < r.Left) { // trim it to the Y axis double delta = (double)(locbase.Y - loc.Y) / (locbase.X - loc.X); int dx = r.Left - (int)locbase.X; int newy = (int)(delta * dx); PointsToDraw.Add(locbase.Point); PointsToDraw.Add(new Point(r.Left, newy + (int)locbase.Y)); break; } else { PointsToDraw.Add(locbase.Point); if (i == points.Count - 1) PointsToDraw.Add(loc.Point); } if (points[i].Show && showselections) { g.DrawRectangle(pen, new Rectangle((int)loc.X - 2, (int)loc.Y - 2, 4, 4)); } locbase = loc; } if (PointsToDraw.Count <= 1) return; g.DrawLines(pen, PointsToDraw.ToArray()); if (graphShadow == null) return; PointsToDraw.Add(new Point(PointsToDraw[PointsToDraw.Count - 1].X, r.Bottom)); PointsToDraw.Add(new Point(PointsToDraw[0].X, r.Bottom)); g.FillPolygon(graphShadow, PointsToDraw.ToArray()); }
private static void DoRender(Graphics g, Rectangle r, DataTimeRange xrange, DataRange yrange, Pen pen, Brush graphShadow, List <DataPoint> points, bool showselections) { if (points.Count == 0) { return; } // draw line 'tween points LongPoint locbase = LongPoint.TranslateToScreen(points[0].Point, xrange, yrange, new LongRectangle(r)); List <Point> PointsToDraw = new List <Point>(); for (int i = 1; i < points.Count; i++) { LongPoint loc = LongPoint.TranslateToScreen(points[i].Point, xrange, yrange, new LongRectangle(r)); if (locbase.X == loc.X) { continue; } if (locbase.X > r.Right && loc.X < r.Left) { // trim it to the Y axis double delta = (double)(locbase.Y - loc.Y) / (locbase.X - loc.X); int dxl = r.Left - (int)locbase.X; int dxr = r.Right - (int)loc.X; int newyr = (int)(delta * dxr); int newyl = (int)(delta * dxl); PointsToDraw.Add(new Point(r.Right, newyr + (int)loc.Y)); PointsToDraw.Add(new Point(r.Left, newyl + (int)locbase.Y)); break; } else if (locbase.X > r.Right) { // trim it to the Y axis double delta = (double)(locbase.Y - loc.Y) / (locbase.X - loc.X); int dx = r.Right - (int)loc.X; int newy = (int)(delta * dx); PointsToDraw.Add(new Point(r.Right, newy + (int)loc.Y)); } else if (loc.X < r.Left) { // trim it to the Y axis double delta = (double)(locbase.Y - loc.Y) / (locbase.X - loc.X); int dx = r.Left - (int)locbase.X; int newy = (int)(delta * dx); PointsToDraw.Add(locbase.Point); PointsToDraw.Add(new Point(r.Left, newy + (int)locbase.Y)); break; } else { PointsToDraw.Add(locbase.Point); if (i == points.Count - 1) { PointsToDraw.Add(loc.Point); } } if (points[i].Show && showselections) { g.DrawRectangle(pen, new Rectangle((int)loc.X - 2, (int)loc.Y - 2, 4, 4)); } locbase = loc; } if (PointsToDraw.Count <= 1) { return; } g.DrawLines(pen, PointsToDraw.ToArray()); if (graphShadow == null) { return; } PointsToDraw.Add(new Point(PointsToDraw[PointsToDraw.Count - 1].X, r.Bottom)); PointsToDraw.Add(new Point(PointsToDraw[0].X, r.Bottom)); g.FillPolygon(graphShadow, PointsToDraw.ToArray()); }
protected override void OnDrawToBuffer(PaintEventArgs paintEventArgs) { Program.AssertOnEventThread(); Rectangle SlightlySmaller = GraphRectangle(paintEventArgs.ClipRectangle); // Fill BG paintEventArgs.Graphics.FillRectangle(Palette.PaperBrush, SlightlySmaller); if (ArchiveMaintainer == null || DataKey == null || DataPlotNav == null) { return; } if (IsSelected) { Rectangle rect = Rectangle.Inflate(paintEventArgs.ClipRectangle, 1, 1); paintEventArgs.Graphics.FillRectangle(Palette.GraphShadow, rect); paintEventArgs.Graphics.FillRectangle(Palette.PaperBrush, SlightlySmaller); } // Draw Rectangle around graph area paintEventArgs.Graphics.DrawRectangle(Palette.GridPen, SlightlySmaller); if (ArchiveMaintainer.LoadingInitialData) { paintEventArgs.Graphics.DrawString(Messages.GRAPH_LOADING, Palette.LabelFont, Palette.LabelBrush, SlightlySmaller.Left + 10, SlightlySmaller.Top + 10); return; } bool require_tools = true; foreach (DataSetCollectionWrapper set in DataKey.CurrentKeys) { if (set.Sets[ArchiveInterval.FiveSecond].TypeString != "memory") { require_tools = false; break; } } if (require_tools && DataKey.CurrentKeys.Count > 0) { Rectangle messageRect = Rectangle.Inflate(SlightlySmaller, -10, -10); paintEventArgs.Graphics.DrawString(Messages.GRAPH_NEEDS_TOOLS, Palette.LabelFont, Palette.LabelBrush, messageRect); return; } // Refresh all sets foreach (DataSet set in DataPlotNav.CurrentArchive.Sets.ToArray()) { if (!set.Draw || !DataKey.DataSourceUUIDsToShow.Contains(set.Uuid)) { continue; } List <DataPoint> todraw; ArchiveInterval current = DataPlotNav.GetCurrentLeftArchiveInterval(); ArchiveInterval currentwidth = DataPlotNav.GetCurrentWidthArchiveInterval(); if (current == currentwidth) { todraw = new List <DataPoint>(set.Points); if (current != ArchiveInterval.FiveSecond) { if (todraw.Count > 0 && todraw[0].X < DataPlotNav.GraphRight.Ticks) { todraw.InsertRange(0, DataPlotNav.GetFinerPoints( set, new DataTimeRange(todraw[0].X, DataPlotNav.GraphRight.Ticks, DataPlotNav.XRange.Resolution), current)); } } } else // currentwidth must be a higer resolution archive { int setindex = ArchiveMaintainer.Archives[currentwidth].Sets.IndexOf(set); todraw = new List <DataPoint>(ArchiveMaintainer.Archives[currentwidth].Sets[setindex].Points); if (todraw.Count > 0) { set.MergePointCollection(set.BinaryChop(set.Points, new DataTimeRange(DataPlotNav.GraphLeft.Ticks, todraw[todraw.Count - 1].X, DataPlotNav.GraphResolution.Ticks)), todraw); } } set.RefreshCustomY(DataPlotNav.XRange, todraw); DataRange ymax = DataRange.UnitRange; foreach (DataSetCollectionWrapper wrapper in DataKey.CurrentKeys) { if (wrapper.Sets.ContainsKey(current)) { DataSet dataSet = wrapper.Sets[current]; if (!dataSet.Hide && dataSet.CustomYRange != null && dataSet.CustomYRange.Units == set.CustomYRange.Units) { ymax.ScaleMode = dataSet.CustomYRange.ScaleMode; if (dataSet.CustomYRange.ScaleMode != RangeScaleMode.Auto) { if (dataSet.CustomYRange.Max > ymax.Max) { ymax = dataSet.CustomYRange; } } else { double maxY = DataSet.GetMaxY(dataSet.BinaryChop(dataSet.CurrentlyDisplayed, DataPlotNav.XRange)); if (maxY < 1) { maxY = 1; } if (maxY >= ymax.Max) { ymax = dataSet.CustomYRange; ymax.Max = maxY; } } } } } if (set.CustomYRange.ScaleMode == RangeScaleMode.Auto) { ymax.RoundToNearestPowerOf10(); } foreach (DataSetCollectionWrapper wrapper in DataKey.CurrentKeys) { foreach (DataSet ds in wrapper.Sets.Values) { if (ds.Hide || ds.CustomYRange == null || ds.CustomYRange.Units != set.CustomYRange.Units) { continue; } ds.CustomYRange.Max = ymax.Max; ds.CustomYRange.Min = ymax.Min; ds.CustomYRange.Resolution = ymax.Resolution; } } } // Draw Axes XAxis.DrawToBuffer(new DrawAxisXArgs(paintEventArgs.Graphics, SlightlySmaller, DataPlotNav != null ? DataPlotNav.XRange : DataTimeRange.MaxRange, ShowLabels)); YAxis.DrawToBuffer(new DrawAxisYArgs(paintEventArgs.Graphics, SlightlySmaller, SelectedYRange, ShowLabels)); // Draw Sets DataSet[] sets_to_show = DataPlotNav.CurrentArchive.Sets.ToArray(); Array.Sort(sets_to_show); Array.Reverse(sets_to_show); foreach (DataSet set in sets_to_show) { if (!set.Draw || DataKey == null || !DataKey.DataSourceUUIDsToShow.Contains(set.Uuid)) { continue; } lock (Palette.PaletteLock) { using (var thickPen = Palette.CreatePen(set.Uuid, Palette.PEN_THICKNESS_THICK)) { using (var normalPen = Palette.CreatePen(set.Uuid, Palette.PEN_THICKNESS_NORMAL)) { using (var shadowBrush = Palette.CreateBrush(set.Uuid)) { LineRenderer.Render(paintEventArgs.Graphics, SlightlySmaller, DataPlotNav.XRange, set.CustomYRange ?? SelectedYRange, set.Selected ? thickPen : normalPen, shadowBrush, set.CurrentlyDisplayed, true); } } } } } if (DataEventList != null) { DataEventList.RenderEvents(paintEventArgs.Graphics, DataPlotNav.XRange, new Rectangle(SlightlySmaller.Left, SlightlySmaller.Top + 2, SlightlySmaller.Width, SlightlySmaller.Height - 2), 16); } SizeF labelsize = new SizeF(0, 0); if (SelectedPoint != null && DataKey.SelectedDataSet != null) { string label = string.Format(string.Format("{0} - {1} = {2}", DataPlotNav.XRange.GetString(SelectedPoint.X + ArchiveMaintainer.ClientServerOffset.Ticks), DataKey.SelectedDataSet.Name, SelectedPoint.Y >= 0 ? SelectedYRange.GetString(SelectedPoint.Y) : Messages.GRAPHS_NO_DATA)); labelsize = paintEventArgs.Graphics.MeasureString(label, Palette.LabelFont); paintEventArgs.Graphics.DrawString(label, Palette.LabelFont, Palette.LabelBrush, SlightlySmaller.Right - labelsize.Width, SlightlySmaller.Top - (labelsize.Height + 1)); } // Draw graph's name if (DisplayName != String.Empty) { Rectangle rect = new Rectangle(SlightlySmaller.Location, SlightlySmaller.Size); rect.Width -= Convert.ToInt32(labelsize.Width); string nameLabel = DisplayName.Ellipsise(paintEventArgs.Graphics, rect, Palette.LabelFont); SizeF nameLabelSize = paintEventArgs.Graphics.MeasureString(nameLabel, Palette.LabelFont); paintEventArgs.Graphics.DrawString(nameLabel, Palette.LabelFont, Palette.LabelBrush, SlightlySmaller.Left, SlightlySmaller.Top - (nameLabelSize.Height + 1)); } // Draw to screen Refresh(); }
public DrawAxisYArgs(Graphics g, Rectangle r, DataRange range, bool showlabels) : base(g, r, showlabels) { Range = range; }
/// <summary> /// Virtual to Screen XY /// </summary> public static LongPoint TranslateToScreen(LongPoint virtualpoint, DataTimeRange xrange, DataRange yrange, LongRectangle rectangle) { if (xrange.Delta == 0 || yrange.Delta == 0) { // have seen this happen when we try to render graphs after the host failed to install a vm // doesn't matter too much what we return as the VM entry is going to get removed. Just don't crash. log.ErrorFormat("Tried to translate datapoint through range of zero. xrange.Delta: {0}, yrange.Delta: {1}", xrange.Delta, yrange.Delta); return(new LongPoint(0, 0)); } // work out x, assume origin is bottom right double x = rectangle.Right - ((rectangle.Width * (virtualpoint.X - xrange.Min)) / xrange.Delta); // work out y double y = rectangle.Bottom - ((rectangle.Height * (virtualpoint.Y - yrange.Min)) / yrange.Delta); y = y > rectangle.Bottom ? rectangle.Bottom : y < rectangle.Y ? rectangle.Y : y; if (x >= ARBITRARY_MICROSOFT_LINE_MAX_LENGTH && y >= ARBITRARY_MICROSOFT_LINE_MAX_LENGTH) { log.DebugFormat("Point translated to more than max line length: x={0} y={1} vx={2} vy={3} xrange_min={4} xrange_max={5} yrange_min={6} yrange_max={7} rectangle_x={8} rectangle_y={9} rectangle_w={10} rectangle_h={11}", x, y, virtualpoint.X, virtualpoint.Y, xrange.Min, xrange.Max, yrange.Min, yrange.Max, rectangle.X, rectangle.Y, rectangle.Width, rectangle.Height); // draw a random line as this is better than crashing return(new LongPoint(0, 0)); } return(new LongPoint((long)x, (long)y)); }
/// <summary> /// Screen XY to Virtual /// </summary> public static LongPoint DeTranslateFromScreen(LongPoint screenpoint, DataTimeRange xrange, DataRange yrange, LongRectangle rectangle) { // work out x, assume origin is bottom right double x = xrange.Min + (xrange.Delta * (rectangle.Right - screenpoint.X)) / (double)rectangle.Width; // work out y double y = yrange.Min + (yrange.Delta * (rectangle.Bottom - screenpoint.Y)) / (double)rectangle.Height; return(new LongPoint((long)x, (long)y)); }