Display SQL Query result in Stacked Bar Chart with C# and WinForms

47 Views Asked by At

I'm working on a C# WinForms application, and I have a problem creating a stacked bar chart. I have a SQL query that retrieves data related to "Company_Dept", "Category", and "Count". I want to display this data in a stacked bar chart where "Company_Dept" should be used as the x-axis labels, "Category" should be stacked in the bars, and "Count" should be the value for each category.

Here is a sample of my query results:

SELECT Company_Dept, Category, COUNT(*) as Count FROM system_audit_requestor GROUP BY Company_Dept, Category;

enter image description here

Here's the code I'm currently using:

private void LoadSystemAuditPlot()
{
    data.Clear();

    query = "SELECT Company_Dept, Category, COUNT(*) as Count FROM system_audit_requestor GROUP BY Company_Dept, Category";
    SQL.ExecuteCommand(query);
    while (SQL.reader.Read())
    {
        string companyDept = SQL.reader["Company_Dept"].ToString();
        string category = SQL.reader["Category"].ToString();
        int count = Convert.ToInt32(SQL.reader["Count"]);

        if (!data.ContainsKey(companyDept))
        {
            data[companyDept] = new Dictionary<string, int>();
        }

        if (!data[companyDept].ContainsKey(category))
        {
            data[companyDept][category] = count;
        }
        else
        {
            data[companyDept][category] += count;
        }
    }
    SQL.CloseConnections();

    // Locate the chart control by its name (assuming it's named CA_SystemAudit)
    Chart chart = CA_SystemAudit;

    // Clear any existing series
    chart.Series.Clear();

    // Create a StackedColumn series
    Series series = new Series("SystemAuditSeries");
    series.ChartType = SeriesChartType.StackedColumn;

    // Create a data point for each "Company_Dept"
    foreach (var companyDept in data.Keys)
    {
        DataPoint dataPoint = new DataPoint();
        dataPoint.AxisLabel = companyDept;

        // Initialize a dictionary to track the displayed categories for each "Company_Dept"
        Dictionary<string, bool> displayedCategories = new Dictionary<string, bool>();

        // Add data points for each category
        foreach (var categoryData in data[companyDept])
        {
            string category = categoryData.Key;
            int count = categoryData.Value;

            // Check if the category for this "Company_Dept" has been displayed
            if (!displayedCategories.ContainsKey(category))
            {
                dataPoint.SetValueY(count);
                dataPoint.Color = GetCategoryColor(category);

                displayedCategories[category] = true; // Mark the category as displayed
            }
            else
            {
                // Add to the existing data point for the same category
                dataPoint.SetValueY(dataPoint.YValues[0] + count);
            }
        }

        series.Points.Add(dataPoint);
    }

    chart.Series.Add(series);
}

private void Dashboard_Form_Load(object sender, EventArgs e)
{
    data = new Dictionary<string, Dictionary<string, int>>();
    LoadSystemAuditPlot();
}

private Color GetCategoryColor(string category)
{
    switch (category)
    {
        case "Major":
            return System.Drawing.Color.Red;
        case "Minor":
            return System.Drawing.Color.Orange;
        case "Observation":
            return System.Drawing.Color.Yellow;
        default:
            return System.Drawing.Color.Gray; // Default color
    }
}

Can someone please help me modify this code to achieve the desired chart behavior, where all "Company_Dept" values are displayed in the chart, and categories are stacked for each "Company_Dept"?

Desired Output Sample:

enter image description here

I appreciate any assistance or suggestions on how to modify the code to achieve the expected chart behavior.

0

There are 0 best solutions below