nplot/src/Marker.cs

415 lines
13 KiB
C#

/*
* NPlot - A charting library for .NET
*
* Marker.cs
* Copyright (C) 2003-2006 Matt Howlett and others.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System.Drawing;
using System.Drawing.Drawing2D;
namespace NPlot
{
/// <summary>
/// Encapsulates functionality relating to markers used by the PointPlot class.
/// </summary>
public class Marker
{
/// <summary>
/// Enumeration of all different types of marker.
/// </summary>
public enum MarkerType
{
/// <summary>
/// A simple cross marker (x).
/// </summary>
Cross1,
/// <summary>
/// Another simple cross marker (+).
/// </summary>
Cross2,
/// <summary>
/// A circle marker.
/// </summary>
Circle,
/// <summary>
/// A square marker.
/// </summary>
Square,
/// <summary>
/// A triangle marker (upwards).
/// </summary>
Triangle,
/// <summary>
/// A triangle marker (upwards).
/// </summary>
TriangleUp,
/// <summary>
/// A triangle marker (upwards).
/// </summary>
TriangleDown,
/// <summary>
/// A diamond,
/// </summary>
Diamond,
/// <summary>
/// A filled circle
/// </summary>
FilledCircle,
/// <summary>
/// A filled square
/// </summary>
FilledSquare,
/// <summary>
/// A filled triangle
/// </summary>
FilledTriangle,
/// <summary>
/// A small flag (up)
/// </summary>
Flag,
/// <summary>
/// A small flag (up)
/// </summary>
FlagUp,
/// <summary>
/// A small flag (down)
/// </summary>
FlagDown,
/// <summary>
/// No marker
/// </summary>
None
}
private Brush brush_ = new SolidBrush(Color.Black);
private bool filled_;
private int h_;
private MarkerType markerType_;
private Pen pen_ = new Pen(Color.Black);
private int size_;
/// <summary>
/// Default constructor.
/// </summary>
public Marker()
{
markerType_ = MarkerType.Square;
Size = 4;
filled_ = false;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="markertype">The marker type.</param>
public Marker(MarkerType markertype)
{
markerType_ = markertype;
Size = 4;
filled_ = false;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="markertype">The marker type.</param>
/// <param name="size">The marker size.</param>
public Marker(MarkerType markertype, int size)
{
markerType_ = markertype;
Size = size;
filled_ = false;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="markertype">The marker type.</param>
/// <param name="size">The marker size.</param>
/// <param name="color">The marker color.</param>
public Marker(MarkerType markertype, int size, Color color)
{
markerType_ = markertype;
Size = size;
Color = color;
filled_ = false;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="markertype">The marker type.</param>
/// <param name="size">The marker size.</param>
/// <param name="pen">The marker Pen.</param>
public Marker(MarkerType markertype, int size, Pen pen)
{
markerType_ = markertype;
Size = size;
Pen = pen;
filled_ = false;
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="markertype">The marker type.</param>
/// <param name="size">The marker size.</param>
/// <param name="pen">The marker Pen.</param>
/// <param name="fill">The fill flag.</param>
public Marker(MarkerType markertype, int size, Pen pen, bool fill)
{
markerType_ = markertype;
Size = size;
Pen = pen;
filled_ = fill;
}
/// <summary>
/// The type of marker.
/// </summary>
public MarkerType Type
{
get { return markerType_; }
set { markerType_ = value; }
}
/// <summary>
/// Whether or not to draw a dropline.
/// </summary>
public bool DropLine { get; set; }
/// <summary>
/// The marker size.
/// </summary>
public int Size
{
get { return size_; }
set
{
size_ = value;
h_ = size_/2;
}
}
/// <summary>
/// The brush used to fill the marker.
/// </summary>
public Brush FillBrush
{
get { return brush_; }
set { brush_ = value; }
}
/// <summary>
/// Fill with color.
/// </summary>
public bool Filled
{
get { return filled_; }
set { filled_ = value; }
}
/// <summary>
/// Sets the pen color and fill brush to be solid with the specified color.
/// </summary>
public Color Color
{
set
{
pen_.Color = value;
brush_ = new SolidBrush(value);
}
get { return pen_.Color; }
}
/// <summary>
/// The Pen used to draw the marker.
/// </summary>
public Pen Pen
{
set { pen_ = value; }
get { return pen_; }
}
/// <summary>
/// Draws the marker at the given position
/// </summary>
/// <param name="g">The graphics surface on which to draw.</param>
/// <param name="x">The [physical] x position to draw the marker.</param>
/// <param name="y">The [physical] y position to draw the marker.</param>
public void Draw(Graphics g, int x, int y)
{
switch (markerType_)
{
case MarkerType.Cross1:
g.DrawLine(pen_, x - h_, y + h_, x + h_, y - h_);
g.DrawLine(pen_, x + h_, y + h_, x - h_, y - h_);
break;
case MarkerType.Cross2:
g.DrawLine(pen_, x, y - h_, x, y + h_);
g.DrawLine(pen_, x - h_, y, x + h_, y);
break;
case MarkerType.Circle:
g.DrawEllipse(pen_, x - h_, y - h_, size_, size_);
if (filled_)
{
g.FillEllipse(brush_, x - h_, y - h_, size_, size_);
}
break;
case MarkerType.Square:
g.DrawRectangle(pen_, x - h_, y - h_, size_, size_);
if (filled_)
{
g.FillRectangle(brush_, x - h_, y - h_, size_, size_);
}
break;
case MarkerType.Triangle:
case MarkerType.TriangleDown:
{
Point p1 = new Point(x - h_, y - h_);
Point p2 = new Point(x, y + h_);
Point p3 = new Point(x + h_, y - h_);
Point[] pts = new Point[3] {p1, p2, p3};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
g.DrawPath(pen_, gp);
if (filled_)
{
g.FillPath(brush_, gp);
}
break;
}
case MarkerType.TriangleUp:
{
Point p1 = new Point(x - h_, y + h_);
Point p2 = new Point(x, y - h_);
Point p3 = new Point(x + h_, y + h_);
Point[] pts = new Point[3] {p1, p2, p3};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
g.DrawPath(pen_, gp);
if (filled_)
{
g.FillPath(brush_, gp);
}
break;
}
case MarkerType.FilledCircle:
g.DrawEllipse(pen_, x - h_, y - h_, size_, size_);
g.FillEllipse(brush_, x - h_, y - h_, size_, size_);
break;
case MarkerType.FilledSquare:
g.DrawRectangle(pen_, x - h_, y - h_, size_, size_);
g.FillRectangle(brush_, x - h_, y - h_, size_, size_);
break;
case MarkerType.FilledTriangle:
{
Point p1 = new Point(x - h_, y - h_);
Point p2 = new Point(x, y + h_);
Point p3 = new Point(x + h_, y - h_);
Point[] pts = new Point[3] {p1, p2, p3};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
g.DrawPath(pen_, gp);
g.FillPath(brush_, gp);
break;
}
case MarkerType.Diamond:
{
Point p1 = new Point(x - h_, y);
Point p2 = new Point(x, y - h_);
Point p3 = new Point(x + h_, y);
Point p4 = new Point(x, y + h_);
Point[] pts = new Point[4] {p1, p2, p3, p4};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
g.DrawPath(pen_, gp);
if (filled_)
{
g.FillPath(brush_, gp);
}
break;
}
case MarkerType.Flag:
case MarkerType.FlagUp:
{
Point p1 = new Point(x, y);
Point p2 = new Point(x, y - size_);
Point p3 = new Point(x + size_, y - size_ + size_/3);
Point p4 = new Point(x, y - size_ + 2*size_/3);
g.DrawLine(pen_, p1, p2);
Point[] pts = new Point[3] {p2, p3, p4};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
g.DrawPath(pen_, gp);
if (filled_)
{
g.FillPath(brush_, gp);
}
break;
}
case MarkerType.FlagDown:
{
Point p1 = new Point(x, y);
Point p2 = new Point(x, y + size_);
Point p3 = new Point(x + size_, y + size_ - size_/3);
Point p4 = new Point(x, y + size_ - 2*size_/3);
g.DrawLine(pen_, p1, p2);
Point[] pts = new Point[3] {p2, p3, p4};
GraphicsPath gp = new GraphicsPath();
gp.AddPolygon(pts);
g.DrawPath(pen_, gp);
if (filled_)
{
g.FillPath(brush_, gp);
}
break;
}
case MarkerType.None:
break;
}
}
}
}