C# 图表:堆叠区域顺序的问题

C# 图表:堆叠区域顺序的问题,c#,winforms,charts,stacked-area-chart,C#,Winforms,Charts,Stacked Area Chart,我想根据其参数显示2个不同的堆叠区域元素。但图表区域未按指定显示,并将第二个块放置在第一个堆叠区域的右上角。它们应该并排展示,而不是堆叠 ... using System.Windows.Forms.DataVisualization.Charting; namespace Gantt_Tool { public partial class ReadModel : Form { public ReadModel() { InitializeComponent()

我想根据其参数显示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;    
    }
}    

我如何设置块并排排列或自由放置?如何得到未填充的矩形

更新:下面是一个示例,说明它应该是什么样子:


从您的评论中,我认为您想要一个带有自由放置、未填充矩形和标签的图表

没有一种
MSChart
类型会这样做

下面是如何使用带有几行所有者图纸的
图表。请注意,调整图表大小时,这将表现得多么好

以下是设置:

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;
现在我们加上你的五个盒子。我使用一个特殊的功能,将点添加到每个点的
标签中,并将框大小填充到每个点的

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;
}
图纸也很简单;只有
功能
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);
            }
        }
}

如果您不想堆叠区域,为什么选择stackedarea???使用面积代替!我想把这些区域堆放起来。如果您查看图像,它将堆叠在(2,2)处,而不是实际预期的(2,0)处。但“堆叠”表示序列>0的点放置在前一序列点的顶部。它们的y值不是位置,而是高度。如果x值不一致,如您的情况,点/区域将被置换。是否有不同的系列图表类型,可能由四个点/参数组成,这让我可以显示矩形,而不是像面积图类型一样。因为面积图类型填充了两个数据点指定的框的整个空间。实际上,像StackedArea这样的面积只会绘制填充区域,不一定是矩形。不幸的是,当绘制边框时,它只会绘制顶线,因此,选择一个透明的颜色加上一个边框是没有帮助的。对于未填充的矩形,最好的方法是在PaintXXX事件中绘制它们。如果你愿意,我可以给你举个例子。。像往常一样,对于图表问题,理想结果的图像将非常有用。我曾尝试在我的项目中实现您的代码,但无法正确执行。似乎每种方法都很有效,只是chart2_Postpaint-method不起作用。此方法如何调用或在何处调用?Chart将在需要重新绘制自身时调用它。它叫什么名字?(使用调试器?)?
private void setMinMax(Chart chart, ChartArea ca)
{
    var allPoints = chart.Series.SelectMany(x => x.Points);
    double minx = allPoints.Select(x => x.XValue).Min();
    double miny = allPoints.Select(x => x.YValues[0]).Min();
    double maxx = allPoints.Select(x => x.XValue + ((SizeF)x.Tag).Width).Max();
    double maxy = allPoints.Select(x => x.YValues[0] + ((SizeF)x.Tag).Height).Max();

    ca.AxisX.Minimum = minx;
    ca.AxisX.Maximum = maxx;
    ca.AxisY.Minimum = miny;
    ca.AxisY.Maximum = maxy;
}