public void RenderRect(OxyRect bounds, OxyColor fill, OxyColor borderColor, double borderThickness) { var border = new[] { new ScreenPoint(bounds.Left, bounds.Top), new ScreenPoint(bounds.Right, bounds.Top), new ScreenPoint(bounds.Right, bounds.Bottom), new ScreenPoint(bounds.Left, bounds.Bottom), new ScreenPoint(bounds.Left, bounds.Top) }; rc.DrawPolygon(border, fill, borderColor, borderThickness, null, true); }
public GraphComponents(OxyColor color) { scatters = new ScatterSeries { BinSize = 8, MarkerFill = color, MarkerSize = 2.0, MarkerStroke = color, MarkerStrokeThickness = 1.0, MarkerType = MarkerType.Circle }; lines = new LineSeries { Color = color, LineStyle = LineStyle.Solid, StrokeThickness = 1.0, Smooth = true }; stems = new StemSeries { Color = color, StrokeThickness = 1.0, }; }
/// <summary> /// Initializes a new instance of the <see cref="CandleStickSeries"/> class. /// </summary> /// <param name="color"> /// The color. /// </param> /// <param name="strokeThickness"> /// The stroke thickness. /// </param> /// <param name="title"> /// The title. /// </param> public CandleStickSeries(OxyColor color, double strokeThickness = 1, string title = null) : this() { this.Color = color; this.StrokeThickness = strokeThickness; this.Title = title; }
/// <summary> /// Draws an ellipse. /// </summary> /// <param name="rect">The rectangle.</param> /// <param name="fill">The fill color.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The thickness.</param> public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness) { var isStroked = stroke.IsVisible() && thickness > 0; var isFilled = fill.IsVisible(); if (!isStroked && !isFilled) { return; } double y = this.doc.PageHeight - rect.Bottom; if (isStroked) { this.SetLineWidth(thickness); this.doc.SetColor(stroke); if (isFilled) { this.doc.SetFillColor(fill); this.doc.DrawEllipse(rect.Left, y, rect.Width, rect.Height, true); } else { this.doc.DrawEllipse(rect.Left, y, rect.Width, rect.Height); } } else { this.doc.SetFillColor(fill); this.doc.FillEllipse(rect.Left, y, rect.Width, rect.Height); } }
/// <summary> /// Initializes a new instance of the <see cref="ScatterSeries"/> class. /// </summary> /// <param name="title"> /// The title. /// </param> /// <param name="markerFill"> /// The marker fill color. /// </param> /// <param name="markerSize"> /// Size of the markers (If ScatterPoint.Size is set, this value will be overriden). /// </param> public ScatterSeries(string title, OxyColor markerFill = null, double markerSize = 5) : this() { this.MarkerFill = markerFill; this.MarkerSize = markerSize; this.Title = title; }
/// <summary> /// Draws the collection of ellipses, where all have the same stroke and fill. /// This performs better than calling DrawEllipse multiple times. /// </summary> /// <param name="rectangles">The rectangles.</param> /// <param name="fill">The fill color.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The stroke thickness.</param> public virtual void DrawEllipses(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness) { foreach (var r in rectangles) { this.DrawEllipse(r, fill, stroke, thickness); } }
/// <summary> /// Construct a new instance of the class. /// </summary> /// <param name="title">The plot title.</param> /// <param name="results">The data to plot.</param> public Plot(string title, List <List <double> > results) { // set up plot model var plotModel = new OxyPlot.PlotModel(); plotModel.Title = title; // set up axes and colors plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis() { Position = OxyPlot.Axes.AxisPosition.Left, Title = "Error" }); plotModel.Axes.Add(new OxyPlot.Axes.LinearAxis() { Position = OxyPlot.Axes.AxisPosition.Bottom, Title = "Epochs" }); var colors = new OxyPlot.OxyColor[] { OxyPlot.OxyColors.Blue, OxyPlot.OxyColors.Green, OxyPlot.OxyColors.Red, OxyPlot.OxyColors.Black }; // set up lines for (int i = 0; i < results.Count; i++) { var lineSeries = new OxyPlot.Series.LineSeries(); lineSeries.ItemsSource = results[i].Select((value, index) => new OxyPlot.DataPoint(index, value)); lineSeries.Title = string.Format("KFold {0}/{1}", i + 1, results.Count); //lineSeries.Color = colors[i]; plotModel.Series.Add(lineSeries); } var plotView = new OxyPlot.Wpf.PlotView(); plotView.Model = plotModel; Title = title; Content = plotView; }
/// <summary> /// Draws a polyline. /// </summary> /// <param name="points">The points.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The stroke thickness.</param> /// <param name="dashArray">The dash array.</param> /// <param name="lineJoin">The line join type.</param> /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param> public abstract void DrawLine( IList<ScreenPoint> points, OxyColor stroke, double thickness, double[] dashArray, OxyPenLineJoin lineJoin, bool aliased);
/// <summary> /// Draws an ellipse. /// </summary> /// <param name="rect">The rectangle.</param> /// <param name="fill">The fill color.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The thickness.</param> public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness) { var isStroked = stroke.IsVisible() && thickness > 0; if (fill.IsVisible()) { if (!isStroked) { this.g.SmoothingMode = SmoothingMode.HighQuality; } this.g.FillEllipse(this.GetCachedBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height); } if (!isStroked) { return; } using (var pen = this.GetCachedPen(stroke, thickness)) { this.g.SmoothingMode = SmoothingMode.HighQuality; this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height); } }
public void AddSeries(IEnumerable<double> x, IEnumerable<double> y, string title, OxyColor fill) { var series = new ScatterSeries { MarkerFill = fill, MarkerSize = 2, MarkerStrokeThickness = 0, MarkerType = MarkerType.Diamond, Title = title }; double[] xPoints = x as double[] ?? x.ToArray(); double[] yPoints = y as double[] ?? y.ToArray(); if (xPoints.Length != yPoints.Length) throw new Exception("The two data arrays must be of equal length."); for (int i = 0; i < xPoints.Length; i++) { var point = new ScatterPoint(xPoints[i], yPoints[i]); series.Points.Add(point); } Model.Series.Add(series); }
/// <summary> /// Encodes the specified image data to png. /// </summary> /// <param name="pixels"> /// The pixel data (bottom line first). /// </param> /// <param name="dpi"> /// The image resolution in dots per inch. /// </param> /// <returns> /// The png image data. /// </returns> public static byte[] Encode(OxyColor[,] pixels, int dpi = 96) { int height = pixels.GetLength(0); int width = pixels.GetLength(1); var bytes = new byte[(width * height * 4) + height]; int k = 0; for (int i = height - 1; i >= 0; i--) { bytes[k++] = 0; // Filter for (int j = 0; j < width; j++) { bytes[k++] = pixels[i, j].R; bytes[k++] = pixels[i, j].G; bytes[k++] = pixels[i, j].B; bytes[k++] = pixels[i, j].A; } } var w = new MemoryWriter(); w.Write((byte)0x89); w.Write("PNG\r\n\x1a\n".ToCharArray()); WriteChunk(w, "IHDR", CreateHeaderData(width, height)); WriteChunk(w, "pHYs", CreatePhysicalDimensionsData(dpi, dpi)); WriteChunk(w, "IDAT", CreateUncompressedBlocks(bytes)); WriteChunk(w, "IEND", new byte[0]); return w.ToArray(); }
/// <summary> /// Draws or measures text containing sub- and superscript. /// </summary> /// <param name="rc">The render context.</param> /// <param name="pt">The point.</param> /// <param name="text">The text.</param> /// <param name="textColor">Color of the text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">The font size.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="angle">The angle.</param> /// <param name="ha">The horizontal alignment.</param> /// <param name="va">The vertical alignment.</param> /// <param name="maxsize">The maximum size of the text.</param> /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param> /// <returns>The size of the text.</returns> /// <example>Subscript: H_{2}O /// Superscript: E=mc^{2} /// Both: A^{2}_{i,j}</example> public static OxySize DrawMathText( this IRenderContext rc, ScreenPoint pt, string text, OxyColor textColor, string fontFamily, double fontSize, double fontWeight, double angle, HorizontalAlignment ha, VerticalAlignment va, OxySize? maxsize, bool measure) { if (string.IsNullOrEmpty(text)) { return OxySize.Empty; } if (text.Contains("^{") || text.Contains("_{")) { double x = pt.X; double y = pt.Y; // Measure var size = InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, true, angle); switch (ha) { case HorizontalAlignment.Right: x -= size.Width; break; case HorizontalAlignment.Center: x -= size.Width * 0.5; break; } switch (va) { case VerticalAlignment.Bottom: y -= size.Height; break; case VerticalAlignment.Middle: y -= size.Height * 0.5; break; } InternalDrawMathText(rc, x, y, text, textColor, fontFamily, fontSize, fontWeight, false, angle); return measure ? size : OxySize.Empty; } rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxsize); if (measure) { return rc.MeasureText(text, fontFamily, fontSize, fontWeight); } return OxySize.Empty; }
private static PlotModel CreateRandomScatterSeriesWithColorAxisPlotModel(int n, OxyPalette palette, MarkerType markerType, AxisPosition colorAxisPosition, OxyColor highColor, OxyColor lowColor) { var model = new PlotModel { Title = string.Format("ScatterSeries (n={0})", n), Background = OxyColors.LightGray }; var colorAxis = new LinearColorAxis { Position = colorAxisPosition, Palette = palette, Minimum = -1, Maximum = 1, HighColor = highColor, LowColor = lowColor }; model.Axes.Add(colorAxis); model.Series.Add(CreateRandomScatterSeries(n, markerType, false, true, colorAxis)); return model; }
/// <summary> /// Draws a polyline. /// </summary> /// <param name="points">The points.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param> /// <param name="dashArray">The dash array (in device independent units, 1/96 inch). Use <c>null</c> to get a solid line.</param> /// <param name="lineJoin">The line join type.</param> /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param> public void DrawLine( IList<ScreenPoint> points, OxyColor stroke, double thickness = 1, double[] dashArray = null, LineJoin lineJoin = LineJoin.Miter, bool aliased = false) { }
/// <summary> /// Draws a polyline. /// </summary> /// <param name="points">The points.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The stroke thickness.</param> /// <param name="dashArray">The dash array.</param> /// <param name="lineJoin">The line join type.</param> /// <param name="aliased">if set to <c>true</c> the shape will be aliased.</param> public override void DrawLine( IList<ScreenPoint> points, OxyColor stroke, double thickness, double[] dashArray, OxyPenLineJoin lineJoin, bool aliased) { var xckdPoints = this.Distort(points); this.rc.DrawLine(xckdPoints, stroke, thickness * this.ThicknessScale, dashArray, lineJoin); }
/// <summary> /// Initializes a new instance of the <see cref="PdfRenderContext" /> class. /// </summary> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="background">The background.</param> public PdfRenderContext(double width, double height, OxyColor background) { this.doc = new PortableDocument(); this.doc.AddPage(width, height); this.RendersToScreen = false; if (background.IsVisible()) { this.doc.SetFillColor(background); this.doc.FillRectangle(0, 0, width, height); } }
/// <summary> /// Initializes a new instance of the <see cref="OxyPen"/> class. /// </summary> /// <param name="color"> /// The color. /// </param> /// <param name="thickness"> /// The thickness. /// </param> /// <param name="lineStyle"> /// The line style. /// </param> /// <param name="lineJoin"> /// The line join. /// </param> public OxyPen( OxyColor color, double thickness = 1.0, LineStyle lineStyle = LineStyle.Solid, OxyPenLineJoin lineJoin = OxyPenLineJoin.Miter) { this.Color = color; this.Thickness = thickness; this.DashArray = LineStyleHelper.GetDashArray(lineStyle); this.LineStyle = lineStyle; this.LineJoin = lineJoin; }
private static void SetPlotData(PlotModel IncomePlot, Transaction data, OxyColor barColor, int number) { var barSeries = new LinearBarSeries { StrokeThickness = 1, FillColor = barColor, Title = data.Description }; barSeries.Points.Add(new DataPoint(DateTimeAxis.ToDouble(data.TimeStamp), double.Parse((number * data.Amount).ToString()))); IncomePlot.Series.Add(barSeries); }
/// <summary> /// Initializes a new instance of the <see cref="SvgRenderContext" /> class. /// </summary> /// <param name="s">The s.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="isDocument">Create an SVG document if set to <c>true</c>.</param> /// <param name="textMeasurer">The text measurer.</param> /// <param name="background">The background.</param> public SvgRenderContext(Stream s, double width, double height, bool isDocument, IRenderContext textMeasurer, OxyColor background) { if (textMeasurer == null) { throw new ArgumentNullException("textMeasurer", "A text measuring render context must be provided."); } this.w = new SvgWriter(s, width, height, isDocument); this.TextMeasurer = textMeasurer; if (background != null) { this.w.WriteRectangle(0, 0, width, height, this.w.CreateStyle(background, null, 0)); } }
/// <summary> /// Interpolates the specified colors to a palette of the specified size. /// </summary> /// <param name="paletteSize">The size of the palette.</param> /// <param name="colors">The colors.</param> /// <returns>A palette.</returns> public static OxyPalette Interpolate(int paletteSize, params OxyColor[] colors) { var palette = new OxyColor[paletteSize]; for (int i = 0; i < paletteSize; i++) { double y = (double)i / (paletteSize - 1); double x = y * (colors.Length - 1); int i0 = (int)x; int i1 = i0 + 1 < colors.Length ? i0 + 1 : i0; palette[i] = OxyColor.Interpolate(colors[i0], colors[i1], x - i0); } return new OxyPalette(palette); }
/// <summary> /// Exports the specified plot model to a stream. /// </summary> /// <param name="model">The plot model.</param> /// <param name="stream">The stream to write to.</param> /// <param name="width">The width of the export image.</param> /// <param name="height">The height of the exported image.</param> /// <param name="background">The background.</param> public static void Export(IPlotModel model, Stream stream, double width, double height, OxyColor background) { var canvas = new Canvas { Width = width, Height = height }; if (background.IsVisible()) { canvas.Background = background.ToBrush(); } canvas.Measure(new Size(width, height)); canvas.Arrange(new Rect(0, 0, width, height)); var rc = new SilverlightRenderContext(canvas); model.Update(true); model.Render(rc, width, height); canvas.UpdateLayout(); var image = canvas.ToImage(); image.WriteToStream(stream); }
/// <summary> /// Draws the ellipse. /// </summary> /// <param name="rect">The rect.</param> /// <param name="fill">The fill.</param> /// <param name="stroke">The stroke.</param> /// <param name="thickness">The thickness.</param> public override void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness) { if (fill != null) { this.g.FillEllipse( this.ToBrush(fill), (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height); } if (stroke == null || thickness <= 0) { return; } using (var pen = new Pen(this.ToColor(stroke), (float)thickness)) { this.g.SmoothingMode = SmoothingMode.HighQuality; this.g.DrawEllipse(pen, (float)rect.Left, (float)rect.Top, (float)rect.Width, (float)rect.Height); } }
/// <summary> /// Encodes the specified image data to png. /// </summary> /// <param name="pixels">The pixel data (bottom line first).</param> /// <returns>The png image data.</returns> public byte[] Encode(OxyColor[,] pixels) { int width = pixels.GetLength(0); int height = pixels.GetLength(1); var bytes = new byte[width * height * 4]; int k = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { bytes[k++] = pixels[x, y].B; bytes[k++] = pixels[x, y].G; bytes[k++] = pixels[x, y].R; bytes[k++] = pixels[x, y].A; } } var ms = new MemoryStream(); var w = new BinaryWriter(ms); const int OffBits = 14 + 40; var size = OffBits + bytes.Length; // Bitmap file header (14 bytes) w.Write((byte)'B'); w.Write((byte)'M'); w.Write((uint)size); w.Write((ushort)0); w.Write((ushort)0); w.Write((uint)OffBits); // Bitmap info header (40 bytes) WriteBitmapInfoHeader(w, width, height, 32, bytes.Length, this.options.DpiX, this.options.DpiY); // Bitmap info V4 header (108 bytes) //// WriteBitmapV4Header(w, width, height, 32, bytes.Length, this.options.DpiX, this.options.DpiY); // Pixel array (from bottom-left corner) w.Write(bytes); return ms.ToArray(); }
public static PlotModel CreateRandomScatterSeriesWithColorAxisPlotModel(int n, OxyPalette palette, MarkerType markerType = MarkerType.Square, AxisPosition colorAxisPosition = AxisPosition.Right, OxyColor highColor = null, OxyColor lowColor = null) { var model = new PlotModel(string.Format("ScatterSeries (n={0})", n)) { Background = OxyColors.LightGray }; model.Axes.Add(new ColorAxis { Position = colorAxisPosition, Palette = palette, Minimum = -1, Maximum = 1, HighColor = highColor, LowColor = lowColor }); var s1 = new ScatterSeries { MarkerType = markerType, MarkerSize = 6, }; var random = new Random(); for (int i = 0; i < n; i++) { double x = random.NextDouble() * 2.2 - 1.1; s1.Points.Add(new ScatterPoint(x, random.NextDouble()) { Value = x }); } model.Series.Add(s1); return model; }
/// <summary> /// Draws a circle at the specified position. /// </summary> /// <param name="rc">The render context.</param> /// <param name="x">The center x-coordinate.</param> /// <param name="y">The center y-coordinate.</param> /// <param name="r">The radius.</param> /// <param name="fill">The fill color.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The thickness.</param> /// <param name="edgeRenderingMode">The edge rendering mode.</param> public static void DrawCircle(this IRenderContext rc, double x, double y, double r, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode) { rc.DrawEllipse(new OxyRect(x - r, y - r, r * 2, r * 2), fill, stroke, thickness, edgeRenderingMode); }
/// <summary> /// Draws an ellipse. /// </summary> /// <param name="rect">The rectangle.</param> /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the ellipse will not be filled.</param> /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the ellipse will not be stroked.</param> /// <param name="thickness">The thickness (in device independent units, 1/96 inch).</param> public void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1) { }
/// <summary> /// Draws a rectangle. /// </summary> /// <param name="rect">The rectangle.</param> /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the rectangle will not be filled.</param> /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the rectangle will not be stroked.</param> /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param> public void DrawRectangle(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness = 1) { }
/// <summary> /// Creates a color defined by an alpha value and another color. /// </summary> /// <param name="a"> /// Alpha value. /// </param> /// <param name="color"> /// The original color. /// </param> /// <returns> /// A color. /// </returns> public static OxyColor FromAColor(byte a, OxyColor color) { return new OxyColor { A = a, R = color.R, G = color.G, B = color.B }; }
/// <summary> /// Initializes a new instance of the <see cref="StairStepSeries"/> class. /// </summary> /// <param name="color"> /// The color. /// </param> /// <param name="strokeThickness"> /// The stroke thickness. /// </param> /// <param name="title"> /// The title. /// </param> public StairStepSeries(OxyColor color, double strokeThickness = 1, string title = null) : base(color, strokeThickness, title) { this.VerticalStrokeThickness = double.NaN; this.VerticalLineStyle = this.LineStyle; }
/// <summary> /// Decodes an image from the specified byte array. /// </summary> /// <param name="bytes">The image data.</param> /// <returns>The 32-bit pixel data, indexed as [x,y].</returns> public OxyColor[,] Decode(byte[] bytes) { // http://www.w3.org/TR/PNG/ // http://en.wikipedia.org/wiki/Portable_Network_Graphics var s = new MemoryStream(bytes); var inputReader = new BinaryReader(s); var signature = inputReader.ReadBytes(8); if (signature[0] != 0x89 || signature[1] != 0x50 || signature[2] != 0x4E || signature[3] != 0x47 || signature[4] != 0x0D || signature[5] != 0x0A || signature[6] != 0x1A || signature[7] != 0x0A) { throw new FormatException("Invalid signature."); } var headerLength = inputReader.ReadBigEndianUInt32(); if (headerLength != 13) { throw new FormatException("Header not supported."); } var headerType = inputReader.ReadString(4); if (headerType != "IHDR") { throw new FormatException("Invalid header."); } var width = (int)inputReader.ReadBigEndianUInt32(); var height = (int)inputReader.ReadBigEndianUInt32(); var bitDepth = inputReader.ReadByte(); var colorType = (ColorType)inputReader.ReadByte(); var compressionMethod = (CompressionMethod)inputReader.ReadByte(); var filterMethod = (FilterMethod)inputReader.ReadByte(); var interlaceMethod = (InterlaceMethod)inputReader.ReadByte(); inputReader.ReadBigEndianUInt32(); // headerCRC if (bitDepth != 8) { throw new NotImplementedException(); } if (colorType != ColorType.TrueColorWithAlpha) { throw new NotImplementedException(); } if (compressionMethod != CompressionMethod.Deflate) { throw new NotImplementedException(); } if (filterMethod != FilterMethod.None) { throw new NotImplementedException(); } if (interlaceMethod != InterlaceMethod.None) { throw new NotImplementedException(); } var ms = new MemoryStream(); while (true) { var length = (int)inputReader.ReadBigEndianUInt32(); var type = inputReader.ReadString(4); if (type == "IEND") { break; } switch (type) { case "PLTE": throw new NotImplementedException(); case "IDAT": { inputReader.ReadByte(); // method inputReader.ReadByte(); // check var chunkBytes = inputReader.ReadBytes(length - 6); var expectedCheckSum = inputReader.ReadBigEndianUInt32(); var deflatedBytes = Deflate(chunkBytes); var actualCheckSum = PngEncoder.Adler32(deflatedBytes); if (actualCheckSum != expectedCheckSum) { throw new FormatException("Invalid checksum."); } ms.Write(deflatedBytes, 0, deflatedBytes.Length); break; } default: { inputReader.ReadBytes(length); break; } } inputReader.ReadBigEndianUInt32(); // crc } var pixels = new OxyColor[width, height]; ms.Position = 0; for (int y = height - 1; y >= 0; y--) { ms.ReadByte(); for (int x = 0; x < width; x++) { var red = (byte)ms.ReadByte(); var green = (byte)ms.ReadByte(); var blue = (byte)ms.ReadByte(); var alpha = (byte)ms.ReadByte(); pixels[x, y] = OxyColor.FromArgb(alpha, red, green, blue); } } /* * var bitReader = new ByteBitReader(ms); * for (int y = 0; y < height; y++) * { * var filterType = bitReader.readByte(); * for (int x = 0; x < width; x++) * { * var red = (byte)bitReader.ReadBits(bitDepth); * var green = (byte)bitReader.ReadBits(bitDepth); * var blue = (byte)bitReader.ReadBits(bitDepth); * var alpha = (byte)bitReader.ReadBits(bitDepth); * * pixels[x, y] = OxyColor.FromArgb(alpha, red, green, blue); * } * }*/ if (ms.Position != ms.Length) { throw new InvalidOperationException(); } return(pixels); }
/// <summary> /// Fills a circle at the specified position. /// </summary> /// <param name="rc">The render context.</param> /// <param name="center">The center.</param> /// <param name="r">The radius.</param> /// <param name="fill">The fill color.</param> /// <param name="edgeRenderingMode">The edge rendering mode.</param> public static void FillCircle(this IRenderContext rc, ScreenPoint center, double r, OxyColor fill, EdgeRenderingMode edgeRenderingMode) { DrawCircle(rc, center.X, center.Y, r, fill, OxyColors.Undefined, 0d, edgeRenderingMode); }
/// <summary> /// Draws the rectangle as an aliased polygon. /// (makes sure pixel alignment is the same as for lines) /// </summary> /// <param name="rc">The render context.</param> /// <param name="rect">The rectangle.</param> /// <param name="fill">The fill.</param> /// <param name="stroke">The stroke.</param> /// <param name="thickness">The thickness.</param> public static void DrawRectangleAsPolygon(this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, double thickness) { var sp0 = new ScreenPoint(rect.Left, rect.Top); var sp1 = new ScreenPoint(rect.Right, rect.Top); var sp2 = new ScreenPoint(rect.Right, rect.Bottom); var sp3 = new ScreenPoint(rect.Left, rect.Bottom); rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, stroke, thickness, null, OxyPenLineJoin.Miter, true); }
/// <summary> /// The internal draw math text. /// </summary> /// <param name="rc">The render context.</param> /// <param name="x">The x.</param> /// <param name="y">The y.</param> /// <param name="s">The s.</param> /// <param name="textColor">The text color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">The font size.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="measureOnly">The measure only.</param> /// <param name="angle">The angle of the text (degrees).</param> /// <returns>The size of the text.</returns> private static OxySize InternalDrawMathText( IRenderContext rc, double x, double y, string s, OxyColor textColor, string fontFamily, double fontSize, double fontWeight, bool measureOnly, double angle) { int i = 0; double angleRadian = (angle * Math.PI) / 180.0; double cosAngle = Math.Round(Math.Cos(angleRadian), 5); double sinAngle = Math.Round(Math.Sin(angleRadian), 5); double currentX = x, maximumX = x, minimumX = x; double currentY = y, maximumY = y, minimumY = y; // http://en.wikipedia.org/wiki/Subscript_and_superscript double superScriptXDisplacement = sinAngle * fontSize * SuperAlignment; double superScriptYDisplacement = cosAngle * fontSize * SuperAlignment; double subscriptXDisplacement = sinAngle * fontSize * SubAlignment; double subscriptYDisplacement = cosAngle * fontSize * SubAlignment; double superscriptFontSize = fontSize * SuperSize; double subscriptFontSize = fontSize * SubSize; Func <double, double, string, double, OxySize> drawText = (xb, yb, text, fSize) => { if (!measureOnly) { rc.DrawText(new ScreenPoint(xb, yb), text, textColor, fontFamily, fSize, fontWeight, angle); } var flatSize = rc.MeasureText(text, fontFamily, fSize, fontWeight); double width = Math.Abs((flatSize.Width * cosAngle) + (flatSize.Height * sinAngle)); double height = Math.Abs((flatSize.Width * sinAngle) + (flatSize.Height * cosAngle)); return(new OxySize(width, height)); }; while (i < s.Length) { // Superscript if (i + 1 < s.Length && s[i] == '^' && s[i + 1] == '{') { int i1 = s.IndexOf('}', i); if (i1 != -1) { string supString = s.Substring(i + 2, i1 - i - 2); i = i1 + 1; double sx = currentX + superScriptXDisplacement; double sy = currentY + superScriptYDisplacement; var size = drawText(sx, sy, supString, superscriptFontSize); if (currentX + size.Width > maximumX) { maximumX = currentX + size.Width; } if (currentX + size.Width < minimumX) { minimumX = currentX + size.Width; } if (currentY + size.Height > maximumY) { maximumY = currentY + size.Height; } if (currentY + size.Height < minimumY) { minimumY = currentY + size.Height; } continue; } } // Subscript if (i + 1 < s.Length && s[i] == '_' && s[i + 1] == '{') { int i1 = s.IndexOf('}', i); if (i1 != -1) { string subString = s.Substring(i + 2, i1 - i - 2); i = i1 + 1; double sx = currentX - subscriptXDisplacement; double sy = currentY + subscriptYDisplacement; var size = drawText(sx, sy, subString, subscriptFontSize); if (currentX + (size.Width * cosAngle) > maximumX) { maximumX = currentX + (size.Width * cosAngle); } if (currentX + (size.Width * cosAngle) < minimumX) { minimumX = currentX + (size.Width * cosAngle); } if (currentY + (size.Height * sinAngle) > maximumY) { maximumY = currentY + (size.Height * sinAngle); } if (currentY + (size.Height * sinAngle) < minimumY) { minimumY = currentY + (size.Height * sinAngle); } continue; } } // Regular text int i2 = s.IndexOfAny("^_".ToCharArray(), i); string regularString; if (i2 == -1) { regularString = s.Substring(i); i = s.Length; } else { regularString = s.Substring(i, i2 - i); i = i2; } currentX = maximumX + (2 * cosAngle); currentY = maximumY + (2 * sinAngle); var size2 = drawText(currentX, currentY, regularString, fontSize); currentX += (size2.Width + 2) * cosAngle; currentY += (size2.Height + 2) * sinAngle; maximumX = Math.Max(currentX, maximumX); maximumY = Math.Max(currentY, maximumY); minimumX = Math.Min(currentX, minimumX); minimumY = Math.Min(currentY, minimumY); } return(new OxySize(maximumX - minimumX, maximumY - minimumY)); }
/// <summary> /// Draws or measures text containing sub- and superscript. /// </summary> /// <param name="rc">The render context.</param> /// <param name="pt">The point.</param> /// <param name="text">The text.</param> /// <param name="textColor">Color of the text.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">The font size.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="angle">The angle.</param> /// <param name="ha">The horizontal alignment.</param> /// <param name="va">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> /// <param name="measure">Measure the size of the text if set to <c>true</c>.</param> /// <returns>The size of the text.</returns> /// <example>Subscript: H_{2}O /// Superscript: E=mc^{2} /// Both: A^{2}_{i,j}</example> public static OxySize DrawMathText( this IRenderContext rc, ScreenPoint pt, string text, OxyColor textColor, string fontFamily, double fontSize, double fontWeight, double angle, HorizontalAlignment ha, VerticalAlignment va, OxySize?maxSize, bool measure) { if (string.IsNullOrEmpty(text)) { return(OxySize.Empty); } if (text.Contains("^{") || text.Contains("_{")) { var x = pt.X; var y = pt.Y; // Measure var size = InternalDrawMathText(rc, x, y, 0, 0, text, textColor, fontFamily, fontSize, fontWeight, true, angle); var dx = 0d; var dy = 0d; switch (ha) { case HorizontalAlignment.Right: dx = -size.Width; break; case HorizontalAlignment.Center: dx = -size.Width * 0.5; break; } switch (va) { case VerticalAlignment.Bottom: dy = -size.Height; break; case VerticalAlignment.Middle: dy = -size.Height * 0.5; break; } InternalDrawMathText(rc, x, y, dx, dy, text, textColor, fontFamily, fontSize, fontWeight, false, angle); return(measure ? size : OxySize.Empty); } rc.DrawText(pt, text, textColor, fontFamily, fontSize, fontWeight, angle, ha, va, maxSize); if (measure) { return(rc.MeasureText(text, fontFamily, fontSize, fontWeight)); } return(OxySize.Empty); }
/// <summary> /// Creates a color defined by an alpha value and another color. /// </summary> /// <param name="a">Alpha value.</param> /// <param name="color">The original color.</param> /// <returns>A color.</returns> public static OxyColor FromAColor(byte a, OxyColor color) { return(FromArgb(a, color.R, color.G, color.B)); }
/// <summary> /// Draws a collection of rectangles, where all have the same stroke and fill. /// This performs better than calling DrawRectangle multiple times. /// </summary> /// <param name="rectangles"> /// The rectangles. /// </param> /// <param name="fill"> /// The fill color. /// </param> /// <param name="stroke"> /// The stroke color. /// </param> /// <param name="thickness"> /// The stroke thickness. /// </param> public virtual void DrawRectangles(IList <OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness) { foreach (var r in rectangles) { this.DrawRectangle(r, fill, stroke, thickness); } }
/// <summary> /// Draws a clipped polyline through the specified points. /// </summary> /// <param name="rc">The render context.</param> /// <param name="clippingRectangle">The clipping rectangle.</param> /// <param name="points">The points.</param> /// <param name="minDistSquared">The minimum line segment length (squared).</param> /// <param name="stroke">The stroke color.</param> /// <param name="strokeThickness">The stroke thickness.</param> /// <param name="edgeRenderingMode">The edge rendering mode.</param> /// <param name="dashArray">The dash array (in device independent units, 1/96 inch).</param> /// <param name="lineJoin">The line join.</param> /// <param name="outputBuffer">The output buffer.</param> /// <param name="pointsRendered">The points rendered callback.</param> public static void DrawClippedLine( this IRenderContext rc, OxyRect clippingRectangle, IList <ScreenPoint> points, double minDistSquared, OxyColor stroke, double strokeThickness, EdgeRenderingMode edgeRenderingMode, double[] dashArray, LineJoin lineJoin, List <ScreenPoint> outputBuffer = null, Action <IList <ScreenPoint> > pointsRendered = null) { var n = points.Count; if (n == 0) { return; } if (outputBuffer != null) { outputBuffer.Clear(); outputBuffer.Capacity = n; } else { outputBuffer = new List <ScreenPoint>(n); } if (rc.SetClip(clippingRectangle)) { ReducePoints(points, minDistSquared, outputBuffer); rc.DrawLine(outputBuffer, stroke, strokeThickness, edgeRenderingMode, dashArray, lineJoin); rc.ResetClip(); if (outputBuffer != null) { outputBuffer.Clear(); outputBuffer.AddRange(points); } pointsRendered?.Invoke(outputBuffer); return; } // draws the points in the output buffer and calls the callback (if specified) Action drawLine = () => { EnsureNonEmptyLineIsVisible(outputBuffer); rc.DrawLine(outputBuffer, stroke, strokeThickness, edgeRenderingMode, dashArray, lineJoin); // Execute the 'callback' if (pointsRendered != null) { pointsRendered(outputBuffer); } }; var clipping = new CohenSutherlandClipping(clippingRectangle); if (n == 1 && clipping.IsInside(points[0])) { outputBuffer.Add(points[0]); } int lastPointIndex = 0; for (int i = 1; i < n; i++) { // Calculate the clipped version of previous and this point. var sc0 = points[i - 1]; var sc1 = points[i]; bool isInside = clipping.ClipLine(ref sc0, ref sc1); if (!isInside) { // the line segment is outside the clipping rectangle // keep the previous coordinate for minimum distance comparison continue; } // length calculation (inlined for performance) var dx = sc1.X - points[lastPointIndex].X; var dy = sc1.Y - points[lastPointIndex].Y; if ((dx * dx) + (dy * dy) > minDistSquared || outputBuffer.Count == 0 || i == n - 1) { // point comparison inlined for performance // ReSharper disable CompareOfFloatsByEqualityOperator if (sc0.X != points[lastPointIndex].X || sc0.Y != points[lastPointIndex].Y || outputBuffer.Count == 0) // ReSharper restore disable CompareOfFloatsByEqualityOperator { outputBuffer.Add(new ScreenPoint(sc0.X, sc0.Y)); } outputBuffer.Add(new ScreenPoint(sc1.X, sc1.Y)); lastPointIndex = i; } if (clipping.IsInside(points[i]) || outputBuffer.Count == 0) { continue; } // we are leaving the clipping region - render the line drawLine(); outputBuffer.Clear(); } if (outputBuffer.Count > 0) { drawLine(); } }
/// <summary> /// Fills a rectangle at the specified position. /// </summary> /// <param name="rc">The render context.</param> /// <param name="rectangle">The rectangle.</param> /// <param name="fill">The fill color.</param> /// <param name="edgeRenderingMode">The edge rendering mode.</param> public static void FillRectangle(this IRenderContext rc, OxyRect rectangle, OxyColor fill, EdgeRenderingMode edgeRenderingMode) { rc.DrawRectangle(rectangle, fill, OxyColors.Undefined, 0d, edgeRenderingMode); }
/// <summary> /// Fills a rectangle at the specified position. /// </summary> /// <param name="rc">The render context.</param> /// <param name="rectangle">The rectangle.</param> /// <param name="fill">The fill color.</param> public static void FillRectangle(this IRenderContext rc, OxyRect rectangle, OxyColor fill) { rc.DrawRectangle(rectangle, fill, OxyColors.Undefined, 0d); }
/// <summary> /// Draws a list of markers. /// </summary> /// <param name="rc"> /// The render context. /// </param> /// <param name="markerPoints"> /// The marker points. /// </param> /// <param name="clippingRect"> /// The clipping rectangle. /// </param> /// <param name="markerType"> /// Type of the marker. /// </param> /// <param name="markerOutline"> /// The marker outline. /// </param> /// <param name="markerSize"> /// Size of the markers. /// </param> /// <param name="markerFill"> /// The marker fill. /// </param> /// <param name="markerStroke"> /// The marker stroke. /// </param> /// <param name="markerStrokeThickness"> /// The marker stroke thickness. /// </param> /// <param name="resolution"> /// The resolution. /// </param> /// <param name="binOffset"> /// The bin Offset. /// </param> public static void DrawMarkers( this IRenderContext rc, IList <ScreenPoint> markerPoints, OxyRect clippingRect, MarkerType markerType, IList <ScreenPoint> markerOutline, IList <double> markerSize, OxyColor markerFill, OxyColor markerStroke, double markerStrokeThickness, int resolution = 0, ScreenPoint binOffset = new ScreenPoint()) { if (markerType == MarkerType.None) { return; } int n = markerPoints.Count; var ellipses = new List <OxyRect>(n); var rects = new List <OxyRect>(n); var polygons = new List <IList <ScreenPoint> >(n); var lines = new List <ScreenPoint>(n); var hashset = new Dictionary <uint, bool>(); int i = 0; double minx = clippingRect.Left; double maxx = clippingRect.Right; double miny = clippingRect.Top; double maxy = clippingRect.Bottom; foreach (var p in markerPoints) { if (resolution > 1) { var x = (int)((p.X - binOffset.X) / resolution); var y = (int)((p.Y - binOffset.Y) / resolution); uint hash = (uint)(x << 16) + (uint)y; if (hashset.ContainsKey(hash)) { i++; continue; } hashset.Add(hash, true); } bool outside = p.x <minx || p.x> maxx || p.y <miny || p.y> maxy; if (!outside) { int j = i < markerSize.Count ? i : 0; AddMarkerGeometry(p, markerType, markerOutline, markerSize[j], ellipses, rects, polygons, lines); } i++; } if (ellipses.Count > 0) { rc.DrawEllipses(ellipses, markerFill, markerStroke, markerStrokeThickness); } if (rects.Count > 0) { rc.DrawRectangles(rects, markerFill, markerStroke, markerStrokeThickness); } if (polygons.Count > 0) { rc.DrawPolygons(polygons, markerFill, markerStroke, markerStrokeThickness); } if (lines.Count > 0) { rc.DrawLineSegments(lines, markerStroke, markerStrokeThickness); } }
/// <summary> /// Draws a circle at the specified position. /// </summary> /// <param name="rc">The render context.</param> /// <param name="center">The center.</param> /// <param name="r">The radius.</param> /// <param name="fill">The fill color.</param> /// <param name="stroke">The stroke color.</param> /// <param name="thickness">The thickness.</param> /// <param name="edgeRenderingMode">The edge rendering mode.</param> public static void DrawCircle(this IRenderContext rc, ScreenPoint center, double r, OxyColor fill, OxyColor stroke, double thickness, EdgeRenderingMode edgeRenderingMode) { DrawCircle(rc, center.X, center.Y, r, fill, stroke, thickness, edgeRenderingMode); }
/// <summary> /// Determines whether the specified <see cref="OxyColor" /> is equal to this instance. /// </summary> /// <param name="other">The <see cref="OxyColor" /> to compare with this instance.</param> /// <returns><c>true</c> if the specified <see cref="OxyColor" /> is equal to this instance; otherwise, <c>false</c> .</returns> public bool Equals(OxyColor other) { return(other.A == this.A && other.R == this.R && other.G == this.G && other.B == this.B); }
/// <summary> /// Draws the clipped line. /// </summary> /// <param name="rc">The render context.</param> /// <param name="points">The points.</param> /// <param name="clippingRectangle">The clipping rectangle.</param> /// <param name="minDistSquared">The min dist squared.</param> /// <param name="stroke">The stroke.</param> /// <param name="strokeThickness">The stroke thickness.</param> /// <param name="lineStyle">The line style.</param> /// <param name="lineJoin">The line join.</param> /// <param name="aliased">if set to <c>true</c> [aliased].</param> /// <param name="pointsRendered">The points rendered callback.</param> public static void DrawClippedLine( this IRenderContext rc, IList <ScreenPoint> points, OxyRect clippingRectangle, double minDistSquared, OxyColor stroke, double strokeThickness, LineStyle lineStyle, OxyPenLineJoin lineJoin, bool aliased, Action <IList <ScreenPoint> > pointsRendered = null) { var clipping = new CohenSutherlandClipping(clippingRectangle.Left, clippingRectangle.Right, clippingRectangle.Top, clippingRectangle.Bottom); var pts = new List <ScreenPoint>(); int n = points.Count; if (n > 0) { if (n == 1) { pts.Add(points[0]); } var last = points[0]; for (int i = 1; i < n; i++) { var s0 = points[i - 1]; var s1 = points[i]; // Clipped version of this and next point. var s0c = s0; var s1c = s1; bool isInside = clipping.ClipLine(ref s0c, ref s1c); s0 = s1; if (!isInside) { // keep the previous coordinate continue; } // render from s0c-s1c double dx = s1c.x - last.x; double dy = s1c.y - last.y; if (dx * dx + dy * dy > minDistSquared || i == 1 || i == n - 1) { if (!s0c.Equals(last) || i == 1) { pts.Add(s0c); } pts.Add(s1c); last = s1c; } // render the line if we are leaving the clipping region);); if (!clipping.IsInside(s1)) { if (pts.Count > 0) { rc.DrawLine( pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased); if (pointsRendered != null) { pointsRendered(pts); } pts = new List <ScreenPoint>(); } } } // Check if the line contains two points and they are at the same point if (pts.Count == 2) { if (pts[0].DistanceTo(pts[1]) < 1) { // Modify to a small horizontal line to make sure it is being rendered pts[1] = new ScreenPoint(pts[0].X + 1, pts[0].Y); pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y); } } // Check if the line contains a single point if (pts.Count == 1) { // Add a second point to make sure the line is being rendered as a small dot pts.Add(new ScreenPoint(pts[0].X + 1, pts[0].Y)); pts[0] = new ScreenPoint(pts[0].X - 1, pts[0].Y); } if (pts.Count > 0) { rc.DrawLine(pts, stroke, strokeThickness, lineStyle.GetDashArray(), lineJoin, aliased); // Execute the 'callback'. if (pointsRendered != null) { pointsRendered(pts); } } } }
private void DrawDVHs() { this.plotModel.Series.Clear(); string ptid1 = patient1.Split(',')[0]; string ptid2 = patient2.Split(',')[0]; try { // search for patient in database foreach (var patientSummary in cur_app.PatientSummaries) { if (patientSummary.Id == ptid1) //this is the first patient { VMS.TPS.Common.Model.API.Patient pt1 = cur_app.OpenPatient(patientSummary); if (pt1 == null) { throw new ApplicationException("Cannot open patient No.1" + patientSummary.Id); } Console.WriteLine("Open patient No.1"); //get patient info rd1.CurPatientInfo.LastName = pt1.LastName; rd1.CurPatientInfo.FirstName = pt1.FirstName; rd1.CurPatientInfo.PatientID = pt1.Id; //loop through courses foreach (var course in pt1.Courses) { Console.WriteLine("course=" + course.Id); //print course name and send to UI rd1.CurPlanInfo.CourseID = course.Id; foreach (var planSetup in course.PlanSetups) { Console.WriteLine("planID=" + planSetup.Id); rd1.CurPlanInfo.PlaneID = planSetup.Id; rd1.CurDosePrescription.Fractionation = planSetup.UniqueFractionation.Id; rd1.CurDosePrescription.TotalPrescribedDose = planSetup.TotalPrescribedDose.ToString(); rd1.CurDosePrescription.PlanNormalization = planSetup.PlanNormalizationValue.ToString(); rd1.CurDosePrescription.PrescribedDoseFractination = planSetup.UniqueFractionation.PrescribedDosePerFraction.ToString(); rd1.CurDosePrescription.NumberOfFraction = planSetup.UniqueFractionation.NumberOfFractions.ToString(); foreach (var beam in planSetup.Beams) { FieldInfo fieldInfo1 = new FieldInfo(); fieldInfo1.BeamID = beam.Id; fieldInfo1.Collimator = beam.ControlPoints[0].CollimatorAngle.ToString(); fieldInfo1.Gantry = beam.ControlPoints[0].GantryAngle.ToString(); fieldInfo1.Couch = beam.ControlPoints[0].PatientSupportAngle.ToString(); fieldInfo1.DoseRate = beam.DoseRate.ToString(); fieldInfo1.Energy = beam.EnergyModeDisplayName; fieldInfo1.Machine = beam.TreatmentUnit.Id; fieldInfo1.MU = beam.Meterset.ToString(); fieldInfo1.X1 = beam.ControlPoints[0].JawPositions.X1.ToString(); fieldInfo1.Y1 = beam.ControlPoints[0].JawPositions.Y1.ToString(); fieldInfo1.X2 = beam.ControlPoints[0].JawPositions.X2.ToString(); fieldInfo1.Y2 = beam.ControlPoints[0].JawPositions.Y2.ToString(); rd1.CurFieldInfoList.Add(fieldInfo1); } // get structure Set StructureSet structureSet = planSetup.StructureSet; foreach (var structure in structureSet.Structures) { //StructureData structureData1 = new StructureData(); if (colors.ContainsKey(structure.Id.ToLower()) || colors.ContainsKey(structure.DicomType.ToLower())) { DVHData dvhData = planSetup.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 0.2); if (dvhData == null) { continue; throw new ApplicationException("DVH data does not exist. Script execution cancelled."); } //To print and anlyze the DVH // if (colors.ContainsKey(structure.Id.ToLower())) { OxyPlot.OxyColor color = colors[structure.Id.ToLower()]; Console.WriteLine("maximum dose of" + structure.Id + " is:" + dvhData.MaxDose.ToString()); AddData(dvhData, structure.Id, color, OxyPlot.MarkerType.Circle); } else if (colors.ContainsKey(structure.DicomType.ToLower())) { OxyPlot.OxyColor color = colors[structure.DicomType.ToLower()]; Console.WriteLine("maximum dose of" + structure.DicomType + " is:" + dvhData.MaxDose.ToString()); AddData(dvhData, structure.Id, color, OxyPlot.MarkerType.Circle); } } } } } cur_app.ClosePatient(); //close the first patient } //Read second patient if (patientSummary.Id == ptid2) //this is the second patient { VMS.TPS.Common.Model.API.Patient pt2 = cur_app.OpenPatient(patientSummary); if (pt2 == null) { throw new ApplicationException("Cannot open patient No.2" + patientSummary.Id); } Console.WriteLine("==========================="); Console.WriteLine("Open patient No.2"); //loop through courses foreach (var course in pt2.Courses) { Console.WriteLine("course=" + course.Id); //print course name and send to UI foreach (var planSetup in course.PlanSetups) { Console.WriteLine("planID=" + planSetup.Id); // get structure Set StructureSet structureSet = planSetup.StructureSet; foreach (var structure in structureSet.Structures) { if (colors.ContainsKey(structure.Id.ToLower()) || colors.ContainsKey(structure.DicomType.ToLower())) { DVHData dvhData2 = planSetup.GetDVHCumulativeData(structure, DoseValuePresentation.Absolute, VolumePresentation.Relative, 1); if (dvhData2 == null) { continue; throw new ApplicationException("DVH data does not exist. Script execution cancelled."); } //To print and anlyze the DVH // if (colors.ContainsKey(structure.Id.ToLower())) { OxyPlot.OxyColor color = colors[structure.Id.ToLower()]; Console.WriteLine("maximum dose of" + structure.Id + " is:" + dvhData2.MaxDose.ToString()); AddData(dvhData2, structure.Id, color, OxyPlot.MarkerType.Cross); } else if (colors.ContainsKey(structure.DicomType.ToLower())) { OxyPlot.OxyColor color = colors[structure.DicomType.ToLower()]; Console.WriteLine("maximum dose of" + structure.Id + " is:" + dvhData2.MaxDose.ToString()); AddData(dvhData2, structure.Id, color, OxyPlot.MarkerType.Cross); } } } } } cur_app.ClosePatient(); //close the second patient } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); cur_app.ClosePatient(); } plotModel.InvalidatePlot(true); }
// Load input file private void MenuItem_Click(object sender, RoutedEventArgs e) { // Create new problem this.p = new Problem(); this.BC_list.Clear(); this.BC_list_nodes.Clear(); this.BC_list_type.Clear(); // Clear plot this.plotModel.Series.Clear(); this.plotModel.Annotations.Clear(); this.plotModel.InvalidatePlot(true); // Import input OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.ShowDialog(); string fileName; fileName = openFileDialog.FileName; if (fileName == "") { this.plotModel.Annotations.Clear(); this.plotModel.Series.Clear(); this.plotModel.InvalidatePlot(true); return; } new inputTxtReader(fileName, this.p); // show and hide components plot this.plot.Visibility = Visibility.Visible; this.button.Visibility = Visibility.Visible; this.calculating_text.Visibility = Visibility.Visible; this.calculating_text.Text = "Black = Frame\tPurple = Truss\tOrange = Spring\t\nHover mouse on blue nodes to view boundary condition\n"; // determine max X Y double xmin, xmax, ymin, ymax; xmin = Node.all[0].x; xmax = Node.all[0].x; ymin = Node.all[0].y; ymax = Node.all[0].y; for (int i = 0; i < Node.all.Count; i++) { if (Node.all[i].x < xmin) { xmin = Node.all[i].x; } if (Node.all[i].x > xmax) { xmax = Node.all[i].x; } if (Node.all[i].y < ymin) { ymin = Node.all[i].y; } if (Node.all[i].y > ymax) { ymax = Node.all[i].y; } } this.l = Math.Max(xmax - xmin, ymax - ymin); // determine maxLoadMagnitude and arrowUnitLenght to scale loads double maxLoadMagnitude = 0; double arrowUnitLength = this.l * 0.1; for (int i = 0; i < p.inputConcentratedLoads.Count; i++) { if (p.inputConcentratedLoads[i].magnitude > maxLoadMagnitude && p.inputConcentratedLoads[i].alpha != null) { maxLoadMagnitude = p.inputConcentratedLoads[i].magnitude; } } for (int i = 0; i < p.inputDistributedLoads.Count; i++) { if (p.inputDistributedLoads[i][0].magnitude > maxLoadMagnitude && p.inputDistributedLoads[i][0].alpha != null) { maxLoadMagnitude = p.inputDistributedLoads[i][0].magnitude; } if (p.inputDistributedLoads[i][1].magnitude > maxLoadMagnitude && p.inputDistributedLoads[i][1].alpha != null) { maxLoadMagnitude = p.inputDistributedLoads[i][1].magnitude; } } this.plotModel.Axes[0].Reset(); this.plotModel.Axes[1].Reset(); if (maxLoadMagnitude == 0) { maxLoadMagnitude = 1; } this.plotModel.Axes[0].Maximum = xmax + this.l / 10.0; this.plotModel.Axes[0].Minimum = xmin - this.l / 10.0; this.plotModel.Axes[1].Maximum = ymax + this.l / 10.0; this.plotModel.Axes[1].Minimum = ymin - this.l / 10.0; // add lines double d = this.l * 0.014; int dx1; int dy1; int dx2; int dy2; for (int i = 0; i < Element.all.Count; i++) { if (Element.all[i].node1.x >= Element.all[i].node2.x) { dx1 = -1; dx2 = 1; } else { dx1 = 1; dx2 = -1; } if (Element.all[i].node1.y >= Element.all[i].node2.y) { dy1 = -1; dy2 = 1; } else { dy1 = 1; dy2 = -1; } // Pick color OxyPlot.OxyColor lineCol = OxyColors.Black; if (Element.all[i].type == "spring") { lineCol = OxyColors.DarkOrange; } if (Element.all[i].type == "truss") { lineCol = OxyColors.DarkOrchid; } addLine(this, Element.all[i].node1.x + dx1 * Math.Abs(d * Math.Cos(Element.all[i].alpha)), Element.all[i].node1.y + dy1 * Math.Abs(d * Math.Sin(Element.all[i].alpha)), Element.all[i].node2.x + dx2 * Math.Abs(d * Math.Cos(Element.all[i].alpha)), Element.all[i].node2.y + dy2 * Math.Abs(d * Math.Sin(Element.all[i].alpha)), lineCol); addNode(this, Element.all[i].node1.x, Element.all[i].node1.y, "Node " + Element.all[i].node1.number + "\n", 5, OxyColors.Black); } // add BCs addBCs(this, 5); // add loads for (int i = 0; i < p.inputConcentratedLoads.Count; i++) { addLoad(this, p.inputConcentratedLoads[i], OxyColors.Aqua, circleSize: 5, maxLoadMagnitude: maxLoadMagnitude, arrowUnitLength: arrowUnitLength); } for (int i = 0; i < p.inputDistributedLoads.Count; i++) { addDistributedLoad(this, p.inputDistributedLoads[i], OxyColors.DeepSkyBlue, circleSize: 5, maxLoadMagnitude: maxLoadMagnitude, arrowUnitLength: arrowUnitLength); } this.plotModel.InvalidatePlot(true); // refresh }
/// <summary> /// Initializes a new instance of the <see cref="PlotModel" /> class. /// </summary> public PlotModel() { this.Axes = new ElementCollection <Axis>(this); this.Series = new ElementCollection <Series.Series>(this); this.Annotations = new ElementCollection <Annotation>(this); this.PlotType = PlotType.XY; this.PlotMargins = new OxyThickness(double.NaN); this.Padding = new OxyThickness(8); this.Background = OxyColors.Undefined; this.PlotAreaBackground = OxyColors.Undefined; this.TextColor = OxyColors.Black; this.TitleColor = OxyColors.Automatic; this.SubtitleColor = OxyColors.Automatic; this.DefaultFont = "Segoe UI"; this.DefaultFontSize = 12; this.TitleToolTip = null; this.TitleFont = null; this.TitleFontSize = 18; this.TitleFontWeight = FontWeights.Bold; this.SubtitleFont = null; this.SubtitleFontSize = 14; this.SubtitleFontWeight = FontWeights.Normal; this.TitlePadding = 6; this.PlotAreaBorderColor = OxyColors.Black; this.PlotAreaBorderThickness = new OxyThickness(1); this.IsLegendVisible = true; this.LegendTitleFont = null; this.LegendTitleFontSize = 12; this.LegendTitleFontWeight = FontWeights.Bold; this.LegendFont = null; this.LegendFontSize = 12; this.LegendFontWeight = FontWeights.Normal; this.LegendSymbolLength = 16; this.LegendSymbolMargin = 4; this.LegendPadding = 8; this.LegendColumnSpacing = 8; this.LegendItemSpacing = 24; this.LegendLineSpacing = 0; this.LegendMargin = 8; this.LegendBackground = OxyColors.Undefined; this.LegendBorder = OxyColors.Undefined; this.LegendBorderThickness = 1; this.LegendTextColor = OxyColors.Automatic; this.LegendTitleColor = OxyColors.Automatic; this.LegendMaxWidth = double.NaN; this.LegendMaxHeight = double.NaN; this.LegendPlacement = LegendPlacement.Inside; this.LegendPosition = LegendPosition.RightTop; this.LegendOrientation = LegendOrientation.Vertical; this.LegendItemOrder = LegendItemOrder.Normal; this.LegendItemAlignment = HorizontalAlignment.Left; this.LegendSymbolPlacement = LegendSymbolPlacement.Left; this.DefaultColors = new List <OxyColor> { OxyColor.FromRgb(0x4E, 0x9A, 0x06), OxyColor.FromRgb(0xC8, 0x8D, 0x00), OxyColor.FromRgb(0xCC, 0x00, 0x00), OxyColor.FromRgb(0x20, 0x4A, 0x87), OxyColors.Red, OxyColors.Orange, OxyColors.Yellow, OxyColors.Green, OxyColors.Blue, OxyColors.Indigo, OxyColors.Violet }; this.AxisTierDistance = 4.0; }
/// <summary> /// Gets the selection fill color it the element is selected, or the specified fill color if it is not. /// </summary> /// <param name="originalColor">The unselected fill color of the element.</param> /// <param name="index">The index of the item to check (use -1 for all items).</param> /// <returns>A fill color.</returns> protected OxyColor GetSelectableFillColor(OxyColor originalColor, int index = -1) { // TODO: rename to GetActualFillColor (13 usages) return(this.GetSelectableColor(originalColor, index)); }
/// <summary> /// Determines whether the specified <see cref="OxyColor"/> is equal to this instance. /// </summary> /// <param name="other"> /// The <see cref="OxyColor"/> to compare with this instance. /// </param> /// <returns> /// <c>true</c> if the specified <see cref="OxyColor"/> is equal to this instance; otherwise, <c>false</c> . /// </returns> public bool Equals(OxyColor other) { if (ReferenceEquals(null, other)) { return false; } if (ReferenceEquals(this, other)) { return true; } return other.A == this.A && other.R == this.R && other.G == this.G && other.B == this.B; }
/// <summary> /// Draws the text. /// </summary> /// <param name="p">The position of the text.</param> /// <param name="text">The text.</param> /// <param name="fill">The fill color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text.</param> public override void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily, double fontSize, double fontWeight, double rotate, HorizontalAlignment halign, VerticalAlignment valign, OxySize?maxSize) { this.doc.SaveState(); this.doc.SetFont(fontFamily, fontSize / 96 * 72, fontWeight > 500); this.doc.SetFillColor(fill); double width, height; this.doc.MeasureText(text, out width, out height); if (maxSize != null) { if (width > maxSize.Value.Width) { width = Math.Max(maxSize.Value.Width, 0); } if (height > maxSize.Value.Height) { height = Math.Max(maxSize.Value.Height, 0); } } double dx = 0; if (halign == HorizontalAlignment.Center) { dx = -width / 2; } if (halign == HorizontalAlignment.Right) { dx = -width; } double dy = 0; if (valign == VerticalAlignment.Middle) { dy = -height / 2; } if (valign == VerticalAlignment.Top) { dy = -height; } double y = this.doc.PageHeight - p.Y; this.doc.Translate(p.X, y); if (Math.Abs(rotate) > 1e-6) { this.doc.Rotate(-rotate); } this.doc.Translate(dx, dy); // this.doc.DrawRectangle(0, 0, width, height); this.doc.SetClippingRectangle(0, 0, width, height); this.doc.DrawText(0, 0, text); this.doc.RestoreState(); }
/// <summary> /// The set default values. /// </summary> /// <param name="model"> /// The model. /// </param> protected internal override void SetDefaultValues(PlotModel model) { // todo: should use ActualLineStyle if (this.Color == null) { if (this.LineStyle == LineStyle.Undefined) { this.LineStyle = model.GetDefaultLineStyle(); } this.defaultColor = model.GetDefaultColor(); // And MarkerFill will be overridden if not set to null if (this.MarkerFill == null) { this.MarkerFill = this.defaultColor; } } }
/// <summary> /// Draws text with sub- and superscript items. /// </summary> /// <param name="rc">The render context.</param> /// <param name="x">The x.</param> /// <param name="y">The y.</param> /// <param name="dx">The x offset (in rotated coordinates).</param> /// <param name="dy">The y offset (in rotated coordinates).</param> /// <param name="s">The s.</param> /// <param name="textColor">The text color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">The font size.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="measureOnly">Only measure if set to <c>true</c>.</param> /// <param name="angle">The angle of the text (degrees).</param> /// <returns>The size of the text.</returns> private static OxySize InternalDrawMathText( IRenderContext rc, double x, double y, double dx, double dy, string s, OxyColor textColor, string fontFamily, double fontSize, double fontWeight, bool measureOnly, double angle) { var i = 0; var angleRadian = (angle * Math.PI) / 180.0; var cosAngle = Math.Round(Math.Cos(angleRadian), 5); var sinAngle = Math.Round(Math.Sin(angleRadian), 5); var currentX = x; var maximumX = x; var minimumX = x; var currentY = y; var maximumY = y; var minimumY = y; // http://en.wikipedia.org/wiki/Subscript_and_superscript var superScriptYDisplacement = fontSize * SuperAlignment; var subscriptYDisplacement = fontSize * SubAlignment; var superscriptFontSize = fontSize * SuperSize; var subscriptFontSize = fontSize * SubSize; Func <double, double, string, double, OxySize> drawText = (xb, yb, text, fSize) => { if (!measureOnly) { var xr = x + ((xb - x + dx) * cosAngle) - ((yb - y + dy) * sinAngle); var yr = y + ((xb - x + dx) * sinAngle) + ((yb - y + dy) * cosAngle); rc.DrawText(new ScreenPoint(xr, yr), text, textColor, fontFamily, fSize, fontWeight, angle); } var flatSize = rc.MeasureText(text, fontFamily, fSize, fontWeight); return(new OxySize(flatSize.Width, flatSize.Height)); }; while (i < s.Length) { // Superscript if (i + 1 < s.Length && s[i] == '^' && s[i + 1] == '{') { var i1 = s.IndexOf('}', i); if (i1 != -1) { var supString = s.Substring(i + 2, i1 - i - 2); i = i1 + 1; var sx = currentX; var sy = currentY + superScriptYDisplacement; var size = drawText(sx, sy, supString, superscriptFontSize); maximumX = Math.Max(sx + size.Width, maximumX); maximumY = Math.Max(sy + size.Height, maximumY); minimumX = Math.Min(sx, minimumX); minimumY = Math.Min(sy, minimumY); continue; } } // Subscript if (i + 1 < s.Length && s[i] == '_' && s[i + 1] == '{') { var i1 = s.IndexOf('}', i); if (i1 != -1) { var subString = s.Substring(i + 2, i1 - i - 2); i = i1 + 1; var sx = currentX; var sy = currentY + subscriptYDisplacement; var size = drawText(sx, sy, subString, subscriptFontSize); maximumX = Math.Max(sx + size.Width, maximumX); maximumY = Math.Max(sy + size.Height, maximumY); minimumX = Math.Min(sx, minimumX); minimumY = Math.Min(sy, minimumY); continue; } } // Regular text var i2 = s.IndexOfAny("^_".ToCharArray(), i); string regularString; if (i2 == -1) { regularString = s.Substring(i); i = s.Length; } else { regularString = s.Substring(i, i2 - i); i = i2; } currentX = maximumX + 2; var size2 = drawText(currentX, currentY, regularString, fontSize); maximumX = Math.Max(currentX + size2.Width, maximumX); maximumY = Math.Max(currentY + size2.Height, maximumY); minimumX = Math.Min(currentX, minimumX); minimumY = Math.Min(currentY, minimumY); currentX = maximumX; } return(new OxySize(maximumX - minimumX, maximumY - minimumY)); }
/// <summary> /// Draws text. /// </summary> /// <param name="p">The position.</param> /// <param name="text">The text.</param> /// <param name="fill">The text color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">Size of the font (in device independent units, 1/96 inch).</param> /// <param name="fontWeight">The font weight.</param> /// <param name="rotate">The rotation angle.</param> /// <param name="halign">The horizontal alignment.</param> /// <param name="valign">The vertical alignment.</param> /// <param name="maxSize">The maximum size of the text (in device independent units, 1/96 inch).</param> public void DrawText( ScreenPoint p, string text, OxyColor fill, string fontFamily = null, double fontSize = 10, double fontWeight = 500, double rotate = 0, HorizontalAlignment halign = HorizontalAlignment.Left, VerticalAlignment valign = VerticalAlignment.Top, OxySize? maxSize = null) { }
/// <summary> /// Draws the rectangle as an aliased polygon. /// (makes sure pixel alignment is the same as for lines) /// </summary> /// <param name="rc">The render context.</param> /// <param name="rect">The rectangle.</param> /// <param name="fill">The fill.</param> /// <param name="stroke">The stroke.</param> /// <param name="thickness">The thickness.</param> public static void DrawRectangleAsPolygon(this IRenderContext rc, OxyRect rect, OxyColor fill, OxyColor stroke, OxyThickness thickness) { if (thickness.Left.Equals(thickness.Right) && thickness.Left.Equals(thickness.Top) && thickness.Left.Equals(thickness.Bottom)) { DrawRectangleAsPolygon(rc, rect, fill, stroke, thickness.Left); return; } var sp0 = new ScreenPoint(rect.Left, rect.Top); var sp1 = new ScreenPoint(rect.Right, rect.Top); var sp2 = new ScreenPoint(rect.Right, rect.Bottom); var sp3 = new ScreenPoint(rect.Left, rect.Bottom); rc.DrawPolygon(new[] { sp0, sp1, sp2, sp3 }, fill, OxyColors.Undefined, 0, null, OxyPenLineJoin.Miter, true); rc.DrawLine(new[] { sp0, sp1 }, stroke, thickness.Top, null, OxyPenLineJoin.Miter, true); rc.DrawLine(new[] { sp1, sp2 }, stroke, thickness.Right, null, OxyPenLineJoin.Miter, true); rc.DrawLine(new[] { sp2, sp3 }, stroke, thickness.Bottom, null, OxyPenLineJoin.Miter, true); rc.DrawLine(new[] { sp3, sp0 }, stroke, thickness.Left, null, OxyPenLineJoin.Miter, true); }
/// <summary> /// Draws a collection of ellipses, where all have the same stroke and fill. /// This performs better than calling DrawEllipse multiple times. /// </summary> /// <param name="rectangles">The rectangles.</param> /// <param name="fill">The fill color. If set to <c>OxyColors.Undefined</c>, the ellipses will not be filled.</param> /// <param name="stroke">The stroke color. If set to <c>OxyColors.Undefined</c>, the ellipses will not be stroked.</param> /// <param name="thickness">The stroke thickness (in device independent units, 1/96 inch).</param> public void DrawEllipses(IList<OxyRect> rectangles, OxyColor fill, OxyColor stroke, double thickness = 1) { }
/// <summary> /// Draws multi-line text at the specified point. /// </summary> /// <param name="rc">The render context.</param> /// <param name="point">The point.</param> /// <param name="text">The text.</param> /// <param name="color">The text color.</param> /// <param name="fontFamily">The font family.</param> /// <param name="fontSize">The font size.</param> /// <param name="fontWeight">The font weight.</param> /// <param name="dy">The line spacing.</param> public static void DrawMultilineText(this IRenderContext rc, ScreenPoint point, string text, OxyColor color, string fontFamily = null, double fontSize = 10, double fontWeight = FontWeights.Normal, double dy = 12) { var lines = StringHelper.SplitLines(text); for (int i = 0; i < lines.Length; i++) { rc.DrawText( new ScreenPoint(point.X, point.Y + (i * dy)), lines[i], color, fontWeight: fontWeight, fontSize: fontSize); } }
/// <summary> /// Draws an ellipse. /// </summary> /// <param name="rect"> /// The rectangle. /// </param> /// <param name="fill"> /// The fill color. /// </param> /// <param name="stroke"> /// The stroke color. /// </param> /// <param name="thickness"> /// The thickness. /// </param> public abstract void DrawEllipse(OxyRect rect, OxyColor fill, OxyColor stroke, double thickness);
/// <summary> /// Gets the actual color. /// </summary> /// <param name="defaultColor">The default color.</param> /// <returns>The default color if the current color equals OxyColors.Automatic, otherwise the color itself.</returns> public OxyColor GetActualColor(OxyColor defaultColor) { return(this.IsAutomatic() ? defaultColor : this); }