在MSChart中的StackedBar100上折叠条形之间的空间

时间:2014-02-08 22:30:59

标签: c# .net charts mschart

基本上我必须在堆积条形图上显示条形行。每个问题都会有一个问题。如果有国家分数或竞争者分数可用,每个问题可选择额外的一两个。

我的问题是演讲。我希望将条形图放在相对于问题标签的中央位置,或者如果不存在国家或竞争对手的分数,则删除间隙。

也许照片会有所帮助:

Charts

我快速将一个例子(生成上面的图片)放到一个MVC项目中。这些是文件:

Index.cshtml

<h2>Attempt 2</h2>
<img src="/Home/StackedBar100" />
<h2>Attempt 1</h2>
<img src="/Home/StackedBar100_FirstAttempt" />

HomeController.cs

<!-- language: c# -->
public class HomeController : Controller
{
    List<Color> colors = new List<Color>();
    string[] rows = new string[] { "Q1", "Q2", "Q3", "Q4" };
    string[] stackTypes = new string[] { "National", "Value", "Competitor" };
    Color[] stackColors = new Color[] { Color.White, Color.Green, Color.Orange };

    protected override void Initialize(RequestContext requestContext)
    {
        // Set up bands of colours for testing purposes.
        int diff = (255 - 20) / 10;
        for (int c = 10; c > 0; c--)
        {
            colors.Add(Color.FromArgb(0, (c * diff) + 10, 0));
        }

        base.Initialize(requestContext);
    }

    public ActionResult Index()
    {
        return View();
    }

    public ActionResult StackedBar100()
    {
        var chart = new Chart();
        var chartArea = new ChartArea("Default");
        chart.ChartAreas.Add(chartArea);
        chart.Width = 640;
        chart.Height = 480;

        var r = new Random();
        for (int s = 0; s < stackTypes.Count(); s++)
        {
            var stack = stackTypes[s];
            var stackColor = stackColors[s];
            {
                for (int i = 1; i <= 10; i++)
                {
                    var series = new Series(stack + i.ToString());
                    series.ChartType = SeriesChartType.StackedBar100;
                    series.Color = colors[i - 1];
                    series.BorderColor = stackColor;
                    series["StackedGroupName"] = stack;
                    series["DrawSideBySide"] = "true";
                    series.IsValueShownAsLabel = true;
                    series.LabelForeColor = Color.White;
                    chart.Series.Add(series);
                }
            }
        }

        var dt = CreateData();

        foreach (DataRow row in dt.Rows)
        {
            var question = row["Question"];
            var stack = row["Stack"];
            var hidden = Convert.ToBoolean(row["Hidden"]);
            var ks = "";
            for (int k = 1; k <= 10; k++)
            {
                ks = k.ToString();
                chart.Series[stack + ks].Points.AddXY(question, row[ks]);
                if (hidden)
                {
                    chart.Series[stack + ks].Points.Last().IsEmpty = true;
                }
                else if ((row[ks] as double?) < 3)
                {
                    chart.Series[stack + ks].Points.Last().IsValueShownAsLabel = false;
                }
            }
        }
        return ReturnChartAsImage(chart);
    }

    private DataTable CreateData()
    {
        var r = new Random();
        var dt = new DataTable("Chart Data");
        dt.Columns.Add("Question", typeof(string));
        dt.Columns.Add("Stack", typeof(string));
        dt.Columns.Add("Hidden", typeof(string));
        for (int i = 1; i <= 10; i++)
        {
            dt.Columns.Add(i.ToString(), typeof(double));
        }

        foreach (var row in rows.OrderByDescending(rw => rw))
        {
            foreach (var stack in stackTypes)
            {
                if (
                  (stack == "Value") && row != "Q4" ||
                  (stack == "National" && (row == "Q2" || row == "Q4")) ||
                  (stack == "Competitor" && (row == "Q3" || row == "Q4")))
                {
                    var dr = dt.NewRow();
                    dr["Question"] = row;
                    dr["Hidden"] = false;
                    dr["Stack"] = stack;

                    for (int k = 1; k <= 10; k++)
                    {

                        dr[k.ToString()] = r.NextDouble() * 10;
                    }
                    dt.Rows.Add(dr);
                }
                else
                {
                    var dr = dt.NewRow();
                    dr["Question"] = row;
                    dr["Stack"] = stack;
                    dr["Hidden"] = true;
                    dt.Rows.Add(dr);
                }
            }
        }
        dt.WriteXml(@"c:\Users\chris_000\Desktop\1.xml");
        return dt;
    }

    public ActionResult StackedBar100_FirstAttempt()
    {
        var chart = new Chart();
        var chartArea = new ChartArea("Default");
        chart.ChartAreas.Add(chartArea);
        chart.Width = 640;
        chart.Height = 480;

        for (int i = 1; i <= 30; i++)
        {
            var series = new Series("Series" + i.ToString());
            series.ChartType = SeriesChartType.StackedBar100;
            series.Color = colors[(i - 1) % 10];

            if (i <= 10)
            {
                series["StackedGroupName"] = "Value";
            }
            else if (i > 10 && i <= 20)
            {
                series["StackedGroupName"] = "National";
                series.BorderColor = Color.Green;
            }
            else
            {
                series["StackedGroupName"] = "Competitor";
                series.BorderColor = Color.Orange;
            }

            chart.Series.Add(series);
        }

        var dt = CreateData_FirstAttempt();

        foreach (DataRow row in dt.Rows)
        {
            var question = row["Question"];
            var group = row["Stack"];

            for (int k = 1; k <= 30; k++)
            {
                chart.Series["Series" + k.ToString()].Points.AddXY(question, row[k.ToString()]);
            }
        }

        return ReturnChartAsImage(chart);
    }

    private DataTable CreateData_FirstAttempt()
    {
        var r = new Random();
        var dt = new DataTable("Chart Data");
        dt.Columns.Add("Question", typeof(string));
        dt.Columns.Add("Stack", typeof(string));  // Value, National, Competitor
        for (int i = 1; i <= 30; i++)
        {
            dt.Columns.Add(i.ToString(), typeof(double));
        }

        foreach (var row in rows.OrderByDescending(rw => rw))
        {
            var dr = dt.NewRow();
            dr["Question"] = row;
            dr["Stack"] = "Score";

            for (int k = 1; k <= 30; k++)
            {
                if (k <= 10)
                {
                    if (row != "Q4") 
                    {
                        dr[k.ToString()] = r.NextDouble() * 100;
                    }
                    else
                    {
                        dr[k.ToString()] = DBNull.Value;
                    }
                }
                else if (k > 10 && k <= 20)
                {
                    if (row == "Q2" || row == "Q4")
                    {
                        dr[k.ToString()] = r.NextDouble();
                    }
                    else
                    {
                        dr[k.ToString()] = DBNull.Value;
                    }
                }
                else
                {
                    if (row == "Q3" || row == "Q4")
                    {
                        dr[k.ToString()] = r.NextDouble();
                    }
                    else
                    {
                        dr[k.ToString()] = DBNull.Value;
                    }
                }
            }

            dt.Rows.Add(dr);
        }
        return dt;
    }

    private ActionResult ReturnChartAsImage(Chart chart)
    {
        MemoryStream ms = new MemoryStream();
        chart.SaveImage(ms, ChartImageFormat.Png);
        return File(ms.ToArray(), "image/png");
    }
}

这是一个很长的例子,但显示了在堆积图表上构建多个条形图的两种不同尝试。一个使用30列,但每组分成10列。第二个(更明智的)在他们应该代表的Value,National或Competitor之后命名堆栈。

所以,简而言之,我可以折叠占用的空间但是丢失的系列/酒吧?这是我提供数据的方式吗?

感谢。

0 个答案:

没有答案