/// <summary> /// Initializes a new instance of the <see cref="MultiLevelLabelsPanel"/> class. /// </summary> /// <param name="panel">The Panel</param> public MultiLevelLabelsPanel(Panel panel) { labelsPanel = panel; textBlockRecycler = new UIElementsRecycler <TextBlock>(panel); polylineRecycler = new UIElementsRecycler <Polyline>(panel); borderRecycler = new UIElementsRecycler <Border>(panel); }
/// <summary> /// Updates the gridlines. /// </summary> /// <param name="axis">The Relevant Axis</param> /// <param name="linesRecycler">The Line Recycler</param> /// <param name="requiredLinescount">The Required Lines Count</param> /// <param name="isMajor">Check For Marjor Axis</param> /// <param name="checkOrginFlag">Check For Origin Flag</param> private static void UpdateGridlines(ChartAxis axis, UIElementsRecycler <Line> linesRecycler, int requiredLinescount, bool isMajor, bool checkOrginFlag) { if (linesRecycler == null || axis == null) { return; } foreach (var line in linesRecycler) { line.ClearValue(FrameworkElement.StyleProperty); } int totalLinesCount = requiredLinescount; if (axis.ShowOrigin && checkOrginFlag) { totalLinesCount += 1; } if (!linesRecycler.BindingProvider.Keys.Contains(FrameworkElement.StyleProperty)) { linesRecycler.BindingProvider.Add(FrameworkElement.StyleProperty, GetGridLineBinding(axis, isMajor)); } if (linesRecycler.Count > 0) { foreach (var line in linesRecycler) { line.SetBinding(FrameworkElement.StyleProperty, GetGridLineBinding(axis, isMajor)); } } linesRecycler.GenerateElements(totalLinesCount); var rangeStyles = axis.RangeStyles; if (rangeStyles != null && rangeStyles.Count > 0) { var values = !isMajor ? axis.SmallTickPoints : (from label in axis.VisibleLabels select label.Position).ToList(); for (int i = 0; i < values.Count; i++) { foreach (var chartAxisRangeStyle in rangeStyles) { var range = chartAxisRangeStyle.Range; var style = isMajor ? chartAxisRangeStyle.MajorGridLineStyle : chartAxisRangeStyle.MinorGridLineStyle; if (range.Start <= values[i] && range.End >= values[i] && style != null) { linesRecycler[i].SetBinding(FrameworkElement.StyleProperty, GetGridLineBinding(chartAxisRangeStyle, isMajor)); break; } } } } //StrokeDashArray applied only for the first line element when it is applied through style. //It is bug in the framework. //And hence manually setting stroke dash array for each and every grid line. ChartExtensionUtils.SetStrokeDashArray(linesRecycler); }
/// <summary> /// Initializes a new instance of the <see cref="ChartCartesianGridLinesPanel"/> class. /// </summary> /// <param name="panel">The Panel</param> /// <exception cref="ArgumentNullException"><see cref="ArgumentNullException"/> may be thrown</exception> public ChartCartesianGridLinesPanel(Panel panel) { // if (panel == null) // throw new ArgumentNullException(); this.panel = panel; stripLines = new UIElementsRecycler <Border>(this.panel); xOriginLine = new Line(); yOriginLine = new Line(); }
/// <summary> /// Initializes a new instance of the <see cref="ChartCartesianAxisElementsPanel"/> class. /// </summary> /// <param name="panel">The Panel</param> public ChartCartesianAxisElementsPanel(Panel panel) { this.labelsPanels = panel; MainAxisLine = new Line(); if (panel != null) { panel.Children.Add(MainAxisLine); } majorTicksRecycler = new UIElementsRecycler <Line>(panel); minorTicksRecycler = new UIElementsRecycler <Line>(panel); }
/// <summary> /// Initializes a new instance of the <see cref="ChartCircularAxisPanel"/> class. /// </summary> /// <param name="panel">The Required Panel</param> public ChartCircularAxisPanel(Panel panel) { if (panel == null) { throw new ArgumentNullException(); } this.panel = panel; lineRecycler = new UIElementsRecycler <Line>(panel); contentControlRecycler = new UIElementsRecycler <ContentControl>(panel); }
/// <summary> /// Updates the tick lines. /// </summary> /// <param name="linescount">The Tick Lines Count</param> /// <param name="lineRecycler">The Tick Lines Recycler</param> /// <param name="lineStylePath">The Tick Lines Style</param> private void UpdateTicks(int linescount, UIElementsRecycler <Line> lineRecycler, String lineStylePath) { int linesCount = linescount; foreach (var line in lineRecycler) { line.ClearValue(FrameworkElement.StyleProperty); } if (!lineRecycler.BindingProvider.Keys.Contains(Line.StyleProperty)) { lineRecycler.BindingProvider.Add(Line.StyleProperty, GetTickLineBinding(Axis, lineStylePath)); lineRecycler.BindingProvider.Add(Line.VisibilityProperty, GetTickLineBinding(Axis, "Visibility")); } if (lineRecycler.Count > 0) { foreach (var line in lineRecycler) { line.SetBinding(FrameworkElement.StyleProperty, GetTickLineBinding(Axis, lineStylePath)); line.SetBinding(Line.VisibilityProperty, GetTickLineBinding(Axis, "Visibility")); } } lineRecycler.GenerateElements(linesCount); var rangeStyles = axis.RangeStyles; if (rangeStyles != null && rangeStyles.Count > 0) { var values = !lineStylePath.Equals("MajorTickLineStyle") ? axis.SmallTickPoints : (from label in axis.VisibleLabels select label.Position).ToList(); for (int i = 0; i < values.Count; i++) { foreach (var chartAxisRangeStyle in rangeStyles) { var range = chartAxisRangeStyle.Range; var style = lineStylePath.Equals("MajorTickLineStyle") ? chartAxisRangeStyle.MajorTickLineStyle : chartAxisRangeStyle.MinorTickLineStyle; if (range.Start <= values[i] && range.End >= values[i] && style != null) { lineRecycler[i].SetBinding(FrameworkElement.StyleProperty, GetTickLineBinding(chartAxisRangeStyle, lineStylePath)); lineRecycler[i].SetBinding(Line.VisibilityProperty, GetTickLineBinding(axis, "Visibility")); break; } } } } }
internal void Dispose() { axis = null; if (majorTicksRecycler != null && majorTicksRecycler.Count > 0) { majorTicksRecycler.Clear(); majorTicksRecycler = null; } if (minorTicksRecycler != null && minorTicksRecycler.Count > 0) { minorTicksRecycler.Clear(); minorTicksRecycler = null; } }
//StrokeDashArray applied only for the first line element when it is applied through style. //It is bug in the framework. //And hence manually setting stroke dash array for each and every line. public static void SetStrokeDashArray(UIElementsRecycler <Line> lineRecycler) { if (lineRecycler.Count > 0) { DoubleCollection collection = lineRecycler[0].StrokeDashArray; if (collection != null && collection.Count > 0) { foreach (Line line in lineRecycler) { DoubleCollection doubleCollection = new DoubleCollection(); foreach (double value in collection) { doubleCollection.Add(value); } line.StrokeDashArray = doubleCollection; } } } }
/// <summary> /// Renders the tick lines. /// </summary> /// <param name="finalSize">The Final Size</param> /// <param name="linesRecycler">The Line Recycler</param> /// <param name="orientation">The Orientation</param> /// <param name="tickSize">The Tick Size</param> /// <param name="tickPosition">The Tick Postion</param> /// <param name="Values">The Values</param> private void RenderTicks( Size finalSize, UIElementsRecycler <Line> linesRecycler, Orientation orientation, double tickSize, AxisElementPosition tickPosition, double[] Values) { int labelsCount = Values.Length; int linesCount = linesRecycler.Count; double width = finalSize.Width; double height = finalSize.Height; for (int i = 0; i < labelsCount; i++) { if (i < linesCount) { double x1 = 0, y1 = 0, x2 = 0, y2 = 0; Line line = linesRecycler[i]; double value = this.Axis.ValueToCoefficientCalc(Values[i]); value = double.IsNaN(value) ? 0 : value; if (orientation == Orientation.Horizontal) { x1 = x2 = Axis.ActualPlotOffset + Math.Round((this.Axis.RenderedRect.Width * value)); } else { y1 = y2 = (Axis.ActualPlotOffset + Math.Round(this.Axis.RenderedRect.Height * (1 - value)) + 0.5); } CalculatePosition(tickPosition, tickSize, width, height, ref x1, ref y1, ref x2, ref y2); line.X1 = x1; line.X2 = x2; line.Y1 = y1; line.Y2 = y2; } } }
/// <summary> /// Draws the gridlines with the specified values. /// </summary> /// <param name="axis">The Axis</param> /// <param name="lines">The Lines</param> /// <param name="left">The Left</param> /// <param name="top">The Top</param> /// <param name="width">The Width</param> /// <param name="height">The Height</param> /// <param name="values">The Values</param> /// <param name="drawOrigin">Check For Draw Origin</param> /// <param name="index">The Index</param> private void DrawGridLines(ChartAxis axis, UIElementsRecycler <Line> lines, double left, double top, double width, double height, double[] values, bool drawOrigin, int index) { if (lines == null || axis == null) { return; } int labelsCount = values.Length; int linesCount = lines.Count; Orientation orienatation = axis.Orientation; if (orienatation == Orientation.Horizontal) { int i; for (i = 0; i < labelsCount; i++) { if (i < linesCount) { Line line = lines[index]; double value = axis.ValueToCoefficientCalc(values[i]); value = double.IsNaN(value) ? 0 : value; //line.X1 = (value=Math.Round(width * value) + 0.5)>width ? value-0.5:value; line.X1 = (Math.Round(width * value)) + left; line.Y1 = top; line.X2 = line.X1; line.Y2 = height; } index++; } if (!axis.ShowOrigin && panel.Children.Contains(xOriginLine)) { panel.Children.Remove(xOriginLine); } if (axis.ShowOrigin && drawOrigin) { double value = Area.InternalSecondaryAxis.ValueToCoefficientCalc(axis.Origin); value = double.IsNaN(value) ? 0 : value; xOriginLine.X1 = 0; xOriginLine.Y1 = xOriginLine.Y2 = Math.Round(height * (1 - value)); xOriginLine.X2 = width; Binding binding = new Binding(); binding.Path = new PropertyPath("OriginLineStyle"); binding.Source = axis; xOriginLine.SetBinding(Line.StyleProperty, binding); if (!panel.Children.Contains(xOriginLine)) { panel.Children.Add(xOriginLine); } } } else { int i; for (i = 0; i < labelsCount; i++) { if (i < linesCount) { Line line = lines[index]; double value = axis.ValueToCoefficientCalc(values[i]); value = double.IsNaN(value) ? 0 : value; line.X1 = left; line.Y1 = Math.Round(height * (1 - value)) + 0.5 + top; line.X2 = width; line.Y2 = line.Y1; } index++; } if (!axis.ShowOrigin && panel.Children.Contains(yOriginLine)) { panel.Children.Remove(yOriginLine); } if (axis.ShowOrigin && axis.VisibleRange.Delta > 0 && drawOrigin) { double value = Area.InternalPrimaryAxis.ValueToCoefficientCalc(axis.Origin); value = double.IsNaN(value) ? 0 : value; yOriginLine.X1 = yOriginLine.X2 = Math.Round(width * (value)); yOriginLine.Y1 = 0; yOriginLine.Y2 = height; Binding binding = new Binding(); binding.Path = new PropertyPath("OriginLineStyle"); binding.Source = axis; yOriginLine.SetBinding(Line.StyleProperty, binding); if (!panel.Children.Contains(yOriginLine)) { panel.Children.Add(yOriginLine); } } } }
/// <summary> /// Renders the 3D tick lines. /// </summary> /// <param name="linesRecycler">The Line Recycler</param> /// <param name="orientation">The Orientation</param> /// <param name="tickSize">The Tick Size</param> /// <param name="tickPosition">The Tick Position</param> /// <param name="values">The Values</param> private void RenderTicks3D( UIElementsRecycler <Line> linesRecycler, Orientation orientation, double tickSize, AxisElementPosition tickPosition, IList <double> values) { var area3D = Axis.Area as SfChart3D; var actualRotationAngle = area3D.ActualRotationAngle; var labelsCount = values.Count; var linesCount = linesRecycler.Count; for (var i = 0; i < labelsCount; i++) { if (i >= linesCount) { continue; } double x1 = 0, y1 = 0, x2 = 0, y2 = 0; var line = linesRecycler[i]; var value = Axis.ValueToCoefficientCalc(values[i]); value = double.IsNaN(value) ? 0 : value; if (orientation == Orientation.Horizontal) { var tempaxis = axis as ChartAxisBase3D; if (tempaxis.IsManhattanAxis && (axis.RegisteredSeries[i] as ChartSeries3D).Segments != null && (axis.RegisteredSeries[i] as ChartSeries3D).Segments.Count > 0) { var segment = (axis.RegisteredSeries[i] as ChartSeries3D).Segments[0] as ChartSegment3D; x1 = x2 = segment.startDepth + (segment.endDepth - segment.startDepth) / 2; } else { x1 = x2 = Math.Round(Axis.ActualPlotOffset + (Axis.RenderedRect.Width * value)); } } else { y1 = y2 = Math.Round(Axis.ActualPlotOffset + (Axis.RenderedRect.Height * (1 - value))); } CalculatePosition3D(tickPosition, tickSize, ref x1, ref y1, ref x2, ref y2, actualRotationAngle); var verticalAxis = area3D.InternalSecondaryAxis.Orientation == Orientation.Vertical ? area3D.InternalSecondaryAxis : area3D.InternalPrimaryAxis; if ((axis as ChartAxisBase3D).IsZAxis) { // Adding one to prevent the tick hidding. var leftPosition = !verticalAxis.OpposedPosition && actualRotationAngle >= 0 && actualRotationAngle < 180 ? axis.ArrangeRect.Left + 1 : axis.ArrangeRect.Left; ((SfChart3D)Axis.Area).Graphics3D.AddVisual(Polygon3D.CreateLine(line, leftPosition, y1, leftPosition, y2, x1, x1, false)); } else { double depth = 0d; var axis3D = this.axis as ChartAxisBase3D; Line3D line3D = null; if (orientation == Orientation.Vertical) { if (axis.ShowAxisNextToOrigin) { if (actualRotationAngle >= 90 && actualRotationAngle < 270) { depth = (axis.Area as SfChart3D).ActualDepth; } line3D = Polygon3D.CreateLine(line, x1, y1, x2, y2, depth, depth, true); } else { if (axis3D.AxisPosition3D == AxisPosition3D.DepthBackRight || axis3D.AxisPosition3D == AxisPosition3D.DepthBackLeft || axis3D.AxisPosition3D == AxisPosition3D.DepthFrontRight || axis3D.AxisPosition3D == AxisPosition3D.DepthFrontLeft) { line3D = Polygon3D.CreateLine(line, axis.ArrangeRect.Left, y1, axis.ArrangeRect.Left, y2, x1, x2, false); } else { depth = axis3D.AxisDepth; line3D = Polygon3D.CreateLine(line, x1, y1, x2, y2, depth, depth, true); } } } else { depth = axis3D.AxisDepth; line3D = Polygon3D.CreateLine(line, x1, y1, x2, y2, depth, depth, true); } ((SfChart3D)Axis.Area).Graphics3D.AddVisual(line3D); } } }