Guys,
I have spent a lot of time on this and keep hitting roadblocks. I bought into the FillSceneGraph vs using annotations since I would have more control. Most looks fine. However, positioning text inside of a box is a nightmare.
Can you tell me an easy way to line them up, especially if rotated, and/or tell me how I can easily adjust the box/text beyond a grid x,y? I would like some double to help move things around ;-]
Here is a mockup (a little inaccurate but close):
Alan
Thanks for the sample. I simply had to take the time to fully understand how things work. I did this by creating a sample including data generation. For anyone else facing this issue, here is a complete code listing (copy and run and it should work as is):
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using Infragistics.UltraChart.Core; using Infragistics.UltraChart.Core.Primitives; using Infragistics.UltraChart.Shared.Events; using Infragistics.UltraChart.Shared.Styles; using Infragistics.Win.UltraWinChart; namespace TestCharting { public partial class Form1 : Form { private DataTable dt; public Form1() { InitializeComponent(); dt = CreateData(); uChart.ChartType = ChartType.LineChart; uChart.BackColor = Color.White; uChart.Dock = DockStyle.Fill; DataView dv = dt.DefaultView; DataTable newDt = dv.ToTable(false, "week", "before", "after"); uChart.DataSource = newDt; uChart.DataBind(); uChart.Data.SwapRowsAndColumns = true; Color[] chartColors = new Color[] { Color.Red, Color.Blue }; uChart.ColorModel.ModelStyle = ColorModels.CustomLinear; uChart.ColorModel.CustomPalette = chartColors; uChart.Axis.Y.Labels.SeriesLabels.FormatString = "Dollars"; uChart.Axis.Y.Labels.ItemFormatString = "<DATA_VALUE:#>"; uChart.Legend.Visible = true; uChart.Legend.SpanPercentage = 10; uChart.Legend.Margins.Bottom = 300; uChart.Legend.Location = LegendLocation.Right; uChart.Axis.X.RangeMax = uChart.Axis.Y.RangeMax; uChart.Axis.X.RangeMin = uChart.Axis.Y.RangeMin; uChart.Axis.X.TickmarkStyle = AxisTickStyle.Smart; uChart.Axis.X.TickmarkIntervalType = AxisIntervalType.Weeks; uChart.Axis.X.Labels.Layout.Behavior = AxisLabelLayoutBehaviors.Auto; uChart.Axis.Y.Extent = 30; uChart.LineChart.TreatDateTimeAsString = true; uChart.FillSceneGraph += new Infragistics.UltraChart.Shared.Events.FillSceneGraphEventHandler(uChart_FillSceneGraph); } void uChart_FillSceneGraph(object sender, Infragistics.UltraChart.Shared.Events.FillSceneGraphEventArgs e) { IAdvanceAxis xAxis = e.Grid["X"] as IAdvanceAxis; IAdvanceAxis yAxis = e.Grid["Y"] as IAdvanceAxis; //Chart axis starts in upper left at 0,0. for (int i = 0; i < dt.Rows.Count; i++) { DataRow dr = dt.Rows[i]; AddYearLines(e, dr,i,xAxis,yAxis); AddPlannerCodeLines(e, i, dr, xAxis, yAxis); } } private void AddPlannerCodeLines(FillSceneGraphEventArgs e, int i, DataRow dr, IAdvanceAxis xAxis, IAdvanceAxis yAxis) { LabelStyle labelStyle = new LabelStyle(); labelStyle.Orientation = TextOrientation.VerticalLeftFacing; labelStyle.HorizontalAlign = StringAlignment.Near; labelStyle.VerticalAlign = StringAlignment.Near; labelStyle.FontColor = Color.Black; string[] codes = new string[] { dr["disco"].ToString(), dr["replace"].ToString(), dr["life"].ToString() }; for (int j = 0; j < codes.Length; j++) { int x = (int)xAxis.Map(i); int y = (int)yAxis.Map((int) dr["after"]); Point p = new Point(x, y); Point p2 = new Point(x + 5, y - 5); Ellipse xb = new Ellipse(p, 10); Text xt = null; switch (codes[j]) { case "12": xt = new Text(p2, "L1", labelStyle); xb.PE.Fill = Color.PaleGoldenrod; break; case "14": xt = new Text(p2, "D1", labelStyle); xb.PE.Fill = Color.DimGray; break; case "95": xt = new Text(p2, "R1", labelStyle); xb.PE.Fill = Color.Orange; break; case "96": xt = new Text(p2, "R2", labelStyle); xb.PE.Fill = Color.OrangeRed; break; } if (xt != null) { e.SceneGraph.Add(xb); e.SceneGraph.Add(xt); } } } private void AddYearLines(FillSceneGraphEventArgs e, DataRow dr, int i, IAdvanceAxis xAxis, IAdvanceAxis yAxis) { DateTime week = (DateTime)dr["week"]; int weekNo = GetWeekNumber(week); if (weekNo == 1) { int xNow = (int)xAxis.Map(i); int yMin = (int)yAxis.MapMinimum; int yMax = (int)yAxis.MapMaximum; Point bottom = new Point(xNow, yMin); Point top = new Point(xNow, yMax); Line myLine = new Line(bottom, top); myLine.PE.StrokeWidth = 3; myLine.lineStyle = new LineStyle(LineCapStyle.ArrowAnchor, LineCapStyle.Flat, LineDrawStyle.Solid); Point top2 = new Point(xNow - 20, yMax); Point top3 = new Point(xNow + 5, yMax); Box b = new Box(top2, 40, 15); b.RotationAngle = -90; b.PE.Fill = Color.Yellow; LabelStyle labelStyle = new LabelStyle(); labelStyle.Orientation = TextOrientation.VerticalLeftFacing; labelStyle.HorizontalAlign = StringAlignment.Near; labelStyle.VerticalAlign = StringAlignment.Near; labelStyle.FontColor = Color.Black; Text t = new Text(top3, week.Year.ToString(), labelStyle); e.SceneGraph.Add(myLine); e.SceneGraph.Add(b); e.SceneGraph.Add(t); } } public static int GetWeekNumber(DateTime dt) { System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.CreateSpecificCulture("no"); System.Globalization.Calendar cal = ci.Calendar; int weekNo = cal.GetWeekOfYear(dt, ci.DateTimeFormat.CalendarWeekRule, ci.DateTimeFormat.FirstDayOfWeek); return weekNo; } private DataTable CreateData() { DataTable dt = new DataTable("SAMPLE"); dt.Columns.Add("disco", typeof(string)); dt.Columns.Add("life", typeof(string)); dt.Columns.Add("replace", typeof(string)); dt.Columns.Add("week", typeof(DateTime)); dt.Columns.Add("before", typeof(int)); dt.Columns.Add("after", typeof(int)); DateTime start = new DateTime(2008, 06, 01); Random r = new Random(); for (int i = 1; i < 50; i++) { string disco = "0"; string replace = "0"; string life = "0"; if (i % 15 == 0) disco = "14"; if (i % 12 == 0) life = "12"; if (i % 25 == 0) replace = "95"; if (i % 27 == 0) replace = "96"; DataRow dr = dt.Rows.Add(disco, life, replace, start.AddDays(i * 7), r.Next(100, 1000), r.Next(100, 1000)); } return dt; } } }
Hello ,
From the attached picture I believe that you are using LineChart. And as far as I understand your requirements you are looking for a way to align labels of X and Y axis. So I have created a small sample that illustrates how you could do this.
Let me know if you have any further questions or I am missing something.
Here is some code I have been playing with.
void uChart_FillSceneGraph(object sender, Infragistics.UltraChart.Shared.Events.FillSceneGraphEventArgs e) { IAdvanceAxis xAxis = e.Grid["X"] as IAdvanceAxis; IAdvanceAxis yAxis = e.Grid["Y"] as IAdvanceAxis; int xNow = (int)xAxis.Map(10); int yMin = (int)yAxis.MapMinimum; int yMax = (int)( yAxis.MapMaximum * 2); Point bottom = new Point(xNow, yMin); Point top = new Point(xNow, yMax); Line myLine = new Line(bottom, top); Box b = new Box(top, 40, 15); //b.RotationAngle = 90; b.PE.Fill = Color.Firebrick; Text t = new Text(top, "2010",labelStyle); e.SceneGraph.Add(myLine); e.SceneGraph.Add(b); e.SceneGraph.Add(t); } }
Also, if I flip rows and columns, does that also flip the x and y axis for mins and maxs? If so, that may be the confusing nature of this whole thing.