Диаграмма: проблема с порядком расположения областей - PullRequest
0 голосов
/ 09 декабря 2018

Я хотел бы отобразить 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 голосов
/ 10 декабря 2018

Из ваших комментариев я понимаю, что вы хотите иметь диаграмму со свободно размещенными, незаполненными прямоугольниками и метками.

Ни один из типов 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 и Maximum для Axes длядержать только правильный размер;Диаграмма не будет делать это сама по себе, поскольку размер в тегах точек неизвестен ...

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...