There are lots of solutions available for fully overlapping, stacked, or side-by-side. But partially overlapping seemed to be missing from all of the posts I found. Very few people were even asking the question of how to do it, although I did find one post that never got answered.
After much searching, and hours of trying different solutions, I finally found a post that gave me some added information regarding Chart Areas that I was missing. However, this post cautioned that if one chart area had tick marks and labels while another did not then there was no way to get the axis lines to match up. Considering I ended up being successful in my endeavours I am not entirely sure what that comment was referring to.
Using this code:
Chart chrt = new Chart();
chrt.ChartAreas.Add("ChartAreaRed");
chrt.ChartAreas["ChartAreaRed"].BackColor = System.Drawing.Color.Transparent;
chrt.ChartAreas["ChartAreaRed"].Position.Height = 100;
chrt.ChartAreas["ChartAreaRed"].Position.Width = 100;
chrt.ChartAreas["ChartAreaRed"].InnerPlotPosition.Height = 90;
chrt.ChartAreas["ChartAreaRed"].InnerPlotPosition.Width = 80;
chrt.ChartAreas["ChartAreaRed"].InnerPlotPosition.X = 10;
chrt.ChartAreas["ChartAreaRed"].AxisY.Maximum = 6;
chrt.ChartAreas["ChartAreaRed"].AxisX.Maximum = 5;
chrt.ChartAreas["ChartAreaRed"].AxisX.Interval = 1;
chrt.ChartAreas["ChartAreaRed"].Position.X = 0;
chrt.ChartAreas.Add("ChartAreaGreen");
chrt.ChartAreas["ChartAreaGreen"].BackColor = System.Drawing.Color.Transparent;
chrt.ChartAreas["ChartAreaGreen"].Position.Height = 100;
chrt.ChartAreas["ChartAreaGreen"].Position.Width = 100;
chrt.ChartAreas["ChartAreaGreen"].InnerPlotPosition.Height = 90;
chrt.ChartAreas["ChartAreaGreen"].InnerPlotPosition.Width = 80;
chrt.ChartAreas["ChartAreaGreen"].InnerPlotPosition.X = 10;
chrt.ChartAreas["ChartAreaGreen"].AxisY.Maximum = 6;
chrt.ChartAreas["ChartAreaGreen"].AxisX.Maximum = 5;
chrt.ChartAreas["ChartAreaGreen"].AxisX.Interval = 1;
chrt.ChartAreas["ChartAreaGreen"].Position.X = 0;
chrt.ChartAreas["ChartAreaGreen"].Axes[0].Enabled = AxisEnabled.False;
chrt.ChartAreas["ChartAreaGreen"].Axes[1].Enabled = AxisEnabled.False;
chrt.ChartAreas.Add("ChartAreaBlue");
chrt.ChartAreas["ChartAreaBlue"].BackColor = System.Drawing.Color.Transparent;
chrt.ChartAreas["ChartAreaBlue"].Position.Height = 100;
chrt.ChartAreas["ChartAreaBlue"].Position.Width = 100;
chrt.ChartAreas["ChartAreaBlue"].InnerPlotPosition.Height = 90;
chrt.ChartAreas["ChartAreaBlue"].InnerPlotPosition.Width = 80;
chrt.ChartAreas["ChartAreaBlue"].InnerPlotPosition.X = 15;
chrt.ChartAreas["ChartAreaBlue"].AxisY.Maximum = 6;
chrt.ChartAreas["ChartAreaBlue"].AxisX.Maximum = 5;
chrt.ChartAreas["ChartAreaBlue"].AxisX.Interval = 1;
chrt.ChartAreas["ChartAreaBlue"].Axes[0].Enabled = AxisEnabled.False;
chrt.ChartAreas["ChartAreaBlue"].Axes[1].Enabled = AxisEnabled.False;
chrt.ChartAreas["ChartAreaBlue"].AxisX.MajorGrid.Enabled = false;
Series chrtS_Red = new Series();
chrtS_Red.Points.Add(new DataPoint(2, 1));
chrtS_Red.Points.Add(new DataPoint(3, 0));
chrtS_Red.Points.Add(new DataPoint(4, 2));
chrtS_Red.ChartType = SeriesChartType.Column;
chrtS_Red.Color = System.Drawing.ColorTranslator.FromHtml("#aa220d"); // massini red
chrtS_Red.IsValueShownAsLabel = true;
chrtS_Red.EmptyPointStyle.IsValueShownAsLabel = false;
chrtS_Red["PointWidth"] = ".5";
chrtS_Red["LabelStyle"] = "TopLeft"; // Auto, Top, Bottom, Right, Left, TopLeft, TopRight, BottomLeft, BottomRight, Center
chrtS_Red.ChartArea = "ChartAreaRed";
chrt.Series.Add(chrtS_Red);
Series chrtS_Green = new Series();
chrtS_Green.Points.Add(new DataPoint(2, 0));
chrtS_Green.Points[0].IsEmpty = true;
chrtS_Green.Points.Add(new DataPoint(3, 5));
chrtS_Green.Points.Add(new DataPoint(4, 0));
chrtS_Green.Points[2].IsEmpty = true;
chrtS_Green.ChartType = SeriesChartType.Column;
chrtS_Green.Color = System.Drawing.ColorTranslator.FromHtml("#94952d"); // massini green
chrtS_Green.IsValueShownAsLabel = true;
chrtS_Green.EmptyPointStyle.IsValueShownAsLabel = false;
chrtS_Green["LabelStyle"] = "TopLeft"; // Auto, Top, Bottom, Right, Left, TopLeft, TopRight, BottomLeft, BottomRight, Center
chrtS_Green["PointWidth"] = ".5";
chrtS_Green.ChartArea = "ChartAreaGreen";
chrt.Series.Add(chrtS_Green);
I was able to produce this graph:
While it is definitely complex and difficult to understand, once you do understand it it allows for a great deal of control. The key is setting all the Chart Areas width and heights to the same values, then doing the same with the InnerPlotPosition attributes.
The InnerPlotPosition allows you to control the area inside the plot area that is dedicated to plotting the values rather than having the grid lines and values included in the width and height calculations.
You have to set a value for both the width and the height for InnerPlotPosition or else a default of 0 will be used and you will see nothing.
Also, if you intend to have grid lines or X and Y axis values then you will need the width and height values for InnerPlotPosition to be less than 100 to allow for room inside the Chart Area for those items, or else they will be hidden.
Finally, when using layers, make sure you set all the backgrounds to transparent or you will only see the last layer added. If you want a background then apply it to the first layer.
No comments:
Post a Comment