从可缩放图C#计算 [英] Calculation from Zoomable Graph C#

查看:201
本文介绍了从可缩放图C#计算的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我有一个从DataTable绑定的图,源自DataGridView。我在图形上有可缩放的功能,我需要使用X Axis SelectionStart和SelectionEnd来计算所选数据块。

Basically I have a graph that is bound from a DataTable which source is from a DataGridView. I have zoomable functions on the graph and I need it use X Axis SelectionStart and SelectionEnd in order to calculate the block of data that is selected.

所以我有一些最小值并将平均值放置在另一个选项卡上的richtextbox中。如下面的代码所示:

So I have some minimums maximums and averages placed in a richtextbox on another tab. As shown below in the code:

//To show the Data from file into the TextBox                                                          
        richTextBox1.AppendText("\n" + "Heart Average : " + HRM.Active.DataRows.Average(r => r.HeartRate) + "\n");
        richTextBox1.AppendText("\n" + "Heart Minimum : " + HRM.Active.DataRows.Min(r => r.HeartRate) + "\n");
        richTextBox1.AppendText("\n" + "Heart Maximum : " + HRM.Active.DataRows.Max(r => r.HeartRate) + "\n");
        richTextBox1.AppendText("\n" + "Average Speed (KM/H): " + HRM.Active.DataRows.Average(r => r.Speed) + "\n");
        richTextBox1.AppendText("\n" + "Maximum Speed : " + HRM.Active.DataRows.Max(r => r.Speed) + "\n");
        richTextBox1.AppendText(Environment.NewLine + " - (MPH): " + "");
        richTextBox1.AppendText("\n" + "Average Power: " + HRM.Active.DataRows.Average(r => r.Power) + "\n");
        richTextBox1.AppendText("\n" + "Maximum Power : " + HRM.Active.DataRows.Max(r => r.Power) + "\n");
        richTextBox1.AppendText("\n" + "Average Altitude (KM/H): " + HRM.Active.DataRows.Average(r => r.Altitude) + "\n");
        richTextBox1.AppendText("\n" + "Maximum Altitude : " + HRM.Active.DataRows.Max(r => r.Altitude) + "\n");
        richTextBox1.AppendText("\n" + "Cadence Average : " + HRM.Active.DataRows.Average(r => r.Cadence) + "\n");
        richTextBox1.AppendText("\n" + "Cadence Maximum : " + HRM.Active.DataRows.Max(r => r.Cadence) + "\n");
        richTextBox1.AppendText("\n" + "Pressure Average : " + HRM.Active.DataRows.Average(r => r.Pressure) + "\n");
        richTextBox1.AppendText("\n" + "Pressure Maximum : " + HRM.Active.DataRows.Max(r => r.Pressure) + "\n");

现在在下面的图片中,您可以看到图形的图像及其上显示的数据,以下是将datatable绑定到图形的代码。

Now in the image below you can see the image of the Graph and the data it shows on there, Here is the code which binds the datatable to the graph.

 protected void drawChart()
    {
        DataTable dt = new DataTable();
        dt.Clear();
        foreach (DataGridViewColumn col in dataGridView1.Columns)
        {
            dt.Columns.Add(col.HeaderText);
        }
        foreach (DataGridViewRow row in dataGridView1.Rows)
        {
            DataRow dRow = dt.NewRow();
            foreach (DataGridViewCell cell in row.Cells)
            {
                dRow[cell.ColumnIndex] = cell.Value;
            }
            dt.Rows.Add(dRow);
        }

现在我需要做的是在Graph附近有另一个文本框,每次我放大,灰色块出来,它显示我选择的块的最小值最大值和平均值!然后当我缩小时,它会重新设置为原始的。

Now what I need to do is have another textbox near the Graph and every time I zoom and the grey block comes out it displays the minimums maximiums and averages for the block i have selected! Then when I zoom out it resets to the original.

如果你不明白我的意思只是告诉我,我会给更多的信息。

If you do not understand what I mean just message me and I will give more information.

推荐答案

根据缩放滚动之间的可见更新统计计算您需要知道两件事情:当您执行时,哪些点可见。

To update a statistical calculation based on the visible Points after zooming or scrolling you need know two things: When should you do it and which points are visible.

要使用的事件是 AxisViewChanged ,很简单。挂钩后,您可以调用函数来更新统计信息:

The event to use is AxisViewChanged, that's easy. After you have hooked it up you can call a function to update your statistics:

private void chart1_AxisViewChanged(object sender, ViewEventArgs e)
{
    updateStats();
}

困难的部分是知道点数集合是可见的。

The difficult part is to know which portion of the Points collection is visible.

乍一看,您可能会认为 ViewEventArgs parm帮助毕竟它有如下有希望的数据: NewPosition NewSize

At first glance you may think that the ViewEventArgs parm helps; after all it has such promising data as: NewPosition and NewSize.

但是看得更近你会看到两者都是双打,所以除非你的 XValues 已经从0开始计数按1,它们不会索引到分数集合。

But looking closer you will see that both are doubles, so unless your XValues have been set counting up from 0 by 1, they won't index into the Points collection.

相反,我们必须做一点搜索值,从左到右为最小值,右边为最大值。这是一个这样做的功能:

Instead we must do a little searching for those values, from left for the minimum and from the right for the maximum. Here is a function to do so:

int getVisiblePoint(Chart chart, Series series, bool first)
{
    Series S = series;
    ChartArea CA = chart.ChartAreas[S.ChartArea];
    DataPoint pt = null;
    if (first)  pt = S.Points.Select(x => x)
                                .Where(x => x.XValue >= CA.AxisX.ScaleView.ViewMinimum)
                                .DefaultIfEmpty(S.Points.First()).First();
    else    pt = S.Points.Select(x => x)
                        .Where(x => x.XValue <= CA.AxisX.ScaleView.ViewMaximum)
                        .DefaultIfEmpty(S.Points.Last()).Last();

    return S.Points.IndexOf(pt);
}

从这里,事情变得容易多了;我们可以对我们的系列进行统计,也许是这样的:

From here on things get a lot easier; we can do statistics on our series, maybe like this:

void updateStats()
{
    int firstPt = getVisiblePoint(chart1, chart1.Series[0], true);
    int lastPt = getVisiblePoint(chart1, chart1.Series[0], false);
    int sCount = chart1.Series.Count;
    double[] avg = new double[sCount];
    double[] min = new double[sCount];
    double[] max = new double[sCount];

    for (int i = 0; i < sCount; i++)
    {
        Series S = chart1.Series[i];
        avg[i] = getAverage(S, firstPt, lastPt);
        min[i] = getMixMax(S, firstPt, lastPt, true);
        max[i] = getMixMax(S, firstPt, lastPt, false);
    }
    // insert code to display the data here!
}

使用简单的函数来做数学:

using simple functions to do the math:

double getAverage(Series series, int first, int last)
{
    double sum = 0;
    for (int i = first; i < last; i++) sum += series.Points[i].YValues[0];
    return sum / (last - first + 1);
}

double getMixMax(Series series, int first, int last, bool min)
{
    double val = 0;

    for (int i = first; i < last; i++)
    {
        double v = series.Points[i].YValues[0];
        if ( (min && val > v) || (!min && val >= v)) val = v;
    }
    return val;
}

这篇关于从可缩放图C#计算的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆