Из ваших комментариев я понимаю, что вы хотите иметь диаграмму со свободно размещенными, незаполненными прямоугольниками и метками.
Ни один из типов 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;
Теперь мыдобавьте свои пять коробок.Я использую специальную функцию, которая добавляет точки и вставляет размер блока в 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;
}