Description:
The predefined set of needle shapes is not sufficient. Is it possible to draw a custom needle?
Answer:
Yes, it is possible, and this is not that difficult. A custom needle shape can be built from a few figures defined by descendants of the DevExpress.XtraGauges.Core.Drawing.BaseShape class. The picture below demonstrates all these classes:
Using these classes one can create a shape as complex as required by combining a few shapes using the ComplexShape object. Each shape has a set of points, describing it. Point coordinates are used inside the shape, and don't affect the position of the needle. The (0, 0) coordinate is the center of the scale. The X axis defines a length of the needle, and the Y axis defines the width of the needle. To create a triangle needle, the following points can be used:
0, -20
100, 0
0, 20
The size is not relevant, because the needle will be scaled. Feel free to chose a size that is convenient to draw all details of your needle.
The color of the shape can be specified via the BaseShape.Appearance.ContentBrush property. The following objects can be assigned to this property:
DevExpress.XtraGauges.Core.Drawing.SolidBrushObject
DevExpress.XtraGauges.Core.Drawing.PenBrushObject
DevExpress.XtraGauges.Core.Drawing.SimpleLinearGradientBrushObject
DevExpress.XtraGauges.Core.Drawing.LinearGradientBrushObject
DevExpress.XtraGauges.Core.Drawing.EllipticalGradientBrushObject
Here is an example of creating a complex needle:
C#private void CreateComplexNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
PolylineShape basic = new PolylineShape(new PointF[] {
new PointF(25, 20), new PointF(100, 0), new PointF(25, -20),
new PointF(95, 0), new PointF(25, 20)
});
basic.Appearance.ContentBrush = new SolidBrushObject(Color.Azure);
basic.Name = "basic";
PolylineShape cap = new PolylineShape(new PointF[] {
new PointF(100, 0), new PointF(105, 5),
new PointF(110, 0), new PointF(105, -5)
});
cap.Appearance.ContentBrush = new SolidBrushObject(Color.BurlyWood);
cap.Name = "cap";
needleShape.AddRange(new BaseShape[] { basic, cap });
}
Visual BasicPrivate Sub CreateComplexNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim basic As New PolylineShape(New PointF() { New PointF(25, 20), New PointF(100, 0), New PointF(25, -20), New PointF(95, 0), New PointF(25, 20) })
basic.Appearance.ContentBrush = New SolidBrushObject(Color.Azure)
basic.Name = "basic"
Dim cap As New PolylineShape(New PointF() { New PointF(100, 0), New PointF(105, 5), New PointF(110, 0), New PointF(105, -5) })
cap.Appearance.ContentBrush = New SolidBrushObject(Color.BurlyWood)
cap.Name = "cap"
needleShape.AddRange(New BaseShape() { basic, cap })
End Sub
Here is a short description of all classes:
- The PathShape represents a shape based on the GraphicsPath - a set of points connected with lines and curves. In the PathShape, the path is defined by the Points property, which is an array of the ShapePoint objects. The ShapePoint contains a PointF instance and PathPointType value, describing the type of a point. If the GraphicsPath can't be created based on the specified set of the ShapePoint objects, the PathShape throws an exception.
The PathShape can be used to create complex multi-line shapes that have smooth corners and edges.
C#private void CreatePathNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
PathShape shape = new PathShape();
shape.Points = new ShapePoint[] {
new ShapePoint(new PointF(0, 20), PathPointType.Start),
new ShapePoint(new PointF(50, 0), PathPointType.Line),
new ShapePoint(new PointF(0, -20), PathPointType.Line),
new ShapePoint(new PointF(100, 0), PathPointType.Line),
new ShapePoint(new PointF(0, 20), PathPointType.CloseSubpath | PathPointType.Line)
};
EllipticalGradientBrushObject contentBrush = new EllipticalGradientBrushObject(new PointF2D(0, 0), 12f, 1f);
contentBrush.StartColor = Color.Green;
contentBrush.EndColor = Color.Yellow;
shape.Appearance.ContentBrush = contentBrush;
shape.Name = "pathNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreatePathNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New PathShape()
shape.Points = New ShapePoint() { New ShapePoint(New PointF(0, 20), PathPointType.Start), New ShapePoint(New PointF(50, 0), PathPointType.Line), New ShapePoint(New PointF(0, -20), PathPointType.Line), New ShapePoint(New PointF(100, 0), PathPointType.Line), New ShapePoint(New PointF(0, 20), PathPointType.CloseSubpath Or PathPointType.Line) }
Dim contentBrush As New EllipticalGradientBrushObject(New PointF2D(0, 0), 12f, 1f)
contentBrush.StartColor = Color.Green
contentBrush.EndColor = Color.Yellow
shape.Appearance.ContentBrush = contentBrush
shape.Name = "pathNeedle"
needleShape.Add(shape)
End Sub
2. The PolygonShape is based on the polygon. The polygone is defined by the Points property, which is an array of the PointF values. The PolygonShape is used to create complex multi-line shapes with sharp-cut faces.
C#private void CreatePolygonNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
PolygonShape shape = new PolygonShape();
shape.Points = new PointF[] {
new PointF(0, 10),
new PointF(75, 10),
new PointF(70, -5),
new PointF(100, 0),
new PointF(65, -10),
new PointF(70, 5),
new PointF(0, -10)
};
shape.Appearance.ContentBrush = new SolidBrushObject(Color.AliceBlue);
shape.Name = "polygonNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreatePolygonNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New PolygonShape()
shape.Points = New PointF() { New PointF(0, 10), New PointF(75, 10), New PointF(70, -5), New PointF(100, 0), New PointF(65, -10), New PointF(70, 5), New PointF(0, -10) }
shape.Appearance.ContentBrush = New SolidBrushObject(Color.AliceBlue)
shape.Name = "polygonNeedle"
needleShape.Add(shape)
End Sub
3. The PolylineShape is based on series of connected line segments. Lines are specified via the Points property, which is an array of the PointF values. The PolylineShape is used for the same purpose as the PolygonShape.
C#private void CreatePolylineNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
PolylineShape shape = new PolylineShape();
shape.Points = new PointF[] {
new PointF(0, 20), new PointF(-40, 25),
new PointF(20, 5), new PointF(100, 0),
new PointF(20, -5), new PointF(-40, -25),
new PointF(0, -20)
};
shape.Appearance.ContentBrush = new SolidBrushObject(Color.Yellow);
shape.Name = "polylineNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreatePolylineNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New PolylineShape()
shape.Points = New PointF() { New PointF(0, 20), New PointF(-40, 25), New PointF(20, 5), New PointF(100, 0), New PointF(20, -5), New PointF(-40, -25), New PointF(0, -20) }
shape.Appearance.ContentBrush = New SolidBrushObject(Color.Yellow)
shape.Name = "polylineNeedle"
needleShape.Add(shape)
End Sub
4. The BoxShape is based on a rectangle. It can be used along with other shapes as a part of the ComplexShape. The bounds of the BoxShape object can be specified in the constructor, or via the Box property.
C#private void CreateBoxNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
BoxShape shape = new BoxShape(new RectangleF2D(new PointF(-10, 0), new SizeF(100, 10)));
shape.Appearance.ContentBrush = new SolidBrushObject(Color.Gray);
shape.Name = "boxNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreateBoxNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New BoxShape(New RectangleF2D(New PointF(-10, 0), New SizeF(100, 10)))
shape.Appearance.ContentBrush = New SolidBrushObject(Color.Gray)
shape.Name = "boxNeedle"
needleShape.Add(shape)
End Sub
5. The EllipseNeedle is based on an ellipse, and can be used as a part of the ComplexShape. The ellipse bounds can be specified in the constructor, or via the Box property.
C#private void CreateEllipseNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
EllipseShape shape = new EllipseShape(new RectangleF2D(new PointF(-10, 0), new SizeF(100, 10)));
LinearGradientBrushObject brush = new LinearGradientBrushObject(new PointF2D(2, 0), new PointF2D(0, 2));
brush.StartColor = Color.Yellow;
brush.EndColor = Color.Magenta;
shape.Appearance.ContentBrush = brush;
shape.Name = "ellipseNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreateEllipseNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New EllipseShape(New RectangleF2D(New PointF(-10, 0), New SizeF(100, 10)))
Dim brush As New LinearGradientBrushObject(New PointF2D(2, 0), New PointF2D(0, 2))
brush.StartColor = Color.Yellow
brush.EndColor = Color.Magenta
shape.Appearance.ContentBrush = brush
shape.Name = "ellipseNeedle"
needleShape.Add(shape)
End Sub
6. The ArcShape represents an arc with connected endpoints. It can be used as a part of the ComplexShape. The ellipse bounds, start and end angles can be specified in the constructor, or via the Box, StartAngle and EndAngle properties.
C#private void CreateArcNeedle(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
ArcShape shape = new ArcShape(new RectangleF2D(new PointF(-10, 0), new SizeF(20, 10)), 180, -60);
shape.Appearance.ContentBrush = new SolidBrushObject(Color.White);
shape.Name = "arcNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreateArcNeedle(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New ArcShape(New RectangleF2D(New PointF(-10, 0), New SizeF(20, 10)), 180, -60)
shape.Appearance.ContentBrush = New SolidBrushObject(Color.White)
shape.Name = "arcNeedle"
needleShape.Add(shape)
End Sub
7. The PieShape represents a pie figure. It can be used as a part of the ComplexShape. Its bounds and angles can be specified in the constructor, or via the Box, StartAngle, and EndAngle properties.
C#private void CreatePieShape(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
PieShape shape = new PieShape(new RectangleF2D(new PointF(0, 30), new SizeF(80, 10)), 40, 270);
shape.Appearance.ContentBrush = new SolidBrushObject(Color.Blue);
shape.Name = "pieNeedle";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreatePieShape(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New PieShape(New RectangleF2D(New PointF(0, 30), New SizeF(80, 10)), 40, 270)
shape.Appearance.ContentBrush = New SolidBrushObject(Color.Blue)
shape.Name = "pieNeedle"
needleShape.Add(shape)
End Sub
8. The SectorShape represents a sector figure. In can be used as a part of the ComplexShape. The bounds and angles are specified in the constructor, or can be assigned via the Box, StartAndle and EndAngle properties.
C#private void CreateSectorShape(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
SectorShape shape = new SectorShape(new RectangleF2D(new PointF(0, 30), new SizeF(80, 10)), 40, 270);
shape.Appearance.ContentBrush = new SolidBrushObject(Color.Red);
shape.Name = "sectorShape";
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreateSectorShape(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New SectorShape(New RectangleF2D(New PointF(0, 30), New SizeF(80, 10)), 40, 270)
shape.Appearance.ContentBrush = New SolidBrushObject(Color.Red)
shape.Name = "sectorShape"
needleShape.Add(shape)
End Sub
9. The TextShape represents some text. The text is assigned via the Text properties. Its bounds are assigned via the Box property. The text settings can be modified via the AppearanceText property.
C#private void CreateTextShape(INeedle needle) {
ComplexShape needleShape = (ComplexShape)needle.Shape;
needleShape.Collection.Clear();
TextShape shape = new TextShape();
shape.Box = new RectangleF2D(new PointF(-10, 0), new SizeF(100, 10));
shape.Text = " > > > > > ";
shape.AppearanceText.TextBrush = new SolidBrushObject(Color.Salmon);
needleShape.Add(shape);
}
Visual BasicPrivate Sub CreateTextShape(ByVal needle As INeedle)
Dim needleShape As ComplexShape = CType(needle.Shape, ComplexShape)
needleShape.Collection.Clear()
Dim shape As New TextShape()
shape.Box = New RectangleF2D(New PointF(-10, 0), New SizeF(100, 10))
shape.Text = " > > > > > "
shape.AppearanceText.TextBrush = New SolidBrushObject(Color.Salmon)
needleShape.Add(shape)
End Sub