Search code examples
c#mysqlmschart

RangeChart Axis repeating data


As per the image, I would like for the entries that are the same to be on the same line instead of being seperated. I think I need to create different series for each entry but being new at this, I have no idea on how to do this. So far, I have one series created as shown. If you could help me out with some code, it would be greatly appreciated. Here is the code I have:

private void LoadChartData()
    {
        var s = new Series();
        s.ChartType = SeriesChartType.RangeBar;

        chart1.Series.Clear();
        chart1.Series.Add(s);

        s.SetCustomProperty("PixelPointWidth", "25");

        chart1.Series[0].YValueType = ChartValueType.DateTime;
        chart1.ChartAreas[0].AxisY.LabelStyle.Format = "yyyy-MM-dd";
        chart1.ChartAreas[0].AxisY.Interval = 1;
        chart1.ChartAreas[0].AxisY.IntervalType = DateTimeIntervalType.Days;
        chart1.ChartAreas[0].AxisY.IntervalOffset = 1;

        chart1.Series[0].XValueType = ChartValueType.String;
        chart1.ChartAreas[0].AxisY.Minimum = minDate.ToOADate();
        chart1.ChartAreas[0].AxisY.Maximum = maxDate.ToOADate();

        ConnectionStringSettings conSettings = ConfigurationManager.ConnectionStrings["shopmanagerConnectionString1"];
        MySqlConnection con = new MySqlConnection(conSettings.ToString());
        MySqlCommand cmd = new MySqlCommand(@"select * from shopmanager.planning;", con);
        MySqlDataReader myReader;
        try
        {
            con.Open();
            myReader = cmd.ExecuteReader();

            while (myReader.Read())
            {
                //check if machine is "en attente"
                string notPlanned;
                notPlanned = myReader.GetString("machine_name");
                if(notPlanned == "En attente")
                {
                    return;
                }
                else
                {
                    s.LabelForeColor = Color.Black;
                    s.Font = new System.Drawing.Font("Arial", 10f);
                    var start_date = myReader.GetDateTime("predicted_start_date");
                    var predicted_finish_date = myReader.GetDateTime("predicted_delivery");
                    var machine = myReader.GetString("machine_name");
                    int pix = s.Points.AddXY(machine, start_date, predicted_finish_date);
                    s.Points[pix].Label = myReader.GetString("project_number") + " " + myReader.GetString("part_name");
                }
            }
            cmd.Parameters.Clear();
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
        con.Close();

    }

enter image description here


Solution

  • Your problem comes from adding the x-values as strings. This is a common mistake, especially since at first all looks well. Also since one sometimes simply has no numeric values; your machines have names, cities are not numbers and IDs may or may not be numeric. People's names never are etc.. so there are many reasons why one would add non-numeric x-values.

    But they are only added to the automatic labels, the actual x-values all are 0 and therefore cannot be grouped correctly or used for other things. This may or may not be a problem. You need grouping so here it is a problem!

    So, if you have no numbers you can use, you must make some up.

    Here is an example that stuffs all (new) names into a Dictionary as Keys and adds their index as a numeric Value:

    // maybe best at class level
    Dictionary<string, int> machines = new Dictionary<string, int>();
    
    
    // your reading loop here..
       ..
       string machine = ..// your retrieval code here
       if (!machines.ContainsKey(machine) ) machines.Add(machine, machines.Count);
       // now add the point:
       int px = yourSeries.Points.AddXY(machines[machine], yourYvalue1, yourYvalue2);
       yourSeries.Points[px].AxisLabel = machine;
       ..
    // loopend