示例#1
0
        /// <inheritdoc cref="ICanvas"/>
        public ICanvas DrawRectangle(PointPair rect, float thickness, float unitsOn)
        {
            ValidationUtil.RequireNonNull(rect);

            var r = rect.ToRectangle(currentDrawingSpace);

            var pen = GetPen(thickness);

            if (unitsOn.CompareTo(1f) == 0)
            {
                pen.DashStyle = XDashStyle.Solid;
            }
            else
            {
                pen.DashStyle = XDashStyle.Dash;
                //var lineLength = rect.ConvertLineLength(currentDrawingSpace);
                var lineLength  = r.Width * 2 + r.Height * 2;
                var numUnits    = lineLength / thickness;
                var numOnUnits  = unitsOn * numUnits;
                var numOffUnits = numUnits - numOnUnits;
                pen.DashPattern = new double[] { Math.Max(1, numOnUnits / numOffUnits), Math.Max(1, numOffUnits / numOnUnits) };
            }

            var from = BindPoint(r.X, r.Y, thickness / 2, currentDrawingSpace);
            var to   = BindPoint(r.X + r.Width, r.Y + r.Height, thickness / 2, currentDrawingSpace);

            //currentGfx.DrawRectangle(pen, r.X, r.Y, r.Width, r.Height);
            currentGfx.DrawRectangle(pen, from.Item1, from.Item2, to.Item1 - from.Item1, to.Item2 - from.Item2);

            return(this);
        }
示例#2
0
            /// <summary>
            /// Adds a line with the specified line information.
            /// </summary>
            /// <param name="points">the values</param>
            /// <param name="line">the design</param>
            /// <param name="lineMarkers">marker above the line; (point index, image)</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if any arguments is null or points contain less than 2 values</exception>
            public Builder AddLine(List <float> points, LineInfo line, List <Tuple <int, Bitmap> > lineMarkers)
            {
                ValidationUtil.RequireNonNull(points);
                ValidationUtil.RequireNonNull(line);
                ValidationUtil.RequirePositive(points.Count - 1, "There must be at least two values in points.");
                ValidationUtil.RequireNonNull(lineMarkers);

                if (lineMarkers.Any(t => t == null))
                {
                    throw new ArgumentException("No line marker can be null.");
                }

                if (lineMarkers.Any(t => t.Item2 == null))
                {
                    throw new ArgumentException("No line marker image can be null.");
                }

                if (lineMarkers.Select(t => t.Item1).Any(i => i >= points.Count || i < 0))
                {
                    throw new ArgumentException("No line marker can have an index outside of the points.");
                }

                lines.Add(new Tuple <List <float>, LineInfo, List <Tuple <int, Bitmap> > >(points, line, lineMarkers));

                return(this);
            }
示例#3
0
        /// <inheritdoc cref="ICanvas"/>
        public ICanvas WriteText(string text, float x, float y)
        {
            ValidationUtil.RequireNonNull(text);
            ValidationUtil.RequireBetween(x, 0, 1, $"x({x}) must be in range [0, 1].");
            ValidationUtil.RequireBetween(y, 0, 1, $"y({y}) must be in range [0, 1].");

            var textWidth  = GetTextWidth(text);
            var textHeight = GetTextHeight(text);

            var textRect = new RectangleF(
                (currentDrawingSpace.Width * x) + currentDrawingSpace.X,
                (currentDrawingSpace.Height * y) + currentDrawingSpace.Y,
                textWidth * currentDrawingSpace.Width,
                textHeight * currentDrawingSpace.Height);


            /*
             * var f = GetFont();
             * if (!currentDrawingSpace.Contains(textRect))
             * {
             *  throw new ArgumentException("The text does not fit in the current drawing space.");
             * }
             */

            //currentGfx.DrawString(text, GetFont(), GetBrush(), currentDrawingSpace.Width * x, currentDrawingSpace.Height * y);
            currentGfx.DrawString(text, GetFont(), GetBrush(), new XPoint(textRect.X, textRect.Y));
            return(this);
        }
示例#4
0
            /// <summary>
            /// Adds a horizontal line across the graph.
            /// </summary>
            /// <param name="line">the line</param>
            /// <param name="yValue">the y value to start the line it</param>
            /// <param name="text">the marker to the left of the line</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if line is null</exception>
            public Builder AddHorizontalLine(LineInfo line, float yValue, string text)
            {
                ValidationUtil.RequireNonNull(line);

                horizontalLines.Add(Tuple.Create(line, yValue, text));

                return(this);
            }
示例#5
0
            /// <summary>
            /// Adds a vertical line across the graph.
            /// </summary>
            /// <param name="line">the line</param>
            /// <param name="xValue">the x value to start the line at</param>
            /// <param name="text">the marker below the line</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if line is null</exception>
            public Builder AddVerticalLine(LineInfo line, int xValue, string text)
            {
                ValidationUtil.RequireNonNull(line);

                verticalLines.Add(Tuple.Create(line, xValue, text));

                return(this);
            }
示例#6
0
        /// <summary>
        /// Adds a IPlottable.
        /// </summary>
        /// <param name="plottable">the plottable to add</param>
        /// <returns>this instance for chaining</returns>
        public Area AddPlottable(IPlottable plottable)
        {
            ValidationUtil.RequireNonNull(plottable);

            plottables.Add(plottable);

            return(this);
        }
示例#7
0
            /// <summary>
            /// Returns a new Builder instance.
            /// </summary>
            /// <param name="lineWidth">the width of the line</param>
            /// <param name="subtitle">the subtitle below</param>
            /// <returns>new Builder instance</returns>
            public static Builder NewInstance(float lineWidth, string subtitle)
            {
                ValidationUtil.RequireBetween(lineWidth, 0, 1, $"lineWidth({lineWidth}) must be in the interval [0, 1]");
                ValidationUtil.RequirePositive(lineWidth, $"lineWidth({lineWidth}) must be greater than 0.");
                ValidationUtil.RequireNonNull(subtitle);

                return(new Builder(lineWidth, subtitle));
            }
示例#8
0
            /// <summary>
            /// Sets the numerical markers on the x and y axis.
            /// </summary>
            /// <param name="numAxisX">number of markers on x axis</param>
            /// <param name="numAxisY">number of markers on y axis</param>
            /// <param name="axisX">function to transform index value to any marker</param>
            /// <param name="axisY">function to transform value to any marker</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if any argument is negative</exception>
            public Builder SetAxisMarkers(int numAxisX, int numAxisY, Func <int, string> axisX, Func <float, string> axisY)
            {
                NumMarkersAxisX = ValidationUtil.RequireNonNegative(numAxisX, $"numAxisX({numAxisX}) cannot be negative.");
                NumMarkersAxisY = ValidationUtil.RequireNonNegative(numAxisY, $"numAxisY({numAxisY}) cannot be negative.");
                AxisX           = ValidationUtil.RequireNonNull(axisX);
                AxisY           = ValidationUtil.RequireNonNull(axisY);

                return(this);
            }
示例#9
0
            /// <summary>
            /// Fills the rectangle in the graph as specified by the two y-values.
            /// </summary>
            /// <param name="fromYValue">the lower y value</param>
            /// <param name="toYValue">the upper y value</param>
            /// <param name="color">the color</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if color is null or fromYValue is equal or greater than toYValue</exception>
            public Builder SetHorizontalFill(float fromYValue, float toYValue, Color color)
            {
                ValidationUtil.RequireNonNull(color);
                ValidationUtil.RequirePositive(toYValue - fromYValue, $"toYValue({toYValue}) cannot be less than or equal to fromYValue({fromYValue}).");

                HorizontalFill = Tuple.Create(fromYValue, toYValue, color);

                return(this);
            }
示例#10
0
            /// <summary>
            /// Returns a new Builder for the version of the form: "vMAJOR.MINOR.PATCH" where
            /// MAJOR = Major, MINOR = Minor and PATCH = Build.
            /// </summary>
            /// <param name="version">the version</param>
            /// <param name="textInfo">the text information</param>
            /// <param name="prefix">the prefix added before the version</param>
            /// <returns>new Builder instance</returns>
            public static Builder NewVersionInstance(Version version, TextInfo textInfo, string prefix)
            {
                ValidationUtil.RequireNonNull(version);
                ValidationUtil.RequireNonNull(textInfo);
                ValidationUtil.RequireNonNull(prefix);

                var versionString = $"{prefix}v{version.Major}.{version.Minor}.{version.Build}";

                return(new Builder(versionString, textInfo));
            }
            /// <summary>
            /// Returns a new Builder instance with the title to the left of the comment lines. One lineSpacing will be
            /// added under the title before the first line.
            /// </summary>
            /// <param name="lineSpacing">the space between the lines</param>
            /// <param name="title">the title; if empty no title is used</param>
            /// <param name="textInfo">the font information of the title</param>
            /// <returns>new Builder instance</returns>
            public static Builder NewInstance(float lineSpacing, string title, TextInfo textInfo)
            {
                ValidationUtil.RequireBetween(lineSpacing, 0, 1, $"lineSpacing({lineSpacing}) must be in the interval [0, 1]");
                ValidationUtil.RequirePositive(lineSpacing, $"lineSpacing({lineSpacing}) must be greater than 0.");

                ValidationUtil.RequireNonNull(title);
                ValidationUtil.RequireNonNull(textInfo);

                return(new Builder(lineSpacing, title, textInfo));
            }
示例#12
0
        /// <inheritdoc cref="ICanvas"/>
        public ICanvas DrawRectangle(PointPair rect)
        {
            ValidationUtil.RequireNonNull(rect);

            var r = rect.ToRectangle(currentDrawingSpace);

            currentGfx.DrawRectangle(GetBrush(), r.X, r.Y, r.Width, r.Height);

            return(this);
        }
示例#13
0
        /*
         * ================================================================================
         * ==========================       Helper Methods       ==========================
         * ================================================================================
         */
        #region HelperMethods

        private XGraphics GetGraphics(int pageId)
        {
            if (!graphics.ContainsKey(pageId))
            {
                graphics.Add(pageId, XGraphics.FromPdfPage(currentPage));
            }

            graphics.TryGetValue(pageId, out var graphic);

            return(ValidationUtil.RequireNonNull(graphic));
        }
示例#14
0
            /// <summary>
            /// Sets a grid in the graph with automatic number of horizontal lines to make a grid of squares.
            /// <para>
            /// Note that the last call to any AddGrid method is applied, rest is ignored.
            /// </para>
            /// </summary>
            /// <param name="grid">the grid lines information</param>
            /// <param name="numVertical">number of vertical lines</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if grid is null</exception>
            public Builder SetGrid(LineInfo grid, int numVertical)
            {
                Grid          = ValidationUtil.RequireNonNull(grid);
                NumVertical   = ValidationUtil.RequirePositive(numVertical, $"numVertical({numVertical}) must be positive..");
                NumHorizontal = -1;

                AgainstMarkersX = false;
                AgainstMarkersY = false;

                return(this);
            }
示例#15
0
            /// <summary>
            /// Sets a grid in the graph where the vertical lines (againstMarkersX) and horizontal lines (againstMarkersY)
            /// are going out from the numerical markers as set by <see cref="SetAxisMarkers(int,int)"/> or <see cref="SetAxisMarkers(int,int,Func{int,string},Func{float,string})"/>
            /// <para>
            /// Note that the last call to any AddGrid method is applied, rest is ignored.
            /// </para>
            /// </summary>
            /// <param name="grid">the grid lines information</param>
            /// <param name="againstMarkersX">if vertical lines from the markers on the x axis</param>
            /// <param name="againstMarkersY">if horizontal lines from the markers on the y axis</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if grid is null</exception>
            public Builder SetGrid(LineInfo grid, bool againstMarkersX, bool againstMarkersY)
            {
                Grid            = ValidationUtil.RequireNonNull(grid);
                AgainstMarkersX = againstMarkersX;
                AgainstMarkersY = againstMarkersY;

                NumVertical   = 0;
                NumHorizontal = 0;

                return(this);
            }
示例#16
0
            /// <summary>
            /// Sets a grid in the graph.
            /// <para>
            /// Note that the last call to any AddGrid method is applied, rest is ignored.
            /// </para>
            /// </summary>
            /// <param name="grid">the grid lines information</param>
            /// <param name="numVertical">number of vertical lines</param>
            /// <param name="numHorizontal">number of horizontal lines</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if grid is null</exception>
            public Builder SetGrid(LineInfo grid, int numVertical, int numHorizontal)
            {
                Grid          = ValidationUtil.RequireNonNull(grid);
                NumVertical   = ValidationUtil.RequireNonNegative(numVertical, $"numAxisY({numVertical}) cannot be negative.");
                NumHorizontal = ValidationUtil.RequireNonNegative(numHorizontal, $"numHorizontal({numHorizontal}) cannot be negative.");

                AgainstMarkersX = false;
                AgainstMarkersY = false;

                return(this);
            }
示例#17
0
            /// <summary>
            /// Adds a legend to the graph.
            /// </summary>
            /// <param name="text">the text</param>
            /// <param name="info">the text display info</param>
            /// <param name="startX">the start x position of the top left corner</param>
            /// <param name="startY">the start y position of the top left corner</param>
            /// <returns>this Builder for chaining</returns>
            /// <exception cref="ArgumentException">if text or info is null or startX or startY not in 0,1 interval</exception>
            public Builder AddLegend(string text, TextInfo info, float startX, float startY)
            {
                ValidationUtil.RequireNonNull(text);
                ValidationUtil.RequireNonNull(info);
                ValidationUtil.RequireBetween(startX, 0f, 1f, $"startX({startX}) has to be in the interval [0, 1].");
                ValidationUtil.RequireBetween(startY, 0f, 1f, $"startY({startY}) has to be in the interval [0, 1].");


                legends.Add(Tuple.Create(text, info, startX, startY));

                return(this);
            }
            /// <summary>
            /// Sets the number of lines. This will result in crash if they cannot fit. Give -1 to mean as many as possible.
            /// <para>
            /// Defaults to -1 and a .5 thickness line with RGB(66, 66, 66) with width of 1f.
            /// </para>
            /// </summary>
            /// <param name="numLines">the number of lines</param>
            /// <param name="lineWidth">the width of the lines</param>
            /// <param name="lineInfo">the line info</param>
            /// <returns>this Builder for chaining</returns>
            public Builder SetLines(int numLines, float lineWidth, LineInfo lineInfo)
            {
                if (numLines != -1)
                {
                    ValidationUtil.RequireNonNegative(numLines, $"numLines({numLines}) must be greater or equal to -1");
                }
                ValidationUtil.RequireBetween(lineWidth, 0, 1, $"lineWidth({lineWidth}) must be in the interval [0, 1]");
                ValidationUtil.RequireNonNull(lineInfo);

                NumLines  = numLines;
                LineWidth = lineWidth;
                LineInfo  = lineInfo;

                return(this);
            }
示例#19
0
        /// <inheritdoc cref="ICanvas"/>
        public ICanvas DrawImage(Bitmap pngImage, PointPair box)
        {
            // Validates the arguments.
            ValidationUtil.RequireNonNull(pngImage);
            ValidationUtil.RequireNonNull(box);

            using (var stream = new MemoryStream())
            {
                pngImage.Save(stream, ImageFormat.Png);
                // Calculates the dimensions.
                var rect  = box.ToRectangle(currentDrawingSpace);
                var image = XImage.FromStream(stream);
                currentGfx.DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
                return(this);
            }
        }
示例#20
0
        /// <inheritdoc cref="ICanvas"/>
        public ICanvas DrawLine(PointPair line, float thickness, float unitsOn)
        {
            ValidationUtil.RequireNonNull(line);
            ValidationUtil.RequirePositive(thickness, $"thickness({thickness}) must be positive (>0).");
            ValidationUtil.RequireBetween(unitsOn, 0, 1, $"unitsOn({unitsOn}) must be in the range [0, 1].");

            // Draws the line with the pen.
            var pen = GetPen(thickness);

            if (unitsOn.CompareTo(1f) == 0)
            {
                pen.DashStyle = XDashStyle.Solid;
            }
            else
            {
                pen.DashStyle = XDashStyle.Dash;
                var lineLength  = line.ConvertLineLength(currentDrawingSpace);
                var numUnits    = lineLength / thickness;
                var numOnUnits  = unitsOn * numUnits;
                var numOffUnits = numUnits - numOnUnits;
                //pen.DashPattern = new double[] {numOnUnits, numOffUnits};
                pen.DashPattern = new double[] { Math.Max(1, numOnUnits / numOffUnits), Math.Max(1, numOffUnits / numOnUnits) };
            }

            var fromX = line.ConvertFromX(currentDrawingSpace);
            var fromY = line.ConvertFromY(currentDrawingSpace);
            var toX   = line.ConvertToX(currentDrawingSpace);
            var toY   = line.ConvertToY(currentDrawingSpace);

            var from = BindPoint(
                fromX,
                fromY,
                thickness / 2,
                currentDrawingSpace);

            var to = BindPoint(
                toX,
                toY,
                thickness / 2,
                currentDrawingSpace);


            //currentGfx.DrawLine(pen, fromX, fromY, toX, toY);
            currentGfx.DrawLine(pen, from.Item1, from.Item2, to.Item1, to.Item2);

            return(this);
        }
示例#21
0
        /// <inheritdoc cref="ICanvas"/>
        public ICanvas DrawImage(string imageFile, PointPair box)
        {
            // Validates the arguments.
            ValidationUtil.RequireFileExist(imageFile);
            if (!FileUtil.IsImageFile(imageFile))
            {
                throw new ArgumentException($"imageFile({imageFile}) is not an image.");
            }

            ValidationUtil.RequireNonNull(box);

            // Calculates the dimensions.
            var rect  = box.ToRectangle(currentDrawingSpace);
            var image = XImage.FromFile(imageFile);

            currentGfx.DrawImage(image, rect.X, rect.Y, rect.Width, rect.Height);
            return(this);
        }
示例#22
0
        /// <summary>
        /// Draws all the added <see cref="IPlottable"/> instances.
        /// </summary>
        /// <param name="canvasConfig">the canvas config use to get the canvas for drawing</param>
        public void Draw(ICanvasConfig canvasConfig)
        {
            ValidationUtil.RequireNonNull(canvasConfig);

            canvasConfig.AddPage(page);

            var canvas = canvasConfig.UsePageArea(box, page);

            if (canvas.GetModeParam() == ModeParam.Boxed ||
                canvas.GetModeParam() == ModeParam.BoxedCalibration)
            {
                canvas.SetColor(Color.Black);
                canvas.DrawRectangle(PointPair.Full, 1f, 1f);
            }

            foreach (var plottable in plottables)
            {
                plottable.Plot(canvas);
            }
        }
示例#23
0
            /// <summary>
            /// Sets the text info of the subtitle.
            /// <para>
            /// Defaults to black Helvetica with font size 8.
            /// </para>
            /// </summary>
            /// <param name="textInfo">the text info</param>
            /// <returns>this Builder for chaining</returns>
            public Builder SetTextInfo(TextInfo textInfo)
            {
                TextInfo = ValidationUtil.RequireNonNull(textInfo);

                return(this);
            }
示例#24
0
            /// <summary>
            /// Sets the line info of the signature line.
            /// <para>
            /// Defaults to a filled .5 thickness line with RGB(66, 66, 66).
            /// </para>
            /// </summary>
            /// <param name="lineInfo">the line info</param>
            /// <returns>this Builder for chaining</returns>
            public Builder SetLineInfo(LineInfo lineInfo)
            {
                LineInfo = ValidationUtil.RequireNonNull(lineInfo);

                return(this);
            }
示例#25
0
        /// <summary>
        /// Creates a new Area defined by the box on the specified page.
        /// </summary>
        /// <param name="box">the area that the plottables will be plotted in</param>
        /// <param name="page">the page on the pdf</param>
        /// <returns>new Area instance</returns>
        public static Area NewInstance(PointPair box, int page)
        {
            ValidationUtil.RequireNonNull(box);

            return(new Area(box, page));
        }
示例#26
0
 /// <summary>
 /// Creates a new LinePlottable.
 /// </summary>
 /// <param name="line">the line</param>
 /// <param name="info">the line info</param>
 /// <returns>new LinePlottable instance</returns>
 public static LinePlottable NewInstance(PointPair line, LineInfo info)
 {
     ValidationUtil.RequireNonNull(line);
     ValidationUtil.RequireNonNull(info);
     return(new LinePlottable(line, info));
 }
示例#27
0
 /// <summary>
 /// Returns a new Builder instance.
 /// </summary>
 /// <param name="text">the text</param>
 /// <param name="textInfo">the text information</param>
 /// <returns>new Builder instance</returns>
 public static Builder NewInstance(string text, TextInfo textInfo)
 {
     ValidationUtil.RequireNonNull(text);
     ValidationUtil.RequireNonNull(textInfo);
     return(new Builder(text, textInfo));
 }
示例#28
0
            /// <summary>
            /// Centers the text inside the specified box.
            /// <para>
            /// Note: this might result in a <see cref="ArgumentException"/> in the <see cref="IPlottable.Plot(ICanvas)"/> method
            /// if the text cannot fit in the box.
            /// </para>
            /// </summary>
            /// <param name="box">the box</param>
            /// <returns>this Builder for chaining</returns>
            public Builder SetCenterIn(PointPair box)
            {
                CenterIn = ValidationUtil.RequireNonNull(box);

                return(this);
            }
示例#29
0
            /// <summary>
            /// Creates a new Builder instance with the PNG as a bitmap.
            /// </summary>
            /// <param name="pngImage">the PNG as a bitmap</param>
            /// <returns>new Builder instance</returns>
            public static Builder NewInstance(Bitmap pngImage)
            {
                ValidationUtil.RequireNonNull(pngImage);

                return(new Builder(pngImage));
            }
示例#30
0
 /// <summary>
 /// Sets the scale of the image inside the specified image box.
 /// <para>
 /// Defaults to <see cref="ScaleType.Fill"/> with maximum <see cref="PointPair"/>.
 /// </para>
 /// </summary>
 /// <param name="scale">the scale type to apply</param>
 /// <param name="imageBox">the box to apply scale typ inside</param>
 /// <returns></returns>
 public Builder SetScale(ScaleType scale, PointPair imageBox)
 {
     Scale    = scale;
     ImageBox = ValidationUtil.RequireNonNull(imageBox);
     return(this);
 }