I need to graph rectangles of different heights and widths in a C# application. The rectangles may or may not overlap.
I thought the System.Windows.Forms.DataVisualization.Charting
would have what I need, but every chart type I've explored wants data points composed of a single value in one dimension and multiple values in the other.
I've considered: Box, Bubble, and Range Bar
.
Here is a minimal example that throws 100 squares of different colors and sizes randomly onto one Chart
of ChartType Point
with custom Marker Images
.
You can modify to de-couple the datapoints from the colors, allow for any sizes or shapes etc..:
int count = 100;
int mSize = 60; // marker size
List<Color> colors = new List<Color>(); // a color list
for (int i = 0; i < count; i++)
colors.Add(Color.FromArgb(255, 255 - i * 2, (i*i) %256, i*2));
Random R = new Random(99);
for (int i = 0; i < count; i++) // create and store the marker images
{
int w = 10 + R.Next(50); // inner width of visible marker
int off = (mSize - w) / 2;
Bitmap bmp = new Bitmap(mSize, mSize);
using (Graphics G = Graphics.FromImage(bmp))
{
G.Clear(Color.Transparent);
G.FillRectangle(new SolidBrush(colors[i]), off, off, w, w);
chart5.Images.Add(new NamedImage("NI" + i, bmp));
}
}
for (int i = 0; i < count; i++) // now add a few points to random locations
{
int p = chart5.Series["S1"].Points.AddXY(R.Next(100), R.Next(100));
chart5.Series["S1"].Points[p].MarkerImage = "NI" + p;
}
Note that this is really just a quick one; in the Link to the original answer about a heat map I show how to resize the Markers
along with the Chart
. Here they will always stay the same size..:
I have lowered the Alpha of the colors for this image from 255 to 155, btw.
The sizes also stay fixed when zooming in on the Chart
; see how nicely they drift apart, so you can see the space between them:
This may or may not be what you want, of course..
Note that I had disabled both Axes
in the first images for nicer looks. For zooming I have turned them back on so I get the simple reset button..
Also note that posting the screenshots here introduces some level of resizing, which doesn't come from the chart!
It turns out that Richard Eriksson has the closest answer in that the Charting package doesn't contain what I needed. The solution I'm moving forward with is to use a Point chart to manage axes and whatnot, but overload the PostPaint event to effectively draw the rectangles I need on top. The Chart provides value-to-pixel (and vice versa) conversions.