예제 #1
0
        /// <summary>
        /// Draw The legend
        /// </summary>
        /// <param name="g">The graphics surface on which to draw</param>
        /// <param name="position">The position of the top left of the axis.</param>
        /// <param name="plots">Array of plot objects to appear in the legend.</param>
        /// <param name="scale">if the legend is set to scale, the amount to scale by.</param>
        /// <returns>bounding box</returns>
        public Rectangle Draw(Graphics g, Point position, ArrayList plots, float scale)
        {
            // first of all determine the Font to use in the legend.
            Font textFont;

            if (this.AutoScaleText)
            {
                textFont = Utils.ScaleFont(this.font_, scale);
            }
            else
            {
                textFont = this.font_;
            }

            // determine max width and max height of label strings and
            // count the labels.
            int labelCount   = 0;
            int maxHt        = 0;
            int maxWd        = 0;
            int unnamedCount = 0;

            for (int i = 0; i < plots.Count; ++i)
            {
                if (!(plots[i] is IPlot))
                {
                    continue;
                }

                IPlot p = (IPlot)plots[i];

                if (!p.ShowInLegend)
                {
                    continue;
                }
                string label = p.Label;
                if (label == "")
                {
                    unnamedCount += 1;
                    label         = "Series " + unnamedCount.ToString();
                }
                SizeF labelSize = g.MeasureString(label, textFont);
                if (labelSize.Height > maxHt)
                {
                    maxHt = (int)labelSize.Height;
                }
                if (labelSize.Width > maxWd)
                {
                    maxWd = (int)labelSize.Width;
                }

                ++labelCount;
            }

            bool extendingHorizontally = numberItemsHorizontally_ == -1;
            bool extendingVertically   = numberItemsVertically_ == -1;

            // determine width in legend items count units.
            int widthInItemCount = 0;

            if (extendingVertically)
            {
                if (labelCount >= numberItemsHorizontally_)
                {
                    widthInItemCount = numberItemsHorizontally_;
                }
                else
                {
                    widthInItemCount = labelCount;
                }
            }
            else if (extendingHorizontally)
            {
                widthInItemCount = labelCount / numberItemsVertically_;
                if (labelCount % numberItemsVertically_ != 0)
                {
                    widthInItemCount += 1;
                }
            }
            else
            {
                throw new NPlotException("logic error in legend base");
            }

            // determine height of legend in items count units.
            int heightInItemCount = 0;

            if (extendingHorizontally)
            {
                if (labelCount >= numberItemsVertically_)
                {
                    heightInItemCount = numberItemsVertically_;
                }
                else
                {
                    heightInItemCount = labelCount;
                }
            }
            else             // extendingVertically
            {
                heightInItemCount = labelCount / numberItemsHorizontally_;
                if (labelCount % numberItemsHorizontally_ != 0)
                {
                    heightInItemCount += 1;
                }
            }

            int lineLength = 20;
            int hSpacing   = (int)(5.0f * scale);
            int vSpacing   = (int)(3.0f * scale);
            int boxWidth   = (int)((float)widthInItemCount * (lineLength + maxWd + hSpacing * 2.0f) + hSpacing);
            int boxHeight  = (int)((float)heightInItemCount * (maxHt + vSpacing) + vSpacing);

            int totalWidth  = boxWidth;
            int totalHeight = boxHeight;

            // draw box around the legend.

            if (this.BorderStyle == BorderType.Line)
            {
                g.FillRectangle(new SolidBrush(this.bgColor_), position.X, position.Y, boxWidth, boxHeight);
                g.DrawRectangle(new Pen(this.borderColor_), position.X, position.Y, boxWidth, boxHeight);
            }
            else if (this.BorderStyle == BorderType.Shadow)
            {
                int offset = (int)(4.0f * scale);
                g.FillRectangle(new SolidBrush(Color.FromArgb(128, Color.Gray)), position.X + offset, position.Y + offset, boxWidth, boxHeight);
                g.FillRectangle(new SolidBrush(this.bgColor_), position.X, position.Y, boxWidth, boxHeight);
                g.DrawRectangle(new Pen(this.borderColor_), position.X, position.Y, boxWidth, boxHeight);

                totalWidth  += offset;
                totalHeight += offset;
            }

            /*
             * else if ( this.BorderStyle == BorderType.Curved )
             * {
             *         // TODO. make this nice.
             * }
             */
            else
            {
                // do nothing.
            }

            // now draw entries in box..
            labelCount   = 0;
            unnamedCount = 0;

            int plotCount = -1;

            for (int i = 0; i < plots.Count; ++i)
            {
                if (!(plots[i] is IPlot))
                {
                    continue;
                }

                IPlot p = (IPlot)plots[i];

                if (!p.ShowInLegend)
                {
                    continue;
                }

                plotCount += 1;

                int xpos, ypos;
                if (extendingVertically)
                {
                    xpos = plotCount % numberItemsHorizontally_;
                    ypos = plotCount / numberItemsHorizontally_;
                }
                else
                {
                    xpos = plotCount / numberItemsVertically_;
                    ypos = plotCount % numberItemsVertically_;
                }

                int lineXPos = (int)(position.X + hSpacing + xpos * (lineLength + maxWd + hSpacing * 2.0f));
                int lineYPos = (int)(position.Y + vSpacing + ypos * (vSpacing + maxHt));
                p.DrawInLegend(g, new Rectangle(lineXPos, lineYPos, lineLength, maxHt));

                int    textXPos = lineXPos + hSpacing + lineLength;
                int    textYPos = lineYPos;
                string label    = p.Label;
                if (label == "")
                {
                    unnamedCount += 1;
                    label         = "Series " + unnamedCount.ToString();
                }

                g.DrawString(label, textFont,
                             new SolidBrush(this.textColor_), textXPos, textYPos);

                ++labelCount;
            }
            return(new Rectangle(position.X, position.Y, totalWidth, totalHeight));
        }
예제 #2
0
파일: LegendBase.cs 프로젝트: wwwK/XwPlot
        /// <summary>
        /// Draw The legend
        /// </summary>
        /// <param name="ctx">The Drawing Context with on which to draw</param>
        /// <param name="position">The position of the top left of the axis.</param>
        /// <param name="plots">Array of plot objects to appear in the legend.</param>
        /// <param name="scale">if the legend is set to scale, the amount to scale by.</param>
        /// <returns>bounding box</returns>
        public Rectangle Draw(Context ctx, Point position, ArrayList plots, double scale)
        {
            // first of all determine the Font to use in the legend.
            Font textFont;

            if (AutoScaleText)
            {
                textFont = font_.WithScaledSize(scale);
            }
            else
            {
                textFont = font_;
            }

            ctx.Save();

            // determine max width and max height of label strings and
            // count the labels.
            int        labelCount   = 0;
            int        unnamedCount = 0;
            double     maxHt        = 0;
            double     maxWd        = 0;
            TextLayout layout       = new TextLayout();

            layout.Font = textFont;

            for (int i = 0; i < plots.Count; ++i)
            {
                if (!(plots[i] is IPlot))
                {
                    continue;
                }

                IPlot p = (IPlot)plots[i];

                if (!p.ShowInLegend)
                {
                    continue;
                }
                string label = p.Label;
                if (label == "")
                {
                    unnamedCount += 1;
                    label         = "Series " + unnamedCount.ToString();
                }
                layout.Text = label;
                Size labelSize = layout.GetSize();
                if (labelSize.Height > maxHt)
                {
                    maxHt = labelSize.Height;
                }
                if (labelSize.Width > maxWd)
                {
                    maxWd = labelSize.Width;
                }
                ++labelCount;
            }

            bool extendingHorizontally = numberItemsHorizontally_ == -1;
            bool extendingVertically   = numberItemsVertically_ == -1;

            // determine width in legend items count units.
            int widthInItemCount = 0;

            if (extendingVertically)
            {
                if (labelCount >= numberItemsHorizontally_)
                {
                    widthInItemCount = numberItemsHorizontally_;
                }
                else
                {
                    widthInItemCount = labelCount;
                }
            }
            else if (extendingHorizontally)
            {
                widthInItemCount = labelCount / numberItemsVertically_;
                if (labelCount % numberItemsVertically_ != 0)
                {
                    widthInItemCount += 1;
                }
            }
            else
            {
                throw new XwPlotException("logic error in legend base");
            }

            // determine height of legend in items count units.
            int heightInItemCount = 0;

            if (extendingHorizontally)
            {
                if (labelCount >= numberItemsVertically_)
                {
                    heightInItemCount = numberItemsVertically_;
                }
                else
                {
                    heightInItemCount = labelCount;
                }
            }
            else                        // extendingVertically
            {
                heightInItemCount = labelCount / numberItemsHorizontally_;
                if (labelCount % numberItemsHorizontally_ != 0)
                {
                    heightInItemCount += 1;
                }
            }

            double lineLength = 20;
            double hSpacing   = (int)(5.0f * scale);
            double vSpacing   = (int)(3.0f * scale);
            double boxWidth   = (int)((float)widthInItemCount * (lineLength + maxWd + hSpacing * 2.0f) + hSpacing);
            double boxHeight  = (int)((float)heightInItemCount * (maxHt + vSpacing) + vSpacing);

            double totalWidth  = boxWidth;
            double totalHeight = boxHeight;

            // draw box around the legend.
            if (BorderStyle == BorderType.Line)
            {
                ctx.SetColor(bgColor_);
                ctx.Rectangle(position.X, position.Y, boxWidth, boxHeight);
                ctx.FillPreserve();
                ctx.SetColor(borderColor_);
                ctx.Stroke();
            }
            else if (BorderStyle == BorderType.Shadow)
            {
                double offset = (4.0 * scale);
                Color  shade  = Colors.Gray;
                shade.Alpha = 0.5;
                ctx.SetColor(Colors.Gray);
                ctx.Rectangle(position.X + offset, position.Y + offset, boxWidth, boxHeight);
                ctx.Fill();
                ctx.SetColor(bgColor_);
                ctx.Rectangle(position.X, position.Y, boxWidth, boxHeight);
                ctx.FillPreserve();
                ctx.SetColor(borderColor_);
                ctx.Stroke();

                totalWidth  += offset;
                totalHeight += offset;
            }

            /*
             * else if ( this.BorderStyle == BorderType.Curved )
             * {
             *         // TODO. make this nice.
             * }
             */
            else
            {
                // do nothing.
            }

            // now draw entries in box..
            labelCount   = 0;
            unnamedCount = 0;

            int plotCount = -1;

            for (int i = 0; i < plots.Count; ++i)
            {
                if (!(plots[i] is IPlot))
                {
                    continue;
                }

                IPlot p = (IPlot)plots[i];

                if (!p.ShowInLegend)
                {
                    continue;
                }

                plotCount += 1;

                double xpos, ypos;
                if (extendingVertically)
                {
                    xpos = plotCount % numberItemsHorizontally_;
                    ypos = plotCount / numberItemsHorizontally_;
                }
                else
                {
                    xpos = plotCount / numberItemsVertically_;
                    ypos = plotCount % numberItemsVertically_;
                }

                double lineXPos = (position.X + hSpacing + xpos * (lineLength + maxWd + hSpacing * 2.0));
                double lineYPos = (position.Y + vSpacing + ypos * (vSpacing + maxHt));
                p.DrawInLegend(ctx, new Rectangle(lineXPos, lineYPos, lineLength, maxHt));

                double textXPos = lineXPos + hSpacing + lineLength;
                double textYPos = lineYPos;
                string label    = p.Label;
                if (label == "")
                {
                    unnamedCount += 1;
                    label         = "Series " + unnamedCount.ToString();
                }

                layout.Text = label;
                ctx.DrawTextLayout(layout, textXPos, textYPos);

                ++labelCount;
            }
            ctx.Restore();
            return(new Rectangle(position.X, position.Y, totalWidth, totalHeight));
        }