protected override void LayoutYValueLabels() { ChartModel model = Model; double marginLeft = MarginLeft, marginTop = MarginTop; double gridWidth = (ChartCanvas.Width - marginLeft - MarginRight); double gridHeight = (ChartCanvas.Height - marginTop - MarginBottom); double cx = marginLeft + gridWidth / 2, cy = marginTop + gridHeight / 2.0; double radius = Math.Min(gridWidth, gridHeight) / 2.0; int vLineCount = this.GetVLineCount(), circleCount = this.GetHLineCount(); double minValue = model.MinYValue, maxValue = model.MaxYValue; string labelXAML = CurrentLookAndFeel.GetYValueLabelXAML(); double textHeight = double.NaN; _addRadarYLabelAt(labelXAML, cx, (double)marginTop, ref textHeight, maxValue); _addRadarYLabelAt(labelXAML, cx, cy, ref textHeight, minValue); // horizontal lines for (int i = 0; i < circleCount - 1; ++i) { double newRadius = (i + 1) * radius / (double)circleCount; double value = ((maxValue - minValue) * (i + 1) / (double)circleCount) + minValue; this._addRadarYLabelAt(labelXAML, cx, radius - newRadius + marginTop, ref textHeight, value); } }
protected override void DrawGroupLabels() { ChartModel model = Model; Canvas container = new Canvas(); HLabelContainer = container; List <UIElement> labelElems = LabelElements; bool animate = (AnimationDuration > 0); string[] groupLabels = model.GroupLabels; int vLineCount = groupLabels.Length; TextBlock labelElem; string labelText; string labelXAML = CurrentLookAndFeel.GetGroupLabelXAML(); double maxWidth = 0, maxHeight = 0; TextBlock [] gLabelElems = new TextBlock[vLineCount]; GroupLabelElems = gLabelElems; for (int i = 0; i < vLineCount; ++i) { labelText = groupLabels[i]; if (labelText == null || labelText.Length == 0) { continue; } labelElem = XamlReader.Load(labelXAML) as TextBlock; if (animate) { labelElems.Add(labelElem); labelElem.Opacity = 0; } labelElem.Text = labelText; container.Children.Add(labelElem); gLabelElems[i] = labelElem; maxWidth = Math.Max(maxWidth, labelElem.ActualWidth); maxHeight = Math.Max(maxHeight, labelElem.ActualHeight); } ChartCanvas.Children.Add(container); HLabelBounds = new Size(maxWidth, maxHeight); }
private void _displayToolTips( object sender, MouseEventArgs e, double[] seriesValues, int [] seriesIndices ) { ChartModel model = Model; string[] seriesLabels = model.SeriesLabels; int seriesCount = seriesLabels.Length; Color[] seriesColors = model.SeriesColors; int tooltipCount = seriesIndices.Length;; Point pt = e.GetPosition(ChartCanvas); double dx, dy; if (_tooltips == null) { _tooltips = new Canvas[seriesCount]; } for (int i = 0; i < tooltipCount; ++i) { int seriesIndex = seriesIndices[i]; Canvas toolTip = _tooltips[seriesIndex]; bool resizeOnInit = false; if (toolTip == null) { toolTip = XamlReader.Load(CurrentLookAndFeel.GetTooltipXAML()) as Canvas; ChartCanvas.Children.Add(toolTip); _tooltips[seriesIndex] = toolTip; resizeOnInit = true; } toolTip.Visibility = Visibility.Visible; Path circleElem = toolTip.Children[0] as Path; Path boundingRectElem = toolTip.Children[1] as Path; //append all the series values as labels TextBlock textElem = toolTip.Children[2] as TextBlock; int textElemCount = seriesValues.Length; textElem.Text = seriesLabels[seriesIndex] + ": " + seriesValues[i].ToString(Format); double rectWidth = textElem.ActualWidth; RectangleGeometry rg = boundingRectElem.Data as RectangleGeometry; Rect rect = rg.Rect; // Initially the template tooltip has an extra text node if (resizeOnInit) { dy = textElem.ActualHeight; rg.Rect = new Rect(rect.X, rect.Y, rect.Width, rect.Height - dy); textElem = toolTip.Children[3] as TextBlock; textElem.Text = ""; } rectWidth += 2 * _TEXT_MARGIN; rect = rg.Rect; rg.Rect = new Rect(rect.X, rect.Y, rectWidth, rect.Height); EllipseGeometry eg = circleElem.Data as EllipseGeometry; dx = pt.X; dy = _seriesYs[i] - rect.Height; if (IsPerspective) { dy -= YOffsetPerspective / 2.0; } double cx, cy; if (dx + rectWidth > ChartCanvas.Width) { dx -= rectWidth; cx = rectWidth; } else { cx = 0; } if (dy - rect.Height < 0) { dy += rect.Height; cy = 0; } else { cy = rect.Height; } eg.Center = new Point(cx, cy); boundingRectElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[seriesIndex])); circleElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[seriesIndex])); TranslateTransform tTrans = new TranslateTransform(); tTrans.X = dx; tTrans.Y = dy; toolTip.RenderTransform = tTrans; } }
private void _draw3DPies( Canvas pieContainer, double quadWidth, double quadHeight, int iGroup) { ChartModel model = Model; double[,] yValues = model.YValues; string[] groupLabels = model.GroupLabels; Color[] seriesColors = model.SeriesColors; var pieSize = Math.Min(quadWidth / 2, quadHeight / 2); if (iGroup == -1) { iGroup = 0; } int nPies = yValues.GetUpperBound(1) + 1; double pieTotal = 0; for (int i = 0; i < nPies; ++i) { pieTotal += yValues[iGroup, i]; } string pathXAML = CurrentLookAndFeel.GetPiePathXAML(); Path pathElem; double pieStart = 0; List <UIElement> dataElems = null; bool animate = (AnimationDuration > 0); if (animate) { dataElems = DataElements; } double perspectiveHeight = pieSize / 4; Path[] pieElems = new Path[nPies], ringElems = new Path[nPies], edgeElems = new Path[nPies]; if (perspectiveHeight > _MAX_PERSPECTIVE_HEIGHT) { perspectiveHeight = _MAX_PERSPECTIVE_HEIGHT; } string gradientXAML = CurrentLookAndFeel.GetElementGradientXAML(); TranslateTransform defaultTransform; for (int i = 0; i < nPies; ++i) { double valueRatio = 1 - (yValues[iGroup, i]) / (pieTotal); double arcBeginX, arcBeginY, arcEndX, arcEndY; arcBeginX = pieSize * Math.Cos(pieStart * Math.PI * 2); arcBeginY = pieSize * Math.Sin(pieStart * Math.PI * 2); StringBuilder sb = new StringBuilder(); sb.Append("M0,0L").Append(arcBeginX).Append(",").Append(arcBeginY); arcEndX = pieSize * Math.Cos((pieStart + valueRatio) * Math.PI * 2); arcEndY = pieSize * Math.Sin((pieStart + valueRatio) * Math.PI * 2); if (valueRatio >= .5) { sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 0 0 "); } else { sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 1 0 "); } sb.Append(arcEndX).Append(",").Append(arcEndY); sb.Append(" z"); pathElem = CreatePathFromXAMLAndData(pathXAML, sb); if (animate) { dataElems.Add(pathElem); defaultTransform = new TranslateTransform(); defaultTransform.X = defaultTransform.Y = -10000; pathElem.SetValue(Canvas.RenderTransformProperty, defaultTransform); _pieAnimAngles.Add(pieStart + valueRatio / 2); } if (gradientXAML != null) { SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0xe5); } else { SetFillOnElement(pathElem, seriesColors[i]); } pathElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i])); // centroid of the pie triangle Point centroid = new Point((arcBeginX + arcEndX) / 3, (arcBeginY + arcEndY) / 3); SetExpandosOnElement(pathElem, iGroup, i, centroid); if (DisplayToolTip) { pathElem.MouseEnter += new MouseEventHandler(ShowToolTip); pathElem.MouseLeave += new MouseEventHandler(HideToolTip); } pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked); sb = new StringBuilder(); sb.Append("M").Append(arcBeginX).Append(",").Append(arcBeginY); if (valueRatio >= .5) // major arc { sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 0 0 "); } else { sb.Append(" A").Append(pieSize).Append(" ").Append(pieSize).Append(" 1 1 0 "); } sb.Append(arcEndX).Append(",").Append(arcEndY); sb.Append(" v").Append(perspectiveHeight); sb.Append(" M").Append(arcEndX).Append(",").Append(arcEndY + perspectiveHeight); if (valueRatio >= .5) // major arc { sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 0 1 "); } else { sb.Append(" A").Append(pieSize).Append(",").Append(pieSize).Append(" 1 1 1 "); } sb.Append(arcBeginX).Append(",").Append(arcBeginY + perspectiveHeight); sb.Append(" v").Append(-perspectiveHeight); Path pathRingElem = CreatePathFromXAMLAndData(pathXAML, sb); if (gradientXAML != null) { SetGradientOnElement(pathRingElem, gradientXAML, seriesColors[i], 0xe5); } else { SetFillOnElement(pathRingElem, seriesColors[i]); } pathRingElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i])); sb = new StringBuilder(); sb.Append("M0,0L"); sb.Append(arcBeginX).Append(",").Append(arcBeginY); sb.Append("v").Append(perspectiveHeight); sb.Append("L").Append(0).Append(",").Append(perspectiveHeight); sb.Append("z"); sb.Append("M0,0L"); sb.Append(arcEndX).Append(",").Append(arcEndY); sb.Append("v").Append(perspectiveHeight); sb.Append("L").Append(0).Append(",").Append(perspectiveHeight); sb.Append("z"); Path pathEdgeElem = CreatePathFromXAMLAndData(pathXAML, sb); if (animate) { dataElems.Add(pathRingElem); defaultTransform = new TranslateTransform(); defaultTransform.X = defaultTransform.Y = -10000; pathRingElem.SetValue(Canvas.RenderTransformProperty, defaultTransform); dataElems.Add(pathEdgeElem); defaultTransform = new TranslateTransform(); defaultTransform.X = defaultTransform.Y = -10000; pathEdgeElem.SetValue(Canvas.RenderTransformProperty, defaultTransform); } (pathEdgeElem.Data as PathGeometry).FillRule = FillRule.Nonzero; if (gradientXAML != null) { SetGradientOnElement(pathEdgeElem, gradientXAML, seriesColors[i], 0xe5); } else { SetFillOnElement(pathEdgeElem, seriesColors[i]); } pathEdgeElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i])); if (DisplayToolTip) { pathRingElem.MouseEnter += new MouseEventHandler(ShowToolTip); pathRingElem.MouseLeave += new MouseEventHandler(HideToolTip); pathEdgeElem.MouseEnter += new MouseEventHandler(ShowToolTip); pathEdgeElem.MouseLeave += new MouseEventHandler(HideToolTip); } SetExpandosOnElement(pathRingElem, iGroup, i, centroid); SetExpandosOnElement(pathEdgeElem, iGroup, i, centroid); pieStart += valueRatio; pieElems[i] = pathElem; ringElems[i] = pathRingElem; edgeElems[i] = pathEdgeElem; } UIElementCollection children = pieContainer.Children; // For the top half, edges have preference over rings double totalRatio = 0; for (int i = 0; i < nPies; ++i) { if (totalRatio <= .5) { children.Add(ringElems[i]); } totalRatio += (yValues[iGroup, i]) / (pieTotal); } totalRatio = 0; for (int i = 0; i < nPies; ++i) { if (totalRatio <= .5) { children.Add(edgeElems[i]); } totalRatio += (yValues[iGroup, i]) / (pieTotal); } // For the bottom half, rings have preference over edges totalRatio = 0; for (int i = 0; i < nPies; ++i) { if (totalRatio > .5) { children.Add(edgeElems[i]); } totalRatio += (yValues[iGroup, i]) / (pieTotal); } totalRatio = 0; for (int i = 0; i < nPies; ++i) { if (totalRatio > .5) { children.Add(ringElems[i]); } totalRatio += (yValues[iGroup, i]) / (pieTotal); } for (int i = 0; i < nPies; ++i) { children.Add(pieElems[i]); } }
private void _drawPies( Canvas pieContainer, double quadWidth, double quadHeight, int iGroup) { ChartModel model = Model; double[,] yValues = model.YValues; string [] groupLabels = model.GroupLabels; Color[] seriesColors = model.SeriesColors; var pieSize = Math.Min(quadWidth / 2, quadHeight / 2); if (iGroup == -1) { iGroup = 0; } double nPies = yValues.GetUpperBound(1) + 1; double pieTotal = 0; for (int i = 0; i < nPies; ++i) { pieTotal += yValues[iGroup, i]; } string pathXAML = CurrentLookAndFeel.GetPiePathXAML(); Path pathElem; double pieStart = 0, animAngleStart = 0; List <UIElement> dataElems = null; bool animate = (AnimationDuration > 0); if (animate) { dataElems = DataElements; } string gradientXAML = CurrentLookAndFeel.GetElementGradientXAML(); TranslateTransform defaultTransform; for (int i = 0; i < nPies; ++i) { double valueRatio = 1 - (yValues[iGroup, i]) / (pieTotal); double x1 = pieSize * Math.Cos(pieStart * Math.PI * 2), y1 = pieSize * Math.Sin(pieStart * Math.PI * 2); StringBuilder sb = new StringBuilder(); sb.Append("M0,0 L"); sb.Append(x1); sb.Append(",").Append(y1); double x2 = pieSize * Math.Cos((pieStart + valueRatio) * Math.PI * 2), y2 = pieSize * Math.Sin((pieStart + valueRatio) * Math.PI * 2); if (valueRatio >= .5) // major arc { sb.Append(" A").Append(pieSize).Append(" ").Append(pieSize).Append(" 1 0 0 "); } else { sb.Append(" A").Append(pieSize).Append(" ").Append(pieSize).Append(" 1 1 0 "); } sb.Append(x2); sb.Append(",").Append(y2); sb.Append(" z"); pathElem = CreatePathFromXAMLAndData(pathXAML, sb); if (animate) { dataElems.Add(pathElem); defaultTransform = new TranslateTransform(); defaultTransform.X = defaultTransform.Y = -10000; pathElem.SetValue(Canvas.RenderTransformProperty, defaultTransform); double curAnimRatio = (yValues[iGroup, i]) / (pieTotal); _pieAnimAngles.Add(animAngleStart + curAnimRatio / 2); animAngleStart += curAnimRatio; } if (gradientXAML != null) { SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0xe5); } else { SetFillOnElement(pathElem, seriesColors[i]); } pathElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[i])); // centroid of the triangle used for tooltips Point centroid = new Point((x1 + x2) / 3, (y1 + y2) / 3); SetExpandosOnElement(pathElem, iGroup, i, centroid); if (DisplayToolTip) { pathElem.MouseEnter += new MouseEventHandler(ShowToolTip); pathElem.MouseLeave += new MouseEventHandler(HideToolTip); } pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked); pieStart += valueRatio; pieContainer.Children.Add(pathElem); } /*for (var i = 0; i< nPies; ++i) * { * // calculate the pie gradient: * pieContainer.appendChild(pieElems[i]); * }*/ }
public override void DrawChartData() { var rootElem = ChartCanvas; // calculate the number of rows and columns ChartModel model = Model; double[,] yValues = model.YValues; int yValueCount = yValues.GetUpperBound(0) + 1; string[] groupLabels = model.GroupLabels; int groupCount = groupLabels != null?groupLabels.Length:1; int nCols = (int)Math.Ceiling(Math.Sqrt(yValueCount)), nRows = (int)Math.Round(Math.Sqrt(yValueCount)); string labelXAML = CurrentLookAndFeel.GetGroupLabelXAML(); TextBlock labelElem = null; double dx = MarginLeft, dy = MarginTop; double quadWidth = (rootElem.Width - dx - MarginRight) / nCols; bool animate = (AnimationDuration > 0); double vGap = 2 * _TEXT_MARGIN; var quadHeight = (rootElem.Height - MarginTop - MarginBottom - (nRows - 1) * vGap) / nRows; if (animate) { _pieAnimAngles = new List <double>(); _pieAnimRadii = new List <double>(); } for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { int iGroup = (groupLabels != null)?(i * nCols + j):(-1); if (iGroup >= yValueCount) { break; } string groupLabel = (iGroup == -1)?null:groupLabels[iGroup]; Canvas pieContainer = new Canvas(); rootElem.Children.Add(pieContainer); double newHeight = DrawGroupLabelTitle(groupLabel, rootElem, labelXAML, ref labelElem, dx, dy, quadWidth, quadHeight); double newWidth = quadWidth - 2 * _TEXT_MARGIN; double cx = dx + quadWidth / 2 + _TEXT_MARGIN, cy = dy + newHeight / 2; if (animate) { _pieAnimRadii.Add(Math.Max(cx, cy)); } if (IsPerspective) { this._draw3DPies(pieContainer, newWidth, newHeight, iGroup); MatrixTransform mt = new MatrixTransform(); mt.Matrix = new Matrix(1, 0, 0, .707, cx, cy); // The chart is draw with the center at 0 so we need to compensate for it. pieContainer.RenderTransform = mt; } else { this._drawPies(pieContainer, newWidth, newHeight, iGroup); TranslateTransform tt = new TranslateTransform(); tt.X = cx; tt.Y = cy; pieContainer.RenderTransform = tt; } dx += quadWidth; } dx = MarginLeft; dy += quadHeight + vGap; } }
/// <summary> /// Method for base classes to provide XAML for the gauge template /// </summary> /// <returns></returns> protected virtual string GetGaugeXAML() { return(CurrentLookAndFeel.GetCircularGauageXAML()); }
public override void DrawChartData() { if (YMinorGridCount < 0) { YMinorGridCount = 4; } var rootCanvas = ChartCanvas; // calculate the number of rows and columns ChartModel model = Model; double[,] yValues = model.YValues; int yValueCount = yValues.GetUpperBound(0) + 1; string [] groupLabels = model.GroupLabels; int groupCount = (groupLabels != null)?groupLabels.Length:1; int nCols = (int)Math.Ceiling(Math.Sqrt(yValueCount)), nRows = (int)Math.Round(Math.Sqrt(yValueCount)); double dx = MarginLeft, dy = MarginTop; double quadWidth = (rootCanvas.Width - MarginLeft - MarginRight) / nCols; double vGap = 2 * _TEXT_MARGIN; double quadHeight = (rootCanvas.Height - MarginTop - MarginBottom - (nRows - 1) * vGap) / nRows; string labelXAML = CurrentLookAndFeel.GetGroupLabelXAML(); TextBlock labelElem = null; for (int i = 0; i < nRows; ++i) { for (int j = 0; j < nCols; ++j) { int iGroup = groupLabels != null?(i * nCols + j):(-1); if (iGroup >= yValueCount) { break; } string groupLabel = (iGroup == -1)?null:groupLabels[iGroup]; Canvas gaugeContainer = new Canvas(); rootCanvas.Children.Add(gaugeContainer); if (groupLabel != null) { labelElem = XamlReader.Load(labelXAML) as TextBlock; } double newHeight = DrawGroupLabelTitle(groupLabel, rootCanvas, labelXAML, ref labelElem, dx, dy, quadWidth, quadHeight); double newWidth = quadWidth - 2 * _TEXT_MARGIN; Size gaugeSize = DrawDial(gaugeContainer, newWidth, newHeight, iGroup); TranslateTransform tt = new TranslateTransform(); tt.X = (dx + _TEXT_MARGIN); tt.Y = dy; gaugeContainer.RenderTransform = tt; if (groupLabel != null) { if (gaugeSize.Height < newHeight - vGap) { var newY = (double)labelElem.GetValue(Canvas.TopProperty); newY -= (newHeight - gaugeSize.Height) / 2 - vGap; labelElem.SetValue(Canvas.TopProperty, newY); } } dx += quadWidth; } dx = MarginLeft; dy += quadHeight + vGap; } }
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); } }
protected override void Draw2DGrid() { List <UIElement> gridElems = GridElements; 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 / (double)2, cy = marginTop + gridHeight / (double)2; double radius = Math.Min(gridWidth, gridHeight) / (double)2; String gridGradientXAML = CurrentLookAndFeel.GetGridGradientXAML(); string circleXAML = CurrentLookAndFeel.GetRadarCircleXAML(); Path circle = XamlReader.Load(circleXAML) as Path; EllipseGeometry eg = circle.Data as EllipseGeometry; eg.Center = new Point(cx, cy); eg.RadiusY = eg.RadiusX = radius; if (gridGradientXAML != null) { circle.Fill = XamlReader.Load(gridGradientXAML) as Brush; } if (animate) { gridElems.Add(circle); circle.Opacity = 0.0; } ChartCanvas.Children.Add(circle); int vLineCount = this.GetVLineCount(); int circleCount = this.GetHLineCount(); // inner circles CurrentLookAndFeel.GetRadarInnerCircleXAML(); for (var i = 0; i < circleCount - 1; ++i) { circle = XamlReader.Load(circleXAML) as Path; eg = circle.Data as EllipseGeometry; eg.Center = new Point(cx, cy); if (animate) { gridElems.Add(circle); circle.Opacity = 0; } double newRadius = radius - (i + 1) * radius / circleCount; eg.RadiusY = eg.RadiusX = newRadius; ChartCanvas.Children.Add(circle); } StringBuilder sb = new StringBuilder(); sb.Append(" M").Append(cx).Append(",").Append(cy); sb.Append(" l").Append(0).Append(",").Append(-radius); for (int i = 0; i < vLineCount - 1; ++i) { double dx = cx + radius * Math.Sin((i + 1) * 2 * Math.PI / (double)vLineCount), dy = cy - radius * Math.Cos((i + 1) * 2 * Math.PI / (double)vLineCount); sb.Append(" M").Append(cx).Append(",").Append(cy); sb.Append(" L").Append(dx).Append(",").Append(dy); } Path pathElem = CreatePathFromXAMLAndData(CurrentLookAndFeel.GetRadarGridPathXAML(), sb); if (animate) { gridElems.Add(pathElem); pathElem.Opacity = 0; } ChartCanvas.Children.Add(pathElem); }
/// <summary> /// Method for base classes to provide XAML for the gauge template /// </summary> /// <returns></returns> protected override string GetGaugeXAML() { return(CurrentLookAndFeel.GetSemiCircularGauageXAML()); }
private void _drawPerspectiveFunnel( Canvas fnlContainer, double quadWidth, double quadHeight, int iGroup) { ChartModel model = Model; double[,] yValues = model.YValues; string [] groupLabels = model.GroupLabels; Color [] seriesColors = model.SeriesColors; if (iGroup == -1) { iGroup = 0; } // Number of segments int nSeg = yValues.GetUpperBound(1) + 1; double total = 0; for (int i = 0; i < nSeg; ++i) { total += yValues[iGroup, i]; } List <UIElement> dataElems = DataElements; bool animate = (AnimationDuration > 0); string funnelXAML = CurrentLookAndFeel.GetFunnelPathXAML(); Path pathElem; string gradientXAML = CurrentLookAndFeel.GetElementGradientXAML(); MatrixTransform defaultTransform; double x = 0, y = 0, slope = (quadWidth / 2.0) / quadHeight, dx = quadWidth, dy, nextX, oldDx, nextY; // the ring height is 1/12 of the width double rx = dx / 2.0, ry = dx / 24.0, oldRx, oldRy; for (int i = nSeg - 1; i >= 0; --i) { double valueRatio = (yValues[iGroup, i]) / (total); StringBuilder sb = new StringBuilder(); sb.Append("M").Append(x).Append(",").Append(y); sb.Append(" A").Append(rx).Append(",").Append(ry); sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(y); sb.Append(" A").Append(rx).Append(",").Append(ry); sb.Append(" 0 1,0 ").Append(x).Append(",").Append(y); oldDx = dx; oldRx = rx; oldRy = ry; dy = (quadHeight) * valueRatio; nextY = y + dy; nextX = quadWidth / 2.0 - slope * (quadHeight - (nextY)); dx = quadWidth - nextX; rx = (dx - nextX) / 2.0; ry = rx / 12.0; if (i != 0) { sb.Append("L").Append(nextX).Append(",").Append(nextY); sb.Append("A").Append(rx).Append(",").Append(ry); sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(nextY); sb.Append("L").Append(oldDx).Append(",").Append(y); } else { double startTipY = (dy / 3.0 <= _MAX_FUNNEL_TIP)?y + (dy - dy / 3.0): quadHeight - _MAX_FUNNEL_TIP; nextX = quadWidth / 2.0 - slope * (quadHeight - (startTipY)); dx = quadWidth - nextX; rx = (dx - nextX) / 2.0; ry = rx / 12.0; sb.Append(" L").Append(nextX).Append(",").Append(startTipY); sb.Append(" L").Append(nextX).Append(",").Append(quadHeight); sb.Append(" A").Append(rx).Append(",").Append(ry); sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(quadHeight); sb.Append(" A").Append(rx).Append(",").Append(ry); sb.Append(" 0 1,0 ").Append(nextX).Append(",").Append(quadHeight); sb.Append(" A").Append(rx).Append(",").Append(ry); sb.Append(" 0 1,0 ").Append(dx).Append(",").Append(quadHeight); sb.Append(" L").Append(dx).Append(",").Append(startTipY); sb.Append(" L").Append(oldDx).Append(",").Append(y); } pathElem = CreatePathFromXAMLAndData(funnelXAML, sb); if (animate) { dataElems.Add(pathElem); defaultTransform = new MatrixTransform(); Matrix m = new Matrix(0, 0, 0, 0, 0, 0); defaultTransform.Matrix = m; pathElem.RenderTransform = defaultTransform; } if (gradientXAML != null) { SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0xE5); } else { SetFillOnElement(pathElem, seriesColors[i]); } (pathElem.Data as PathGeometry).FillRule = FillRule.Nonzero; pathElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[i])); pathElem.SetValue(Canvas.ZIndexProperty, i + 1); SetExpandosOnElement(pathElem, iGroup, i, new Point(nextX + (dx - nextX) / 2.0, y + (nextY - y) / 2.0)); if (DisplayToolTip) { pathElem.MouseEnter += new MouseEventHandler(ShowToolTip); pathElem.MouseLeave += new MouseEventHandler(HideToolTip); } pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked); fnlContainer.Children.Add(pathElem); y = nextY; x = nextX; } }