首页 文章

图表:堆积区域订单的问题

提问于
浏览
1

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

如何将块设置为并排或自由放置?我怎样才能得到未填充的矩形?

更新:以下是它应该如何显示的示例:

1 回答

  • 2

    根据您的评论,我认为您想要一张图表,其中包含可自由放置,未填充的矩形和标签 .

    MSChart 类型都不会这样做 .

    以下是如何使用带有几行所有者绘图的 Point 图表 . 请注意在调整图表大小时这会有多好...

    这是设置:

    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;
    

    现在我们添加你的五个盒子 . 我使用了一个sepcial函数,它将点大小添加到每个点的 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 chart2_PostPaint(object sender, ChartPaintEventArgs e)
    {
        if (chart2.Series[0].Points.Count <= 0) return;
    
        Axis ax = chart2.ChartAreas[0].AxisX;
        Axis ay = chart2.ChartAreas[0].AxisY;
        Graphics g = e.ChartGraphics.Graphics;
        using (StringFormat fmt = new StringFormat()
        { Alignment = StringAlignment.Center, 
          LineAlignment = StringAlignment.Center})
            foreach (Series s in chart2.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 来计算 AxesMinimumMaximum 值,以保持正确的大小;图表不会自行完成,因为点的标签中的大小是未知的...

    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;
    }
    

相关问题