图表:堆积面积顺序问题

时间:2018-12-09 13:11:37

标签: c# winforms charts stacked-area-chart

我想根据它们的参数显示2个不同的堆叠区域元素。但是图表区域未按指定显示它,并将第二个块放在第一个堆叠区域的右上角。它们应该并排显示而不是堆叠。

...
using System.Windows.Forms.DataVisualization.Charting;

namespace Gantt_Tool
{
public partial class ReadModel : Form
{
    public ReadModel()
    {
        InitializeComponent();
        CreateChart();
    }

    private void ReadModel_Load(object sender, EventArgs e)
    {            
    }

    private void CreateChart()
    {
        chart1.Series.Add($"a");
        chart1.Series[$"a"].Points.Add(new DataPoint(0, 2));
        chart1.Series[$"a"].Points.Add(new DataPoint(2, 2));
        chart1.Series[$"a"].ChartType = SeriesChartType.StackedArea;

        chart1.Series.Add($"b");
        chart1.Series[$"b"].Points.Add(new DataPoint(2, 3));
        chart1.Series[$"b"].Points.Add(new DataPoint(5, 3));
        chart1.Series[$"b"].ChartType = SeriesChartType.StackedArea;    
    }
}    

https://i.stack.imgur.com/FHuRT.png

如何设置积木并排放置或自由放置?以及如何获得未填充的矩形?

更新:这是一个示例,看起来像这样:

enter image description here

1 个答案:

答案 0 :(得分:2)

根据您的评论,我认为您希望有一个带有自由放置的,未填充的矩形和标签的图表。

MSChart类型中的任何一个都不能做到这一点。

这里是如何使用带有几行所有者绘图的Point图表的方法。请注意,调整图表大小时,这将表现得很好...

enter image description here

这是设置:

Axis ax = chart1.ChartAreas[0].AxisX;
Axis ay = chart1.ChartAreas[0].AxisY;
ax.Maximum = 9;  // pick or calculate
ay.Maximum = 6;  // minimum and..
ax.Interval = 1; // maximum values..
ay.Interval = 1; // .. needed
ax.MajorGrid.Enabled = false;
ay.MajorGrid.Enabled = false;

Series s1 = chart1.Series.Add("A");
s1.ChartType = SeriesChartType.Point;

现在,我们添加您的五个方框。我使用了一个分隔函数,该函数添加点并将框的大小填充到每个点的Tag中。.:

AddBox(s1, 1, 0, 3, 1, "# 1");
AddBox(s1, 2, 1, 2, 2, "# 2");
AddBox(s1, 4, 0, 4, 2, "# 3");
AddBox(s1, 4, 2, 2, 2, "# 4");
AddBox(s1, 4, 4, 1, 1, "# 5");

int AddBox(Series s, float x, float y, float w, float h, string label)
{
    return AddBox(s, new PointF(x, y), new SizeF(w, h), label);
}


int AddBox(Series s, PointF pt, SizeF sz, string label)
{
    int i = s.Points.AddXY(pt.X, pt.Y);
    s.Points[i].Tag = sz;
    s.Points[i].Label = label;
    s.Points[i].LabelForeColor = Color.Transparent;
    s.Points[i].Color = Color.Transparent;
    return i;
}

绘图也很简单;值得注意的是,只有Axes函数ValueToPixelPosition的使用..:

private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
    if (chart1.Series[0].Points.Count <= 0) return;

    Axis ax = chart1.ChartAreas[0].AxisX;
    Axis ay = chart1.ChartAreas[0].AxisY;
    Graphics g = e.ChartGraphics.Graphics;
    using (StringFormat fmt = new StringFormat()
    { Alignment = StringAlignment.Center, 
      LineAlignment = StringAlignment.Center})
        foreach (Series s in chart1.Series)
        {
            foreach (DataPoint dp in s.Points)
            {
            if (dp.Tag == null) break;
            SizeF sz = (SizeF)dp.Tag;
            double vx2 = dp.XValue + sz.Width;
            double vy2 = dp.YValues[0] + sz.Height;
            int x1 = (int)ax.ValueToPixelPosition(dp.XValue);
            int y1 = (int)ay.ValueToPixelPosition(dp.YValues[0]);
            int x2 = (int)ax.ValueToPixelPosition(vx2);
            int y2 = (int)ay.ValueToPixelPosition(vy2);
            Rectangle rect = Rectangle.FromLTRB(x1, y2, x2, y1);

            using (Pen pen = new Pen(s.Color, 2f))
                g.DrawRectangle(pen, rect);
            g.DrawString(dp.Label, Font, Brushes.Black, rect, fmt);
            }
        }
}

这里有些Linq可以计算Minimum的{​​{1}}和Maximum值,使其仅保持正确的大小;图表不会单独执行此操作,因为点标记中的大小未知...

Axes