public void UpdateAxes() { PlotDetails = new PlotDetails(Chart); ClearAxesPanel(); PopulateInternalAxesXList(); PopulateInternalAxesYList(); if (PlotDetails.ChartOrientation != ChartOrientationType.NoAxis) SetAxesProperties(); RenderAxes(this._plotAreaSize); SetAxesProperties(); }
/// <summary> /// Get visual object for stacked column chart /// </summary> /// <param name="width">Width of the PlotArea</param> /// <param name="height">Height of the PlotArea</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">PlankDepth</param> /// <param name="animationEnabled">Whether animation is enabled for chart</param> /// <returns>StackedColumn chart canvas</returns> internal static Canvas GetVisualObjectForStackedColumnChart(RenderAs chartType, Panel preExistingPanel, Double width, Double height, PlotDetails plotDetails, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; Canvas visual, labelCanvas, columnCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out columnCanvas, width, height); List<PlotGroup> plotGroupList = (from plots in plotDetails.PlotGroups where plots.RenderAs == chartType select plots).ToList(); Double depth3d = plankDepth / plotDetails.Layer3DCount * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[plotGroupList[0].DataSeriesList[0]] + 1); visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); List<DataSeries> seriesList = plotDetails.GetSeriesListByRenderAs(chartType); Dictionary<Axis, Dictionary<Axis, Int32>> seriesIndex = ColumnChart.GetSeriesIndex(seriesList); Double minDiff, widthPerColumn, maxColumnWidth; DataSeries currentDataSeries = null; foreach (PlotGroup plotGroup in plotGroupList) { if (!seriesIndex.ContainsKey(plotGroup.AxisY)) continue; currentDataSeries = plotGroup.DataSeriesList[0]; List<Double> xValuesList = plotGroup.XWiseStackedDataList.Keys.ToList(); plotGroup.DrawingIndex = seriesIndex[plotGroup.AxisY][plotGroup.AxisX]; widthPerColumn = CalculateWidthOfEachStackedColumn(chart, plotGroup, width, out minDiff, out maxColumnWidth); Double limitingYValue = 0; if (plotGroup.AxisY.InternalAxisMinimum > 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMinimum; if (plotGroup.AxisY.InternalAxisMaximum < 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMaximum; foreach (Double xValue in xValuesList) { DrawStackedColumnsAtXValue(chartType, xValue, plotGroup, columnCanvas, labelCanvas, plotGroup.DrawingIndex, widthPerColumn, maxColumnWidth, limitingYValue, depth3d, animationEnabled); } } // Apply animation if (animationEnabled && currentDataSeries != null) { if (currentDataSeries.Storyboard == null) currentDataSeries.Storyboard = new Storyboard(); // Apply animation to the marker and labels currentDataSeries.Storyboard = AnimationHelper.ApplyOpacityAnimation(labelCanvas, currentDataSeries, currentDataSeries.Storyboard, 1, 1, 0, 1); } ColumnChart.CreateOrUpdatePlank(chart, plotGroupList[0].AxisY, columnCanvas, depth3d, Orientation.Horizontal); // Remove old visual and add new visual in to the existing panel if (preExistingPanel != null) { visual.Children.RemoveAt(1); visual.Children.Add(columnCanvas); } else { labelCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelCanvas); visual.Children.Add(columnCanvas); } RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, -chart.ChartArea.PLANK_DEPTH - (chart.View3D ? 0 : 5), width + chart.ChartArea.PLANK_DEPTH, height + chart.ChartArea.PLANK_DEPTH + chart.ChartArea.PLANK_THICKNESS + (chart.View3D ? 0 : 10)); visual.Clip = clipRectangle; return visual; }
/// <summary> /// Draw chartarea /// </summary> /// <param name="chart">Chart</param> public void Draw(Chart chart) { isScrollingActive = Chart.IsScrollingActivated; //System.Diagnostics.Debug.WriteLine("Draw() > "); _renderCount = 0; Chart = chart; ClearAxesPanel(); ResetTitleAndLegendPannelsSize(); SetSeriesStyleFromTheme(); SetTitleStyleFromTheme(); SetDataPointColorFromColorSet(chart.Series); PopulateInternalAxesXList(); PopulateInternalAxesYList(); PopulateInternalSeriesList(); PlotDetails = new PlotDetails(chart); SetLegendStyleFromTheme(); CalculatePlankParameters(); ClearTitlePanels(); ClearLegendPanels(); Boolean isLeftOrRightAlignedTitlesExist; Size actualChartSize = GetActualChartSize(); // Add all the legends to chart of type dock outside AddTitles(chart, false, actualChartSize.Height, actualChartSize.Width, out isLeftOrRightAlignedTitlesExist); // Calculate max size for legend Size remainingSizeAfterAddingTitles = CalculateLegendMaxSize(actualChartSize); // Add all the legends to chart of type dock outside AddLegends(chart, false, remainingSizeAfterAddingTitles.Height, remainingSizeAfterAddingTitles.Width); // Create PlotArea CreatePlotArea(chart); // Calculate PlotArea Size _plotAreaSize = CalculatePlotAreaSize(remainingSizeAfterAddingTitles); // Need to recalculate PlotArea size if any title exist with left or right aligned if (isLeftOrRightAlignedTitlesExist) { ClearTitlePanels(); AddTitles(chart, false, _plotAreaSize.Height, actualChartSize.Width, out isLeftOrRightAlignedTitlesExist); ResetTitleAndLegendPannelsSize(); remainingSizeAfterAddingTitles = CalculateLegendMaxSize(actualChartSize); _plotAreaSize = CalculatePlotAreaSize(remainingSizeAfterAddingTitles); } HideAllAxesScrollBars(); // Check if drawing axis is necessary or not if (PlotDetails.ChartOrientation != ChartOrientationType.NoAxis) SetAxesProperties(); Size remainingSize = DrawChart(_plotAreaSize); // Add all the titles to chart of type dock inside AddTitles(Chart, true, remainingSize.Height, remainingSize.Width, out isLeftOrRightAlignedTitlesExist); // Add all the legends to chart of type dock inside AddLegends(Chart, true, remainingSize.Height, remainingSize.Width); RetainOldScrollOffsetOfScrollViewer(); //Chart.AttachEvents2Visual(Chart.PlotArea, PlotAreaCanvas); AttachOrDetachIntaractivity(chart.InternalSeries); if (!_isFirstTimeRender || !chart.AnimationEnabled) { AttachScrollEvents(); Visifire.Charts.Chart.SelectDataPoints(Chart); chart.Dispatcher.BeginInvoke(new Action(chart.UnlockRender)); } chart._forcedRedraw = false; AddOrRemovePanels(chart); }
/// <summary> /// Get visual object for Polar chart /// </summary> /// <param name="width">Width</param> /// <param name="height">Height</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of series</param> /// <param name="chart">Chart</param> /// <param name="isAnimationEnabled">Whether animation is enabled for chart</param> /// <returns>Canvas</returns> internal static Canvas GetVisualObjectForPolarChart(Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, bool isAnimationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; Canvas visual = new Canvas() { Width = width, Height = height }; Axis axisX = seriesList[0].PlotGroup.AxisX; Size radarSize = new Size(width, height); foreach (DataSeries ds in seriesList) { if (ds.InternalDataPoints.Count == 0) continue; Canvas polarCanvas = GetDataSeriesVisual(chart, radarSize.Width, radarSize.Height, ds, axisX.CircularPlotDetails); visual.Children.Add(polarCanvas); } return visual; }
/// <summary> /// Returns the visual object for funnel chart /// </summary> /// <param name="width">PlotArea width</param> /// <param name="height">PlotArea height</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of line series</param> /// <param name="chart">Chart</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <param name="isStreamLine">Whether funnel chart is a Streamline funnel chart</param> /// <returns></returns> public static Grid GetVisualObjectForFunnelChart(Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, bool animationEnabled, Boolean isStreamLine) { if (seriesList.Count > 0) { DataSeries funnelSeries; // DataSeries used for drawing funnel chart List<DataPoint> funnelDataPoints; // DataPoints considered for drawing funnel chart // Select DataSeries for render List<DataSeries> selectedDataSeriesList = (from ds in seriesList where (Boolean)ds.Enabled == true select ds).ToList(); if (selectedDataSeriesList.Count > 0) { funnelSeries = selectedDataSeriesList.First(); foreach (DataPoint dp in funnelSeries.DataPoints) dp.VisualParams = null; funnelSeries.Faces = null; } else return null; List<DataPoint> tempDataPoints = (from dp in funnelSeries.DataPoints where dp.Enabled == true && dp.YValue >= 0 select dp).ToList(); if ((from dp in tempDataPoints where dp.YValue == 0 select dp).Count() == tempDataPoints.Count) return null; // If number of DataPoints is equals to 0 then dont do any operation if (tempDataPoints.Count == 0 || (tempDataPoints.Count == 1 && tempDataPoints[0].YValue == 0)) return null; if (isStreamLine) { if (tempDataPoints.Count <= 1) throw new Exception("Invalid DataSet. StreamLineFunnel chart must have more than one DataPoint in a DataSeries with YValue > 0."); funnelDataPoints = (from dp in tempDataPoints orderby dp.YValue descending select dp).ToList(); } else funnelDataPoints = tempDataPoints.ToList(); // Create funnel chart canvas Grid _funnelChartGrid = new Grid() { Height = height, Width = width }; #region Create layout for Funnel chart and labels // Create canvas for label Canvas labelCanvas = new Canvas() { Height = height }; // Create canvas for funnel Canvas funnelCanvas = new Canvas() { Height = height, HorizontalAlignment = HorizontalAlignment.Left }; _funnelChartGrid.Children.Add(funnelCanvas); _funnelChartGrid.Children.Add(labelCanvas); #endregion funnelSeries.Storyboard = null; if ((funnelSeries.Chart as Chart).InternalAnimationEnabled) funnelSeries.Storyboard = new Storyboard(); // Creating labels for CreateLabelsAndSetFunnelCanvasSize(isStreamLine, _funnelChartGrid, labelCanvas, funnelCanvas, funnelDataPoints); Double minPointHeight = funnelSeries.MinPointHeight; Double yScale = 40; Boolean isSameSlantAngle = true; Double bottomRadius = 5; Double gapRatio = (chart.View3D) ? 0.04 : 0.02; funnelCanvas = CreateFunnelChart(_funnelChartGrid, funnelSeries, funnelDataPoints, isStreamLine, funnelCanvas, minPointHeight, chart.View3D, yScale, gapRatio, isSameSlantAngle, bottomRadius, animationEnabled); // here // funnelChartCanvas.Background = new SolidColorBrush(Colors.Red); if (!chart.InternalAnimationEnabled || chart.IsInDesignMode || !chart.ChartArea._isFirstTimeRender) { foreach (DataPoint dp in funnelDataPoints) { if (dp.Faces != null) { foreach (Shape shape in dp.Faces.BorderElements) { InteractivityHelper.ApplyBorderEffect(shape, (BorderStyles)dp.BorderStyle, dp.InternalBorderThickness.Left, dp.BorderColor); } } } } RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, 0, width, chart.PlotArea.Visual.Height); _funnelChartGrid.Clip = clipRectangle; return _funnelChartGrid; } return null; }
/// <summary> /// Return visual object for doughnut chart /// </summary> /// <param name="width">Width of the PlotArea</param> /// <param name="height">Height of the PlotArea</param> /// <param name="plotDetails">PlotDetails reference</param> /// <param name="seriesList">List of series list</param> /// <param name="chart">Chart reference</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <returns>Canvas</returns> internal static Canvas GetVisualObjectForDoughnutChart(Double widthOfPlotArea, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, bool animationEnabled) { if (Double.IsNaN(widthOfPlotArea) || Double.IsNaN(height) || widthOfPlotArea <= 0 || height <= 0) return null; DataSeries currentDataSeries = null; Canvas visual = new Canvas(); visual.Width = widthOfPlotArea; visual.Height = height; DataSeries series = seriesList[0]; if (series.Enabled == false) return visual; // List<DataPoint> enabledDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Enabled == true && datapoint.InternalYValue != 0 && !Double.IsNaN(datapoint.InternalYValue) select datapoint).ToList(); List<DataPoint> enabledDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Enabled == true && !Double.IsNaN(datapoint.InternalYValue) select datapoint).ToList(); if ((from dp in enabledDataPoints select dp.InternalYValue).Sum() == 0) enabledDataPoints.Clear(); Double absoluteSum = plotDetails.GetAbsoluteSumOfDataPoints(enabledDataPoints); absoluteSum = (absoluteSum == 0) ? 1 : absoluteSum; Double centerX = widthOfPlotArea / 2; Double centerY = height / 2; Double offsetX = 0; Double offsetY = 0; Size pieCanvas = new Size(); Canvas labelCanvas = CreateAndPositionLabels(absoluteSum, enabledDataPoints, widthOfPlotArea, height, ((chart.View3D) ? 0.4 : 1), chart.View3D, ref pieCanvas); Double radius = Math.Min(pieCanvas.Width, pieCanvas.Height) / (chart.View3D ? 1 : 2); Double startAngle = series.InternalStartAngle; Double endAngle = 0; Double angle; Double meanAngle; Double absoluteYValue; Double radiusDiff = 0; var explodedDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Exploded == true && datapoint.InternalYValue != 0 select datapoint); radiusDiff = (explodedDataPoints.Count() > 0) ? radius * 0.3 : 0; if (chart.View3D) { _elementPositionData = new List<ElementPositionData>(); } if (labelCanvas != null) { labelCanvas.SetValue(Canvas.ZIndexProperty, 50001); labelCanvas.IsHitTestVisible = false; } if (series.Storyboard == null) series.Storyboard = new Storyboard(); currentDataSeries = series; SectorChartShapeParams doughnutParams = null; Int32 labelStateCounter = 0; if (!chart.View3D) { foreach (DataPoint dataPoint in enabledDataPoints) { if (dataPoint.LabelStyle == LabelStyles.Inside || !(Boolean)dataPoint.LabelEnabled) labelStateCounter++; } } foreach (DataPoint dataPoint in enabledDataPoints) { if (Double.IsNaN(dataPoint.InternalYValue))// || dataPoint.InternalYValue == 0) continue; absoluteYValue = Math.Abs(dataPoint.InternalYValue); angle = (absoluteYValue / absoluteSum) * Math.PI * 2; endAngle = startAngle + angle; meanAngle = (startAngle + endAngle) / 2; doughnutParams = new SectorChartShapeParams(); dataPoint.VisualParams = doughnutParams; doughnutParams.AnimationEnabled = animationEnabled; doughnutParams.Storyboard = series.Storyboard; doughnutParams.ExplodeRatio = chart.View3D ? 0.2 : 0.1; doughnutParams.Center = new Point(centerX, centerY); doughnutParams.DataPoint = dataPoint; doughnutParams.InnerRadius = radius / 2; doughnutParams.OuterRadius = radius; if (chart.View3D) { doughnutParams.StartAngle = doughnutParams.FixAngle((startAngle) % (Math.PI * 2)); doughnutParams.StopAngle = doughnutParams.FixAngle((endAngle) % (Math.PI * 2)); } else { doughnutParams.StartAngle = startAngle; doughnutParams.StopAngle = endAngle; } doughnutParams.Lighting = (Boolean)dataPoint.LightingEnabled; doughnutParams.Bevel = series.Bevel; doughnutParams.IsLargerArc = (angle / (Math.PI)) > 1; doughnutParams.Background = dataPoint.Color; doughnutParams.Width = widthOfPlotArea; doughnutParams.Height = height; doughnutParams.TiltAngle = Math.Asin(0.4); doughnutParams.Depth = 20 / doughnutParams.YAxisScaling; doughnutParams.MeanAngle = meanAngle; doughnutParams.LabelLineEnabled = (Boolean)dataPoint.LabelLineEnabled; doughnutParams.LabelLineColor = dataPoint.LabelLineColor; doughnutParams.LabelLineThickness = (Double)dataPoint.LabelLineThickness; doughnutParams.LabelLineStyle = ExtendedGraphics.GetDashArray((LineStyles)dataPoint.LabelLineStyle); offsetX = radius * doughnutParams.ExplodeRatio * Math.Cos(meanAngle); offsetY = radius * doughnutParams.ExplodeRatio * Math.Sin(meanAngle); doughnutParams.OffsetX = offsetX; doughnutParams.OffsetY = offsetY * (chart.View3D ? doughnutParams.YAxisScaling : 1); if (dataPoint.LabelVisual != null) { if (dataPoint.LabelVisual.Visibility == Visibility.Collapsed) doughnutParams.LabelLineEnabled = false; Double left = (Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty); if (left < widthOfPlotArea / 2) { doughnutParams.LabelLineTargetToRight = true; // pieParams.LabelPoint = new Point((Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty) + dataPoint.LabelVisual.DesiredSize.Width, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.DesiredSize.Height / 2); doughnutParams.LabelPoint = new Point(left + dataPoint.LabelVisual.Width + LabelPlacementHelper.LABEL_LINE_GAP, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.Height / 2); } else { doughnutParams.LabelLineTargetToRight = false; doughnutParams.LabelPoint = new Point(left - LabelPlacementHelper.LABEL_LINE_GAP, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.Height / 2); } //if ((Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty) < width / 2) //{ // doughnutParams.LabelPoint = new Point((Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty) + dataPoint.LabelVisual.Width + LABEL_LINE_GAP, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.Height / 2); //} //else //{ // doughnutParams.LabelPoint = new Point((Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty) - LABEL_LINE_GAP, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.Height / 2); //} // apply animation to the labels if (animationEnabled) { series.Storyboard = CreateOpacityAnimation(currentDataSeries, doughnutParams.DataPoint, series.Storyboard, dataPoint.LabelVisual, 2, 1, 0.5); dataPoint.LabelVisual.Opacity = 0; } } if (dataPoint.LabelStyle == LabelStyles.Inside && dataPoint.InternalYValue == 0) doughnutParams.LabelLineEnabled = false; Faces faces = new Faces(); faces.Parts = new List<DependencyObject>(); doughnutParams.TagReference = dataPoint; if (chart.View3D) { PieDoughnut3DPoints unExplodedPoints = new PieDoughnut3DPoints(); PieDoughnut3DPoints explodedPoints = new PieDoughnut3DPoints(); List<Shape> doughnutFaces = GetDoughnut3D(currentDataSeries, ref faces, doughnutParams, ref unExplodedPoints, ref explodedPoints, ref dataPoint.LabelLine, enabledDataPoints); foreach (Shape path in doughnutFaces) { if (path != null) { visual.Children.Add(path); faces.VisualComponents.Add(path); faces.BorderElements.Add(path); path.RenderTransform = new TranslateTransform(); // apply animation to the 3D sections if (animationEnabled) { series.Storyboard = CreateOpacityAnimation(currentDataSeries, doughnutParams.DataPoint, series.Storyboard, path, 1.0 / (series.InternalDataPoints.Count) * (series.InternalDataPoints.IndexOf(dataPoint)), dataPoint.InternalOpacity, 0.5); path.Opacity = 0; } } } if (dataPoint.LabelLine != null && doughnutParams.LabelLineEnabled) { dataPoint.LabelLine.RenderTransform = new TranslateTransform(); visual.Children.Add(dataPoint.LabelLine); if (dataPoint.InternalYValue == 0) { Double yOffset = doughnutParams.YAxisScaling; Line zeroLine = new Line(); zeroLine.X1 = doughnutParams.Center.X + doughnutParams.InnerRadius * Math.Cos(doughnutParams.MeanAngle); zeroLine.Y1 = doughnutParams.Center.Y + doughnutParams.InnerRadius * Math.Sin(doughnutParams.MeanAngle); zeroLine.Y1 -= offsetY; zeroLine.Y1 += doughnutParams.Depth / 2 * doughnutParams.ZAxisScaling; zeroLine.X2 = unExplodedPoints.LabelLineStartPoint.X; zeroLine.Y2 = unExplodedPoints.LabelLineStartPoint.Y; zeroLine.Stroke = doughnutParams.LabelLineColor; zeroLine.StrokeThickness = 0.25; zeroLine.IsHitTestVisible = false; visual.Children.Add(zeroLine); if (animationEnabled) { series.Storyboard = CreateOpacityAnimation(currentDataSeries, doughnutParams.DataPoint, series.Storyboard, zeroLine, 2, zeroLine.Opacity, 0.5); zeroLine.Opacity = 0; } } faces.VisualComponents.Add(dataPoint.LabelLine); } faces.Visual = visual; UpdateExplodedPosition(doughnutParams, dataPoint, offsetX, unExplodedPoints, explodedPoints, widthOfPlotArea); ///------------------------ dataPoint.ExplodeAnimation = new Storyboard(); dataPoint.ExplodeAnimation = CreateExplodingOut3DAnimation(currentDataSeries, dataPoint, dataPoint.ExplodeAnimation, doughnutFaces, dataPoint.LabelVisual as Canvas, dataPoint.LabelLine, unExplodedPoints, explodedPoints, doughnutParams.OffsetX, doughnutParams.OffsetY); dataPoint.UnExplodeAnimation = new Storyboard(); dataPoint.UnExplodeAnimation = CreateExplodingIn3DAnimation(currentDataSeries, dataPoint, dataPoint.UnExplodeAnimation, doughnutFaces, dataPoint.LabelVisual as Canvas, dataPoint.LabelLine, unExplodedPoints, explodedPoints, doughnutParams.OffsetX, doughnutParams.OffsetY); } else { PieDoughnut2DPoints unExplodedPoints = new PieDoughnut2DPoints(); PieDoughnut2DPoints explodedPoints = new PieDoughnut2DPoints(); if (labelStateCounter == enabledDataPoints.Count) { doughnutParams.OuterRadius -= doughnutParams.OuterRadius * doughnutParams.ExplodeRatio; doughnutParams.InnerRadius = doughnutParams.OuterRadius / 2; } Canvas pieVisual = GetDoughnut2D(currentDataSeries, ref faces, doughnutParams, ref unExplodedPoints, ref explodedPoints, ref dataPoint.LabelLine, enabledDataPoints); UpdateExplodedPosition(doughnutParams, dataPoint, offsetX, unExplodedPoints, explodedPoints, widthOfPlotArea); TranslateTransform translateTransform = new TranslateTransform(); pieVisual.RenderTransform = translateTransform; dataPoint.ExplodeAnimation = new Storyboard(); dataPoint.ExplodeAnimation = CreateExplodingOut2DAnimation(currentDataSeries, dataPoint, dataPoint.ExplodeAnimation, pieVisual, dataPoint.LabelVisual as Canvas, dataPoint.LabelLine, translateTransform, unExplodedPoints, explodedPoints, offsetX, offsetY); dataPoint.UnExplodeAnimation = new Storyboard(); dataPoint.UnExplodeAnimation = CreateExplodingIn2DAnimation(currentDataSeries, dataPoint, dataPoint.UnExplodeAnimation, pieVisual, dataPoint.LabelVisual as Canvas, dataPoint.LabelLine, translateTransform, unExplodedPoints, explodedPoints, offsetX, offsetY); pieVisual.SetValue(Canvas.TopProperty, height / 2 - pieVisual.Height / 2); pieVisual.SetValue(Canvas.LeftProperty, widthOfPlotArea / 2 - pieVisual.Width / 2); visual.Children.Add(pieVisual); faces.VisualComponents.Add(pieVisual); faces.Visual = pieVisual; } dataPoint.Faces = faces; startAngle = endAngle; if (!chart.AnimationEnabled || chart.IsInDesignMode || !chart.ChartArea._isFirstTimeRender) { if (dataPoint.Faces != null) { foreach (Shape shape in dataPoint.Faces.BorderElements) { InteractivityHelper.ApplyBorderEffect(shape, (BorderStyles)dataPoint.BorderStyle, dataPoint.InternalBorderThickness.Left, dataPoint.BorderColor); } } } } if (chart.View3D) { Int32 zindex1, zindex2; _elementPositionData.Sort(ElementPositionData.CompareAngle); zindex1 = 1000; zindex2 = -1000; for (Int32 i = 0; i < _elementPositionData.Count; i++) { SetZIndex(_elementPositionData[i].Element, ref zindex1, ref zindex2, _elementPositionData[i].StartAngle); } } if (labelCanvas != null) visual.Children.Add(labelCanvas); RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, 0, widthOfPlotArea, height); visual.Clip = clipRectangle; return visual; }
///// <summary> ///// Get visual object for area chart ///// </summary> ///// <param name="width">Width of the PlotArea</param> ///// <param name="height">Height of the PlotArea</param> ///// <param name="plotDetails">PlotDetails</param> ///// <param name="seriesList">List of DataSeries with render as area chart</param> ///// <param name="chart">Chart</param> ///// <param name="plankDepth">PlankDepth</param> ///// <param name="animationEnabled">Whether animation is enabled for chart</param> ///// <returns>Area chart canvas</returns> /* internal static Canvas GetVisualObjectForAreaChart(Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; Boolean plankDrawn = false; Canvas visual = new Canvas() { Width = width, Height = height }; Canvas labelCanvas = new Canvas() { Width = width, Height = height }; Canvas areaCanvas = new Canvas() { Width = width, Height = height }; Double depth3d = plankDepth / plotDetails.Layer3DCount * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1); areaCanvas.SetValue(Canvas.TopProperty, visualOffset); areaCanvas.SetValue(Canvas.LeftProperty, -visualOffset); labelCanvas.SetValue(Canvas.TopProperty, visualOffset); labelCanvas.SetValue(Canvas.LeftProperty, -visualOffset); Marker marker; foreach (DataSeries series in seriesList) { if (series.Enabled == false) continue; if (series.Storyboard == null) series.Storyboard = new Storyboard(); CurrentDataSeries = series; PlotGroup plotGroup = series.PlotGroup; Brush areaBrush = series.Color; Double limitingYValue = 0; if (plotGroup.AxisY.InternalAxisMinimum > 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMinimum; if (plotGroup.AxisY.InternalAxisMaximum < 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMaximum; PolygonalChartShapeParams areaParams = GetAreaParms(series, areaBrush, depth3d); areaParams.Storyboard = series.Storyboard; areaParams.AnimationEnabled = animationEnabled; areaParams.Size = new Size(width, height); PointCollection points = new PointCollection(); List<DataPoint> enabledDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Enabled == true select datapoint).ToList(); if (enabledDataPoints.Count <= 0) continue; Faces faces = new Faces(); series.Faces = faces; series.Faces.Parts = new List<DependencyObject>(); DataPoint currentDataPoint = enabledDataPoints[0]; DataPoint nextDataPoint; Double xPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, currentDataPoint.InternalXValue); Double yPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); points.Add(new Point(xPosition, yPosition)); for (Int32 i = 0; i < enabledDataPoints.Count - 1; i++) { currentDataPoint = enabledDataPoints[i]; nextDataPoint = enabledDataPoints[i + 1]; if (Double.IsNaN(currentDataPoint.InternalYValue)) continue; xPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, currentDataPoint.InternalXValue); yPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, currentDataPoint.InternalYValue); points.Add(new Point(xPosition, yPosition)); marker = GetMarkerForDataPoint(chart, currentDataPoint, yPosition, currentDataPoint.InternalYValue > 0); if (marker != null) { marker.AddToParent(labelCanvas, xPosition, yPosition, new Point(0.5, 0.5)); // Apply marker animation if (animationEnabled) { if (currentDataPoint.Parent.Storyboard == null) currentDataPoint.Parent.Storyboard = new Storyboard(); // Apply marker animation currentDataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, CurrentDataSeries, currentDataPoint.Parent.Storyboard, 1, currentDataPoint.Opacity * currentDataPoint.Parent.Opacity); } } if (Math.Sign(currentDataPoint.InternalYValue) != Math.Sign(nextDataPoint.InternalYValue)) { Double xNextPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, nextDataPoint.InternalXValue); Double yNextPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, nextDataPoint.InternalYValue); Double limitingYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); Double xNew = Graphics.ConvertScale(yPosition, yNextPosition, limitingYPosition, xPosition, xNextPosition); Double yNew = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); points.Add(new Point(xNew, yNew)); // get the faces areaParams.Points = points; areaParams.IsPositive = (currentDataPoint.InternalYValue > 0); if (chart.View3D) { Canvas areaVisual3D = Get3DArea(ref faces, areaParams); areaVisual3D.SetValue(Canvas.ZIndexProperty, GetAreaZIndex(xPosition, yPosition, areaParams.IsPositive)); areaCanvas.Children.Add(areaVisual3D); series.Faces.VisualComponents.Add(areaVisual3D); } else { areaCanvas.Children.Add(Get2DArea(ref faces, areaParams)); series.Faces.VisualComponents.Add(areaCanvas); } points = new PointCollection(); points.Add(new Point(xNew, yNew)); } } DataPoint lastDataPoint = enabledDataPoints[enabledDataPoints.Count - 1]; xPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, lastDataPoint.InternalXValue); yPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, lastDataPoint.InternalYValue); points.Add(new Point(xPosition, yPosition)); marker = GetMarkerForDataPoint(chart, lastDataPoint, yPosition, lastDataPoint.InternalYValue > 0); if (marker != null) { marker.AddToParent(labelCanvas, xPosition, yPosition, new Point(0.5, 0.5)); // Apply marker animation if (animationEnabled) { if (lastDataPoint.Parent.Storyboard == null) lastDataPoint.Parent.Storyboard = new Storyboard(); // Apply marker animation lastDataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, CurrentDataSeries, lastDataPoint.Parent.Storyboard, 1, lastDataPoint.Opacity * lastDataPoint.Parent.Opacity); } } xPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, lastDataPoint.InternalXValue); yPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); points.Add(new Point(xPosition, yPosition)); // Get the faces areaParams.Points = points; areaParams.IsPositive = (lastDataPoint.InternalYValue > 0); if (chart.View3D) { Canvas areaVisual3D = Get3DArea(ref faces, areaParams); areaVisual3D.SetValue(Canvas.ZIndexProperty, GetAreaZIndex(xPosition, yPosition, areaParams.IsPositive)); areaCanvas.Children.Add(areaVisual3D); series.Faces.VisualComponents.Add(areaVisual3D); } else { areaCanvas.Children.Add(Get2DArea(ref faces, areaParams)); series.Faces.VisualComponents.Add(areaCanvas); } if (!plankDrawn && chart.View3D && plotGroup.AxisY.InternalAxisMinimum < 0 && plotGroup.AxisY.InternalAxisMaximum > 0) { RectangularChartShapeParams columnParams = new RectangularChartShapeParams(); columnParams.BackgroundBrush = new SolidColorBrush(Color.FromArgb((Byte)255, (Byte)127, (Byte)127, (Byte)127)); columnParams.Lighting = true; columnParams.Size = new Size(width, 1); columnParams.Depth = depth3d; Faces zeroPlank = ColumnChart.Get3DColumn(columnParams); Panel zeroPlankVisual = zeroPlank.Visual as Panel; Double top = height - Graphics.ValueToPixelPosition(0, height, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, 0); zeroPlankVisual.SetValue(Canvas.LeftProperty, (Double)0); zeroPlankVisual.SetValue(Canvas.TopProperty, top); zeroPlankVisual.SetValue(Canvas.ZIndexProperty, 0); zeroPlankVisual.Opacity = 0.7; areaCanvas.Children.Add(zeroPlankVisual); } series.Faces.Visual = visual; series.Faces.LabelCanvas = labelCanvas; } visual.Children.Add(areaCanvas); visual.Children.Add(labelCanvas); return visual; } */ /// <summary> /// Get visual object for stacked area chart /// </summary> /// <param name="width">Width of the PlotArea</param> /// <param name="height">Height of the PlotArea</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of DataSeries with render as StackedArea chart</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">PlankDepth</param> /// <param name="animationEnabled">Whether animation is enabled for chart</param> /// <returns>StackedArea chart canvas</returns> internal static Canvas GetVisualObjectForStackedAreaChart(Panel preExistingPanel, Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; DataSeries currentDataSeries; Boolean plankDrawn = false; Double depth3d = plankDepth / plotDetails.Layer3DCount * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1); if (Double.IsNaN(visualOffset) || Double.IsInfinity(visualOffset)) return null; Canvas visual, labelCanvas, areaCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out areaCanvas, width, height); //labelCanvas.Background = Graphics.GetRandomColor(); //Canvas visual = new Canvas() { Width = width, Height = height }; //Canvas labelCanvas = new Canvas() { Width = width, Height = height }; //Canvas areaCanvas = new Canvas() { Width = width, Height = height }; visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); //labelCanvas.SetValue(Canvas.TopProperty, (Double) 0); //labelCanvas.SetValue(Canvas.LeftProperty,(Double) 0); //labelCanvas.SetValue(Canvas.ZIndexProperty, (Int32)1); var plotgroups = (from series in seriesList where series.PlotGroup != null select series.PlotGroup); if (plotgroups.Count() == 0) return visual; PlotGroup plotGroup = plotgroups.First(); Dictionary<Double, List<Double>> dataPointValuesInStackedOrder = plotDetails.GetDataPointValuesInStackedOrder4StackedArea(plotGroup); Dictionary<Double, List<DataPoint>> dataPointInStackedOrder = plotDetails.GetDataPointInStackOrder4StackedArea(plotGroup); // Double[] xValues = dataPointValuesInStackedOrder.Keys.ToArray(); Double[] xValues = RenderHelper.GetXValuesUnderViewPort(dataPointValuesInStackedOrder.Keys.ToList(), plotGroup.AxisX, plotGroup.AxisY, false); Double minimumXValue = plotGroup.MinimumX; Double maximumXValue = plotGroup.MaximumX; Double limitingYValue = 0; if (plotGroup.AxisY.InternalAxisMinimum > 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMinimum; if (plotGroup.AxisY.InternalAxisMaximum < 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMaximum; foreach (DataSeries ds in seriesList) { ds.Faces = null; if (ds.ToolTipElement != null) ds.ToolTipElement.Hide(); } Double limitingYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); Marker marker; for (Int32 i = 0; i < xValues.Length - 1; i++) { List<Double> curYValues = dataPointValuesInStackedOrder[xValues[i]]; List<Double> nextYValues = dataPointValuesInStackedOrder[xValues[i + 1]]; Double curBase = limitingYValue; Double nextBase = limitingYValue; List<DataPoint> curDataPoints = dataPointInStackedOrder[xValues[i]]; List<DataPoint> nextDataPoints = dataPointInStackedOrder[xValues[i + 1]]; Double totalOfCurrBase = 0; Double totalOfNextBase = 0; Double currTot = 0; Double nextTot = 0; for (Int32 index = 0; index < curYValues.Count; index++) { if (index >= nextYValues.Count || index >= curYValues.Count || curDataPoints[index] == null || nextDataPoints[index] == null) continue; Double curXPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, xValues[i]); Double nextXPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, xValues[i + 1]); Double totalOfCurrSucessiveDpValues = 0; Double totalOfNextSucessiveDpValues = 0; if (plotGroup.AxisY.Logarithmic) { totalOfCurrSucessiveDpValues = Math.Log(curBase + curYValues[index], plotGroup.AxisY.LogarithmBase); if (Double.IsNegativeInfinity(totalOfCurrSucessiveDpValues)) totalOfCurrSucessiveDpValues = 0; totalOfNextSucessiveDpValues = Math.Log(nextBase + nextYValues[index], plotGroup.AxisY.LogarithmBase); if (Double.IsNegativeInfinity(totalOfNextSucessiveDpValues)) totalOfNextSucessiveDpValues = 0; } else { totalOfCurrSucessiveDpValues = curBase + curYValues[index]; totalOfNextSucessiveDpValues = nextBase + nextYValues[index]; totalOfCurrBase = curBase; totalOfNextBase = nextBase; } Double curYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, totalOfCurrSucessiveDpValues); Double nextYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, totalOfNextSucessiveDpValues); Double curYBase = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, totalOfCurrBase); Double nextYBase = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, totalOfNextBase); if (plotGroup.AxisY.Logarithmic) { currTot += curYValues[index]; nextTot += nextYValues[index]; totalOfCurrBase = Math.Log(currTot, plotGroup.AxisY.LogarithmBase); if (Double.IsNegativeInfinity(totalOfCurrBase)) totalOfCurrBase = 0; totalOfNextBase = Math.Log(nextTot, plotGroup.AxisY.LogarithmBase); if (Double.IsNegativeInfinity(totalOfNextBase)) totalOfNextBase = 0; } Point intersect = GetIntersection(new Point(curXPosition, curYBase), new Point(nextXPosition, nextYBase), new Point(curXPosition, curYPosition), new Point(nextXPosition, nextYPosition)); Boolean isTopOfStack = false; if (index == curYValues.Count - 1) isTopOfStack = true; marker = GetMarkerForDataPoint(chart, height, isTopOfStack, curDataPoints[index], curYPosition, curDataPoints[index].InternalYValue > 0); if (marker != null) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); currentDataSeries = curDataPoints[index].Parent; marker.AddToParent(labelCanvas, curXPosition, curYPosition, new Point(0.5, 0.5)); // Apply marker animation if (animationEnabled) curDataPoints[index].Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, currentDataSeries, curDataPoints[index].Parent.Storyboard, 1, (Double)curDataPoints[index].Opacity * (Double)curDataPoints[index].Parent.Opacity); } curDataPoints[index]._visualPosition = new Point(curXPosition, curYPosition); if (i + 1 == xValues.Length - 1) { marker = GetMarkerForDataPoint(chart, height, isTopOfStack, nextDataPoints[index], nextYPosition, nextDataPoints[index].InternalYValue > 0); if (marker != null) { if (nextDataPoints[index].Parent.Storyboard == null) nextDataPoints[index].Parent.Storyboard = new Storyboard(); currentDataSeries = nextDataPoints[index].Parent; marker.AddToParent(labelCanvas, nextXPosition, nextYPosition, new Point(0.5, 0.5)); // Apply marker animation if (animationEnabled) nextDataPoints[index].Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, currentDataSeries, nextDataPoints[index].Parent.Storyboard, 1, (Double)nextDataPoints[index].Opacity * (Double)nextDataPoints[index].Parent.Opacity); } nextDataPoints[index]._visualPosition = new Point(nextXPosition, nextYPosition); } if (curDataPoints[index].Parent.Faces == null) { curDataPoints[index].Parent.Faces = new Faces(); } List<PointCollection> pointSet = null; if ((!Double.IsNaN(intersect.X) && !Double.IsInfinity(intersect.X)) && (intersect.X >= curXPosition && intersect.X <= nextXPosition)) { List<PointCollection> set1 = GeneratePointsCollection(curXPosition, curYPosition, curYBase, intersect.X, intersect.Y, intersect.Y, limitingYPosition); List<PointCollection> set2 = GeneratePointsCollection(intersect.X, intersect.Y, intersect.Y, nextXPosition, nextYPosition, nextYBase, limitingYPosition); pointSet = set1; pointSet.InsertRange(pointSet.Count, set2); } else { pointSet = GeneratePointsCollection(curXPosition, curYPosition, curYBase, nextXPosition, nextYPosition, nextYBase, limitingYPosition); } DataSeries series = curDataPoints[index].Parent; Brush areaBrush = series.Color; currentDataSeries = series; PolygonalChartShapeParams areaParams = GetAreaParms(series, areaBrush, depth3d); // This is used to set some pixel padding for the last two points of a PointCollection Double pixelPadding = 0.8; foreach (PointCollection points in pointSet) { points[points.Count - 2] = new Point(points[points.Count - 2].X + pixelPadding, points[points.Count - 2].Y); points[points.Count - 1] = new Point(points[points.Count - 1].X + pixelPadding, points[points.Count - 1].Y); areaParams.Points = points; Faces faces = curDataPoints[index].Parent.Faces; if (faces.Parts == null) faces.Parts = new List<DependencyObject>(); if (chart.View3D) { Point centroid = GetCentroid(points); areaParams.IsPositive = centroid.Y < limitingYPosition; Canvas frontface = GetStacked3DAreaFrontFace(ref faces, areaParams); Canvas sideface = GetStacked3DSideFaces(ref faces, areaParams); sideface.SetValue(Canvas.ZIndexProperty, GetStackedAreaZIndex(centroid.X, centroid.Y, areaParams.IsPositive, index)); frontface.SetValue(Canvas.ZIndexProperty, 50000); areaCanvas.Children.Add(sideface); areaCanvas.Children.Add(frontface); curDataPoints[index].Parent.Faces.VisualComponents.Add(sideface); curDataPoints[index].Parent.Faces.VisualComponents.Add(frontface); // Apply Animation if (animationEnabled) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); Storyboard storyboard = curDataPoints[index].Parent.Storyboard; // apply animation to the various faces storyboard = ApplyStackedAreaAnimation(currentDataSeries, sideface, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)) + 0.05, 1.0 / seriesList.Count); storyboard = ApplyStackedAreaAnimation(currentDataSeries, frontface, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)), 1.0 / seriesList.Count); } } else { Canvas area2d = GetStacked2DArea(ref faces, areaParams); areaCanvas.Children.Add(area2d); curDataPoints[index].Parent.Faces.VisualComponents.Add(area2d); if (animationEnabled) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); Storyboard storyboard = curDataPoints[index].Parent.Storyboard; // apply animation to the various faces storyboard = ApplyStackedAreaAnimation(currentDataSeries, area2d, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)), 1.0 / seriesList.Count); } } curDataPoints[index].Parent.Faces.Visual = visual; if (VisifireControl.IsMediaEffectsEnabled) { if ((Boolean)series.ShadowEnabled) { if (series.Faces != null && series.Faces.Visual != null) { #if !WP series.Faces.Visual.Effect = ExtendedGraphics.GetShadowEffect(135, 2, 1); #endif } } } } curBase += curYValues[index]; nextBase += nextYValues[index]; } } if (xValues.Count() > 0) { if (!plankDrawn && chart.View3D && plotGroup.AxisY.InternalAxisMinimum < 0 && plotGroup.AxisY.InternalAxisMaximum > 0) { //RectangularChartShapeParams columnParams = new RectangularChartShapeParams(); //Brush brush = new SolidColorBrush(Color.FromArgb((Byte)255, (Byte)255, (Byte)255, (Byte)255)); //columnParams.Lighting = true; //columnParams.Size = new Size(width, 1); //columnParams.Depth = depth3d; Brush frontBrush, topBrush, rightBrush; ExtendedGraphics.GetBrushesForPlank(chart, out frontBrush, out topBrush, out rightBrush, true); Faces zeroPlank = ColumnChart.Get3DPlank(width, 1, depth3d, frontBrush, topBrush, rightBrush); Panel zeroPlankVisual = zeroPlank.Visual as Panel; Double top = height - Graphics.ValueToPixelPosition(0, height, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, 0); zeroPlankVisual.SetValue(Canvas.LeftProperty, (Double)0); zeroPlankVisual.SetValue(Canvas.TopProperty, top); zeroPlankVisual.SetValue(Canvas.ZIndexProperty, 0); zeroPlankVisual.Opacity = 0.7; visual.Children.Add(zeroPlankVisual); } } //visual.Children.Add(areaCanvas); //visual.Children.Add(labelCanvas); chart.ChartArea.DisableIndicators(); // Remove old visual and add new visual in to the existing panel if (preExistingPanel != null) { visual.Children.RemoveAt(1); visual.Children.Add(areaCanvas); } else { labelCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelCanvas); visual.Children.Add(areaCanvas); } PlotArea plotArea = chart.PlotArea; RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, plotArea.BorderThickness.Top - depth3d, width + depth3d, height + depth3d + chart.ChartArea.PLANK_THICKNESS - plotArea.BorderThickness.Bottom - plotArea.BorderThickness.Top); areaCanvas.Clip = clipRectangle; // Clip the label canvas clipRectangle = new RectangleGeometry(); Double clipLeft = 0; Double clipTop = -depth3d - 4; Double clipWidth = width + depth3d; Double clipHeight = height + depth3d + chart.ChartArea.PLANK_THICKNESS + 10; GetClipCoordinates(chart, ref clipLeft, ref clipTop, ref clipWidth, ref clipHeight, minimumXValue, maximumXValue); clipRectangle.Rect = new Rect(clipLeft, clipTop, clipWidth, clipHeight); labelCanvas.Clip = clipRectangle; return visual; }
private static void CreateColumnDataPointVisual( Canvas parentCanvas, Canvas labelCanvas, PlotDetails plotDetails, DataPoint dataPoint, Boolean isPositive, Double widthOfAcolumn, Double depth3D, Boolean animationEnabled) { if (widthOfAcolumn < 0) return; DataSeries currentDataSeries = dataPoint.Parent; Chart chart = dataPoint.Chart as Chart; dataPoint.Parent.Faces = new Faces { Visual = parentCanvas, LabelCanvas = labelCanvas }; Double left, bottom, top, columnHeight; Size columnVisualSize; PlotGroup plotGroup = dataPoint.Parent.PlotGroup; Double limitingYValue = 0; if (plotGroup.AxisY.InternalAxisMinimum > 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMinimum; if (plotGroup.AxisY.InternalAxisMaximum < 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMaximum; List<DataSeries> indexSeriesList = plotDetails.GetSeriesFromDataPoint(dataPoint); Int32 drawingIndex = indexSeriesList.IndexOf(dataPoint.Parent); // if (dataPoint.InternalYValue > (Double)plotGroup.AxisY.InternalAxisMaximum) // System.Diagnostics.Debug.WriteLine("Max Value greater then axis max"); left = Graphics.ValueToPixelPosition(0, parentCanvas.Width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, dataPoint.InternalXValue); left = left + ((Double)drawingIndex - (Double)indexSeriesList.Count() / (Double)2) * widthOfAcolumn; // Double midPosition = Graphics.ValueToPixelPosition(0, parentCanvas.Width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, dataPoint.InternalXValue); Double zeroBaseLinePos = Graphics.ValueToPixelPosition(parentCanvas.Height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, 0); if (isPositive) { bottom = Graphics.ValueToPixelPosition(parentCanvas.Height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); top = Graphics.ValueToPixelPosition(parentCanvas.Height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, Double.IsNaN(dataPoint.InternalYValue) ? 0 : dataPoint.InternalYValue); if (plotGroup.AxisY.AxisMinimum != null && dataPoint.InternalYValue < limitingYValue && chart.View3D) { bottom = top = zeroBaseLinePos; } } else { bottom = Graphics.ValueToPixelPosition(parentCanvas.Height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, Double.IsNaN(dataPoint.InternalYValue) ? 0 : dataPoint.InternalYValue); top = Graphics.ValueToPixelPosition(parentCanvas.Height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); if (plotGroup.AxisY.AxisMinimum != null && limitingYValue>0 && dataPoint.InternalYValue < limitingYValue && chart.View3D) { top = bottom = bottom + 100; } } columnHeight = Math.Abs(top - bottom); if(columnHeight < dataPoint.Parent.MinPointHeight) { if (dataPoint.InternalYValue == 0) { if (plotGroup.AxisY.InternalAxisMaximum <= 0) bottom += (dataPoint.Parent.MinPointHeight - columnHeight); else top -= (dataPoint.Parent.MinPointHeight - columnHeight); } else if (isPositive) top -= (dataPoint.Parent.MinPointHeight - columnHeight); else bottom += (dataPoint.Parent.MinPointHeight - columnHeight); columnHeight = dataPoint.Parent.MinPointHeight; } columnVisualSize = new Size(widthOfAcolumn, columnHeight); Faces columnFaces = null; Panel columnVisual = null; if (chart.View3D) { columnFaces = Get3DColumn(dataPoint, widthOfAcolumn, columnHeight, depth3D, dataPoint.Color, null, null, null, (Boolean)dataPoint.LightingEnabled, (BorderStyles)dataPoint.BorderStyle, dataPoint.BorderColor, dataPoint.BorderThickness.Left); columnVisual = columnFaces.Visual as Panel; columnVisual.SetValue(Canvas.ZIndexProperty, GetColumnZIndex(left, top, (dataPoint.InternalYValue > 0))); dataPoint.Faces = columnFaces; if (!VisifireControl.IsMediaEffectsEnabled) ColumnChart.ApplyOrRemoveShadow4XBAP(dataPoint, false, false); } else { columnFaces = Get2DColumn(dataPoint, widthOfAcolumn, columnHeight, false, false); columnVisual = columnFaces.Visual as Panel; } dataPoint.Faces = columnFaces; if (VisifireControl.IsMediaEffectsEnabled) ColumnChart.ApplyOrRemoveShadow(chart, dataPoint); columnVisual.SetValue(Canvas.LeftProperty, left); columnVisual.SetValue(Canvas.TopProperty, top); parentCanvas.Children.Add(columnVisual); dataPoint.IsTopOfStack = true; CreateOrUpdateMarker4VerticalChart(dataPoint, labelCanvas, columnVisualSize, left, top); if(isPositive) dataPoint._visualPosition = new Point(left + columnVisualSize.Width / 2, top); else dataPoint._visualPosition = new Point(left + columnVisualSize.Width / 2, bottom); // Apply animation if (animationEnabled) { if (dataPoint.Parent.Storyboard == null) dataPoint.Parent.Storyboard = new Storyboard(); currentDataSeries = dataPoint.Parent; //dataPoint.Parent.Storyboard.Stop(); // Apply animation to the data points dataSeriesIndex.e to the rectangles that form the columns dataPoint.Parent.Storyboard = ApplyColumnChartAnimation(currentDataSeries, columnVisual, dataPoint.Parent.Storyboard, isPositive, 1, new Double[] { 0, 1 }, new Double[] { 0, 1 }, dataPoint.Parent.RenderAs); } dataPoint.Faces.Visual.Opacity = (Double)dataPoint.Opacity * (Double)dataPoint.Parent.Opacity; dataPoint.AttachEvent2DataPointVisualFaces(dataPoint); dataPoint.AttachEvent2DataPointVisualFaces(dataPoint.Parent); dataPoint._parsedToolTipText = dataPoint.TextParser(dataPoint.ToolTipText); if(!chart.IndicatorEnabled) dataPoint.AttachToolTip(chart, dataPoint, dataPoint.Faces.Visual); //dataPoint.AttachToolTip(chart, dataPoint, dataPoint.Faces.VisualComponents); dataPoint.AttachHref(chart, dataPoint.Faces.Visual, dataPoint.Href, (HrefTargets)dataPoint.HrefTarget); //dataPoint.AttachHref(chart, dataPoint.Faces.VisualComponents, dataPoint.Href, (HrefTargets)dataPoint.HrefTarget); dataPoint.SetCursor2DataPointVisualFaces(); chart._toolTip.Hide(); }
/// <summary> /// Get visual object for bubble chart /// </summary> /// <param name="width">Width of the chart</param> /// <param name="height">Height of the chart</param> /// <param name="plotDetails">plotDetails</param> /// <param name="seriesList">List of DataSeries</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">Plank depth</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <returns>Bubble chart canvas</returns> internal static Canvas GetVisualObjectForBubbleChart(Panel preExistingPanel, Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; // Visual for all bubble charts, Nothing but presisting visual for buble chart Canvas visual; // Holds all bubbles of all series Canvas bubbleChartCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out bubbleChartCanvas, width, height); Double depth3d = plankDepth / (plotDetails.Layer3DCount == 0 ? 1 : plotDetails.Layer3DCount) * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1 - (plotDetails.Layer3DCount == 0 ? 0 : 1)); visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); Double minimumZVal, maximumZVal; CalculateMaxAndMinZValueFromAllSeries(ref seriesList, out minimumZVal, out maximumZVal); foreach (DataSeries series in seriesList) { Faces dsFaces = new Faces() { Visual = bubbleChartCanvas }; series.Faces = dsFaces; if (series.Enabled == false) continue; //out Double minimumZVal, out Double maximumZVal PlotGroup plotGroup = series.PlotGroup; List<DataPoint> dataPointsInViewPort = RenderHelper.GetDataPointsUnderViewPort(series, false); foreach (DataPoint dataPoint in dataPointsInViewPort) { CreateOrUpdateAPointDataPoint(bubbleChartCanvas, dataPoint, minimumZVal, maximumZVal, width, height); // Apply animation if (animationEnabled && dataPoint.Marker != null) { if (dataPoint.Parent.Storyboard == null) dataPoint.Parent.Storyboard = new Storyboard(); // Apply animation to the bubbles dataPoint.Parent.Storyboard = ApplyBubbleChartAnimation(dataPoint.Parent, dataPoint.Marker.Visual, dataPoint.Parent.Storyboard, width, height); } } } RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, -chart.ChartArea.PLANK_DEPTH, width + chart.ChartArea.PLANK_OFFSET, height + chart.ChartArea.PLANK_DEPTH); visual.Clip = clipRectangle; return visual; }
/// <summary> /// Get visual object for stacked area100 chart /// </summary> /// <param name="width">Width of the PlotArea</param> /// <param name="height">Height of the PlotArea</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of DataSeries with render as StackedArea100 chart</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">PlankDepth</param> /// <param name="animationEnabled">Whether animation is enabled for chart</param> /// <returns>StackedArea100 chart canvas</returns> internal static Canvas GetVisualObjectForStackedArea100Chart(Panel preExistingPanel,Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; DataSeries currentDataSeries; Boolean plankDrawn = false; Double depth3d = plankDepth / plotDetails.Layer3DCount * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1); if (Double.IsNaN(visualOffset) || Double.IsInfinity(visualOffset)) return null; Canvas visual, labelCanvas, areaCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out areaCanvas, width, height); //Canvas visual = new Canvas() { Width = width, Height = height }; //Canvas labelCanvas = new Canvas() { Width = width, Height = height }; //Canvas areaCanvas = new Canvas() { Width = width, Height = height }; visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); labelCanvas.SetValue(Canvas.TopProperty, (Double)0); labelCanvas.SetValue(Canvas.LeftProperty, (Double)0); labelCanvas.SetValue(Canvas.ZIndexProperty, (Int32)1); var plotgroups = (from series in seriesList where series.PlotGroup != null select series.PlotGroup); if (plotgroups.Count() == 0) return visual; PlotGroup plotGroup = plotgroups.First(); Dictionary<Double, List<Double>> dataPointValuesInStackedOrder = plotDetails.GetDataPointValuesInStackedOrder(plotGroup); Dictionary<Double, List<DataPoint>> dataPointInStackedOrder = plotDetails.GetDataPointInStackOrder(plotGroup); Double[] xValues = dataPointValuesInStackedOrder.Keys.ToArray(); Double minimumXValue = plotGroup.MinimumX; Double maximumXValue = plotGroup.MaximumX; Double limitingYValue = 0; if (plotGroup.AxisY.InternalAxisMinimum > 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMinimum; if (plotGroup.AxisY.InternalAxisMaximum < 0) limitingYValue = (Double)plotGroup.AxisY.InternalAxisMaximum; foreach (DataSeries ds in seriesList) { ds.Faces = null; } Double limitingYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); Marker marker; for (Int32 i = 0; i < xValues.Length - 1; i++) { List<Double> curYValues = dataPointValuesInStackedOrder[xValues[i]]; List<Double> nextYValues = dataPointValuesInStackedOrder[xValues[i + 1]]; Double curBase = limitingYValue; Double nextBase = limitingYValue; Double curAbsoluteSum = plotGroup.XWiseStackedDataList[xValues[i]].AbsoluteYValueSum; Double nextAbsoluteSum = plotGroup.XWiseStackedDataList[xValues[i + 1]].AbsoluteYValueSum; List<DataPoint> curDataPoints = dataPointInStackedOrder[xValues[i]]; List<DataPoint> nextDataPoints = dataPointInStackedOrder[xValues[i + 1]]; if (Double.IsNaN(curAbsoluteSum)) curAbsoluteSum = 1; if (Double.IsNaN(nextAbsoluteSum)) nextAbsoluteSum = 1; for (Int32 index = 0; index < curYValues.Count; index++) { if (index >= nextYValues.Count || index >= curYValues.Count || curDataPoints[index] == null || nextDataPoints[index] == null) continue; Double curPercentageY = curYValues[index] / curAbsoluteSum * 100; Double nextPercentageY = nextYValues[index] / nextAbsoluteSum * 100; if (Double.IsNaN(nextPercentageY) || Double.IsNaN(curPercentageY)) continue; Double curXPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, xValues[i]); Double nextXPosition = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, xValues[i + 1]); Double curYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, curBase + curPercentageY); Double nextYPosition = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, nextBase + nextPercentageY); Double curYBase = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, curBase); Double nextYBase = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, nextBase); Point intersect = GetIntersection(new Point(curXPosition, curYBase), new Point(nextXPosition, nextYBase), new Point(curXPosition, curYPosition), new Point(nextXPosition, nextYPosition)); marker = GetMarkerForDataPoint(chart, height, false, curDataPoints[index], curYPosition, curDataPoints[index].InternalYValue > 0); if (marker != null) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); currentDataSeries = curDataPoints[index].Parent; marker.AddToParent(labelCanvas, curXPosition, curYPosition, new Point(0.5, 0.5)); // Apply marker animation if (animationEnabled) curDataPoints[index].Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, currentDataSeries, curDataPoints[index].Parent.Storyboard, 1, curDataPoints[index].Opacity * curDataPoints[index].Parent.Opacity); } if (i + 1 == xValues.Length - 1) { marker = GetMarkerForDataPoint(chart, height, false, nextDataPoints[index], nextYPosition, nextDataPoints[index].InternalYValue > 0); if (marker != null) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); currentDataSeries = curDataPoints[index].Parent; marker.AddToParent(labelCanvas, nextXPosition, nextYPosition, new Point(0.5, 0.5)); // Apply marker animation if (animationEnabled) nextDataPoints[index].Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, currentDataSeries, nextDataPoints[index].Parent.Storyboard, 1, nextDataPoints[index].Opacity * nextDataPoints[index].Parent.Opacity); } } if (curDataPoints[index].Parent.Faces == null) { curDataPoints[index].Parent.Faces = new Faces(); } List<PointCollection> pointSet = null; if ((!Double.IsNaN(intersect.X) && !Double.IsInfinity(intersect.X)) && (intersect.X >= curXPosition && intersect.X <= nextXPosition)) { List<PointCollection> set1 = GeneratePointsCollection(curXPosition, curYPosition, curYBase, intersect.X, intersect.Y, intersect.Y, limitingYPosition); List<PointCollection> set2 = GeneratePointsCollection(intersect.X, intersect.Y, intersect.Y, nextXPosition, nextYPosition, nextYBase, limitingYPosition); pointSet = set1; pointSet.InsertRange(pointSet.Count, set2); } else { pointSet = GeneratePointsCollection(curXPosition, curYPosition, curYBase, nextXPosition, nextYPosition, nextYBase, limitingYPosition); } DataSeries series = curDataPoints[index].Parent; Brush areaBrush = series.Color; currentDataSeries = series; PolygonalChartShapeParams areaParams = GetAreaParms(series, areaBrush, depth3d); Faces faces = curDataPoints[index].Parent.Faces; if (faces.Parts == null) faces.Parts = new List<DependencyObject>(); foreach (PointCollection points in pointSet) { areaParams.Points = points; if (chart.View3D) { Point centroid = GetCentroid(points); areaParams.IsPositive = centroid.Y < limitingYPosition; Canvas frontface = GetStacked3DAreaFrontFace(ref faces, areaParams); Canvas sideface = GetStacked3DSideFaces(ref faces, areaParams); sideface.SetValue(Canvas.ZIndexProperty, GetStackedAreaZIndex(centroid.X, centroid.Y, areaParams.IsPositive, index)); frontface.SetValue(Canvas.ZIndexProperty, 50000); areaCanvas.Children.Add(sideface); areaCanvas.Children.Add(frontface); curDataPoints[index].Parent.Faces.VisualComponents.Add(sideface); curDataPoints[index].Parent.Faces.VisualComponents.Add(frontface); // Apply Animation if (animationEnabled) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); Storyboard storyboard = curDataPoints[index].Parent.Storyboard; // apply animation to the various faces storyboard = ApplyStackedAreaAnimation(currentDataSeries, sideface, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)) + 0.05, 1.0 / seriesList.Count); storyboard = ApplyStackedAreaAnimation(currentDataSeries, frontface, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)), 1.0 / seriesList.Count); } } else { Canvas area2d = Get2DArea(currentDataSeries, ref faces, areaParams); areaCanvas.Children.Add(area2d); curDataPoints[index].Parent.Faces.VisualComponents.Add(area2d); if (animationEnabled) { if (curDataPoints[index].Parent.Storyboard == null) curDataPoints[index].Parent.Storyboard = new Storyboard(); Storyboard storyboard = curDataPoints[index].Parent.Storyboard; // apply animation to the various faces storyboard = ApplyStackedAreaAnimation(currentDataSeries, area2d, storyboard, (1.0 / seriesList.Count) * (seriesList.IndexOf(curDataPoints[index].Parent)), 1.0 / seriesList.Count); } } curDataPoints[index].Parent.Faces.Visual = visual; } curBase += curPercentageY; nextBase += nextPercentageY; } } if (!plankDrawn && chart.View3D && plotGroup.AxisY.InternalAxisMinimum < 0 && plotGroup.AxisY.InternalAxisMaximum > 0) { //RectangularChartShapeParams columnParams = new RectangularChartShapeParams(); //columnParams.BackgroundBrush = new SolidColorBrush(Color.FromArgb((Byte)255, (Byte)255, (Byte)255, (Byte)255)); //columnParams.Lighting = true; //columnParams.Size = new Size(width, 1); //columnParams.Depth = depth3d; Brush frontBrush, topBrush, rightBrush; ExtendedGraphics.GetBrushesForPlank(chart, out frontBrush, out topBrush, out rightBrush, true); Faces zeroPlank = ColumnChart.Get3DPlank(width, 1, depth3d, frontBrush, topBrush, rightBrush); Panel zeroPlankVisual = zeroPlank.Visual as Panel; Double top = height - Graphics.ValueToPixelPosition(0, height, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, 0); zeroPlankVisual.SetValue(Canvas.LeftProperty, (Double)0); zeroPlankVisual.SetValue(Canvas.TopProperty, top); zeroPlankVisual.SetValue(Canvas.ZIndexProperty, 0); zeroPlankVisual.Opacity = 0.7; visual.Children.Add(zeroPlankVisual); } //visual.Children.Add(areaCanvas); //visual.Children.Add(labelCanvas); // Remove old visual and add new visual in to the existing panel if (preExistingPanel != null) { visual.Children.RemoveAt(1); visual.Children.Add(areaCanvas); } else { labelCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelCanvas); visual.Children.Add(areaCanvas); } RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, -depth3d - 4, width + depth3d, height + depth3d + chart.ChartArea.PLANK_THICKNESS + 10); areaCanvas.Clip = clipRectangle; // Clip the label canvas clipRectangle = new RectangleGeometry(); Double clipLeft = 0; Double clipTop = -depth3d - 4; Double clipWidth = width + depth3d; Double clipHeight = height + depth3d + chart.ChartArea.PLANK_THICKNESS + 10; GetClipCoordinates(chart, ref clipLeft, ref clipTop, ref clipWidth, ref clipHeight, minimumXValue, maximumXValue); clipRectangle.Rect = new Rect(clipLeft, clipTop, clipWidth, clipHeight); labelCanvas.Clip = clipRectangle; return visual; }
/// <summary> /// Get visual object for area chart /// </summary> /// <param name="width">Width of the PlotArea</param> /// <param name="height">Height of the PlotArea</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of DataSeries with render as area chart</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">PlankDepth</param> /// <param name="animationEnabled">Whether animation is enabled for chart</param> /// <returns>Area chart canvas</returns> internal static Canvas GetVisualObjectForAreaChart(Panel preExistingPanel, Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; DataSeries series = seriesList[0] as DataSeries; if (animationEnabled) { if (series.Storyboard == null) series.Storyboard = new Storyboard(); } Canvas visual, labelCanvas, areaCanvas, areaFaceCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out areaCanvas, width, height); areaFaceCanvas = new Canvas() { Height = height, Width = width }; Double depth3d = plankDepth / plotDetails.Layer3DCount * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[series] + 1); visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); labelCanvas.SetValue(Canvas.TopProperty, (Double)0); labelCanvas.SetValue(Canvas.LeftProperty, (Double)0); areaFaceCanvas.SetValue(Canvas.TopProperty, (Double)0); areaFaceCanvas.SetValue(Canvas.LeftProperty, (Double)0); //areaFaceCanvas.SetValue(Canvas.ZIndexProperty, (Int32)1); DataSeries currentDataSeries; Double minimumXValue = Double.MaxValue; Double maximumXValue = Double.MinValue; if ((Boolean)series.Enabled) { if (series.Storyboard == null) series.Storyboard = new Storyboard(); currentDataSeries = series; PlotGroup plotGroup = series.PlotGroup; Double limitingYValue = plotGroup.GetLimitingYValue(); minimumXValue = Math.Min(minimumXValue, plotGroup.MinimumX); maximumXValue = Math.Max(maximumXValue, plotGroup.MaximumX); //List<DataPoint> enabledDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Enabled == true select datapoint).ToList(); Faces dataSeriesFaces = new Faces(); dataSeriesFaces.FrontFacePaths = new List<Path>(); dataSeriesFaces.Visual = areaFaceCanvas; dataSeriesFaces.LabelCanvas = labelCanvas; series.Faces = dataSeriesFaces; List<List<DataPoint>> brokenAreaDataPointsCollection = BrokenAreaDataPointsGroup(width, height, series); DataPoint currentDataPoint; DataPoint nextDataPoint; DataPoint previusDataPoint; Double plankYPos = Graphics.ValueToPixelPosition(height, 0, (Double)plotGroup.AxisY.InternalAxisMinimum, (Double)plotGroup.AxisY.InternalAxisMaximum, limitingYValue); foreach (List<DataPoint> dataPointList in brokenAreaDataPointsCollection) { if (dataPointList.Count <= 0) continue; currentDataPoint = dataPointList[0]; previusDataPoint = currentDataPoint; PointCollection points = new PointCollection(); List<DataPoint> dataPoints = new List<DataPoint>(); Path frontFacePath = null; PathGeometry frontFacePathGeometry; PathFigure frontFacePathFigure = null; Int32 maxZIndex = 0; for (Int32 i = 0; i < dataPointList.Count - 1; i++) { Path areaBase = new Path(); Faces dataPointFaces; Faces nextDataPointFaces = new Faces(); currentDataPoint = dataPointList[i]; currentDataPoint._parsedToolTipText = currentDataPoint.TextParser(currentDataPoint.ToolTipText); nextDataPoint = dataPointList[i + 1]; if (currentDataPoint.Faces == null) { dataPointFaces = new Faces(); currentDataPoint.Faces = dataPointFaces; } else dataPointFaces = currentDataPoint.Faces; nextDataPoint.Faces = nextDataPointFaces; dataPointFaces.PreviousDataPoint = previusDataPoint; dataPointFaces.NextDataPoint = nextDataPoint; if (i == 0) { // For the first DataPoint left and top face are drawn. Double xPosDataPoint = Graphics.ValueToPixelPosition(0, width, (Double)plotGroup.AxisX.InternalAxisMinimum, (Double)plotGroup.AxisX.InternalAxisMaximum, currentDataPoint.InternalXValue); if (chart.View3D) { // Set points for left face Area3DDataPointFace leftFace = new Area3DDataPointFace(depth3d); leftFace.FrontFacePoints.Add(new Point(xPosDataPoint, plankYPos)); // Bottom Point leftFace.FrontFacePoints.Add(currentDataPoint._visualPosition); // Top Point currentDataPoint.Faces.Area3DLeftFace = leftFace; // Set points for top left face Area3DDataPointFace topFace = new Area3DDataPointFace(depth3d); topFace.FrontFacePoints.Add(currentDataPoint._visualPosition); // Front Left Point topFace.FrontFacePoints.Add(nextDataPoint._visualPosition); // Front Right Point currentDataPoint.Faces.Area3DRightTopFace = topFace; nextDataPointFaces.Area3DLeftTopFace = topFace; } // Start creating front face of 3D area frontFacePath = new Path() { Opacity = currentDataPoint.Parent.Opacity }; //frontFacePath = new Path() { Opacity = 0.5 }; ApplyBorderProperties(frontFacePath, currentDataPoint.Parent); dataSeriesFaces.FrontFacePaths.Add(frontFacePath); frontFacePathGeometry = new PathGeometry(); frontFacePathFigure = new PathFigure() { StartPoint = new Point(xPosDataPoint, plankYPos), IsClosed = true }; frontFacePathGeometry.Figures.Add(frontFacePathFigure); frontFacePath.Data = frontFacePathGeometry; // Area front face Line path from end point to first LineSegment ls = new LineSegment() { Point = currentDataPoint._visualPosition }; frontFacePathFigure.Segments.Add(ls); dataPointFaces.AreaFrontFaceLineSegment = ls; } else { if (chart.View3D) { // DataPoint which has two different top faces at the left and right side of it position. Area3DDataPointFace topFace = new Area3DDataPointFace(depth3d); topFace.FrontFacePoints.Add(currentDataPoint._visualPosition); // Front Left Point topFace.FrontFacePoints.Add(nextDataPoint._visualPosition); // Front Right Point currentDataPoint.Faces.Area3DRightTopFace = topFace; nextDataPointFaces.Area3DLeftTopFace = topFace; } else { if(currentDataPoint.Parent.Bevel) CreateBevelFor2DArea(areaFaceCanvas, currentDataPoint, previusDataPoint,false, false); } // Area front face Line path LineSegment ls = new LineSegment() { Point = currentDataPoint._visualPosition }; frontFacePathFigure.Segments.Add(ls); dataPointFaces.AreaFrontFaceLineSegment = ls; } #region Create Marker if (nextDataPoint.MarkerEnabled == true || nextDataPoint.LabelEnabled == true) { Double xPos, yPos; // Create Marker Marker marker = LineChart.CreateMarkerAForLineDataPoint(currentDataPoint, width, height, ref labelCanvas, out xPos, out yPos); //if (marker != null) //{ // //LineChart.ApplyDefaultInteractivityForMarker(dataPoint); // //marker.AddToParent(labelCanvas, currentDataPoint._visualPosition.X, currentDataPoint._visualPosition.Y, new Point(0.5, 0.5)); // // Apply marker animation // if (animationEnabled) // { // if (currentDataPoint.Parent.Storyboard == null) // currentDataPoint.Parent.Storyboard = new Storyboard(); // // Apply marker animation // currentDataPoint.Parent.Storyboard = AnimationHelper.ApplyOpacityAnimation(marker, CurrentDataSeries, currentDataPoint.Parent.Storyboard, 1, currentDataPoint.Opacity * currentDataPoint.Parent.Opacity); // } //} } #endregion if (chart.View3D) { Int32 zindex = Draw3DArea(areaFaceCanvas, previusDataPoint, currentDataPoint, nextDataPoint, ref dataSeriesFaces, ref dataPointFaces, currentDataPoint.Parent, plankYPos); maxZIndex = Math.Max(maxZIndex, zindex); } else { //areaCanvas.Children.Add(Get2DArea(ref faces, areaParams)); } if (i == dataPointList.Count - 2) // If next DataPoint is the last DataPoint { if (chart.View3D) { DataPoint lastDataPoint = nextDataPoint; Area3DDataPointFace rightFace = new Area3DDataPointFace(depth3d); rightFace.FrontFacePoints.Add(nextDataPoint._visualPosition); // Front top point rightFace.FrontFacePoints.Add(new Point(nextDataPoint._visualPosition.X, plankYPos)); nextDataPoint.Faces.Area3DRightFace = rightFace; // Draw base of the 3d area areaBase = new Path(); areaBase.Fill = (Boolean)dataPointList[0].Parent.LightingEnabled ? Graphics.GetTopFaceBrush(dataPointList[0].Parent.Color) : dataPointList[0].Parent.Color; PathGeometry pg = new PathGeometry(); PathFigure pf = new PathFigure() { StartPoint = new Point(dataPointList[0]._visualPosition.X, plankYPos) }; pg.Figures.Add(pf); pf.Segments.Add(new LineSegment() { Point = new Point(dataPointList[0]._visualPosition.X + depth3d, plankYPos - depth3d) }); pf.Segments.Add(new LineSegment() { Point = new Point(lastDataPoint._visualPosition.X + depth3d, plankYPos - depth3d) }); pf.Segments.Add(new LineSegment() { Point = new Point(lastDataPoint._visualPosition.X, plankYPos) }); areaBase.Data = pg; areaBase.SetValue(Canvas.ZIndexProperty, (Int32) 1); areaBase.Opacity = lastDataPoint.Parent.Opacity; areaCanvas.Children.Add(areaBase); dataSeriesFaces.FrontFacePaths.Add(areaBase); series.Faces.VisualComponents.Add(areaBase); // Animating AreaBase opacity if (animationEnabled) series.Storyboard = AnimationHelper.ApplyOpacityAnimation(areaBase, series, series.Storyboard, 0.25, 1, 0, 1); } else { if (nextDataPoint.Parent.Bevel) CreateBevelFor2DArea(areaFaceCanvas, nextDataPoint, currentDataPoint, false, false); } // Front face for 3D and 2D both LineSegment ls = new LineSegment() { Point = nextDataPoint._visualPosition }; frontFacePathFigure.Segments.Add(ls); nextDataPointFaces.AreaFrontFaceLineSegment = ls; ls = new LineSegment() { Point = new Point(nextDataPoint._visualPosition.X, plankYPos) }; frontFacePathFigure.Segments.Add(ls); nextDataPointFaces.AreaFrontFaceBaseLineSegment = ls; nextDataPointFaces.NextDataPoint = nextDataPoint; // Graphics.DrawPointAt(rightFace.FrontFacePoints[0], areaCanvas, Colors.Yellow); if (chart.View3D) { Int32 zindex = Draw3DArea(areaFaceCanvas, previusDataPoint, nextDataPoint, nextDataPoint, ref dataSeriesFaces, ref nextDataPointFaces, nextDataPoint.Parent, plankYPos); maxZIndex = Math.Max(maxZIndex, zindex); } else { // areaCanvas.Children.Add(Get2DArea(ref faces, areaParams)); } if (nextDataPoint.MarkerEnabled == true || nextDataPoint.LabelEnabled == true) { Double xPos, yPos; Marker marker = LineChart.CreateMarkerAForLineDataPoint(nextDataPoint, width, height, ref labelCanvas, out xPos, out yPos); } nextDataPoint._parsedToolTipText = nextDataPoint.TextParser(nextDataPoint.ToolTipText); } previusDataPoint = currentDataPoint; } if (frontFacePath != null) { if (chart.View3D) frontFacePath.Fill = (Boolean)dataPointList[0].Parent.LightingEnabled ? Graphics.GetFrontFaceBrush(dataPointList[0].Parent.Color) : dataPointList[0].Parent.Color; else frontFacePath.Fill = (Boolean)dataPointList[0].Parent.LightingEnabled ? Graphics.GetLightingEnabledBrush(dataPointList[0].Parent.Color, "Linear", null) : dataPointList[0].Parent.Color; series.Faces.VisualComponents.Add(frontFacePath); frontFacePath.SetValue(Canvas.ZIndexProperty, maxZIndex); areaFaceCanvas.Children.Add(frontFacePath); } foreach (FrameworkElement face in series.Faces.VisualComponents) VisifireElement.AttachEvents2AreaVisual(currentDataPoint, currentDataPoint, face); } foreach (FrameworkElement face in series.Faces.VisualComponents) VisifireElement.AttachEvents2AreaVisual(series, series, face); series.AttachAreaToolTip(chart, dataSeriesFaces.VisualComponents); areaFaceCanvas.Tag = null; Canvas plank = ColumnChart.CreateOrUpdatePlank(chart, series.PlotGroup.AxisY, areaCanvas, depth3d, Orientation.Horizontal); // apply area animation if (animationEnabled) { // if (series.Storyboard == null) // series.Storyboard = new Storyboard(); ScaleTransform scaleTransform = new ScaleTransform() { ScaleY = 0 }; areaFaceCanvas.RenderTransformOrigin = new Point(0.5, plankYPos / height); areaFaceCanvas.RenderTransform = scaleTransform; List<KeySpline> splines = AnimationHelper.GenerateKeySplineList ( new Point(0, 0), new Point(1, 1), new Point(0, 1), new Point(0.5, 1) ); // Apply animation to the entire canvas that was used to create the area series.Storyboard = AnimationHelper.ApplyPropertyAnimation(scaleTransform, "(ScaleTransform.ScaleY)", series, series.Storyboard, 1, new Double[] { 0, 1 }, new Double[] { 0, 1 }, splines); // Animating plank opacity //series.Storyboard = AnimationHelper.ApplyOpacityAnimation(areaBase, series, series.Storyboard, 1.25, 1, 0, 1); // Apply animation for label canvas series.Storyboard = AnimationHelper.ApplyOpacityAnimation(labelCanvas, series, series.Storyboard, 1.25, 1, 0, 1); } } areaFaceCanvas.SetValue(Canvas.ZIndexProperty, (Int32)2); areaCanvas.Children.Add(areaFaceCanvas); // Remove old visual and add new visual in to the existing panel if (preExistingPanel != null) { visual.Children.RemoveAt(1); visual.Children.Add(areaCanvas); } else { labelCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelCanvas); visual.Children.Add(areaCanvas); } RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, -depth3d - 4, width + depth3d, height + depth3d + chart.ChartArea.PLANK_THICKNESS + 10); areaCanvas.Clip = clipRectangle; // Clip the label canvas clipRectangle = new RectangleGeometry(); Double clipLeft = 0; Double clipTop = -depth3d - 4; Double clipWidth = width + depth3d; Double clipHeight = height + depth3d + chart.ChartArea.PLANK_THICKNESS + 10; GetClipCoordinates(chart, ref clipLeft, ref clipTop, ref clipWidth, ref clipHeight, minimumXValue, maximumXValue); clipRectangle.Rect = new Rect(clipLeft, clipTop, clipWidth, clipHeight); labelCanvas.Clip = clipRectangle; return visual; }
/// <summary> /// Draw ChartArea /// </summary> /// <param name="chart">Chart</param> public void Draw(Chart chart) { isScrollingActive = Chart.IsScrollingActivated; _renderCount = 0; Chart = chart; ClearAxesPanel(); ResetTitleAndLegendPannelsSize(); SetSeriesStyleFromTheme(); SetTitleStyleFromTheme(); PopulateInternalAxesXList(); PopulateInternalAxesYList(); PopulateInternalSeriesList(false); SetDataPointColorFromColorSet(chart.Series); CreateDefaultToolTipsForSeries(chart); PlotDetails = new PlotDetails(chart); // Calculate all the required PlotDetails PlotDetails.Calculate(true); ApplySampling(); SetLegendStyleFromTheme(); CalculatePlankParameters(); ClearTitlePanels(); ClearLegendPanels(); Boolean isLeftOrRightAlignedTitlesExist; Size actualChartSize = GetActualChartSize(); // Add all the legends to chart of type dock outside AddTitles(chart, false, actualChartSize.Height, actualChartSize.Width, out isLeftOrRightAlignedTitlesExist); // Calculate max size for legend Size remainingSizeAfterAddingTitles = CalculateLegendMaxSize(actualChartSize); // Add all the legends to chart of type dock outside AddLegends(chart, false, remainingSizeAfterAddingTitles.Height, remainingSizeAfterAddingTitles.Width); // Create PlotArea CreatePlotArea(chart); // Calculate PlotArea Size _plotAreaSize = CalculatePlotAreaSize(remainingSizeAfterAddingTitles); // Need to recalculate PlotArea size if any title exist with left or right aligned if (isLeftOrRightAlignedTitlesExist) { ClearTitlePanels(); AddTitles(chart, false, _plotAreaSize.Height, actualChartSize.Width, out isLeftOrRightAlignedTitlesExist); ResetTitleAndLegendPannelsSize(); remainingSizeAfterAddingTitles = CalculateLegendMaxSize(actualChartSize); _plotAreaSize = CalculatePlotAreaSize(remainingSizeAfterAddingTitles); } HideAllAxesScrollBars(); // Check if drawing axis is necessary or not if (PlotDetails.ChartOrientation != ChartOrientationType.NoAxis) { SetAxesProperties(); Chart._elementCanvas.Children.Clear(); CreateTrendLinesLabel(); if (PlotDetails.ChartOrientation != ChartOrientationType.Circular) { /* Zoom icons should be enabled if chart type is changed from Pie/Doughnut/Funnel/Radar/Polar to any other chart type which supports zooming */ if (chart.ZoomingEnabled && AxisX.ScrollBarElement != null && (!Double.IsNaN(AxisX.ScrollBarElement.Scale) && AxisX.ScrollBarElement.Scale != 1)) EnableZoomIcons(chart); } else { /* Zoom icons should be disabled if chart type is changed to Radar/Polar from any other chart type which supports zooming */ DisableZoomIcons(chart); } } else if (PlotDetails.ChartOrientation == ChartOrientationType.NoAxis) { /* Zoom icons should be disabled if chart type is changed to Pie/Doughnut/Funnel from any other chart type which supports zooming */ DisableZoomIcons(chart); } Size remainingSize = DrawChart(_plotAreaSize); // Add all the titles to chart of type dock inside AddTitles(Chart, true, remainingSize.Height, remainingSize.Width, out isLeftOrRightAlignedTitlesExist); // Add all the legends to chart of type dock inside AddLegends(Chart, true, remainingSize.Height, remainingSize.Width); AttachEventToRetainOldScrollOffsetOfScrollViewer(); AttachOrDetachIntaractivity(chart.InternalSeries); if (!_isFirstTimeRender || !chart.InternalAnimationEnabled) { AttachScrollBarOffsetChangedEventWithAxes(); Visifire.Charts.Chart.SelectDataPoints(Chart); chart.Dispatcher.BeginInvoke(new Action(chart.UnlockRender)); } chart._forcedRedraw = false; chart._clearAndResetZoomState = false; AddOrRemovePanels(chart); AttachEvents2ZoomOutIcons(chart); SettingsForVirtualRendering(); // System.Diagnostics.Debug.WriteLine("xxxxxxx--- Render End"); }
/// <summary> /// Get AxisY for Circular chart /// </summary> /// <param name="width"></param> /// <param name="height"></param> /// <param name="plotDetails"></param> /// <param name="circularPlotDetails"></param> /// <returns></returns> private Canvas CreateAxis4CircularChart(Axis axis, Double width, Double height, PlotDetails plotDetails, CircularPlotDetails circularPlotDetails) { Chart chart = plotDetails.Chart; if (axis != null && plotDetails.ChartOrientation == ChartOrientationType.Circular) { axis.Width = width; axis.Height = height; axis.CircularPlotDetails = circularPlotDetails; axis.CreateVisualObject(chart); return axis.CircularAxisVisual; } return null; }
/// <summary> /// Create and position Axes for Circular chart /// </summary> /// <param name="visual"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="plotDetails"></param> /// <param name="circularPlotDetails"></param> private void CreateAndPositionAxes4CircularChart(Canvas visual, Double width, Double height, PlotDetails plotDetails, CircularPlotDetails circularPlotDetails) { if (AxisX != null) { CreateAxis4CircularChart(AxisX, width, height, plotDetails, circularPlotDetails); if (AxisX.CircularAxisVisual != null) visual.Children.Add(AxisX.CircularAxisVisual); } if (AxisY != null) { CreateAxis4CircularChart(AxisY, width, height, plotDetails, circularPlotDetails); if (AxisY.CircularAxisVisual != null) visual.Children.Add(AxisY.CircularAxisVisual); } }
/// <summary> /// Get visual object for point chart /// </summary> /// <param name="width">Width of the charat</param> /// <param name="height">Height of the charat</param> /// <param name="plotDetails">plotDetails</param> /// <param name="seriesList">List of DataSeries</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">Plank depth</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <returns>Point chart canvas</returns> internal static Canvas GetVisualObjectForPointChart(Panel preExistingPanel, Double plotAreaWidth, Double plotAreaHeight, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(plotAreaWidth) || Double.IsNaN(plotAreaHeight) || plotAreaWidth <= 0 || plotAreaHeight <= 0) return null; Canvas visual, pointChartCanvas; // pointChartCanvas holds all points for all series RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out pointChartCanvas, plotAreaWidth, plotAreaHeight); Double depth3d = plankDepth / (plotDetails.Layer3DCount == 0 ? 1 : plotDetails.Layer3DCount) * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1 - (plotDetails.Layer3DCount == 0 ? 0 : 1)); visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); foreach (DataSeries series in seriesList) { series.Faces = new Faces() { Visual = pointChartCanvas }; if (series.Enabled == false) continue; List<DataPoint> dataPointsInViewPort = RenderHelper.GetDataPointsUnderViewPort(series, false); foreach (DataPoint dataPoint in dataPointsInViewPort) { CreateOrUpdateAPointDataPoint(pointChartCanvas, dataPoint, plotAreaWidth, plotAreaHeight); // Apply initial animation if (animationEnabled && dataPoint.Marker != null) { if (dataPoint.Parent.Storyboard == null) dataPoint.Parent.Storyboard = new Storyboard(); // Apply animation to the points dataPoint.Parent.Storyboard = ApplyPointChartAnimation(dataPoint.Parent, dataPoint.Marker.Visual, dataPoint.Parent.Storyboard, plotAreaWidth, plotAreaHeight); } } } Double tickLengthOfAxisX = (from tick in chart.AxesX[0].Ticks where (Boolean)chart.AxesX[0].Enabled && (Boolean)tick.Enabled select (Double)tick.TickLength).Sum(); if (tickLengthOfAxisX == 0) tickLengthOfAxisX = 5; Double tickLengthOfPrimaryAxisY = (from axis in chart.AxesY where axis.AxisType == AxisTypes.Primary from tick in axis.Ticks where (Boolean)axis.Enabled && (Boolean)tick.Enabled select (Double)tick.TickLength).Sum(); if (tickLengthOfPrimaryAxisY == 0) tickLengthOfPrimaryAxisY = 8; Double tickLengthOfSecondaryAxisY = (from axis in chart.AxesY where axis.AxisType == AxisTypes.Secondary from tick in axis.Ticks where (Boolean)axis.Enabled && (Boolean)tick.Enabled select (Double)tick.TickLength).Sum(); if (tickLengthOfSecondaryAxisY == 0) tickLengthOfSecondaryAxisY = 8; Double plotGroupCount = (from c in chart.PlotDetails.PlotGroups where c.AxisY.AxisType == AxisTypes.Secondary select c).Count(); RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(-tickLengthOfPrimaryAxisY, -chart.ChartArea.PLANK_DEPTH - 4, plotAreaWidth + tickLengthOfSecondaryAxisY + (plotGroupCount > 0 ? tickLengthOfPrimaryAxisY : 8) + chart.ChartArea.PLANK_OFFSET, plotAreaHeight + chart.ChartArea.PLANK_DEPTH + chart.ChartArea.PLANK_THICKNESS + tickLengthOfAxisX + 4); visual.Clip = clipRectangle; return visual; }
internal static Panel GetVisualObject(Panel preExistingPanel, RenderAs chartType, Double width, Double height, PlotDetails plotDetails, List<DataSeries> dataSeriesList4Rendering, Chart chart, Double plankDepth, bool animationEnabled) { Panel renderedCanvas = null; ResetMarkersForSeries(dataSeriesList4Rendering); switch (chartType) { case RenderAs.Column: renderedCanvas = ColumnChart.GetVisualObjectForColumnChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Bar: renderedCanvas = ColumnChart.GetVisualObjectForColumnChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); // renderedCanvas = BarChart.GetVisualObjectForBarChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Line: case RenderAs.Spline: renderedCanvas = LineChart.GetVisualObjectForLineChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.QuickLine: renderedCanvas = QuickLineChart.GetVisualObjectForQuickLineChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Point: renderedCanvas = PointChart.GetVisualObjectForPointChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Bubble: renderedCanvas = BubbleChart.GetVisualObjectForBubbleChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.Area: renderedCanvas = AreaChart.GetVisualObjectForAreaChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.StackedColumn: renderedCanvas = ColumnChart.GetVisualObjectForStackedColumnChart(chartType, preExistingPanel, width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.StackedColumn100: renderedCanvas = ColumnChart.GetVisualObjectForStackedColumnChart(chartType, preExistingPanel, width, height, plotDetails, chart, plankDepth, animationEnabled); //renderedCanvas = ColumnChart.GetVisualObjectForStackedColumn100Chart(width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.StackedBar: renderedCanvas = BarChart.GetVisualObjectForStackedBarChart(chartType, preExistingPanel, width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.StackedBar100: renderedCanvas = BarChart.GetVisualObjectForStackedBarChart(chartType, preExistingPanel, width, height, plotDetails, chart, plankDepth, animationEnabled); // renderedCanvas = BarChart.GetVisualObjectForStackedBar100Chart(width, height, plotDetails, chart, plankDepth, animationEnabled); break; case RenderAs.Pie: renderedCanvas = PieChart.GetVisualObjectForPieChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.Doughnut: renderedCanvas = PieChart.GetVisualObjectForDoughnutChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.Radar: renderedCanvas = RadarChart.GetVisualObjectForRadarChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.Polar: renderedCanvas = PolarChart.GetVisualObjectForPolarChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.StackedArea: renderedCanvas = AreaChart.GetVisualObjectForStackedAreaChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.StackedArea100: renderedCanvas = AreaChart.GetVisualObjectForStackedArea100Chart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.SectionFunnel: renderedCanvas = FunnelChart.GetVisualObjectForFunnelChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled, false); break; case RenderAs.StreamLineFunnel: renderedCanvas = FunnelChart.GetVisualObjectForFunnelChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled, true); break; case RenderAs.Pyramid: renderedCanvas = PyramidChart.GetVisualObjectForPyramidChart(width, height, plotDetails, dataSeriesList4Rendering, chart, animationEnabled); break; case RenderAs.Stock: renderedCanvas = StockChart.GetVisualObjectForStockChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.CandleStick: renderedCanvas = CandleStick.GetVisualObjectForCandleStick(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; case RenderAs.StepLine: renderedCanvas = StepLineChart.GetVisualObjectForLineChart(preExistingPanel, width, height, plotDetails, dataSeriesList4Rendering, chart, plankDepth, animationEnabled); break; } return renderedCanvas; }
/// <summary> /// Return visual object for pie chart /// </summary> /// <param name="width">Width of the PlotArea</param> /// <param name="height">Height of the PlotArea</param> /// <param name="plotDetails">PlotDetails reference</param> /// <param name="seriesList">List of series list</param> /// <param name="chart">Chart reference</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <returns>Canvas</returns> internal static Canvas GetVisualObjectForPieChart(Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, bool isAnimationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; DataSeries currentDataSeries = null; // Debug.WriteLine("PieStart: " + DateTime.Now.ToLongTimeString()); Canvas visual = new Canvas() { Width = width, Height = height }; DataSeries series = seriesList[0]; if (series.Enabled == false) return visual; // List<DataPoint> enabledDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Enabled == true && datapoint.InternalYValue != 0 && !Double.IsNaN(datapoint.InternalYValue) select datapoint).ToList(); List<DataPoint> enabledDataPoints = (from datapoint in series.InternalDataPoints where datapoint.Enabled == true && !Double.IsNaN(datapoint.InternalYValue) select datapoint).ToList(); if ((from dp in enabledDataPoints select dp.InternalYValue).Sum() == 0) enabledDataPoints.Clear(); Double absoluteSum = plotDetails.GetAbsoluteSumOfDataPoints(enabledDataPoints); absoluteSum = (absoluteSum == 0) ? 1 : absoluteSum; Double centerX = width / 2; Double centerY = height / 2; Double offsetX = 0; Double offsetY = 0; Boolean IsLabelEnabled; Size pieSize = new Size(); Canvas labelCanvas = CreateAndPositionLabels(absoluteSum, enabledDataPoints, width, height, ((chart.View3D) ? 0.4 : 1), chart.View3D, ref pieSize); Debug.WriteLine("Labels Positioning over: " + DateTime.Now.ToLongTimeString()); if (labelCanvas == null) IsLabelEnabled = false; else { IsLabelEnabled = true; labelCanvas.SetValue(Canvas.ZIndexProperty, 50001); labelCanvas.IsHitTestVisible = false; } Double radius = Math.Min(pieSize.Width, pieSize.Height) / (chart.View3D ? 1 : 2); Double startAngle = series.InternalStartAngle; Double endAngle = 0; Double angle; Double absoluteYValue; Double meanAngle = 0; Int32 zindex = 0; if (chart.View3D) _elementPositionData = new List<ElementPositionData>(); if (series.Storyboard == null) series.Storyboard = new Storyboard(); currentDataSeries = series; SectorChartShapeParams pieParams = null; Int32 labelStateCounter = 0; if (!chart.View3D) { foreach (DataPoint dataPoint in enabledDataPoints) { if (dataPoint.LabelStyle == LabelStyles.Inside || !(Boolean)dataPoint.LabelEnabled) labelStateCounter++; } } foreach (DataPoint dataPoint in enabledDataPoints) { if (Double.IsNaN(dataPoint.InternalYValue))// || dataPoint.InternalYValue == 0) continue; absoluteYValue = Math.Abs(dataPoint.InternalYValue); angle = (absoluteYValue / absoluteSum) * Math.PI * 2; endAngle = startAngle + angle; meanAngle = (startAngle + endAngle) / 2; pieParams = new SectorChartShapeParams(); dataPoint.VisualParams = pieParams; pieParams.Storyboard = series.Storyboard; pieParams.AnimationEnabled = isAnimationEnabled; pieParams.Center = new Point(centerX, centerY); pieParams.ExplodeRatio = chart.View3D ? 0.2 : 0.1; pieParams.InnerRadius = 0; pieParams.OuterRadius = radius; pieParams.DataPoint = dataPoint; if (chart.View3D) { pieParams.StartAngle = pieParams.FixAngle((startAngle) % (Math.PI * 2)); pieParams.StopAngle = pieParams.FixAngle((endAngle) % (Math.PI * 2)); } else { pieParams.StartAngle = startAngle; pieParams.StopAngle = endAngle; } pieParams.Lighting = (Boolean)dataPoint.LightingEnabled; pieParams.Bevel = series.Bevel; pieParams.IsLargerArc = (angle / (Math.PI)) > 1; pieParams.Background = dataPoint.Color; pieParams.Width = width; pieParams.Height = height; pieParams.TiltAngle = Math.Asin(0.4); pieParams.Depth = 20 / pieParams.YAxisScaling; pieParams.MeanAngle = meanAngle; pieParams.LabelLineEnabled = (Boolean)dataPoint.LabelLineEnabled; pieParams.LabelLineColor = dataPoint.LabelLineColor; pieParams.LabelLineThickness = (Double)dataPoint.LabelLineThickness; pieParams.LabelLineStyle = ExtendedGraphics.GetDashArray((LineStyles)dataPoint.LabelLineStyle); pieParams.IsZero = (dataPoint.InternalYValue == 0); offsetX = radius * pieParams.ExplodeRatio * Math.Cos(meanAngle); offsetY = radius * pieParams.ExplodeRatio * Math.Sin(meanAngle); pieParams.OffsetX = offsetX; pieParams.OffsetY = offsetY * (chart.View3D ? pieParams.YAxisScaling : 1); if (dataPoint.LabelVisual != null) { if (dataPoint.LabelVisual.Visibility == Visibility.Collapsed) pieParams.LabelLineEnabled = false; Double left = (Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty); if (left < width / 2) { pieParams.LabelLineTargetToRight = true; // pieParams.LabelPoint = new Point((Double)dataPoint.LabelVisual.GetValue(Canvas.LeftProperty) + dataPoint.LabelVisual.DesiredSize.Width, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.DesiredSize.Height / 2); pieParams.LabelPoint = new Point(left + dataPoint.LabelVisual.Width + LabelPlacementHelper.LABEL_LINE_GAP, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.Height / 2); } else { pieParams.LabelLineTargetToRight = false; pieParams.LabelPoint = new Point(left - LabelPlacementHelper.LABEL_LINE_GAP, (Double)dataPoint.LabelVisual.GetValue(Canvas.TopProperty) + dataPoint.LabelVisual.Height / 2); } // apply animation to the labels if (isAnimationEnabled) { series.Storyboard = CreateOpacityAnimation(currentDataSeries, dataPoint, series.Storyboard, dataPoint.LabelVisual, 2, dataPoint.InternalOpacity * dataPoint.Parent.InternalOpacity, 0.5); dataPoint.LabelVisual.Opacity = 0; } } if (dataPoint.LabelStyle == LabelStyles.Inside && dataPoint.InternalYValue == 0) pieParams.LabelLineEnabled = false; Faces faces = new Faces(); if (chart.View3D) { Create3DPie(currentDataSeries, width, height, series, enabledDataPoints, dataPoint, ref visual, ref faces, ref pieParams, ref offsetX, ref zindex, isAnimationEnabled); } else { Create2DPie(currentDataSeries, width, height, series, enabledDataPoints, dataPoint, ref visual, ref faces, ref pieParams, ref offsetX, ref offsetY, ref zindex, isAnimationEnabled, labelStateCounter); } Debug.WriteLine("Datapoint" + enabledDataPoints.IndexOf(dataPoint) + ": " + DateTime.Now.ToLongTimeString()); dataPoint.Faces = faces; startAngle = endAngle; if (!chart.AnimationEnabled || chart.IsInDesignMode || !chart.ChartArea._isFirstTimeRender) { if (dataPoint.Faces != null) { foreach (Shape shape in dataPoint.Faces.BorderElements) { InteractivityHelper.ApplyBorderEffect(shape, (BorderStyles)dataPoint.BorderStyle, dataPoint.InternalBorderThickness.Left, dataPoint.BorderColor); } } } } if (chart.View3D) { Int32 zindex1, zindex2; _elementPositionData.Sort(ElementPositionData.CompareAngle); zindex1 = 1000; zindex2 = -1000; for (Int32 i = 0; i < _elementPositionData.Count; i++) { SetZIndex(_elementPositionData[i].Element, ref zindex1, ref zindex2, _elementPositionData[i].StartAngle); } } if (IsLabelEnabled && labelCanvas != null) visual.Children.Add(labelCanvas); RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, 0, width, height); visual.Clip = clipRectangle; return visual; }
/// <summary> /// Get visual object for CandleStick chart /// </summary> /// <param name="width">Width of the chart</param> /// <param name="height">Height of the chart</param> /// <param name="plotDetails">plotDetails</param> /// <param name="seriesList">List of DataSeries</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">Plank depth</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <returns>CandleStick chart canvas</returns> internal static Canvas GetVisualObjectForCandleStick(Panel preExistingPanel, Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { // return new Canvas() { Background = Graphics.GetRandonColor() , Width = width, Height = height}; if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; Canvas visual, labelCanvas, candleStickCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out candleStickCanvas, width, height); Double depth3d = plankDepth / (plotDetails.Layer3DCount == 0 ? 1 : plotDetails.Layer3DCount) * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1 - (plotDetails.Layer3DCount == 0 ? 0 : 1)); visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); Double animationBeginTime = 0; DataSeries _tempDataSeries = null; // Calculate width of a DataPoint Double dataPointWidth = CalculateDataPointWidth(width, height, chart); foreach (DataSeries series in seriesList) { if (series.Enabled == false) continue; Faces dsFaces = new Faces() { Visual = candleStickCanvas, LabelCanvas = labelCanvas }; series.Faces = dsFaces; PlotGroup plotGroup = series.PlotGroup; _tempDataSeries = series; foreach (DataPoint dataPoint in series.InternalDataPoints) CreateOrUpdateACandleStick(dataPoint, candleStickCanvas, labelCanvas, width, height, dataPointWidth); // Apply animation to series if (animationEnabled) { if (_tempDataSeries.Storyboard == null) _tempDataSeries.Storyboard = new Storyboard(); _tempDataSeries.Storyboard = AnimationHelper.ApplyOpacityAnimation(candleStickCanvas, _tempDataSeries, _tempDataSeries.Storyboard, animationBeginTime, 1, 0, 1); animationBeginTime += 0.5; } } // Label animation if (animationEnabled && _tempDataSeries != null) _tempDataSeries.Storyboard = AnimationHelper.ApplyOpacityAnimation(labelCanvas, _tempDataSeries, _tempDataSeries.Storyboard, animationBeginTime, 1, 0, 1); candleStickCanvas.Tag = null; // ColumnChart.CreateOrUpdatePlank(chart, seriesList[0].PlotGroup.AxisY, candleStickCanvas, depth3d, Orientation.Horizontal); // Remove old visual and add new visual in to the existing panel if (preExistingPanel != null) { visual.Children.RemoveAt(1); visual.Children.Add(candleStickCanvas); } else { labelCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelCanvas); visual.Children.Add(candleStickCanvas); } RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, -chart.ChartArea.PLANK_DEPTH, width + chart.ChartArea.PLANK_OFFSET, height + chart.ChartArea.PLANK_DEPTH); visual.Clip = clipRectangle; return visual; // visual.Children.Add(candleStickCanvas); // visual.Children.Add(labelCanvas); // return visual; }
/// <summary> /// Returns the visual object for line chart /// </summary> /// <param name="width">PlotArea width</param> /// <param name="height">PlotArea height</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of line series</param> /// <param name="chart">Chart</param> /// <param name="plankDepth">PlankDepth</param> /// <param name="animationEnabled">Whether animation is enabled for chart</param> /// <returns>Canvas</returns> internal static Canvas GetVisualObjectForLineChart(Panel preExistingPanel, Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, Double plankDepth, bool animationEnabled) { if (Double.IsNaN(width) || Double.IsNaN(height) || width <= 0 || height <= 0) return null; DataSeries currentDataSeries; Canvas visual, labelsCanvas, chartsCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelsCanvas, out chartsCanvas, width, height); Double depth3d = plankDepth / (plotDetails.Layer3DCount == 0 ? 1 : plotDetails.Layer3DCount) * (chart.View3D ? 1 : 0); Double visualOffset = depth3d * (plotDetails.SeriesDrawingIndex[seriesList[0]] + 1 - (plotDetails.Layer3DCount == 0 ? 0 : 1)); // Set visual canvas position visual.SetValue(Canvas.TopProperty, visualOffset); visual.SetValue(Canvas.LeftProperty, -visualOffset); // visual.Background = new SolidColorBrush(Colors.Yellow); Boolean isMovingMarkerEnabled = false; // Whether moving marker is enabled for atleast one series Double minimumXValue = Double.MaxValue; Double maximumXValue = Double.MinValue; foreach (DataSeries series in seriesList) { currentDataSeries = series; CreateAstepLineSeries(series, width, height, labelsCanvas, chartsCanvas, animationEnabled); isMovingMarkerEnabled = isMovingMarkerEnabled || series.MovingMarkerEnabled; minimumXValue = Math.Min(minimumXValue, series.PlotGroup.MinimumX); maximumXValue = Math.Max(maximumXValue, series.PlotGroup.MaximumX); } // Detach attached events chart.ChartArea.PlotAreaCanvas.MouseMove -= PlotAreaCanvas_MouseMove; chart.ChartArea.PlotAreaCanvas.MouseLeave -= PlotAreaCanvas_MouseLeave; chart.ChartArea.PlotAreaCanvas.MouseEnter -= PlotAreaCanvas_MouseEnter; if (isMovingMarkerEnabled) { chart.ChartArea.PlotAreaCanvas.Tag = chart.PlotArea; chart.ChartArea.PlotAreaCanvas.MouseMove += new MouseEventHandler(PlotAreaCanvas_MouseMove); chart.ChartArea.PlotAreaCanvas.MouseLeave += new MouseEventHandler(PlotAreaCanvas_MouseLeave); chart.ChartArea.PlotAreaCanvas.MouseEnter += new MouseEventHandler(PlotAreaCanvas_MouseEnter); } // If animation is not enabled or if there are no series in the serieslist the dont apply animation if (animationEnabled && seriesList.Count > 0) { // Apply animation to the label canvas currentDataSeries = seriesList[0]; if (currentDataSeries.Storyboard == null) currentDataSeries.Storyboard = new Storyboard(); currentDataSeries.Storyboard = LineChart.ApplyLineChartAnimation(currentDataSeries, labelsCanvas, currentDataSeries.Storyboard, false); } // Remove old visual and add new visual in to the existing panel if (preExistingPanel != null) { visual.Children.RemoveAt(1); // chartsCanvas.Background = Graphics.GetRandomColor(); visual.Children.Add(chartsCanvas); } else { labelsCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelsCanvas); visual.Children.Add(chartsCanvas); } chartsCanvas.Height = height; labelsCanvas.Height = height; chartsCanvas.Width = width; labelsCanvas.Width = width; LineChart.Clip(chart, chartsCanvas, labelsCanvas, seriesList[0].PlotGroup); return visual; }
/// <summary> /// Returns the visual object for pyramid chart /// </summary> /// <param name="width">PlotArea width</param> /// <param name="height">PlotArea height</param> /// <param name="plotDetails">PlotDetails</param> /// <param name="seriesList">List of line series</param> /// <param name="chart">Chart</param> /// <param name="animationEnabled">Whether animation is enabled</param> /// <param name="isStreamLine">Whether pyramid chart is a Streamline pyramid chart</param> /// <returns></returns> public static Grid GetVisualObjectForPyramidChart(Double width, Double height, PlotDetails plotDetails, List<DataSeries> seriesList, Chart chart, bool animationEnabled) { if (seriesList.Count > 0) { DataSeries pyramidSeries; // DataSeries used for drawing pyramid chart List<DataPoint> pyramidDataPoints; // DataPoints considered for drawing pyramid chart // Select DataSeries for render List<DataSeries> selectedDataSeriesList = (from ds in seriesList where (Boolean)ds.Enabled == true select ds).ToList(); if (selectedDataSeriesList.Count > 0) { pyramidSeries = selectedDataSeriesList.First(); foreach (DataPoint dp in pyramidSeries.DataPoints) dp.VisualParams = null; pyramidSeries.Faces = null; } else return null; List<DataPoint> tempDataPoints = (from dp in pyramidSeries.DataPoints where dp.Enabled == true && dp.YValue >= 0 select dp).ToList(); if ((from dp in tempDataPoints where dp.YValue == 0 select dp).Count() == tempDataPoints.Count) return null; // If number of DataPoints is equals to 0 then dont do any operation if (tempDataPoints.Count == 0 || (tempDataPoints.Count == 1 && tempDataPoints[0].YValue == 0)) return null; pyramidDataPoints = tempDataPoints.ToList(); // Create pyramid chart canvas Grid _pyramidChartGrid = new Grid() { Height = height, Width = width }; #region Create layout for Pyramid chart and labels // Create canvas for label Canvas labelCanvas = new Canvas() { Height = height }; // Create canvas for pyramid Canvas pyramidCanvas = new Canvas() { Height = height, HorizontalAlignment = HorizontalAlignment.Left }; _pyramidChartGrid.Children.Add(pyramidCanvas); _pyramidChartGrid.Children.Add(labelCanvas); #endregion pyramidSeries.Storyboard = null; if ((pyramidSeries.Chart as Chart).InternalAnimationEnabled) pyramidSeries.Storyboard = new Storyboard(); // Creating labels for CreateLabelsAndSetPyramidCanvasSize(_pyramidChartGrid, labelCanvas, pyramidCanvas, pyramidDataPoints); Double minPointHeight = pyramidSeries.MinPointHeight; Double yScale = 40; Boolean isSameSlantAngle = true; Double bottomRadius = 5; Double gapRatio = (chart.View3D) ? 0.06 : 0.02; pyramidCanvas = CreatePyramidChart(_pyramidChartGrid, pyramidSeries, pyramidDataPoints, pyramidCanvas, minPointHeight, chart.View3D, yScale, gapRatio, isSameSlantAngle, bottomRadius, animationEnabled); // Here // pyramidChartCanvas.Background = new SolidColorBrush(Colors.Red); if(chart.View3D) pyramidCanvas.Margin = new Thickness(0, - yScale / 2, 0, 0); RectangleGeometry clipRectangle = new RectangleGeometry(); clipRectangle.Rect = new Rect(0, 0, width, chart.PlotArea.Visual.Height); _pyramidChartGrid.Clip = clipRectangle; return _pyramidChartGrid; } return null; }