private void _drawPerspectiveAreas(int mod, int rem) { bool animate = (this.AnimationDuration > 0); double xOffset = XOffsetPerspective, yOffset = YOffsetPerspective; double marginLeft = MarginLeft, marginTop = MarginTop; double marginRight = MarginRight, marginBottom = MarginBottom; double gridWidth = (ChartCanvas.Width - marginLeft - marginRight - xOffset); double gridHeight = (ChartCanvas.Height - marginTop - marginBottom - yOffset); LookAndFeel lf = CurrentLookAndFeel; string pathXAML = lf.GetAreaPathXAML(); Path pathElem; List <UIElement> dataElems = null; MatrixTransform defaultTransform = null; if (animate) { dataElems = DataElements; } bool isStacked = (Type == ChartType.AREA_STACKED); ChartModel model = Model; string [] groupLabels = model.GroupLabels; int groupCount = groupLabels.Length; string [] seriesLabels = model.SeriesLabels; int seriesCount = seriesLabels.Length; Color [] seriesColors = model.SeriesColors; double[,] yValues = model.YValues; double minValue = model.MinYValue, maxValue = model.MaxYValue; int yValueCount = yValues.GetUpperBound(0) + 1; double barWidth = (gridWidth / (Math.Max(yValueCount, groupCount))), stackBase; double barHeight; double gridBottom = gridHeight + marginTop + yOffset, dx, dy; double[] cumYs = isStacked? new double[yValueCount] : null; if (isStacked) { cumYs = new double[yValueCount]; for (int j = 0; j < yValueCount; ++j) { cumYs[j] = double.NaN; } } string gradientXAML = lf.GetElementGradientXAML(); for (int i = 0; i < seriesCount; ++i) { // for combo charts we draw a bar every once in a mod. if ((mod > 1) && (i % mod) != rem) { continue; } dx = marginLeft + barWidth / 2.0; // If we use non zero min and it is a stacked graph, we need to remove the min for only // the first series. stackBase = (i == 0?minValue:0); StringBuilder sb = new StringBuilder(); for (int j = 0; j < yValueCount; ++j) { barHeight = gridHeight * (yValues[j, i] - stackBase) / (maxValue - minValue); if (isStacked) { if (double.IsNaN(cumYs[j])) { cumYs[j] = gridBottom; } dy = (cumYs[j] -= barHeight); } else { dy = gridBottom - barHeight; } if (j == yValueCount - 1) { break; } sb.Append("M").Append(dx).Append(",").Append(dy); sb.Append(" l").Append(xOffset).Append(",").Append(-yOffset); if (i == 0 || !isStacked) { sb.Append(" L").Append(dx + xOffset).Append(",").Append(gridHeight + marginTop); } else { sb.Append(" v").Append(barHeight); } sb.Append(" l").Append(-xOffset).Append(",").Append(yOffset); sb.Append(" z"); sb.Append("M").Append(dx).Append(",").Append(dy); sb.Append(" l").Append(xOffset).Append(",").Append(-yOffset); double nextdy, nextdx = dx + barWidth; if (isStacked) { if (double.IsNaN(cumYs[j + 1])) { cumYs[j + 1] = gridBottom; } nextdy = (cumYs[j + 1] - gridHeight * (yValues[j + 1, i] - stackBase) / (maxValue - minValue)); } else { nextdy = gridBottom - gridHeight * (yValues[j + 1, i] - minValue) / (maxValue - minValue); } sb.Append(" L").Append(nextdx + xOffset).Append(",").Append(nextdy - yOffset); sb.Append(" l").Append(-xOffset).Append(",").Append(yOffset); sb.Append(" L").Append(dx).Append(",").Append(dy); sb.Append(" M").Append(nextdx).Append(",").Append(nextdy); sb.Append(" l").Append(xOffset).Append(",").Append(-yOffset); if (i == 0 || !isStacked) { sb.Append(" L").Append(nextdx + xOffset).Append(",").Append(gridHeight + marginTop); } else { sb.Append(" L").Append(nextdx + xOffset).Append(",").Append(cumYs[j + 1] - yOffset); } sb.Append(" l").Append(-xOffset).Append(",").Append(yOffset); sb.Append(" L").Append(nextdx).Append(",").Append(nextdy); sb.Append(" M").Append(dx).Append(",").Append(dy); sb.Append(" L").Append(nextdx).Append(",").Append(nextdy); if (i == 0 || !isStacked) { sb.Append(" L").Append(nextdx).Append(",").Append(gridBottom); sb.Append(" L").Append(dx).Append(",").Append(gridBottom); } else { sb.Append(" L").Append(nextdx).Append(",").Append(cumYs[j + 1]); sb.Append(" L").Append(dx).Append(",").Append( cumYs[j] + gridHeight * (yValues[j, i] - stackBase) / (maxValue - minValue)); } sb.Append(" L").Append(dx).Append(",").Append(dy); dx += barWidth; } pathElem = CreatePathFromXAMLAndData(pathXAML, sb); SetExpandosOnElement(pathElem, -1, i, new Point()); if (DisplayToolTip) { pathElem.MouseMove += new MouseEventHandler(ShowToolTip); pathElem.MouseLeave += new MouseEventHandler(HideToolTip); } pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked); if (gradientXAML != null) { SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0x7F); } else { SetFillOnElement(pathElem, seriesColors[i]); } pathElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[i])); (pathElem.Data as PathGeometry).FillRule = FillRule.Nonzero; if (animate) { dataElems.Add(pathElem); defaultTransform = new MatrixTransform(); Matrix m = new Matrix(); m.M11 = 0.0; defaultTransform.Matrix = m; pathElem.SetValue(UIElement.RenderTransformProperty, defaultTransform); } ChartCanvas.Children.Add(pathElem); } }
private void _drawRadar() { ChartModel model = Model; List <UIElement> dataElems = DataElements; bool animate = (AnimationDuration > 0); double marginLeft = MarginLeft, marginTop = MarginTop; double gridWidth = (ChartCanvas.Width - marginLeft - MarginRight); double gridHeight = (ChartCanvas.Height - marginTop - MarginBottom); double cx = marginLeft + gridWidth / 2.0, cy = marginTop + gridHeight / 2.0; double radius = Math.Min(gridWidth, gridHeight) / 2.0; bool isRadarArea = (Type == Chart.ChartType.RADAR_AREA); LookAndFeel lf = CurrentLookAndFeel; string pathXAML = isRadarArea ? lf.GetAreaPathXAML() : lf.GetLinePathXAML(); string lineDotXAML = null; string[] seriesLabels = model.SeriesLabels; int seriesCount = seriesLabels.Length; Color [] seriesColors = model.SeriesColors; double[,] yValues = model.YValues; double minValue = model.MinYValue, maxValue = model.MaxYValue; string gradientXAML = lf.GetElementGradientXAML(); MatrixTransform defaultTransform = null; int yValueCount = yValues.GetUpperBound(0) + 1; double dx, dy; if (!isRadarArea) { lineDotXAML = CurrentLookAndFeel.GetLineDotXAML(); } if (animate && _dotElements == null) { _dotElements = new UIElement[seriesCount, yValueCount]; } for (int i = 0; i < seriesCount; ++i) { StringBuilder sb = new StringBuilder(); for (int j = 0; j < yValueCount; ++j) { double yPoint = radius * (yValues[j, i] - minValue) / (maxValue - minValue); dx = cx + yPoint * Math.Sin((j) * 2 * Math.PI / yValueCount); dy = cy - yPoint * Math.Cos((j) * 2 * Math.PI / yValueCount); if (j == 0) { sb.Append("M").Append(dx).Append(",").Append(dy); } else { sb.Append(" L").Append(dx).Append(",").Append(dy); } if (!isRadarArea) { Path dotElem = XamlReader.Load(lineDotXAML) as Path; EllipseGeometry eg = dotElem.Data as EllipseGeometry; eg.Center = new Point(dx, dy); if (gradientXAML != null) { SetGradientOnElement(dotElem, gradientXAML, seriesColors[i], 0xe5); } else { SetFillOnElement(dotElem, seriesColors[i]); } dotElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[i])); if (animate) { _dotElements[i, j] = dotElem; defaultTransform = new MatrixTransform(); Matrix m = new Matrix(); m.M11 = m.M22 = 0.0; defaultTransform.Matrix = m; dotElem.SetValue(UIElement.RenderTransformProperty, defaultTransform); } ChartCanvas.Children.Add(dotElem); } } sb.Append("Z"); Path pathElem = CreatePathFromXAMLAndData(pathXAML, sb); if (animate) { dataElems.Add(pathElem); defaultTransform = new MatrixTransform(); Matrix m = new Matrix(); m.M11 = m.M22 = 0.0; defaultTransform.Matrix = m; pathElem.SetValue(UIElement.RenderTransformProperty, defaultTransform); } if (isRadarArea) { if (gradientXAML != null) { SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0x72); } else { SetFillOnElement(pathElem, seriesColors[i]); } } pathElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[i])); (pathElem.Data as PathGeometry).FillRule = FillRule.Nonzero; SetExpandosOnElement(pathElem, -1, i, new Point()); if (DisplayToolTip) { pathElem.MouseMove += new MouseEventHandler(ShowToolTip); pathElem.MouseLeave += new MouseEventHandler(HideToolTip); } pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked); ChartCanvas.Children.Add(pathElem); } }