protected void InitializeAxes() { this.XAxis = new TimeAxis(this.ChartComponent, this.ChartCore, AxisNumber.X_Axis); this.YAxis = new SetLabelAxis(this.ChartComponent, this.ChartCore, AxisNumber.Y_Axis, SetLabelAxisType.ContinuousData); Axis oldX = (Axis)this.Grid["X"]; Axis oldY = (Axis)this.Grid["Y"]; #region setup data for X axis DataTable allDates = new DataTable(); allDates.Columns.Add("DateTime", typeof(DateTime)); int rowCount = this.Data.GetRowCount(); for (int r = 0; r < rowCount; r++) { allDates.Rows.Add(new object[] { this.Data.GetObjectValue(r, this.StartDateTimeColumnNumber) }); allDates.Rows.Add(new object[] { this.Data.GetObjectValue(r, this.EndDateTimeColumnNumber) }); } Infragistics.UltraChart.Data.DataTableToChartAdapter dateAdapter = new Infragistics.UltraChart.Data.DataTableToChartAdapter(allDates); Infragistics.UltraChart.Data.ChartDataFilter dateFilter = new Infragistics.UltraChart.Data.ChartDataFilter(dateAdapter); #endregion AxisAppearance yAppearance = (AxisAppearance)oldY.GetAppearance(); this.XAxis.SetBounds(yAppearance.Extent, this.OuterBound.Y + this.OuterBound.Height, this.ChartCore.GetBorderLayer().OuterBound.Width - this.OuterBound.Width, this.OuterBound.Height); this.XAxis.Minimum = this.MinDateTime; this.XAxis.Maximum = this.MaxDateTime; this.XAxis.MapMinimum = this.OuterBound.X + yAppearance.Extent; this.XAxis.MapMaximum = this.OuterBound.X + this.OuterBound.Width - 20; AxisAppearance xAppearance = (AxisAppearance)oldX.GetAppearance(); this.XAxis.startPoint = new Point(this.OuterBound.X, this.OuterBound.Y + this.OuterBound.Height - xAppearance.Extent); this.XAxis.endPoint = new Point(this.OuterBound.X + this.OuterBound.Width, this.OuterBound.Y + this.OuterBound.Height - xAppearance.Extent); this.XAxis.drawingStyle = oldX.drawingStyle; // this.XAxis.MajorLabelStyle=oldX.MajorLabelStyle; this.XAxis.SetData(dateFilter); this.YAxis.SetBounds(0, 0, this.ChartCore.GetBorderLayer().OuterBound.Width - this.OuterBound.Width, this.OuterBound.Height); this.YAxis.Minimum = 0; this.YAxis.Maximum = this.Data.GetRowCount(); this.YAxis.MapMinimum = 20; this.YAxis.MapMaximum = this.XAxis.startPoint.Y; this.XAxis.span_1 = (int)this.YAxis.MapMinimum; this.XAxis.span_2 = (int)this.YAxis.MapMaximum; }
/// <summary> /// Layer's main piece of code that does the drawing. This method calculates and /// populates a scene graph with various primitive that constitue the chart. /// </summary> /// <param name="scene">Collection of Scene items (primitives) to hold items that draw chart.</param> public void FillSceneGraph(SceneGraph scene) { //Draw the axes, use the settings from the y axis properties. AxisAppearance YApp = (AxisAppearance)this.ChartComponent.GetChartAppearance(ChartAppearanceTypes.AxisY); // Check if appearance and Y-axis appearance are defined. if (_Appearance != null && YApp != null) { #region Initialization // initilize the variable. // Minimum value a needle can have. double min = 0; // Maximum value a needle can have. double max = 100; // Tick increments. double delta = 10; // Check to see if the Gauge should assume size and layout automatically // centering the dial and assuming available width as its size. if (this._Appearance.Layout == DialLayout.Automatic) { this._Appearance.Radius = Math.Min(this.innerBounds.Width / 3, this.innerBounds.Height / 3); this._Appearance.Center = new Point(this.innerBounds.X + this.innerBounds.Width / 2, this.innerBounds.Y + this.innerBounds.Height / 2); } // check for axis settings // If cutom rage is specified use custom range. if (YApp.RangeType == AxisRangeType.Custom) { min = YApp.RangeMin; max = YApp.RangeMax; } else { // Automatic: add up the specified sections. if (this._Appearance.Sections.Count > 0) { min = 0; max = 0; foreach (GaugeSection sec in this._Appearance.Sections) { max += sec.Value; } } } // Assume and calculate the default increment. delta = (max - min) / 10; // check for y-axis appearance for specified data interval. if (YApp.TickmarkStyle == AxisTickStyle.DataInterval) { // Actual value is specified. delta = YApp.TickmarkInterval; } else { // Convert the percentage value in actual value. delta = (max - min) * YApp.TickmarkPercentage / 100; } // set up ruler with value. This will be used for measurement purposes. _Ruler.Maximum = max; _Ruler.Minimum = min; // Check the direction of the dial ticks. if (this.Appearance.Direction == Direction.RightToLeft) { _Ruler.MapMinimum = _Appearance.StartAngle; _Ruler.MapMaximum = _Appearance.EndAngle; } else { _Ruler.MapMinimum = _Appearance.EndAngle; _Ruler.MapMaximum = _Appearance.StartAngle; } // copy scoll-scale. _Ruler.Scale = YApp.ScrollScale.Scale; _Ruler.Scroll = YApp.ScrollScale.Scroll; #endregion #region Draw dial and sections // start from the minimum double d_i = (double)_Ruler.WindowMinimum; // calculate various radii. int r1 = this._Appearance.TickStart * this._Appearance.Radius / 100; int r2 = this._Appearance.TickEnd * this._Appearance.Radius / 100; int r3 = this._Appearance.TextLoc * this._Appearance.Radius / 100; // draw dial or background. Ellipse dial = new Ellipse(this._Appearance.Center, this._Appearance.Radius); dial.PE = this.Appearance.DialPE; // add dial background. scene.Add(dial); // draw the sections // variable to hold present value. double presentVal = 0; // start the section from the window minimum. double lastVal = (double)_Ruler.WindowMinimum; // foreach section, draw a section. foreach (GaugeSection sec in this._Appearance.Sections) { presentVal = lastVal + sec.Value; // section start angle. int ang0 = -(int)_Ruler.Map(lastVal); // section end angle. int ang1 = -(int)_Ruler.Map(presentVal); // create the wedge Wedge w = new Wedge(this._Appearance.Center, sec.EndWidth * this._Appearance.Radius / 100, ang0, (ang1 - ang0)); w.PE = sec.PE; w.RadiusInner = Math.Max(0, Math.Min(w.Radius - 1, sec.StartWidth * this._Appearance.Radius / 100)); scene.Add(w); lastVal = presentVal; } #endregion #region Draw axis' tick marks on dial // sanity check for increment. Without this it will go into infinite loop. if (delta < 2 * double.Epsilon) { delta = 5 * double.Epsilon; } // loop thru and add the items. while (d_i < (double)_Ruler.WindowMaximum + 2 * double.Epsilon + delta) { // convert the tickmark value to angle int ang = (int)_Ruler.Map(d_i); // see if major grid lines are visible. if (YApp.MajorGridLines.Visible) { // Convert polar co-ordinates into cartiesian. // In simple words: Convert a pair of (radius, angle) in a point (x and y). Point p1 = Infragistics.UltraChart.Core.Util.Geometry.AngularToCartesian(this._Appearance.Center, r1, -Geometry.DegreeToRadian(ang)); Point p2 = Infragistics.UltraChart.Core.Util.Geometry.AngularToCartesian(this._Appearance.Center, r2, -Geometry.DegreeToRadian(ang)); // Draw the line for tick marks. Use Y-axis's properties to color and style it. Line l = new Line(p1, p2); l.PE.Stroke = YApp.MajorGridLines.Color; l.PE.StrokeOpacity = YApp.MajorGridLines.Color.A; l.lineStyle.DrawStyle = YApp.MajorGridLines.DrawStyle; l.PE.StrokeWidth = YApp.MajorGridLines.Thickness; // add to scene. scene.Add(l); } // see if minor grid lines are visible. If yes draw them half // a tick far from major grid line. It will use Y-axis's minor // grid lines appearance for color and style. if (YApp.MinorGridLines.Visible) { if (d_i + delta / 2 < (double)_Ruler.WindowMaximum) { // convert the tickmark value to angle int ang1 = (int)_Ruler.Map(d_i + delta / 2); int tfp = Math.Abs((r2 - r1) / 4); // Convert a pair of (radius, angle) in a point (x and y). Point p1 = Infragistics.UltraChart.Core.Util.Geometry.AngularToCartesian(this._Appearance.Center, r1 + tfp, -Geometry.DegreeToRadian(ang1)); Point p2 = Infragistics.UltraChart.Core.Util.Geometry.AngularToCartesian(this._Appearance.Center, r2 - tfp, -Geometry.DegreeToRadian(ang1)); // draw a minor tick line Line l = new Line(p1, p2); l.PE.Stroke = YApp.MinorGridLines.Color; l.PE.StrokeOpacity = YApp.MinorGridLines.Color.A; l.lineStyle.DrawStyle = YApp.MinorGridLines.DrawStyle; l.PE.StrokeWidth = YApp.MinorGridLines.Thickness; // add to scene. scene.Add(l); } } // see if labels are visible. if (YApp.Labels.Visible) { // Draw the labels: Convert the angle and radius into point location for the label. Point p3 = Infragistics.UltraChart.Core.Util.Geometry.AngularToCartesian(this._Appearance.Center, r3, -Geometry.DegreeToRadian(ang)); _Labels["DATA_VALUE"] = d_i; // Use the label formatter and use Y-axis label format. Text t = new Text(p3, LabelFormatter.replaceKeywords(_Labels, YApp.Labels.ItemFormatString), YApp.Labels.LabelStyle.Copy()); t.labelStyle.VerticalAlign = StringAlignment.Center; t.labelStyle.HorizontalAlign = StringAlignment.Center; // Use custom orienation as we need to rotate them to // place them on angular axis. t.labelStyle.Orientation = TextOrientation.Custom; // rotate with respect to present tick angle. t.labelStyle.RotationAngle = ang - 90; // add to scene. scene.Add(t); } // increment current value of tick by the data interval: delta. d_i += delta; } // See if axis line is visible. if (YApp.Visible) { // create new line style LineStyle ls = new LineStyle(); // use y-axis's draw style. ls.DrawStyle = YApp.LineDrawStyle; // draw an arc that looks takes place of axis line. Arc el = new Arc(this._Appearance.Center, (r1 + r2) / 2, (float)this._Appearance.StartAngle, -(float)Math.Abs(this._Appearance.EndAngle - this._Appearance.StartAngle), ls); // use the axes line's color and thickness. el.PE.Stroke = YApp.LineColor; el.PE.StrokeOpacity = YApp.LineColor.A; el.PE.StrokeWidth = YApp.LineThickness; // add to scene. scene.Add(el); } #endregion #region Draw needles // sort needles according to needle length. shortest comes on the top. double[] ar = new Double[this.Appearance.Needles.Count]; for (int i = 0; i < this.Appearance.Needles.Count; i++) { // store the length of needle in temporary array. ar[i] = this.Appearance.Needles[i].Length; } // sort the order. This function takes the length of // needle array and get the sorted order. int[] order = null; if (ar.Length > 0) { order = MiscFunctions.GetSortedOrderDouble(ar); } // draw the needles on the dials for (int i = 0; i < this.Appearance.Needles.Count; i++) { // get n-th needle. Needle nd = this.Appearance.Needles[order[i]]; // depending upon needle's present value find out the // angle at which it should be inclined. int theta_i = (int)_Ruler.Map(nd.Value); // convert, angle of needle and its length into a point location. Point p = Infragistics.UltraChart.Core.Util.Geometry.AngularToCartesian(this._Appearance.Center, nd.Length * this._Appearance.Radius / 100, Geometry.DegreeToRadian(-theta_i)); // draw a line from the center of dial to location of needle's head. Line l = new Line(this._Appearance.Center, p); l.lineStyle.EndStyle = LineCapStyle.ArrowAnchor; l.lineStyle.StartStyle = LineCapStyle.RoundAnchor; // attach the paint element from needle to the line primitive. l.PE = nd.PE; // add to scene. scene.Add(l); } #endregion } }