Title: Graph points in WPF and C#
This example extends the previous example Draw a graph in WPF and C# to draw ellipses marking the data sets' points. See that example for an explanation of how most of the program works.
The following code shows how the program draws its data sets. Scroll down to the blue lines to see the code that is used to graph points.
// Draw a simple graph.
private void Window_Loaded(object sender, RoutedEventArgs e)
{
const double margin = 10;
double xmin = margin;
double xmax = canGraph.Width - margin;
double ymin = margin;
double ymax = canGraph.Height - margin;
const double step = 10;
// Make the X axis.
GeometryGroup xaxis_geom = new GeometryGroup();
xaxis_geom.Children.Add(new LineGeometry(
new Point(0, ymax), new Point(canGraph.Width, ymax)));
for (double x = xmin + step; x <= canGraph.Width - step; x += step)
{
xaxis_geom.Children.Add(new LineGeometry(
new Point(x, ymax - margin / 2),
new Point(x, ymax + margin / 2)));
}
Path xaxis_path = new Path();
xaxis_path.StrokeThickness = 1;
xaxis_path.Stroke = Brushes.Black;
xaxis_path.Data = xaxis_geom;
canGraph.Children.Add(xaxis_path);
// Make the Y ayis.
GeometryGroup yaxis_geom = new GeometryGroup();
yaxis_geom.Children.Add(new LineGeometry(
new Point(xmin, 0), new Point(xmin, canGraph.Height)));
for (double y = step; y <= canGraph.Height - step; y += step)
{
yaxis_geom.Children.Add(new LineGeometry(
new Point(xmin - margin / 2, y),
new Point(xmin + margin / 2, y)));
}
Path yaxis_path = new Path();
yaxis_path.StrokeThickness = 1;
yaxis_path.Stroke = Brushes.Black;
yaxis_path.Data = yaxis_geom;
canGraph.Children.Add(yaxis_path);
// Make some data sets.
Brush[] brushes = { Brushes.Red, Brushes.Green, Brushes.Blue };
Random rand = new Random();
for (int data_set = 0; data_set < 3; data_set++)
{
int last_y = rand.Next((int)ymin, (int)ymax);
PointCollection points = new PointCollection();
for (double x = xmin; x <= xmax; x += step)
{
last_y = rand.Next(last_y - 10, last_y + 10);
if (last_y < ymin) last_y = (int)ymin;
if (last_y > ymax) last_y = (int)ymax;
points.Add(new Point(x, last_y));
}
Polyline polyline = new Polyline();
polyline.StrokeThickness = 1;
polyline.Stroke = brushes[data_set];
polyline.Points = points;
canGraph.Children.Add(polyline);
// Display ellipses at the points.
const float width = 4;
const float radius = width / 2;
foreach (Point point in points)
{
Ellipse ellipse = new Ellipse();
ellipse.SetValue(Canvas.LeftProperty, point.X - radius);
ellipse.SetValue(Canvas.TopProperty, point.Y - radius);
ellipse.Fill = brushes[data_set];
ellipse.Stroke = brushes[data_set];
ellipse.StrokeThickness = 1;
ellipse.Width = width;
ellipse.Height = width;
canGraph.Children.Add(ellipse);
}
}
}
The blue lines of code loop through a data set's points. For each point, the code creates a new Ellipse object. It uses the SetValue method to set the Left and Top dependency properties provided by the Canvas control that will contain the Ellipse. If you create an Ellipse in the Window Designer, those properties appear in the Properties window as Canvas.Left and Canvas.Top.
The code then fills in the Ellipse object's other properties such as its Fill color, Stroke color, StrokeThickness, Width, and Height. The loop finishes by adding the Ellipse to the Canvas control's Children collection.
Download the example to experiment with it and to see additional details.
|