/// <summary> /// Draw DataSeries visual (Path) for Polar /// </summary> /// <param name="series"></param> /// <param name="pointCollection"></param> /// <param name="polarCanvas"></param> private static void DrawDataSeriesPath(DataSeries series, List <DataPoint> pointCollection, Canvas polarCanvas) { if (series.InternalDataPoints.Count > 0) { Path path = new Path() { Tag = new ElementData() { Element = series, VisualElementName = "PolarVisual" } }; path.Stroke = (Boolean)series.LightingEnabled ? Graphics.GetLightingEnabledBrush(series.Color, "Linear", null) : series.Color; path.StrokeDashArray = ExtendedGraphics.GetDashArray(series.LineStyle); path.StrokeThickness = (Double)series.LineThickness; path.StrokeMiterLimit = 1; path.Opacity = series.Opacity; path.Data = GetPathGeometry(pointCollection); series.Faces.Parts.Add(path); polarCanvas.Children.Add(path); } }
/// <summary> /// UpdateVisual is used for partial update /// </summary> /// <param name="propertyName">Name of the property</param> /// <param name="value">Value of the property</param> internal override void UpdateVisual(VcProperties property, object value) { if (Visual != null) { foreach (Line line in Visual.Children) { line.Stroke = LineColor; line.StrokeThickness = LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); } } else { FirePropertyChanged(property); } }
/// <summary> /// Apply properties of TrendLine to line visual and line-shadow visual /// </summary> private void ApplyProperties() { Line.Stroke = LineColor; Line.StrokeThickness = LineThickness; Line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); Shadow.StrokeThickness = LineThickness + 2; Shadow.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); Shadow.Stroke = new SolidColorBrush(Colors.LightGray); Shadow.Opacity = 0.7; Shadow.StrokeDashCap = PenLineCap.Round; Shadow.StrokeLineJoin = PenLineJoin.Round; Shadow.Visibility = ShadowEnabled ? Visibility.Visible : Visibility.Collapsed; }
/// <summary> /// Draw DataSeries visual (polygon) for Radar /// </summary> /// <param name="listOfRadarPoints"></param> /// <param name="series"></param> /// <param name="radarCanvas"></param> private static void DrawDataSeriesPolygon(List <Point> listOfRadarPoints, DataSeries series, Canvas radarCanvas) { if (listOfRadarPoints.Count > 0) { Polygon polygon = new Polygon() { Tag = new ElementData() { Element = series, VisualElementName = "RadarVisual" } }; polygon.Fill = (Boolean)series.LightingEnabled ? Graphics.GetLightingEnabledBrush(series.Color, "Linear", null) : series.Color; polygon.Stroke = (series.BorderColor == null) ? GetDarkerColor(series.Color) : series.BorderColor; polygon.StrokeDashArray = ExtendedGraphics.GetDashArray(series.BorderStyle); polygon.StrokeThickness = (series.BorderThickness.Left == 0) ? 0.5 : series.BorderThickness.Left; polygon.StrokeMiterLimit = 1; polygon.Opacity = series.Opacity; PointCollection pointCollection = new PointCollection(); foreach (Point point in listOfRadarPoints) { pointCollection.Add(point); } Rect polygonBounds = AreaChart.GetBounds(pointCollection); polygon.Width = polygonBounds.Width; polygon.Height = polygonBounds.Height; polygon.SetValue(Canvas.TopProperty, polygonBounds.Y); polygon.SetValue(Canvas.LeftProperty, polygonBounds.X); polygon.Points = pointCollection; polygon.Stretch = Stretch.Fill; series.Faces.Visual = polygon; radarCanvas.Children.Add(polygon); } }
/// <summary> /// Update visual used for partial update /// </summary> /// <param name="propertyName">Name of the property</param> /// <param name="value">Value of the property</param> internal override void UpdateVisual(VcProperties propertyName, object value) { if (Visual != null) { foreach (Rectangle rec in InterlacedRectangles) { rec.Fill = InterlacedColor; } foreach (Line line in InterlacedLines) { line.Stroke = LineColor; line.StrokeThickness = LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); } } else { FirePropertyChanged(propertyName); } }
/// <summary> /// Create and position ChartGrid for circular chart /// </summary> internal void CreateAndPositionChartGrid4CircularAxesY() { Double interval = (Double)Interval; // Interval for the chart grid Decimal index = 0; // starting point for the loop that generates grids Decimal minVal = (Decimal)Minimum; // smallest value from where the grid must be drawn Decimal maxVal = (Decimal)Maximum; // largest value from where the grid must be drawn // gap between two intervals Decimal gap = (Decimal)interval; Int32 countRectangles = 0; // counts the number of color bands for animating them alternately in opposite direction Double position = 0; // value of the line position for the running loop cycle InterlacedPaths = new List <Path>(); InterlacedLines = new List <Line>(); List <Point> previousPoints = new List <Point>(); List <Point> currPoints = new List <Point>(); CircularPlotDetails plotDetails = ParentAxis.CircularPlotDetails; if (minVal != maxVal) { Decimal xValue; for (xValue = minVal; xValue <= maxVal;) { position = Graphics.ValueToPixelPosition(Height, 0, Minimum, Maximum, (Double)xValue); Double radius = Height - position; List <Point> points; if (plotDetails.CircularChartType == RenderAs.Radar) { points = GetGridPoints4Radar(radius, plotDetails.Center, plotDetails.ListOfPoints4CircularAxis.Count); } else { points = GetGridPoints4Polar(radius, plotDetails.Center, plotDetails.AnglesInRadian); } currPoints = points; Int32 i; for (i = 0; i < points.Count - 1; i++) { Line line = new Line(); InterlacedLines.Add(line); line.Stroke = LineColor; line.StrokeThickness = (Double)LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); line.X1 = points[i].X; line.X2 = points[i + 1].X; line.Y1 = points[i].Y; line.Y2 = points[i + 1].Y; Visual.Children.Add(line); } // Create last line Line lastLine = new Line(); InterlacedLines.Add(lastLine); lastLine.Stroke = LineColor; lastLine.StrokeThickness = (Double)LineThickness; lastLine.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); lastLine.X1 = points[i].X; lastLine.X2 = points[0].X; lastLine.Y1 = points[i].Y; lastLine.Y2 = points[0].Y; Visual.Children.Add(lastLine); if (index % 2 == 1) { Path path = new Path(); path.StrokeThickness = 0; List <Point> listOfPreAndCurrPoints = new List <Point>(); for (Int32 newPointIndex = 0; newPointIndex < currPoints.Count; newPointIndex++) { listOfPreAndCurrPoints.Add(currPoints[newPointIndex]); } listOfPreAndCurrPoints.Add(currPoints[0]); for (Int32 prePointIndex = 0; prePointIndex < previousPoints.Count; prePointIndex++) { listOfPreAndCurrPoints.Add(previousPoints[prePointIndex]); } listOfPreAndCurrPoints.Add(previousPoints[0]); listOfPreAndCurrPoints.Add(currPoints[0]); path.Data = ParentAxis.GetPathGeometry(listOfPreAndCurrPoints); countRectangles++; path.Fill = InterlacedColor; path.SetValue(Canvas.ZIndexProperty, 10); Visual.Children.Add(path); InterlacedPaths.Add(path); } previousPoints = currPoints; index += (ParentAxis.SkipOffset + 1); xValue = minVal + index * gap; } } }
/// <summary> /// Creates grids and also position them appropriately /// </summary> /// <param name="animationEnabled">Whether animation is enabled</param> /// <param name="animationDuration">Animation duration</param> private void CreateAndPositionChartGrid(bool animationEnabled, Double animationDuration) { Double interval = (Double)Interval; // Interval for the chart grid Decimal index = 0; // = (Decimal)Minimum; // starting point for the loop that generates grids Decimal minVal = (Decimal)Minimum; // smallest value from where the grid must be drawn Decimal maxVal = (Decimal)Maximum; // largest value from where the grid must be drawn // gap between two intervals Decimal gap = (Decimal)interval;// +(((Nullable<Double>)GetValue(IntervalProperty) == null) ? ParentAxis.SkipOffset : 0); //Int32 count = 0; // counts the number of lines required for alternate colored bands Int32 countRectangles = 0; // counts the number of color bands for animating them alternately in opposite direction Double position = 0; // value of the line position for the running loop cycle Double prevPosition = 0; // value of the line position for the previous position // if axisX and the first data point is in a gap between the prescribed interval, the index must dateTime from the // datapoint rather than the axis minimum // if ((DataMinimum - interval) < Minimum && ParentAxis.AxisRepresentation == AxisRepresentations.AxisX) // index = (Decimal)DataMinimum; if (ParentAxis.AxisRepresentation == AxisRepresentations.AxisX) { if (Double.IsNaN((Double)ParentAxis.AxisMinimumNumeric)) { if (ParentAxis.XValueType != ChartValueTypes.Numeric) { minVal = (Decimal)ParentAxis.FirstLabelPosition; } else { if ((DataMinimum - Minimum) / interval >= 1) { minVal = (Decimal)(DataMinimum - Math.Floor((DataMinimum - Minimum) / interval) * interval); } else { minVal = (Decimal)DataMinimum; } } } } // index = minval; // maxVal = maxVal + gap / 1000; #if WPF if (Storyboard != null && Storyboard.GetValue(Storyboard.TargetProperty) != null) { Storyboard.Stop(); } #else if (Storyboard != null) { Storyboard.Stop(); } #endif InterlacedRectangles = new List <Rectangle>(); InterlacedLines = new List <Line>(); if (minVal != maxVal) { Decimal xValue; for (xValue = minVal; xValue <= maxVal;) { Line line = new Line(); InterlacedLines.Add(line); line.Stroke = LineColor; line.StrokeThickness = (Double)LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); line.Width = Width; line.Height = Height; switch (Placement) { case PlacementTypes.Top: case PlacementTypes.Bottom: position = Graphics.ValueToPixelPosition(0, Width, Minimum, Maximum, (Double)xValue); line.X1 = position; line.X2 = position; line.Y1 = 0; line.Y2 = Height; if (index % 2 == 1) { Rectangle rectangle = new Rectangle(); if (animationEnabled) { ScaleTransform scaleTransform; if (countRectangles % 2 == 0) { scaleTransform = new ScaleTransform() { ScaleX = 1, ScaleY = 0 }; rectangle.RenderTransformOrigin = new Point(0.5, 1); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleY)", 0, 1, 0.5, animationDuration)); } else { scaleTransform = new ScaleTransform() { ScaleX = 1, ScaleY = 0 }; rectangle.RenderTransformOrigin = new Point(0.5, 0); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleY)", 0, 1, 0.5, animationDuration)); } rectangle.RenderTransform = scaleTransform; } countRectangles++; rectangle.Width = Math.Abs(position - prevPosition); rectangle.Height = Height; rectangle.Fill = InterlacedColor; rectangle.SetValue(Canvas.LeftProperty, prevPosition); rectangle.SetValue(Canvas.TopProperty, (Double)0); rectangle.SetValue(Canvas.ZIndexProperty, (Int32)(-countRectangles)); Visual.Children.Add(rectangle); InterlacedRectangles.Add(rectangle); } break; case PlacementTypes.Left: case PlacementTypes.Right: position = Graphics.ValueToPixelPosition(Height, 0, Minimum, Maximum, (Double)xValue); if (position == 0) { position += (Double)this.LineThickness; } line.X1 = 0; line.X2 = Width; line.Y1 = position; line.Y2 = position; if (index % 2 == 1) { Rectangle rectangle = new Rectangle(); if (animationEnabled) { ScaleTransform scaleTransform; if (countRectangles % 2 == 0) { scaleTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 1 }; rectangle.RenderTransformOrigin = new Point(0, 0.5); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleX)", 0, 1, 0.5, animationDuration)); } else { scaleTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 1 }; rectangle.RenderTransformOrigin = new Point(1, 0.5); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleX)", 0, 1, 0.5, animationDuration)); } rectangle.RenderTransform = scaleTransform; } countRectangles++; rectangle.Width = Width; rectangle.Height = Math.Abs(position - prevPosition); rectangle.Fill = InterlacedColor; rectangle.SetValue(Canvas.LeftProperty, (Double)0); rectangle.SetValue(Canvas.TopProperty, position); rectangle.SetValue(Canvas.ZIndexProperty, (Int32)(-countRectangles)); Visual.Children.Add(rectangle); InterlacedRectangles.Add(rectangle); } break; } Visual.Children.Add(line); prevPosition = position; index += (ParentAxis.SkipOffset + 1); if (ParentAxis.IsDateTimeAxis) { DateTime dt = DateTimeHelper.UpdateDate(ParentAxis.FirstLabelDate, (Double)(index * gap), ParentAxis.InternalIntervalType); Decimal oneUnit = (Decimal)DateTimeHelper.DateDiff(dt, ParentAxis.FirstLabelDate, ParentAxis.MinDateRange, ParentAxis.MaxDateRange, ParentAxis.InternalIntervalType, ParentAxis.XValueType); xValue = minVal + oneUnit; } else { xValue = minVal + index * gap; } } if (index % 2 == 1) { Rectangle rectangle = new Rectangle(); ScaleTransform scaleTransform = null; switch (Placement) { case PlacementTypes.Top: case PlacementTypes.Bottom: rectangle.Width = Math.Abs(Width - position); rectangle.Height = Height; if (animationEnabled) { if (countRectangles % 2 == 0) { scaleTransform = new ScaleTransform() { ScaleX = 1, ScaleY = 0 }; rectangle.RenderTransformOrigin = new Point(0.5, 1); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleY)", 0, 1, 0.5, animationDuration)); } else { scaleTransform = new ScaleTransform() { ScaleX = 1, ScaleY = 0 }; rectangle.RenderTransformOrigin = new Point(0.5, 0); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleY)", 0, 1, 0.5, animationDuration)); } } rectangle.SetValue(Canvas.LeftProperty, position); rectangle.SetValue(Canvas.TopProperty, (Double)0); break; case PlacementTypes.Left: case PlacementTypes.Right: rectangle.Width = Width; rectangle.Height = Math.Abs(position); if (animationEnabled) { if (countRectangles % 2 == 0) { scaleTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 1 }; rectangle.RenderTransformOrigin = new Point(0, 0.5); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleX)", 0, 1, 0.5, animationDuration)); } else { scaleTransform = new ScaleTransform() { ScaleX = 0, ScaleY = 1 }; rectangle.RenderTransformOrigin = new Point(1, 0.5); Storyboard.Children.Add(CreateDoubleAnimation(scaleTransform, "(ScaleTransform.ScaleX)", 0, 1, 0.5, animationDuration)); } } rectangle.SetValue(Canvas.LeftProperty, (Double)0); rectangle.SetValue(Canvas.TopProperty, (Double)0); break; } rectangle.RenderTransform = scaleTransform; rectangle.Fill = InterlacedColor; rectangle.SetValue(Canvas.ZIndexProperty, (Int32)(-countRectangles)); Visual.Children.Add(rectangle); InterlacedRectangles.Add(rectangle); } } Visual.Width = Width; Visual.Height = Height; }
/// <summary> /// Update visual used for partial update /// </summary> /// <param name="propertyName">Name of the property</param> /// <param name="value">Value of the property</param> internal override void UpdateVisual(VcProperties propertyName, object value) { if (Visual != null) { if (InterlacedRectangles != null) { foreach (Rectangle rec in InterlacedRectangles) { rec.Fill = InterlacedColor; } } if (InterlacedPaths != null) { foreach (Path path in InterlacedPaths) { path.Fill = InterlacedColor; } } if (InterlacedLines != null) { foreach (Line line in InterlacedLines) { line.Stroke = LineColor; line.StrokeThickness = (Double)LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); } } Chart chart = Chart as Chart; if (Chart != null && ParentAxis != null && chart.ChartArea != null) { if (ParentAxis.AxisRepresentation == AxisRepresentations.AxisY && ParentAxis.AxisType == AxisTypes.Primary) { List <Line> interlacedLinesOverVerticalPlank = chart.ChartArea.InterlacedLinesOverVerticalPlank; if (interlacedLinesOverVerticalPlank != null) { foreach (Line line in interlacedLinesOverVerticalPlank) { line.Stroke = LineColor; line.StrokeThickness = (Double)LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); } } List <Path> interlacedPathsOverVerticalPlank = chart.ChartArea.InterlacedPathsOverVerticalPlank; if (interlacedPathsOverVerticalPlank != null) { foreach (Path path in interlacedPathsOverVerticalPlank) { path.Fill = InterlacedColor; } } } } } else { FirePropertyChanged(propertyName); } }
/// <summary> /// /// </summary> /// <param name="obj">Object may be DataSeries or DataPoint</param> /// <param name="property"></param> /// <param name="newValue"></param> private static void UpdateDataSeries(ObservableObject obj, VcProperties property, object newValue) { DataPoint dataPoint = null; DataSeries dataSeries = obj as DataSeries; Boolean isDataPoint = false; if (dataSeries == null) { isDataPoint = true; dataPoint = obj as DataPoint; dataSeries = dataPoint.Parent; } Chart chart = dataSeries.Chart as Chart; if (chart == null) { return; } PlotGroup plotGroup = dataSeries.PlotGroup; Canvas line2dCanvas = null; Canvas label2dCanvas = null; Path linePath = null; Path lineShadowPath = null; if (dataSeries.Faces != null) { if (dataSeries.Faces.Parts.Count > 0) { linePath = dataSeries.Faces.Parts[0] as Path; if (dataSeries.Faces.Parts.Count > 1) { lineShadowPath = dataSeries.Faces.Parts[1] as Path; } } line2dCanvas = dataSeries.Faces.Visual as Canvas; label2dCanvas = dataSeries.Faces.LabelCanvas as Canvas; } else if (dataSeries.Faces == null && property == VcProperties.Enabled && (Boolean)newValue == true) { ColumnChart.Update(chart, dataSeries.RenderAs, (from ds in chart.InternalSeries where ds.RenderAs == RenderAs.QuickLine select ds).ToList()); return; } else { return; } Double height = chart.ChartArea.ChartVisualCanvas.Height; Double width = chart.ChartArea.ChartVisualCanvas.Width; switch (property) { case VcProperties.Color: if (linePath != null) { Brush lineColorValue = (newValue != null) ? newValue as Brush : dataSeries.Color; linePath.Stroke = ((Boolean)dataSeries.LightingEnabled) ? Graphics.GetLightingEnabledBrush(lineColorValue, "Linear", new Double[] { 0.65, 0.55 }) : lineColorValue; //dataPoint.Color; } break; case VcProperties.LightingEnabled: if (linePath != null) { linePath.Stroke = ((Boolean)newValue) ? Graphics.GetLightingEnabledBrush(dataSeries.Color, "Linear", new Double[] { 0.65, 0.55 }) : dataSeries.Color; } break; case VcProperties.Opacity: if (linePath != null) { linePath.Opacity = (Double)dataSeries.Opacity; } break; case VcProperties.LineStyle: case VcProperties.LineThickness: if (lineShadowPath != null) { lineShadowPath.StrokeThickness = (Double)dataSeries.LineThickness; } if (linePath != null) { linePath.StrokeThickness = (Double)dataSeries.LineThickness; } if (lineShadowPath != null) { lineShadowPath.StrokeDashArray = ExtendedGraphics.GetDashArray(dataSeries.LineStyle); } if (linePath != null) { linePath.StrokeDashArray = ExtendedGraphics.GetDashArray(dataSeries.LineStyle); } break; case VcProperties.Enabled: if (!isDataPoint && line2dCanvas != null) { if ((Boolean)newValue == false) { line2dCanvas.Visibility = Visibility.Collapsed; label2dCanvas.Visibility = Visibility.Collapsed; } else { if (line2dCanvas.Parent == null) { ColumnChart.Update(chart, dataSeries.RenderAs, (from ds in chart.InternalSeries where ds.RenderAs == RenderAs.QuickLine select ds).ToList()); return; } line2dCanvas.Visibility = Visibility.Visible; label2dCanvas.Visibility = Visibility.Visible; } chart._toolTip.Hide(); break; } goto RENDER_SERIES; case VcProperties.ShadowEnabled: case VcProperties.DataPoints: case VcProperties.YValue: case VcProperties.YValues: case VcProperties.XValue: case VcProperties.ViewportRangeEnabled: case VcProperties.DataPointUpdate: RENDER_SERIES: LineChart.UpdateLineSeries(dataSeries, width, height, label2dCanvas); break; } }
/// <summary> /// Creates the major ticks and also positions them appropriately /// </summary> private void CreateAndPositionMajorTicks() { Double startOffset = Double.IsNaN(ParentAxis.StartOffset) ? 0 : ParentAxis.StartOffset; Double endOffset = Double.IsNaN(ParentAxis.EndOffset) ? 0 : ParentAxis.EndOffset; // Calculate interval Double interval = (Double)Interval; Decimal index = 0; Decimal minval = (Decimal)Minimum; Decimal maxVal = (Decimal)Maximum; // Decimal gap = (Decimal)interval + (((Nullable<Double>)GetValue(IntervalProperty) == null) ? ParentAxis.SkipOfset : 0); Decimal gap = (Decimal)interval; Double position; if (ParentAxis.AxisRepresentation == AxisRepresentations.AxisX) { if (Double.IsNaN((Double)ParentAxis.AxisMinimumNumeric)) { if (ParentAxis.XValueType != ChartValueTypes.Numeric) { minval = (Decimal)ParentAxis.FirstLabelPosition; } else { if ((DataMinimum - Minimum) / interval >= 1) { minval = (Decimal)(DataMinimum - Math.Floor((DataMinimum - Minimum) / interval) * interval); } else { minval = (Decimal)DataMinimum; } } } } //minval = index; //maxVal = maxVal + gap / 1000; if (minval != maxVal) { Decimal xValue; for (xValue = minval; xValue <= maxVal;) { Line line = new Line(); line.Stroke = LineColor; line.StrokeThickness = LineThickness; line.StrokeDashArray = ExtendedGraphics.GetDashArray(LineStyle); switch (Placement) { case PlacementTypes.Top: position = Graphics.ValueToPixelPosition(startOffset, Width - endOffset, Minimum, Maximum, (Double)xValue); if (Double.IsNaN(position)) { return; } line.X1 = position; line.X2 = position; line.Y1 = 0; line.Y2 = TickLength; break; case PlacementTypes.Bottom: position = Graphics.ValueToPixelPosition(startOffset, Width - endOffset, Minimum, Maximum, (Double)xValue); if (Double.IsNaN(position)) { return; } line.X1 = position; line.X2 = position; line.Y1 = 0; line.Y2 = TickLength; break; case PlacementTypes.Left: case PlacementTypes.Right: position = Graphics.ValueToPixelPosition(Height - endOffset, startOffset, Minimum, Maximum, (Double)xValue); if (Double.IsNaN(position)) { return; } line.X1 = 0; line.X2 = TickLength; line.Y1 = position; line.Y2 = position; break; } //System.Diagnostics.Debug.WriteLine("XValue=" + xValue.ToString()); Visual.Children.Add(line); index += (ParentAxis.SkipOffset + 1); if (ParentAxis.IsDateTimeAxis) { DateTime dt = DateTimeHelper.UpdateDate(ParentAxis.FirstLabelDate, (Double)(index * gap), ParentAxis.InternalIntervalType); Decimal oneUnit = (Decimal)DateTimeHelper.DateDiff(dt, ParentAxis.FirstLabelDate, ParentAxis.MinDateRange, ParentAxis.MaxDateRange, ParentAxis.InternalIntervalType, ParentAxis.XValueType); xValue = minval + oneUnit; } else { xValue = minval + index * gap; } } } switch (Placement) { case PlacementTypes.Top: case PlacementTypes.Bottom: Visual.Width = Width; Visual.Height = TickLength; break; case PlacementTypes.Left: case PlacementTypes.Right: Visual.Height = Height; Visual.Width = TickLength; break; } }