Reputation: 139
I have a problem with charts in my application. I want to use charts to display histograms of pictures. I want to add a gradient rectangle under chart with colors from black to R/G/B/White, so I draw it as Background Image of each chart. When values on AxisY ar greater then 1k everything is fine, but when those values have less then 4 digits there is a problem screen. Anyone know how to prevent extension of AxisX?
Init charts:
for(int i = 0; i < 3; i++)
{
ca = new ChartArea();
ca.AxisX.Interval = 1D;
ca.AxisX.IntervalOffsetType = System.Windows.Forms.DataVisualization.Charting.DateTimeIntervalType.Number;
ca.AxisX.LabelAutoFitStyle = System.Windows.Forms.DataVisualization.Charting.LabelAutoFitStyles.WordWrap;
ca.AxisX.MajorGrid.Enabled = false;
ca.AxisY.MajorGrid.LineColor = System.Drawing.Color.DarkGray;
ca.BackColor = System.Drawing.Color.Transparent;
ca.BackSecondaryColor = System.Drawing.Color.Transparent;
ca.BorderWidth = 0;
ca.Name = "ChartArea" + i.ToString();
ca.AxisY.LabelAutoFitStyle = LabelAutoFitStyles.DecreaseFont;
ca.AxisX.Minimum = 0;
ca.AxisX.Interval = 256;
ca.AxisY.IntervalAutoMode = IntervalAutoMode.VariableCount;
s = new Series();
s.BorderWidth = 0;
s.ChartArea = "ChartArea" + i.ToString();
s.IsVisibleInLegend = false;
s.Name = "Series" + i.ToString(); ;
s.Color = Colors[i];
s["PointWidth"] = "1";
HistCharts[i] = new Chart();
HistCharts[i].Anchor = AnchorStyles.Top | AnchorStyles.Right;
HistCharts[i].BackColor = Color.Transparent;
HistCharts[i].BackgroundImageLayout = ImageLayout.None;
HistCharts[i].BorderlineWidth = 0;
HistCharts[i].ChartAreas.Add(ca);
HistCharts[i].Location = new System.Drawing.Point(405, (i + 3) * Form.Height / 6 - 28);
HistCharts[i].Name = "Chart" + i.ToString();
HistCharts[i].Series.Add(s);
HistCharts[i].Size = new System.Drawing.Size(297, Form.Height / 6 - 27);
HistCharts[i].TabIndex = 6;
HistCharts[i].Text = "chart" + i.ToString();
HistCharts[i].Visible = false;
HistCharts[i].SendToBack();
}
SetChartImage();
for(int i = 0; i < 3; i++)
HistCharts[i].BackgroundImage = HistImages[i];
Set new series and paint:
if(Hists == null)
{
HistCharts[0].Visible = false;
HistCharts[1].Visible = false;
HistCharts[2].Visible = false;
UpdateStatTimer(Time);
return;
}
HistCharts[0].BackgroundImage = HistImages[Hists.Length > 1 ? 1 : 0];
if(Hists[0].SequenceEqual(Hists[1]) && Hists[0].SequenceEqual(Hists[2]))
{
HistCharts[0].Series[0].Color = Color.Black;
HistCharts[0].BackgroundImage = HistImages[0];
HistCharts[0].Visible = true;
HistCharts[1].Visible = false;
HistCharts[2].Visible = false;
}
else
{
HistCharts[0].Series[0].Color = Color.Red;
HistCharts[0].BackgroundImage = HistImages[1];
HistCharts[0].Visible = true;
HistCharts[1].Visible = true;
HistCharts[2].Visible = true;
}
int Max = 0;
for(int i = 0; i < 3; i++)
{
HistCharts[i].Series[0].Points.Clear();
HistCharts[i].ChartAreas[0].AxisY.Maximum = Double.NaN;
for(int j = 0; j < Hists[i].Length; j++)
HistCharts[i].Series[0].Points.AddXY(j + 0.5, Hists[i][j]);
HistCharts[i].Update();
if(HistCharts[i].ChartAreas[0].AxisY.Maximum > Max)
Max = (int) HistCharts[i].ChartAreas[0].AxisY.Maximum;
}
if(StatisticsItemCheck.Checked == false)
{
for(int i = 0; i < 3; i++)
HistCharts[i].ChartAreas[0].AxisY.Maximum = Max;
}
if all Hists are equal Green and Blue histograms are invisible and Red Histogram becomes GrayScale Histogram
Upvotes: 2
Views: 5278
Reputation: 54433
This is not really about scaling..:
The reason your images don't always align with the Y-Axis is that the Y-Axis legend takes more or less room in various cases. This make the inner plot area move to the right and your carefully aligned image doesn't fit anymore.
When the Y-Axis moves to the right the whole plotarea shrinks, at least if the default vlaues of Auto
are still valid for the various elements..
The simplest workaround is to set the position from Auto
to a fixed value that suits all your data:
chart1.ChartAreas[0].InnerPlotPosition.X = someValue;
Note that all element position values are in percent of the whole chart! So maybe you will want to modify it upon resizing the chart..? As you have noticed, you also have to resize you images..
To find a good value you can use the debugger to see which are the current ones in both of your cases and pick the larger one and then some extra for safety..
In the same veign you may want to get better control over the format, i.e. the number of digits on your y-axis label values, maybe like this..:
chart1.ChartAreas[0].AxisY.LabelStyle.Format = "0.00"; // some formatstring
Update:
To make use of the system's AutoScaling
during(after a resize, you can use this workaround:
First set the Auto
on and copy the resulting Elementposition
. Then use those values to create a new one under control:
int LeftEdge = yourValue;
chart1.ChartAreas[0].InnerPlotPosition.Auto = true;
ElementPosition EP = chart1.ChartAreas[0].InnerPlotPosition;
chart1.ChartAreas[0].InnerPlotPosition =
new ElementPosition(LeftEdge, EP.Y, EP.Height, 100 - LeftEdge);
Upvotes: 1