Search code examples
c#winformsgraphline

graph line (X,Y,Z) control


Hello I am searching for a graph that will allow me to make Z Line Graph control now I have X (Payment_Date) & Y (collected) line how to make Z (username) line I want every username to have his line alone

Can someone help me?

I want to make the program on normal C# win form application

My Form My Form

SqlDataReader reader = sqlcomm.ExecuteReader();
                    DataTable sd = new DataTable();
                    sd.Load(reader);
                    dataGridView1.DataSource = sd;
                    reader.Close();



                    chart1.Series["collected"].XValueMember = "Payment_Date";
                    chart1.Series["collected"].XValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Date;
                    chart1.Series["collected"].YValueMembers = "collected";
                    chart1.Series["collected"].YValueType = System.Windows.Forms.DataVisualization.Charting.ChartValueType.Int32;
                    chart1.DataSource = sd;
                    chart1.DataBind();

enter image description here


Solution

  • Step one: Create a separate BindingSource for each element you want to bind and set an appropriate Filter so it will only display the data of one user each.

    Step two: Show and hide the Series you want to.

    I have created a DataTable dt with 3 columns:

    dt.Columns.Add("User", typeof(string));
    dt.Columns.Add("Date", typeof(DateTime));
    dt.Columns.Add("Value", typeof(double));
    

    and filled it randomly. Next I pull out the distinct users:

    var users = dt.Rows.Cast<DataRow>()
                      .Select(x => x.Field<string>("User"))
                      .Distinct()
                      .OrderBy(x => x)
                      .ToList();
    

    Most likely you will reverse this and start with a list of users.

    Now I create a Series with its own filtered BindingSource for each user:

    for (int i = 0; i < users.Count; i++)
    {
        Series s = chart1.Series.Add(users[i]);
        s.ChartType = SeriesChartType.Line;
        BindingSource bs = new BindingSource();
        bs.DataSource = dt;
        bs.Filter = "User='" + users[i] + "'";
        s.Points.DataBindXY(bs, "Date", bs, "Value");
    }
    

    Now I bind my DGV:

    BindingSource bsdgv = new BindingSource();
    bsdgv.DataSource = dt;
    bsdgv.Filter = "";
    dataGridView1.DataSource = bsdgv;
    

    I have hidden the Series by making them Transparent. This way the names still show in the Legend. The trick is to keep the original colors in the Series' Tags..:

    void hideAllSeries(Chart chart)
    {
        chart.ApplyPaletteColors();
        foreach (Series s in chart.Series)
        {
            if (s.Color != Color.Transparent) s.Tag = s.Color;
            s.Color = Color.Transparent;
        }
    }
    

    To show or hide a Series I code the MouseClick event:

    private void Chart1_MouseClick(object sender, MouseEventArgs e)
    {
        var hitt = chart1.HitTest(e.X, e.Y);
        if (hitt.ChartElementType == ChartElementType.LegendItem)
        {
            Series s = hitt.Series;
            if (s.Color == Color.Transparent)
            {
                s.Color = (Color)s.Tag;
            }
            else
            {
                s.Tag = s.Color;
                s.Color = Color.Transparent;
            }
        }
    }
    

    Let's see it at work:

    enter image description here

    Instead of this solution you may want to add a User selection Checklist and set the DGV's BindingSource's Filter..