在c# winforms中,是否可以匹配图表中来自两个不同数据集的两个数据系列

jdgnovmf  于 2023-01-14  发布在  C#
关注(0)|答案(2)|浏览(182)

我正在开发一个应用程序,用于根据工作订单号绘制已检查电路板和有缺陷电路板的图表。在查看图表并比较实际数据后,我意识到系列与工作订单号不匹配。我不知道如何将两个系列与工作订单号匹配以获得正确的图表。
下面是我的代码,用于首先提取数据Boards_Inspected

public DataSet Get_Boards_Inspected(string startDate, string endDate, int location)
    {
        DataSet ds = new DataSet();

        NpgsqlConnection conn = DatabaseConnection.getConnectionString();
        try
        {
            conn.Open();
            NpgsqlDataAdapter da = new NpgsqlDataAdapter("select new_table.top_or_bottom, new_table.board_wo_number, count(new_table.board_serial_number) from" +
            " (select distinct master_board.board_serial_number, board_wo.board_wo_number,board_wo.board_part_number, board_time.top_or_bottom from master_board" +
            " inner join board_time on board_time.board_time_id = master_board.id" +
            " inner join board_wo on board_wo.board_wo_number = master_board.board_wo_number" +
            " where time_in between '" + startDate + "' and '" + endDate + "'" +
            " and board_time.location_id = '" + location + "')" +
            " as new_table" +
            " group by new_table.top_or_bottom, new_table.board_wo_number" +
            " order by top_or_bottom;", conn);
            ds.Reset();
            da.Fill(ds);
            da.Dispose();
        }
        catch (Exception ex)
        {
            MessageBox.Show("An unexpected error has occured with the application. \n" +
            "An email has been sent to the software developer for analysis. \n" +
            "this program will now close.", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            eMessageBody = ex.ToString();
            Mail sendMessage = new Mail();
            sendMessage.SendSMTP(eMessageBody, eMessageSubject);
            Application.Exit();
        }
        finally
        {
            conn.Close();
        }
        return ds;
    }

有缺陷的板

public DataSet Get_Boards_With_Issue(string startDate, string endDate, int location)
    {
        DataSet ds = new DataSet();
        NpgsqlConnection conn = DatabaseConnection.getConnectionString();
        try
        {
            conn.Open();
            NpgsqlDataAdapter da = new NpgsqlDataAdapter("select new_table.top_or_bottom, new_table.board_wo_number, count(new_table.defect_id) from" +
            " (select distinct defect_id, top_or_bottom, board_wo_number from defect" +
            " inner join master_board on defect.defect_id = master_board.id" +
            " where defect_time between '" + startDate + "' and '" + endDate + " 23:59:59'" +
            " and location_id = '" + location + "')" +
            " as new_table" +
            " group by new_table.top_or_bottom, new_table.board_wo_number" +
            " order by top_or_bottom;", conn);

            ds.Reset();
            da.Fill(ds);
            da.Dispose();
        }
        catch(Exception ex)
        {
            MessageBox.Show("An unexpected error has occured with the application. \n" +
            "An email has been sent to the software developer for analysis. \n" +
            "this program will now close.", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            eMessageBody = ex.ToString();
            Mail sendMessage = new Mail();
            sendMessage.SendSMTP(eMessageBody, eMessageSubject);
            Application.Exit();
        }
        finally
        {
            conn.Close();
        }
        return ds;
    }

这是我的图表系列分配代码

private void Boards_Without_Issue_Chart(string starDate, string endDate, int location)
    {
        try
        {
            #region Chart Setup
            chart1.Series.Clear();
            chart1.Series.Add("Boards Inspected");
            chart1.Series.Add("Boards Without Issue");
            chart1.Series.Add("Boards With Issue");

            chart1.Series["Boards Inspected"].Points.Clear();
            chart1.Series["Boards Without Issue"].Points.Clear();
            chart1.Series["Boards With Issue"].Points.Clear();

            chart1.Series["Boards Inspected"]["LabelStyle"] = "Top";
            chart1.Series["Boards Without Issue"]["LabelStyle"] = "Top";
            chart1.Series["Boards With Issue"]["LabelStyle"] = "Top";

            chart1.ChartAreas[0].AxisX.Interval = 1;
            chart1.Series["Boards Inspected"].ChartType = SeriesChartType.Column;
            chart1.Series["Boards Without Issue"].ChartType = SeriesChartType.Column;
            chart1.Series["Boards With Issue"].ChartType = SeriesChartType.Column;

            chart1.Series["Boards Inspected"]["DrawingStyle"] = "LightToDark";
            chart1.Series["Boards Without Issue"]["DrawingStyle"] = "LightToDark";
            chart1.Series["Boards With Issue"]["DrawingStyle"] = "LightToDark";

            if (chart1.Titles.Contains(t1))
            {
                t1.Font = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
                t1.Text = titleText + " - Boards Without Issue - (" + startDate + " - " +endDate+ ")";
            }
            else
            {
                t1.Name = "tTitle1";
                t1.Font = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
                t1.Text = titleText + " - Boards Without Issue - (" + startDate + " - " + endDate + ")";
                chart1.Titles.Add(t1);
            }

            chart1.ChartAreas[0].BorderDashStyle = ChartDashStyle.Solid;
            chart1.ChartAreas[0].AxisX.MajorGrid.LineWidth = 0;
            chart1.ChartAreas[0].AxisY.TitleFont = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
            chart1.ChartAreas[0].AxisY.Title = "Amount of Boards";
            chart1.ChartAreas[0].AxisX.TitleFont = new System.Drawing.Font("Microsoft Sans serif", 14, FontStyle.Bold);
            chart1.ChartAreas[0].AxisX.Title = "Work Order";
            chart1.ChartAreas[0].AxisX.LabelStyle.Angle = -45;
            chart1.ChartAreas[0].AxisX.LabelStyle.Font = new System.Drawing.Font("Microsoft Sans serif", 12, FontStyle.Regular);
            chart1.Series["Boards Inspected"].IsValueShownAsLabel = true;
            chart1.Series["Boards With Issue"].IsValueShownAsLabel = true;

            #endregion

            #region Chart Data Assignment
            DataAccess DA = new DataAccess();
            DataAccess DA2 = new DataAccess();
            DataSet mda = new DataSet();
            if ((DA.Get_Boards_Inspected(startDate, endDate, location).Tables[0].Rows.Equals(0)) && 
                (DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables[0].Rows.Equals(0)))
                lblError.Text = "No information Availiable";
            else
            {
                foreach (DataTable tb in DA.Get_Boards_Inspected(startDate, endDate, location).Tables)
                {
                    foreach (DataRow dr in tb.Rows)
                    {
                        object tpn = dr["top_or_bottom"];
                        var ct = (dr["count"].ToString());
                        var wo = (dr["board_wo_number"].ToString());

                        if (tpn == DBNull.Value)
                            chart1.Series["Boards Inspected"].Points.AddXY(wo, ct);
                        else
                            chart1.Series["Boards Inspected"].Points.AddXY(wo + " - " + tpn, ct);
                    }
                }
                DA.Get_Boards_Inspected(startDate, endDate, location).Clear();
                DA.Get_Boards_Inspected(startDate, endDate, location).Dispose();

                foreach (DataTable tb2 in DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables)
                {
                    foreach (DataRow dr2 in tb2.Rows)
                    {
                        object tpn2 = dr2["top_or_bottom"];
                        var ct = (dr2["count"].ToString());
                        var wo = (dr2["board_wo_number"].ToString());

                        if (tpn2 == DBNull.Value)
                            chart1.Series["Boards With Issue"].Points.AddXY(wo, ct);
                        else
                            chart1.Series["Boards With Issue"].Points.AddXY(wo + " - " + tpn2, ct);
                    }
                }
                DA2.Get_Boards_With_Issue(startDate, endDate, location).Clear();
                DA2.Get_Boards_With_Issue(startDate, endDate, location).Dispose();
            }

            #endregion
        }
        catch(Exception ex)
        {
            MessageBox.Show("An unexpected error has occured with the application. \n" +
            "An email has been sent to the software developer for analysis. \n" +
            "this program will now close.", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            eMessageBody = ex.ToString();
            Mail sendMessage = new Mail();
            sendMessage.SendSMTP(eMessageBody, eMessageSubject);
            Application.Exit();
            MessageBox.Show(ex.ToString());
        }
    }

编辑:下面是图表数据的代码

DataAccess DA = new DataAccess();
            DataAccess DA2 = new DataAccess();
            DataSet mda = new DataSet();
            if ((DA.Get_Boards_Inspected(startDate, endDate, location).Tables[0].Rows.Equals(0)) && 
                (DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables[0].Rows.Equals(0)))
                lblError.Text = "No information Availiable";
            else
            {
                foreach (DataTable tb in DA.Get_Boards_Inspected(startDate, endDate, location).Tables)
                {
                    foreach (DataRow dr in tb.Rows)
                    {
                        object tpn = dr["top_or_bottom"];
                        var ct = (dr["count"].ToString());
                        var wo = (dr["board_wo_number"].ToString());

                        if (tpn == DBNull.Value)
                            chart1.Series["Boards Inspected"].Points.AddXY(wo, ct);
                        else
                            chart1.Series["Boards Inspected"].Points.AddXY(wo + " - " + tpn, ct);
                    }
                }
                DA.Get_Boards_Inspected(startDate, endDate, location).Clear();
                DA.Get_Boards_Inspected(startDate, endDate, location).Dispose();

                foreach (DataTable tb2 in DA2.Get_Boards_With_Issue(startDate, endDate, location).Tables)
                {
                    foreach (DataRow dr2 in tb2.Rows)
                    {
                        object tpn2 = dr2["top_or_bottom"];
                        var ct = (dr2["count"].ToString());
                        var wo = (dr2["board_wo_number"].ToString());

                        if (tpn2 == DBNull.Value)
                            chart1.Series["Boards With Issue"].Points.AddXY(wo, ct);
                        else
                            chart1.Series["Boards With Issue"].Points.AddXY(wo + " - " + tpn2, ct);
                    }
                }
                DA2.Get_Boards_With_Issue(startDate, endDate, location).Clear();
                DA2.Get_Boards_With_Issue(startDate, endDate, location).Dispose();

编辑:链接
Both data sets, trying to line them up in a chart
Recent chart

qvk1mo1f

qvk1mo1f1#

这是使用图表控件时的典型错误。
他们似乎做每件事都自动正确,直到你走近一点,碰到问题。
规则是这样的:

    • 所有值、X值和所有Y值都在内部存储为双精度值。**

如果你输入数字,一切都很好。如果你输入任何其他数据类型,你就会在某个地方遇到麻烦。
一开始,所有的东西似乎都起作用了,你输入的东西在标签上显示得很好。
但是当你想使用Chart的任何高级能力时,它很可能不会起作用。
这可以像格式化标签一样简单,它只适用于字符串格式。如果你想使用数字格式,你需要输入数字!
你碰到了在不同的系列中匹配上升点的问题。
您已经将X值作为字符串输入,因此,一旦数据点需要超出添加顺序进行匹配,麻烦就开始了。
你可以按精确的顺序喂它们,但你需要了解会发生什么。
让我们来看看幕后..:如果你使用调试器来查看你的系列数据点的x值,你会惊讶地发现它们都是0!你输入的字符串已经进入了标签,但是这些x值都是转换成double失败的结果,结果是0。这意味着所有的数据点都有相同的x值!
您有两种选择:

  • 或者同步添加它们,所有序列中的点都以相同的顺序和相同的数量。
  • X值使用数字。

您的工作单看起来像一个数字;如果是的话,你可以使用它,如果你想的话,但是它会根据这些数字来展开数据。可能不是一个好主意。相反,你可以为每个工作单分配一个索引,然后使用这个索引。
要创建漂亮的标签,请为每个数据点使用AxisLabel属性!
最简单的方法是先创建一个DataPoint,其中包含值和axislabel,可能还有工具提示和颜色等等,然后将其添加到points集合中。
现在,为了让大家理解这一点,请看下面的图表:

下面是创建它的代码:

private void Form1_Load(object sender, EventArgs e)
{
    Random R = new Random(1);
    List<Tuple<Series, int>> misses = new List<Tuple<Series, int>>();
    chart1.Series.Clear();

    for (int i = 0; i < 3; i++ )
    {
        Series s = new Series("S" + (i + 1));
        s.ChartType = SeriesChartType.Column;
        chart1.Series.Add(s);
    }

    chart1.ChartAreas[0].AxisX.Interval = 1;

    foreach(Series s in chart1.Series)
    {
        for (int i = 0; i < 30; i+=3)
        {
            if (R.Next(3) > 0) s.Points.AddXY(i, i+1);
            else misses.Add(new Tuple<Series, int>(s, i));
        }
    }

    foreach (Tuple<Series, int> m in misses)
    {
        if (m.Item1.Name == "S1") m.Item1.Points.AddXY(m.Item2 + "X", m.Item2 + 5);
        else m.Item1.Points.AddXY(m.Item2, m.Item2 + 5);
    }

    for (int i = 0; i < chart1.Series[0].Points.Count - 1; i++)
    {
        chart1.Series[0].Points[i].AxisLabel = chart1.Series[0].Points[i].XValue + "%";
    }
}

我们来看看发生的事情:
我首先创建三个系列,然后在其中填充几个点。然而,我随机留下几个插槽空。
我将它们存储在一个元组列表中,这样以后就可以乱序地添加它们。
您可以看到,它们都匹配,除了蓝色系列"S1"。
你知道为什么吗?
我总是用一个很好的数字来表示X值,但不用于蓝调系列中的失分,我在数字上附加了一个"X"。
现在也添加了这些点,但它们的X值都为0,因此它们都位于位置0。

    • 注意**:请注意,以上不是您可以使用的代码。它是学习以了解Chart值的数据类型以及添加字符串作为X值的后果的代码!
mklgxw1f

mklgxw1f2#

我想明白了,我首先将数据集更改为数据表,然后在数据表1中创建一个新列,用于保存数据表2中的计数字段,然后循环遍历数据表1中的所有行,循环遍历数据表2,设置一个选择条件以匹配top_or_bottom和board_wo_field,并从数据表2中取出每个匹配项的计数值,然后将它们放入数据表1中。

DataTable dt1 = DA.Get_Boards_Inspected(startDate, endDate, location);
                DataTable dt2 = DA2.Get_Boards_With_Issue(startDate, endDate, location);

                DataColumn newCol = new DataColumn("dcount", typeof(System.Object));
                newCol.AllowDBNull = true;
                dt1.Columns.Add(newCol);
                foreach(DataRow r in dt1.Rows)
                {
                    object wo = (r["board_wo_number"]).ToString();
                    object tp = (r["top_or_bottom"]).ToString();

                    if (tp == "")
                    {
                        foreach (DataRow r1 in dt2.Select("board_wo_number = '" + wo + "'"))
                        {
                            if (r1["count"] == DBNull.Value)
                                r["dcount"] = 0;
                            else
                                r["dcount"] = (r1["count"]);
                        }
                    }
                    else
                    {
                        foreach (DataRow r1 in dt2.Select("board_wo_number = '" + wo + "' and top_or_bottom = '" + tp + "'"))
                        {
                            if (r1["count"] == DBNull.Value)
                                r["dcount"] = 0;
                            else
                                r["dcount"] = (r1["count"]);
                        }
                    }
                }

                foreach (DataRow dr in dt1.Rows)
                {
                    object tpn = (dr["top_or_bottom"]);
                    object ct = (dr["count"]).ToString();
                    object wo = (dr["board_wo_number"]).ToString();
                    object ct2 = (dr["dcount"]).ToString();

                    if (tpn == DBNull.Value)
                    {
                        chart1.Series["Boards Inspected"].Points.AddXY(wo, ct);
                        chart1.Series["Boards With Issue"].Points.AddXY(wo, ct2);
                    }
                    else
                    {
                        chart1.Series["Boards Inspected"].Points.AddXY(wo + " - " + tpn, ct);
                        chart1.Series["Boards With Issue"].Points.AddXY(wo + " - " + tpn, ct2);
                    }
                }

相关问题