【问题标题】:Calculation from Zoomable Graph C#从可缩放图 C# 计算
【发布时间】:2015-05-09 15:41:04
【问题描述】:

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

所以我有一些最小值最大值和平均值放置在另一个选项卡上的富文本框中。如下代码所示:

//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");

现在在下图中,您可以看到图表的图像及其显示的数据,这是将数据表绑定到图表的代码。

 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);
        }

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

如果您不明白我的意思,请给我发消息,我会提供更多信息。

【问题讨论】:

  • 请联系this post。这里解决了一个非常相似的问题。至少如何计算所选/可见点的平均值。 - 在图表中显示它们是另一回事;你可以添加一个自定义图例来显示实时统计数据..
  • 除了在这里寻求更多帮助外,我还有什么其他方式可以联系您吗?.. 更快,因为我还没有聊天功能。
  • 您可以通过在左上角的 stackExchnge 下拉菜单中选择聊天,或重新输入 the old room 来进行聊天(现在)

标签: c# graph datagridview charts axis


【解决方案1】:

要在缩放滚动之后根据可见的Points更新统计计算,您需要知道两件事:何时您应该这样做它和哪些点是可见的。

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

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

困难的部分是要知道Points 集合的哪一部分是可见的。

乍一看,您可能认为ViewEventArgs 参数有帮助;毕竟它有如下有希望的数据:NewPositionNewSize

但仔细观察,您会发现两者都是双精度数,因此除非您的 XValues 已设置为从 0 到 1 计数,否则它们不会索引到 Points 集合中。

相反,我们必须对这些值进行一些搜索,从左侧搜索最小值,从右侧搜索最大值。这是一个这样做的函数:

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);
}

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

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!
}

使用简单的函数进行数学运算:

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;
}

【讨论】:

    猜你喜欢
    • 2017-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 1970-01-01
    • 2012-06-04
    • 2020-09-24
    • 2018-09-04
    相关资源
    最近更新 更多