具有自动缩放功能的简单绘图算法
我需要在 C# 中实现一个简单的绘图组件(更准确地说是 WPF)。我拥有的是包含时间(X 轴)和值(均为双精度类型)的数据样本集合。
我有一个固定大小(宽度 x 高度)的绘图画布和一个可以在其上绘图的 DrawLine 方法/函数。我现在面临的问题是如何绘制绘图以使其自动缩放?换句话说,如何将我拥有的样本映射到宽度 x 高度画布上的实际像素?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
一种可能有效的黑客方法是使用 Viewbox 控件。该控件将缩放其内容的呈现以适合可用的大小。但是,这可能会导致您的线条和标签看起来太粗或太细。
不过,您可能追求的更明智的方法是如何首先确定以什么比例绘制图表。为此,请计算给定轴上的值范围(例如,Y 轴值的范围可能是从 0 到 100)。计算出该轴上的可用绘图空间(例如,画布的高度可能为 400 像素)。绘制图表时,Y 轴“比例因子”将为
/ <数据范围>
- 或者,在本例中为4
。画布的坐标从左上角的零开始,因此,要计算给定数据点的 Y 位置,您可以这样计算:
plottableY
的值是您要计算的 y 坐标。将用于在画布上绘制该点。(显然,这段代码需要分布在您的绘图方法中,这样您就不会重新计算每个点的所有值,但它演示了数学)。
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:
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).