protected override void OnMouseUp(MouseEventArgs e) { base.OnMouseUp(e); if (ArchiveMaintainer == null || ArchiveMaintainer.LoadingInitialData) { return; } // Do the same thing for everything here for consistency DataTimeRange everything = CurrentArchiveRange; if (MouseDragging == DragMode.New && e.X == MouseDragStart) { LongPoint virtualclicked = LongPoint.DeTranslateFromScreen(new LongPoint(e.Location), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)); long proposedoffset = ArchiveMaintainer.GraphNow.Ticks - (virtualclicked.X + (GraphWidth.Ticks / 2)); GraphOffset = TimeSpan.FromTicks(proposedoffset > 0 ? proposedoffset : 0); } TimerScroll = ScrollMode.None; Scroller.Stop(); AutoScaleGraph(); GridSpacing = BodgeSpacing(GraphWidth); RefreshXRange(false); MouseDragging = DragMode.None; MouseResizing = ResizeMode.None; }
/// <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)); }
protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); if (ArchiveMaintainer == null || ArchiveMaintainer.LoadingInitialData) { return; } DataTimeRange everything = CurrentArchiveRange; long selectedleft = LongPoint.TranslateToScreen(new LongPoint(GraphLeft.Ticks, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)).X; long selectedright = LongPoint.TranslateToScreen(new LongPoint(GraphRight.Ticks, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)).X; if (e.Location.X > selectedleft - 3 && e.Location.X < selectedleft + 3) { MouseResizing = ResizeMode.Left; } else if (e.Location.X > selectedright - 3 && e.Location.X < selectedright + 3) { MouseResizing = ResizeMode.Right; } else if (e.Location.X > selectedleft - 3 && e.Location.X < selectedright + 3) { MouseDragging = DragMode.Existing; } else { MouseDragStart = e.X; MouseDragging = DragMode.New; } }
/// <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 bool Contains(LongPoint p) { // draw a line horizontally right to infinity // count the number of times a line crosses this line // if odd return true // if even return false int crosses = 0; int j = Points.Count - 1; for (int i = 0; i < Points.Count; i++) { double x1 = Points[i].X; double x2 = Points[j].X; double y1 = Points[i].Y; double y2 = Points[j].Y; double x = (((x2 - x1) * (p.Y - y1)) / (y2 - y1)) + x1; if (((y1 <= p.Y && p.Y < y2) || (y2 <= p.Y && p.Y < y1)) && p.X < x) { crosses++; } j = i; } return(crosses % 2 != 0); }
public override void DrawToBuffer(DrawAxisArgs drawArgs) { var args = drawArgs as DrawAxisYArgs; if (args == null) { return; } for (double i = args.Range.Min; i <= args.Range.Max; i += args.Range.Resolution) { // make sure that the last point is args.Range.Max if (i + args.Range.Resolution > args.Range.Max) { i = args.Range.Max; } string label = args.Range.GetRelativeString(i); LongPoint pt = LongPoint.TranslateToScreen(new LongPoint(0, (long)i), DataTimeRange.UnitRange, args.Range, new LongRectangle(args.Rectangle)); if (i != 0) { args.Graphics.DrawLine(Palette.GridPen, new Point(args.Rectangle.Right, (int)pt.Y), new Point(args.Rectangle.Left, (int)pt.Y)); } if (!args.ShowLabels) { continue; } if (Labels == GridLabels.All) { SizeF labelsize = args.Graphics.MeasureString(label, Palette.LabelFont); args.Graphics.DrawString(label, Palette.LabelFont, Palette.LabelBrush, new PointF(args.Rectangle.Right, i == args.Range.Min ? (int)pt.Y - labelsize.Height : i == args.Range.Max ? (int)pt.Y : (int)pt.Y - (labelsize.Height / 2))); } else if (Labels == GridLabels.MinMax) { if (i == args.Range.Min || i + args.Range.Resolution > args.Range.Max) { SizeF labelsize = args.Graphics.MeasureString(label, Palette.LabelFont); args.Graphics.DrawString(label, Palette.LabelFont, Palette.LabelBrush, new PointF(args.Rectangle.Right, i == args.Range.Min ? (int)pt.Y - labelsize.Height : i == args.Range.Max ? (int)pt.Y : (int)pt.Y - (labelsize.Height / 2))); } // draw units string unitString = args.Range.UnitString; if (!string.IsNullOrEmpty(unitString)) { SizeF unitssize = args.Graphics.MeasureString(unitString, Palette.LabelFont); args.Graphics.DrawString(unitString, Palette.LabelFont, Palette.LabelBrush, new PointF(args.Rectangle.Right, args.Rectangle.Top + (args.Rectangle.Height / 2) - (unitssize.Height / 2))); } } } }
public DataPoint OnMouseMove(MouseActionArgs args) { if (Deselected) { return(null); } LongPoint p = LongPoint.DeTranslateFromScreen(new LongPoint(args.Point), args.XRange, args.YRange, new LongRectangle(args.Rectangle)); return(ClosestPointTo(p)); }
/// <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)); }
public override void DrawToBuffer(DrawAxisArgs drawArgs) { var args = drawArgs as DrawAxisXArgs; if (args == null) { return; } Dictionary <long, string> labels = new Dictionary <long, string>(); long last_i = long.MinValue; for (long i = args.Range.Min - (args.Range.Min % -args.Range.Resolution); i >= args.Range.Max; i += args.Range.Resolution) { string label = args.Range.GetRelativeString(i + ArchiveMaintainer.ClientServerOffset.Ticks, ArchiveMaintainer.GraphNow); if (last_i != long.MinValue && label == labels[last_i]) { labels.Remove(last_i); } labels[i] = label; last_i = i; } for (long i = args.Range.Min - (args.Range.Min % -args.Range.Resolution); i >= args.Range.Max; i += args.Range.Resolution) { LongPoint pt = LongPoint.TranslateToScreen(new LongPoint(i, 0), args.Range, DataRange.UnitRange, new LongRectangle(args.Rectangle)); if (i != 0) { args.Graphics.DrawLine(Palette.GridPen, new Point((int)pt.X, args.Rectangle.Bottom), new Point((int)pt.X, args.Rectangle.Top)); } if (!args.ShowLabels) { continue; } if (!labels.ContainsKey(i)) { continue; } string label = labels[i]; if (Labels == GridLabels.MinMax && (i == args.Range.Min - (args.Range.Min % -args.Range.Resolution) || i + args.Range.Resolution < args.Range.Max)) { SizeF labelsize = args.Graphics.MeasureString(label, Palette.LabelFont); args.Graphics.DrawString(label, Palette.LabelFont, Palette.LabelBrush, new PointF(i == args.Range.Min - (args.Range.Min % -args.Range.Resolution) ? (int)pt.X - labelsize.Width : (int)pt.X, args.Rectangle.Bottom)); } else if (Labels == GridLabels.All) { SizeF labelsize = args.Graphics.MeasureString(label, Palette.LabelFont); args.Graphics.DrawString(label, Palette.LabelFont, Palette.LabelBrush, new PointF(i == args.Range.Min ? (int)pt.X - labelsize.Width : i == args.Range.Max ? (int)pt.X : (int)pt.X - (labelsize.Width / 2), args.Rectangle.Bottom)); } } }
internal void OnEventsMouseClick(MouseActionArgs args) { foreach (DataEvent e in DataEvents) { LongPoint pt = LongPoint.TranslateToScreen(e.Point, args.XRange, args.YRange, new LongRectangle(args.Rectangle)); if (pt.X - 8 <= args.Point.X && args.Point.X <= pt.X + 8) { SelectedItem = e; return; } } SelectedItem = null; }
public void RenderEvents(Graphics graphics, DataTimeRange xrange, Rectangle bounds, int spaceheight) { if (DataEvents == null) { return; } foreach (DataEvent vent in DataEvents) { if (vent.X < xrange.Max || vent.X > xrange.Min) { continue; } LongPoint loc = LongPoint.TranslateToScreen(vent.Point, xrange, DataRange.UnitRange, new LongRectangle(bounds)); vent.DrawToBuffer(graphics, loc.Point, bounds, spaceheight); } }
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))); }
private DataPoint ClosestPointTo(LongPoint p) { if (CurrentlyDisplayed.Count == 0 || CurrentlyDisplayed[CurrentlyDisplayed.Count - 1].X > p.X || CurrentlyDisplayed[0].X < p.X) { return(null); } for (int i = 1; i < CurrentlyDisplayed.Count; i++) { if (CurrentlyDisplayed[i - 1].X >= p.X && CurrentlyDisplayed[i].X < p.X) { if (p.X - CurrentlyDisplayed[i].X > (CurrentlyDisplayed[i - 1].X - CurrentlyDisplayed[i].X) / 2) { return(CurrentlyDisplayed[i - 1]); } else { return(CurrentlyDisplayed[i]); } } } return(null); }
public override void DrawToBuffer(DrawAxisArgs drawArgs) { var args = drawArgs as DrawAxisNavArgs; if (args == null) { return; } for (long i = args.Range.Min - (args.Range.Min % -args.Range.Resolution); i >= args.Range.Max; i += args.Range.Resolution) { string label = args.Range.GetRelativeString(i + ArchiveMaintainer.ClientServerOffset.Ticks, ArchiveMaintainer.GraphNow); LongPoint pt = LongPoint.TranslateToScreen(new LongPoint(i, 0), args.Range, DataRange.UnitRange, new LongRectangle(args.Rectangle)); if (i != 0) { args.Graphics.DrawLine(Palette.GridPen, new Point((int)pt.X, args.Rectangle.Bottom), new Point((int)pt.X, args.Rectangle.Top)); } if (args.ShowLabels && Labels == GridLabels.All) { args.Graphics.DrawString(label, Palette.LabelFont, Palette.LabelBrush, new PointF((int)pt.X, args.Rectangle.Top)); } } }
public bool Contains(LongPoint p) { // draw a line horizontally right to infinity // count the number of times a line crosses this line // if odd return true // if even return false int crosses = 0; int j = Points.Count - 1; for(int i = 0; i < Points.Count; i++) { double x1 = Points[i].X; double x2 = Points[j].X; double y1 = Points[i].Y; double y2 = Points[j].Y; double x = (((x2 - x1) * (p.Y - y1)) / (y2 - y1)) + x1; if (((y1 <= p.Y && p.Y < y2) || (y2 <= p.Y && p.Y < y1)) && p.X < x) crosses++; j = i; } return crosses % 2 != 0; }
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 rect = new Rectangle(ScrollViewRectangle.Left, ScrollViewRectangle.Top, ScrollViewRectangle.Width - 1, ScrollViewRectangle.Height - 1); paintEventArgs.Graphics.FillRectangle(Palette.PaperBrush, ScrollViewRectangle); paintEventArgs.Graphics.DrawRectangle(SystemPens.ActiveBorder, rect); if (ArchiveMaintainer == null || Axis == null) { return; } if (ArchiveMaintainer.LoadingInitialData) { paintEventArgs.Graphics.DrawString(Messages.GRAPH_LOADING, Palette.LabelFont, Palette.LabelBrush, ScrollViewRectangle.Left + 10, ScrollViewRectangle.Top + 10); return; } DataTimeRange everything = Animating ? AnimateTimeRange : CurrentArchiveRange; RectangleF clip = paintEventArgs.Graphics.ClipBounds; paintEventArgs.Graphics.SetClip(rect); foreach (DataSet set in ScrollWideArchive.Sets.ToArray()) { if (!set.Draw || !DisplayedUuids.Contains(set.Uuid)) { continue; } List <DataPoint> todraw; ArchiveInterval current = ScrollViewLeftArchiveInterval; ArchiveInterval currentwidth = ScrollViewWidthArchiveInterval; if (current == currentwidth) { todraw = new List <DataPoint>(set.Points); if (current != ArchiveInterval.FiveSecond) { if (todraw.Count > 0 && todraw[0].X < ScrollViewRight.Ticks) { todraw.InsertRange(0, GetFinerPoints( set, new DataTimeRange(todraw[0].X, ScrollViewRight.Ticks, 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(ScrollViewLeft.Ticks, todraw[todraw.Count - 1].X, GraphResolution.Ticks)), todraw); } } set.RefreshCustomY(everything, todraw); if (set.CustomYRange.ScaleMode == RangeScaleMode.Auto) { set.CustomYRange.Max = DataSet.GetMaxY(set.CurrentlyDisplayed); set.CustomYRange.RoundToNearestPowerOf10(); } } Axis.DrawToBuffer(new DrawAxisNavArgs(paintEventArgs.Graphics, ScrollViewRectangle, new DataTimeRange(everything.Max, everything.Min, -BodgeSpacing(new TimeSpan(-everything.Delta)).Ticks), true)); foreach (DataSet set in ScrollWideArchive.Sets.ToArray()) { if (!set.Draw || !DisplayedUuids.Contains(set.Uuid)) { continue; } lock (Palette.PaletteLock) { using (var normalPen = Palette.CreatePen(set.Uuid, Palette.PEN_THICKNESS_NORMAL)) { LineRenderer.Render(paintEventArgs.Graphics, ScrollViewRectangle, everything, set.CustomYRange, normalPen, null, set.CurrentlyDisplayed, false); } } } if (DataEventList != null) { DataEventList.RenderEvents(paintEventArgs.Graphics, everything, ScrollViewRectangle, 5); } paintEventArgs.Graphics.SetClip(clip); long selectedleft = LongPoint.TranslateToScreen(new LongPoint(GraphLeft.Ticks, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)).X; long selectedright = LongPoint.TranslateToScreen(new LongPoint(GraphRight.Ticks, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)).X; paintEventArgs.Graphics.FillRectangle(Palette.ShadowRangeBrush, ScrollViewRectangle.Left, ScrollViewRectangle.Top, selectedleft - (ScrollViewRectangle.Left), ScrollViewRectangle.Height); paintEventArgs.Graphics.FillRectangle(Palette.ShadowRangeBrush, selectedright, ScrollViewRectangle.Top, ScrollViewRectangle.Width + (ScrollViewRectangle.Left) - selectedright, ScrollViewRectangle.Height); DrawGripper(paintEventArgs.Graphics, selectedright); DrawGripper(paintEventArgs.Graphics, selectedleft); }
protected override void OnMouseMove(MouseEventArgs e) { base.OnMouseMove(e); if (ArchiveMaintainer == null || ArchiveMaintainer.LoadingInitialData) { return; } DataTimeRange everything = CurrentArchiveRange; LongPoint virtualclicked = LongPoint.DeTranslateFromScreen(new LongPoint(e.Location), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)); long selectedleft = LongPoint.TranslateToScreen(new LongPoint(GraphLeft.Ticks, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)).X; long selectedright = LongPoint.TranslateToScreen(new LongPoint(GraphRight.Ticks, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)).X; if (MouseDragging == DragMode.Existing) { long proposedoffset = ArchiveMaintainer.GraphNow.Ticks - (virtualclicked.X + (GraphWidth.Ticks / 2)); if (proposedoffset + GraphWidth.Ticks > ScrollViewOffset.Ticks + ScrollViewWidth.Ticks) { // ------------------------- // | _______________________|____________________________________ // | | ------------- | _______-------- | // | | / \___|__________/ \ | // | |---- | ---- -| // | |_______________________|_______________________________\__/_| // ------------------------- // // we have scrolled too far left (off the scroll view) GraphOffset = TimeSpan.FromTicks(ScrollViewWidth.Ticks + ScrollViewOffset.Ticks - GraphWidth.Ticks); } else if (proposedoffset < ScrollViewOffset.Ticks) { // ------------------------- // ___________________________________|_______________________ | // | ------------- _|_____-------- | | // | / \______________/ | \ | | // |---- | ---- -| | // |____________________________________|__________________\__/_| | // ------------------------- // // we have scrolled too far right (off the scroll view) if (GraphOffset == ScrollViewOffset) { return; } GraphOffset = ScrollViewOffset; } else { // ------------------------- // ___________|_________________________|______________________ // | -----|------- __|____-------- | // | / | \______________/ | \ | // |---- | | ---- -| // |___________|_________________________|_________________\__/_| // ------------------------- // // everything is fine, we are in the middle GraphOffset = TimeSpan.FromTicks(proposedoffset > 0 ? proposedoffset : 0); } if (GraphOffset.Ticks + GraphWidth.Ticks - ScrollViewOffset.Ticks > 0.90 * ScrollViewWidth.Ticks) { ScrollStrength = TimeSpan.FromTicks(GraphOffset.Ticks + GraphWidth.Ticks - (ScrollViewOffset.Ticks + (long)(0.90 * ScrollViewWidth.Ticks))); TimerScroll = ScrollMode.Left; Scroller.Start(); } else if (GraphOffset.Ticks - ScrollViewOffset.Ticks < 0.1 * ScrollViewWidth.Ticks) { ScrollStrength = TimeSpan.FromTicks((long)(0.1 * ScrollViewWidth.Ticks) - (GraphOffset.Ticks - ScrollViewOffset.Ticks)); TimerScroll = ScrollMode.Right; Scroller.Start(); } else { TimerScroll = ScrollMode.None; } } else if (MouseDragging == DragMode.New) { LongPoint virtualstart = LongPoint.DeTranslateFromScreen(new LongPoint(MouseDragStart, 1), everything, DataRange.UnitRange, new LongRectangle(ScrollViewRectangle)); if (e.X > MouseDragStart && e.X < ScrollViewRectangle.Width) { GraphOffset = new TimeSpan(ArchiveMaintainer.GraphNow.Ticks - virtualclicked.X); GraphWidth = new TimeSpan(virtualclicked.X - virtualstart.X); } else if (e.X < MouseDragStart && e.X > 0) { GraphOffset = new TimeSpan(ArchiveMaintainer.GraphNow.Ticks - virtualstart.X); GraphWidth = new TimeSpan(virtualstart.X - virtualclicked.X); } else if (e.X < MouseDragStart) { GraphOffset = new TimeSpan(ArchiveMaintainer.GraphNow.Ticks - virtualstart.X); GraphWidth = ScrollViewOffset + ScrollViewWidth - GraphOffset; } else if (e.X > MouseDragStart) { GraphOffset = ScrollViewOffset; GraphWidth = new TimeSpan(ScrollViewRight.Ticks - virtualstart.X); } } else if (MouseResizing == ResizeMode.Left) { long proposedwidth = ArchiveMaintainer.GraphNow.Ticks - (virtualclicked.X + GraphOffset.Ticks); if (((proposedwidth * ScrollViewRectangle.Width) / ScrollViewWidth.Ticks) > 2) { GraphWidth = proposedwidth + GraphOffset.Ticks < ScrollViewWidth.Ticks + ScrollViewOffset.Ticks ? TimeSpan.FromTicks(proposedwidth) : ScrollViewWidth + ScrollViewOffset - GraphOffset; } else { GraphWidth = TimeSpan.FromTicks((2 * ScrollViewWidth.Ticks) / ScrollViewRectangle.Width); } } else if (MouseResizing == ResizeMode.Right) { long proposedwidth = virtualclicked.X - GraphRight.Ticks; if (ArchiveMaintainer.GraphNow.Ticks - virtualclicked.X < ScrollViewOffset.Ticks) { GraphWidth += GraphOffset - ScrollViewOffset; GraphOffset = ScrollViewOffset; } else if ((((GraphWidth.Ticks + proposedwidth) * ScrollViewRectangle.Width) / ScrollViewWidth.Ticks) > 2) { GraphWidth += TimeSpan.FromTicks(virtualclicked.X - GraphRight.Ticks); GraphOffset = TimeSpan.FromTicks(ArchiveMaintainer.GraphNow.Ticks - virtualclicked.X); } else { long oldwidth = GraphWidth.Ticks; GraphWidth = TimeSpan.FromTicks((2 * ScrollViewWidth.Ticks) / ScrollViewRectangle.Width); GraphOffset += TimeSpan.FromTicks(oldwidth - GraphWidth.Ticks); } } else if (e.Location.X > selectedleft - 3 && e.Location.X < selectedleft + 3) { Cursor = Cursors.SizeWE; return; } else if (e.Location.X > selectedright - 3 && e.Location.X < selectedright + 3) { Cursor = Cursors.SizeWE; return; } else if (e.Location.X > selectedleft - 3 && e.Location.X < selectedright + 3) { Cursor = Cursors.SizeAll; return; } else { Cursor = Cursors.Cross; return; } GridSpacing = BodgeSpacing(GraphWidth); RefreshXRange(false); }
/// <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); }