/// <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); 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; Double minimumZVal, maximumZVal; CalculateMaxAndMinZValue(series, out minimumZVal, out maximumZVal); // Boolean pixelLavelShadow = false; //if (series.InternalDataPoints.Count <= 25) // pixelLavelShadow = true; foreach (DataPoint dataPoint in series.InternalDataPoints) { 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 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; } foreach (DataPoint dataPoint in series.InternalDataPoints) { 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 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 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 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); }
/// <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 GetVisualObjectForStockChart(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); } Canvas visual, labelCanvas, stockChartCanvas; RenderHelper.RepareCanvas4Drawing(preExistingPanel as Canvas, out visual, out labelCanvas, out stockChartCanvas, 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 = CandleStick.CalculateDataPointWidth(width, height, chart); foreach (DataSeries series in seriesList) { if (series.Enabled == false) { continue; } Faces dsFaces = new Faces() { Visual = stockChartCanvas, LabelCanvas = labelCanvas }; series.Faces = dsFaces; PlotGroup plotGroup = series.PlotGroup; _tempDataSeries = series; foreach (DataPoint dataPoint in series.InternalDataPoints) { CreateOrUpdateAStockDataPoint(dataPoint, stockChartCanvas, labelCanvas, width, height, dataPointWidth); } } // Apply animation to series if (animationEnabled) { if (_tempDataSeries.Storyboard == null) { _tempDataSeries.Storyboard = new Storyboard(); } _tempDataSeries.Storyboard = AnimationHelper.ApplyOpacityAnimation(stockChartCanvas, _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); } stockChartCanvas.Tag = null; // ColumnChart.CreateOrUpdatePlank(chart, seriesList[0].PlotGroup.AxisY, stockChartCanvas, 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(stockChartCanvas); } else { labelCanvas.SetValue(Canvas.ZIndexProperty, 1); visual.Children.Add(labelCanvas); visual.Children.Add(stockChartCanvas); } 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> /// 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 GetVisualObjectForQuickLineChart(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; LineChart.CreateAlineSeries(series, width, height, labelsCanvas, chartsCanvas, animationEnabled); isMovingMarkerEnabled = isMovingMarkerEnabled || series.MovingMarkerEnabled; minimumXValue = Math.Min(minimumXValue, series.PlotGroup.MinimumX); maximumXValue = Math.Max(maximumXValue, series.PlotGroup.MaximumX); } // 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> /// 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); }