tags:

views:

61

answers:

1

I need to implement a simple plotting component in C#(WPF to be more precise). What i have is a collection of data samples containing time (X axis) and a value (both double types).

I have a drawing canvas of a fixed size (Width x Height) and a DrawLine method/function that can draw on it. The problem I am facing now is how do I draw the plot so that it is autoscaled? In other words how do I map the samples I have to actual pixels on my Width x Height canvas?

A: 

One hacky method that may work is to use a Viewbox control. This control will scale the rendering of its content to fit the size available. However, this might lead to your lines and labels looking too thick or thin.

The more sensible method that you're probably after, though, is how to work out at what scale to draw your graph at in the first place. To do that, work out the range of values on a given axis (for example, your Y-axis value might range from 0 to 100). Work out the available drawing space on that axis (for example, your canvas might have 400 pixels of height). Your Y-axis "scale factor" when drawing the graph would be <available space> / <data range> - or, in this case, 4.

Your canvas' coordinates start from zero in the top-left so, to calculate the Y-position for a given data point, you would calculate like this:

double availableSpace = 400.0; // the size of your canvas
double dataRange = 100.0;      // the range of your values
double scaleFactor = availableSpace / dataRange;

double currentValue = 42.0;    // the value we're trying to plot
double plottableY = availableSpace - (currentValue * scaleFactor);  // the position on screen to draw at

The value of plottableY is the y-coordinate that you would use to draw this point on the canvas.

(Obviously this code would need to be spread out across your drawing method so you're not recalculating all of the values for each point, but it demonstrates the math).

Dan Puzey