/*
* 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.
* 3. Neither the name of NPlot nor the names of its contributors may
* be used to endorse or promote products derived from this software without
* specific prior written permission.
*
* 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
{
///
/// Encapsulates functionality relating to markers used by the PointPlot class.
///
public class Marker
{
///
/// Enumeration of all different types of marker.
///
public enum MarkerType
{
///
/// A simple cross marker (x).
///
Cross1,
///
/// Another simple cross marker (+).
///
Cross2,
///
/// A circle marker.
///
Circle,
///
/// A square marker.
///
Square,
///
/// A triangle marker (upwards).
///
Triangle,
///
/// A triangle marker (upwards).
///
TriangleUp,
///
/// A triangle marker (upwards).
///
TriangleDown,
///
/// A diamond,
///
Diamond,
///
/// A filled circle
///
FilledCircle,
///
/// A filled square
///
FilledSquare,
///
/// A filled triangle
///
FilledTriangle,
///
/// A small flag (up)
///
Flag,
///
/// A small flag (up)
///
FlagUp,
///
/// A small flag (down)
///
FlagDown,
///
/// No marker
///
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_;
///
/// Default constructor.
///
public Marker()
{
markerType_ = MarkerType.Square;
Size = 4;
filled_ = false;
}
///
/// Constructor
///
/// The marker type.
public Marker(MarkerType markertype)
{
markerType_ = markertype;
Size = 4;
filled_ = false;
}
///
/// Constructor
///
/// The marker type.
/// The marker size.
public Marker(MarkerType markertype, int size)
{
markerType_ = markertype;
Size = size;
filled_ = false;
}
///
/// Constructor
///
/// The marker type.
/// The marker size.
/// The marker color.
public Marker(MarkerType markertype, int size, Color color)
{
markerType_ = markertype;
Size = size;
Color = color;
filled_ = false;
}
///
/// Constructor
///
/// The marker type.
/// The marker size.
/// The marker Pen.
public Marker(MarkerType markertype, int size, Pen pen)
{
markerType_ = markertype;
Size = size;
Pen = pen;
filled_ = false;
}
///
/// Constructor
///
/// The marker type.
/// The marker size.
/// The marker Pen.
/// The fill flag.
public Marker(MarkerType markertype, int size, Pen pen, bool fill)
{
markerType_ = markertype;
Size = size;
Pen = pen;
filled_ = fill;
}
///
/// The type of marker.
///
public MarkerType Type
{
get { return markerType_; }
set { markerType_ = value; }
}
///
/// Whether or not to draw a dropline.
///
public bool DropLine { get; set; }
///
/// The marker size.
///
public int Size
{
get { return size_; }
set
{
size_ = value;
h_ = size_/2;
}
}
///
/// The brush used to fill the marker.
///
public Brush FillBrush
{
get { return brush_; }
set { brush_ = value; }
}
///
/// Fill with color.
///
public bool Filled
{
get { return filled_; }
set { filled_ = value; }
}
///
/// Sets the pen color and fill brush to be solid with the specified color.
///
public Color Color
{
set
{
pen_.Color = value;
brush_ = new SolidBrush(value);
}
get { return pen_.Color; }
}
///
/// The Pen used to draw the marker.
///
public Pen Pen
{
set { pen_ = value; }
get { return pen_; }
}
///
/// Draws the marker at the given position
///
/// The graphics surface on which to draw.
/// The [physical] x position to draw the marker.
/// The [physical] y position to draw the marker.
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;
}
}
}
}