Пример #1
0
        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);
            }
        }
Пример #2
0
        protected virtual void SetIndicatorPosition(double yValue, UIElement indicator, double ratio)
        {
            double theta, cx = _animCenter.X, cy = _animCenter.Y;

            ChartModel model    = Model;
            double     minValue = model.MinYValue,
                       maxValue = model.MaxYValue;

            double valueRatio = ratio * (yValue - minValue) / (maxValue - minValue);

            theta = Math.PI / 6 + valueRatio * (5 * Math.PI / 3);

            if (theta < Math.PI / 2)
            {
                theta += 3 * Math.PI / 2;
            }
            else
            {
                theta -= Math.PI / 2;
            }
            theta *= 180 / Math.PI;

            RotateTransform rt = new RotateTransform();

            rt.CenterX = cx;
            rt.CenterY = cy;
            rt.Angle   = theta;

            indicator.RenderTransform = rt;
        }
Пример #3
0
        protected override void LayoutGroupLabels()
        {
            ChartModel model = Model;
            double     marginLeft = MarginLeft, marginTop = MarginTop;
            double     gridWidth = (ChartCanvas.Width - marginLeft - MarginRight);
            double     gridHeight, cy = 0;
            double     cx = marginLeft + gridWidth / 2, radius = 0;

            string [] groupLabels = model.GroupLabels;
            int       vLineCount  = groupLabels.Length;

            TextBlock labelElem;

            double groupWidth = gridWidth / (double)vLineCount;
            Canvas container  = HLabelContainer;

            UIElementCollection childNodes = container.Children;

            bool firstLabelDrawn = false;

            TextBlock[] gLabelElems = GroupLabelElems;

            if (childNodes.Count == 0)
            {
                return;
            }

            for (int i = 0; i < vLineCount; ++i)
            {
                labelElem = gLabelElems[i];

                if (labelElem == null)
                {
                    continue;
                }

                if (!firstLabelDrawn)
                {
                    gridHeight = (ChartCanvas.Height - marginTop - MarginBottom);
                    cy         = marginTop + gridHeight / (double)2;
                    radius     = Math.Min(gridWidth, gridHeight) / (double)2 +
                                 labelElem.ActualHeight - _TEXT_MARGIN / (double)2;
                    firstLabelDrawn = true;
                }

                double theta = (i) * 2 * Math.PI / (double)vLineCount;

                double dx = cx + radius * Math.Sin(theta),
                       dy = cy - radius * Math.Cos(theta);

                labelElem.SetValue(Canvas.TopProperty, dy - labelElem.ActualHeight / (double)2);

                if (theta > Math.PI)
                {
                    dx -= labelElem.ActualWidth;
                }

                labelElem.SetValue(Canvas.LeftProperty, dx);
            }
        }
Пример #4
0
        /// <summary>
        /// Draws the dial for the gauge and returns the actual size of the gauge
        /// </summary>
        /// <param name="gaugeContainer"></param>
        /// <param name="quadWidth"></param>
        /// <param name="quadHeight"></param>
        /// <param name="iGroup"></param>
        /// <returns></returns>
        protected virtual Size DrawDial(
            Canvas gaugeContainer,
            double quadWidth,
            double quadHeight,
            int iGroup)
        {
            ChartModel model = Model;

            if (iGroup == -1)
            {
                iGroup = 0;
            }

            List <UIElement> dataElems = DataElements;
            bool             animate   = (AnimationDuration > 0);
            Canvas           gauge     = XamlReader.Load(GetGaugeXAML()) as Canvas;

            gaugeContainer.Children.Add(gauge);

            double gaugeWidth = gauge.Width, gaugeHeight = gauge.Height;
            double gaugeR = gaugeWidth / 2;

            Canvas indicator = gauge.FindName("indicator") as Canvas;

            SetExpandosOnElement(indicator, iGroup, 0, new Point());

            if (DisplayToolTip)
            {
                indicator.MouseEnter += new MouseEventHandler(ShowToolTip);
                indicator.MouseLeave += new MouseEventHandler(HideToolTip);
            }

            indicator.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

            if (_animCenter.X == 0)
            {
                _animCenter.X = _animCenter.Y = indicator.Width / 2;
            }

            if (animate)
            {
                dataElems.Add(indicator);
            }

            else
            {
                // If there is no animation lets move the indicators to the last position
                SetIndicatorPosition(model.YValues[iGroup, 0], indicator, 1);
            }

            CreateTextMarkerGroup(gauge, gaugeR);

            return(ScaleGauge(gauge, quadWidth, quadHeight, gaugeWidth, gaugeHeight));
        }
Пример #5
0
        protected override ChartEventArgs GetChartEvent(object sender, MouseEventArgs e)
        {
            Point           pt = e.GetPosition(ChartCanvas);
            ElementExpandos ee = Expandos[sender];
            int             i  = ee.SeriesIndex;

            bool       isPerspective = IsPerspective;
            double     yOffset       = YOffsetPerspective;
            ChartModel model         = Model;

            double[,] xValues = model.XValues;
            double[,] yValues = model.YValues;
            int nValues = yValues.GetUpperBound(0) + 1;

            double minYValue = model.MinYValue, maxYValue = model.MaxYValue;
            double minXValue = model.MinXValue, maxXValue = model.MaxXValue;

            double marginLeft = MarginLeft, marginTop = MarginTop;
            double gridWidth  = (ChartCanvas.Width - marginLeft - MarginRight);
            double gridHeight = (ChartCanvas.Height - marginTop - MarginBottom);

            double gridBottom = gridHeight + marginTop + (isPerspective?yOffset:0);
            double dx, dy, xValue = 0.0, yValue = 0.0;
            double nextdy, nextdx;

            for (int j = 0; j < nValues; ++j)
            {
                if (j != nValues - 1)
                {
                    dx     = marginLeft + gridWidth * (xValues[j, i] - minXValue) / (maxXValue - minXValue);
                    nextdx = marginLeft + gridWidth * (xValues[j + 1, i] - minXValue) / (maxXValue - minXValue);

                    if (pt.X > dx && pt.X < (dx + nextdx))
                    {
                        dy     = gridBottom - gridHeight * (yValues[j, i] - minYValue) / (maxYValue - minYValue);
                        nextdy = gridBottom -
                                 gridHeight * (yValues[j + 1, i] - minYValue) / (maxYValue - minYValue);

                        yValue = yValues[j, i] + (yValues[j + 1, i] - yValues[j, i]) * (pt.Y - dy) / (nextdy - dy);
                        xValue = xValues[j, i] + (xValues[j + 1, i] - xValues[j, i]) * (pt.X - dx) / (nextdx - dx);
                        break;
                    }
                }
            }

            int[] seriesIndices = { i };
            //double[] yEventValues = {yValue};
            //double[] xEventValues = {xValue};

            return(new ChartEventArgs(seriesIndices, null, new double[] { yValue }, new double[] { xValue }));
        }
Пример #6
0
        public override void SetDataAnimStep(double ratio)
        {
            double marginLeft = MarginLeft, marginTop = MarginTop;

            bool isRadarArea = (Type == Chart.ChartType.RADAR_AREA);

            ChartModel model = Model;

            string [] seriesLabels = model.SeriesLabels;
            int       seriesCount  = seriesLabels.Length;

            double gridWidth = (ChartCanvas.Width - marginLeft - MarginRight);
            double gridHeight = (ChartCanvas.Height - marginTop - MarginBottom);
            double cx = marginLeft + gridWidth / 2.0, cy = marginTop + gridHeight / 2.0;
            double newRatio        = ratio * (double)seriesCount;
            int    animSeriesIndex = 0;

            if (newRatio > 1)
            {
                animSeriesIndex = (int)Math.Floor(newRatio);
                if (animSeriesIndex >= seriesCount)
                {
                    animSeriesIndex = seriesCount - 1;
                }
                newRatio = newRatio - (int)Math.Floor(newRatio);
            }

            double tx = (1 - newRatio) * cx, ty = (1 - newRatio) * cy;
            Matrix m = new Matrix(newRatio, 0, 0, newRatio, tx, ty);

            // We will make each series appear separately
            int i = animSeriesIndex;

            this._setRadarSeriesAnimStep(i, isRadarArea, m);

            if (i > 0)
            {
                _setRadarSeriesAnimStep(i - 1, isRadarArea, Matrix.Identity);
            }

            // make sure that everything is scaled properly at the end
            if (ratio == 1)
            {
                for (int j = 0; j < seriesCount; ++j)
                {
                    _setRadarSeriesAnimStep(j, isRadarArea, Matrix.Identity);
                }
                _dotElements = null;
            }
        }
Пример #7
0
        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);
        }
Пример #8
0
        protected override Size FillToolTipData(
            object sender,
            MouseEventArgs e,
            Path boundingRectElem,
            Path circleElem)
        {
            ChartEventArgs chartEvent = GetChartEvent(sender, e);

            int i = chartEvent.SeriesIndices[0];

            double yValue = chartEvent.YValues[0],
                   xValue = chartEvent.XValues[0];

            ChartModel model = Model;

            string[] seriesLabels = model.SeriesLabels;

            TextBlock textElem = ToolTip.Children[2] as TextBlock;

            textElem.Text = seriesLabels[i] + ": (" + xValue.ToString(Format) + ")    (" + yValue.ToString() + ")";

            double labelWidth  = textElem.ActualWidth;
            double labelHeight = textElem.ActualHeight;

            //We do not need the next label
            textElem = ToolTip.Children[3] as TextBlock;

            textElem.Text = "";

            double rectWidth = labelWidth + 2 * _TEXT_MARGIN;

            RectangleGeometry rg = boundingRectElem.Data as RectangleGeometry;
            Rect   rect          = rg.Rect;
            double rectHeight    = rect.Height;

            if (rectHeight > 2 * labelHeight)
            {
                rectHeight -= labelHeight;
            }
            rg.Rect = new Rect(rect.X, rect.Y, rectWidth, rectHeight);
            boundingRectElem.SetValue(Path.StrokeProperty, new SolidColorBrush(Model.SeriesColors[i]));

            EllipseGeometry eg = circleElem.Data as EllipseGeometry;

            eg.RadiusX = eg.RadiusY = 0;
            return(new Size(rectWidth, 2 * (labelHeight + _TEXT_MARGIN)));
        }
Пример #9
0
        protected override ChartEventArgs GetChartEvent(object sender, MouseEventArgs e)
        {
            Point           pt = e.GetPosition(ChartCanvas);
            ElementExpandos ee = Expandos[sender];
            int             i  = ee.SeriesIndex;

            bool   isPerspective = IsPerspective;
            double yOffset       = YOffsetPerspective;

            ChartModel model = Model;

            double [,] yValues = model.YValues;

            string [] groupLabels = model.GroupLabels;
            int       groupCount  = groupLabels.Length;

            double marginLeft = MarginLeft, marginTop = MarginTop;
            double gridWidth   = (ChartCanvas.Width - marginLeft - MarginRight);
            double gridHeight  = (ChartCanvas.Height - marginTop - MarginBottom);
            int    yValueCount = yValues.GetUpperBound(0) + 1;

            double barWidth = (gridWidth / Math.Max(yValueCount, groupCount));

            double gridBottom = gridHeight + marginTop + (isPerspective?yOffset:0);
            double dx = marginLeft + barWidth / 2, value = 0.0;

            for (int j = 0; j < yValueCount; ++j)
            {
                if (j == yValueCount - 1)
                {
                    continue;
                }

                if (pt.X > dx && pt.X < (dx + barWidth))
                {
                    value = yValues[j, i] + (yValues[j + 1, i] - yValues[j, i]) * (pt.X - dx) / barWidth;
                    break;
                }
                dx += barWidth;
            }

            int[]    seriesIndices = { i };
            double[] values        = { value };

            return(new ChartEventArgs(seriesIndices, null, values, null));
        }
Пример #10
0
        public override void SetDataAnimStep(double ratio)
        {
            List <UIElement> animElems = DataElements;
            int animCount = animElems.Count;

            ChartModel model = Model;

            double[,] yValues = Model.YValues;

            for (int i = 0; i < animCount; ++i)
            {
                // For Dial Chart only one value is applicable
                double yValue = yValues[i, 0];

                SetIndicatorPosition(yValue, animElems[i], ratio);
            }
        }
Пример #11
0
        protected override void SetIndicatorPosition(double yValue, UIElement indicator, double ratio)
        {
            double     cx = _animCenter.X, cy = _animCenter.Y;
            ChartModel model    = Model;
            double     minValue = model.MinYValue,
                       maxValue = model.MaxYValue;
            double valueRatio   = ratio * (yValue - minValue) / (maxValue - minValue);

            double theta = valueRatio * Math.PI;

            theta *= 180 / Math.PI;

            RotateTransform rt = new RotateTransform();

            rt.CenterX = cx;
            rt.CenterY = cy;
            rt.Angle   = theta;

            indicator.RenderTransform = rt;
        }
Пример #12
0
        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;
            }
        }
Пример #13
0
 public PieChart(ChartType type, ChartModel model) : base(type, model)
 {
 }
Пример #14
0
 public ScatterPlotChart(ChartType type, ChartModel model) : base(type, model)
 {
 }
Пример #15
0
        protected virtual void CreateTextMarkerGroup(Canvas gauge, double gaugeR)
        {
            ChartModel model = Model;
            Canvas     gElem = new Canvas();

            gauge.Children.Add(gElem);

            LookAndFeel lf = CurrentLookAndFeel;

            int    majorMarkerCount = YMajorGridCount;
            int    minorMarkerCount = YMinorGridCount;
            string majorMarkerXAML  = lf.GetGauageMarkerMajorXAML(),
                   minorMarkerXAML  = lf.GetGauageMarkerMinorXAML();
            string    textXAML      = lf.GetGauageTextXAML();
            TextBlock textElem;

            Canvas markerContainerCanvas = gauge.FindName("markerContainer") as Canvas;

            double markerContainerR = markerContainerCanvas.Width / 2;
            double minValue = model.MinYValue, maxValue = model.MaxYValue;

            double x, y, angle, textMargin = 0.0;

            double theta = Math.PI / 6;

            for (int i = 0;
                 i <= majorMarkerCount; ++i, theta += (5.0 * Math.PI / 3.0) / majorMarkerCount)
            {
                double adjustedTheta;

                if (theta < Math.PI / 2)
                {
                    adjustedTheta = theta + 3.0 * Math.PI / 2.0;
                }
                else
                {
                    adjustedTheta = theta - Math.PI / 2.0;
                }

                x = gaugeR - markerContainerR * (Math.Cos(adjustedTheta));
                y = gaugeR - markerContainerR * (Math.Sin(adjustedTheta));

                angle = adjustedTheta * 180 / Math.PI;

                Path marker = XamlReader.Load(majorMarkerXAML) as Path;

                TransformGroup     tg = new TransformGroup();
                TranslateTransform tt = new TranslateTransform();
                RotateTransform    rt = new RotateTransform();

                tt.X     = x;
                tt.Y     = y;
                rt.Angle = angle;
                tg.Children.Add(rt);
                tg.Children.Add(tt);
                marker.RenderTransform = tg;
                gElem.Children.Add(marker);

                double value = minValue + i * (maxValue - minValue) / (majorMarkerCount);
                textElem      = XamlReader.Load(textXAML) as TextBlock;
                textElem.Text = value.ToString(Format);

                if (i == 0)
                {
                    textMargin = textElem.ActualHeight / 2;
                }

                x = gaugeR - (markerContainerR - textMargin) * (Math.Cos(adjustedTheta));
                y = gaugeR - (markerContainerR - textMargin) * (Math.Sin(adjustedTheta));

                if (theta >= 5 * Math.PI / 6 && theta <= 7 * Math.PI / 6)
                {
                    x -= textElem.ActualWidth / 2;
                }
                else
                {
                    y -= textElem.ActualHeight / 2;

                    if (theta < Math.PI)
                    {
                        x += 2 * _TEXT_MARGIN;
                    }
                    else
                    {
                        x -= textElem.ActualWidth + 2 * _TEXT_MARGIN;
                    }
                }

                tt   = new TranslateTransform();
                tt.X = x;
                tt.Y = y;

                textElem.RenderTransform = tt;
                gElem.Children.Add(textElem);
            }

            theta = Math.PI / 6 + (5 * Math.PI / 3) / (majorMarkerCount * minorMarkerCount);
            for (int i = (minorMarkerCount + 1);
                 i <= (majorMarkerCount + 1) * minorMarkerCount;
                 ++i, theta += (5 * Math.PI / 3) / (majorMarkerCount * minorMarkerCount))
            {
                if (i % minorMarkerCount == 0)
                {
                    continue;
                }

                double adjustedTheta;
                if (theta < Math.PI / 2)
                {
                    adjustedTheta = theta + 3 * Math.PI / 2;
                }
                else
                {
                    adjustedTheta = theta - Math.PI / 2;
                }

                x     = gaugeR - markerContainerR * (Math.Cos(adjustedTheta));
                y     = gaugeR - markerContainerR * (Math.Sin(adjustedTheta));
                angle = adjustedTheta * 180 / Math.PI;

                Path               marker = XamlReader.Load(minorMarkerXAML) as Path;
                TransformGroup     tg     = new TransformGroup();
                TranslateTransform tt     = new TranslateTransform();
                RotateTransform    rt     = new RotateTransform();

                tt.X     = x;
                tt.Y     = y;
                rt.Angle = angle;
                tg.Children.Add(rt);
                tg.Children.Add(tt);
                marker.RenderTransform = tg;
                gElem.Children.Add(marker);
            }
        }
Пример #16
0
        private void _drawPerspectiveBars(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.GetBarPathXAML();
            Path             pathElem;
            List <UIElement> dataElems        = null;
            MatrixTransform  defaultTransform = null;

            if (animate)
            {
                dataElems = DataElements;
            }

            int  barItemPadding = _BARITEM_PADDING;
            bool isStacked      = (Type == ChartType.HBAR_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;

            // For combo graphs we display every once in mod
            int    seriesBars = (mod > 1) ? (int)Math.Ceiling(1 / (double)mod) : seriesCount;
            int    yValueCount = yValues.GetUpperBound(0) + 1;
            double barHeight, stackBase = minValue;

            if (isStacked)
            {
                barHeight = gridHeight / Math.Max(yValueCount, groupCount) - 2 * barItemPadding;
            }
            else
            {
                barHeight = (gridHeight / Math.Max(yValueCount, groupCount)
                             - 2 * barItemPadding - (seriesCount) * barItemPadding) / seriesBars;
            }

            double dx = marginLeft, dy = gridHeight + marginTop + yOffset, barWidth;
            string gradientXAML = lf.GetElementGradientXAML();

            for (int i = 0; i < yValueCount; ++i)
            {
                dy -= barItemPadding;
                dx  = marginLeft;
                for (var j = 0; j < seriesCount; ++j)
                {
                    // for combo charts we draw a bar every once in a mod.
                    if ((mod > 1) && j % mod != rem)
                    {
                        continue;
                    }

                    // If we use non zero min and it is a stacked graph, we need to remove the min for only
                    // the first series.
                    if (isStacked)
                    {
                        stackBase = (j == 0 ? minValue : 0);
                    }

                    barWidth = gridWidth * (yValues[i, j] - stackBase) / (maxValue - minValue);


                    StringBuilder sb = new StringBuilder();
                    sb.Append("M").Append(dx).Append(",").Append(dy);
                    sb.Append(" h").Append(barWidth);
                    sb.Append(" v").Append(-barHeight);
                    sb.Append(" h").Append(-barWidth);
                    sb.Append(" v").Append(barHeight);

                    sb.Append(" M").Append(dx).Append(",").Append(dy - barHeight);
                    sb.Append(" l").Append(xOffset).Append(",").Append(-yOffset);
                    sb.Append(" h").Append(barWidth);
                    sb.Append(" l").Append(-xOffset).Append(",").Append(yOffset);
                    sb.Append(" z");
                    sb.Append(" M").Append(dx + barWidth).Append(",").Append(dy);
                    sb.Append(" v").Append(-barHeight);
                    sb.Append(" l").Append(xOffset).Append(",").Append(-yOffset);
                    sb.Append(" v").Append(barHeight);
                    sb.Append(" z");

                    pathElem = CreatePathFromXAMLAndData(lf.GetBarPathXAML(), sb);

                    if (animate)
                    {
                        dataElems.Add(pathElem);
                        defaultTransform = new MatrixTransform();
                        Matrix m = new Matrix();
                        m.M11 = 0.0;
                        defaultTransform.Matrix = m;
                        pathElem.SetValue(UIElement.RenderTransformProperty, defaultTransform);
                    }

                    pathElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[j]));

                    if (gradientXAML != null)
                    {
                        SetGradientOnElement(pathElem, gradientXAML, seriesColors[j], 0xe5);
                    }
                    else
                    {
                        SetFillOnElement(pathElem, seriesColors[j]);
                    }

                    SetExpandosOnElement(pathElem, i, j, new Point(dx + barWidth + (xOffset) / 2.0, dy - (barHeight + yOffset) / 2.0));

                    if (DisplayToolTip)
                    {
                        pathElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                        pathElem.MouseLeave += new MouseEventHandler(HideToolTip);
                    }

                    pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

                    ChartCanvas.Children.Add(pathElem);
                    if (isStacked)
                    {
                        dx += barWidth;
                    }
                    else
                    {
                        dy -= barHeight;
                        dy -= barItemPadding;
                    }
                }
                if (isStacked)
                {
                    dy -= barHeight;
                }
                dy -= barItemPadding;
            }
        }
Пример #17
0
 public AreaChart(ChartType type, ChartModel model) : base(type, model)
 {
 }
Пример #18
0
        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;
            }
        }
Пример #19
0
        protected override ChartEventArgs GetChartEvent(object sender, MouseEventArgs e)
        {
            Point pt = e.GetPosition(ChartCanvas);

            bool       isStacked     = (Type == ChartType.AREA_STACKED);
            ChartModel model         = Model;
            bool       isPerspective = IsPerspective;

            double xOffset = XOffsetPerspective, yOffset = YOffsetPerspective;

            string [] groupLabels = model.GroupLabels;
            int       groupCount  = groupLabels.Length;

            double[,] yValues = model.YValues;
            double minValue = model.MinYValue, maxValue = model.MaxYValue;
            int    yValueCount = yValues.GetUpperBound(0) + 1;

            double marginLeft = MarginLeft, marginTop = MarginTop;
            double gridWidth  = (ChartCanvas.Width - marginLeft - MarginRight);
            double gridHeight = (ChartCanvas.Height - marginTop - MarginBottom);
            double barWidth   = (gridWidth / (Math.Max(yValueCount, groupCount)));

            if (isPerspective)
            {
                gridWidth  -= xOffset;
                gridHeight -= yOffset;
            }

            if (pt.X < marginLeft ||
                pt.X > (marginLeft + gridWidth + (isPerspective?xOffset:0)) ||
                pt.Y < marginTop ||
                pt.Y > (marginTop + gridHeight + (isPerspective?yOffset:0)))
            {
                return(null);
            }

            int           seriesCount = model.SeriesLabels.Length;
            double        stackBase;
            bool          insideStacked = false;
            double        dx, dy, dy1, dy2, value;
            List <int>    seriesIndices = new List <int>(seriesCount);
            List <double> seriesValues  = new List <double>(seriesCount);

            double[] cumYs = isStacked? new double[yValueCount] : null;

            if (isStacked)
            {
                cumYs = new double[yValueCount];
                for (int j = 0; j < yValueCount; ++j)
                {
                    cumYs[j] = double.NaN;
                }
            }

            double gridBottom = gridHeight + marginTop + (isPerspective?yOffset:0);

            _seriesYs = new List <double>(seriesCount);

            for (int i = 0; i < seriesCount && !insideStacked; ++i)
            {
                // for combo charts we draw a bar every once in a mod.
                if ((_mod > 1) && (i % _mod) != _rem)
                {
                    continue;
                }

                dx = marginLeft + barWidth / 2;

                stackBase = (i == 0?minValue:0);

                for (int j = 0; j < yValueCount; ++j)
                {
                    if (isStacked)
                    {
                        if (double.IsNaN(cumYs[j]))
                        {
                            cumYs[j] = gridBottom;
                        }

                        if ((j != yValueCount - 1) && double.IsNaN(cumYs[j + 1]))
                        {
                            cumYs[j + 1] = gridBottom;
                        }

                        cumYs[j] -= gridHeight * (yValues[j, i] - stackBase) / (maxValue - minValue);
                    }

                    if (j == yValueCount - 1)
                    {
                        continue;
                    }

                    if (pt.X > dx && pt.X < (dx + barWidth))
                    {
                        if (isStacked)
                        {
                            dy1 = cumYs[j];
                            dy2 = (cumYs[j + 1] - gridHeight * (yValues[j + 1, i] - stackBase) / (maxValue - minValue));
                            dy  = dy1 - (dy1 - dy2) * (pt.X - dx) / barWidth;

                            if (pt.Y >= dy)
                            {
                                value = yValues[j, i] + (yValues[j + 1, i] - yValues[j, i]) * (pt.X - dx) / barWidth;
                                seriesValues.Add(value);
                                seriesIndices.Add(i);
                                _seriesYs.Add(dy);
                                insideStacked = true;
                                break;
                            }
                        }
                        else
                        {
                            dy1 = gridBottom -
                                  gridHeight * (yValues[j, i] - minValue) / (maxValue - minValue);

                            dy = dy1 - (gridHeight * (yValues[j + 1, i] - yValues[j, i]) / (maxValue - minValue)) * (pt.X - dx) / barWidth;

                            // find all the series that the y point matches
                            if (dy <= pt.Y)
                            {
                                value = yValues[j, i] + (yValues[j + 1, i] - yValues[j, i]) * (pt.X - dx) / barWidth;
                                seriesValues.Add(value);
                                seriesIndices.Add(i);
                                _seriesYs.Add(dy);
                            }
                            break;
                        }
                    }
                    dx += barWidth;
                }
            }
            return(new ChartEventArgs(seriesIndices.ToArray(), null, seriesValues.ToArray(), null));
        }
Пример #20
0
 internal XYLineChart(ChartType type, ChartModel model) : base(type, model)
 {
 }
Пример #21
0
        private void _drawPerspectiveXYValues()
        {
            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.GetLinePath3DXAML();
            Path             pathElem;
            List <UIElement> dataElems = null;

            if (animate)
            {
                dataElems = DataElements;
            }

            ChartModel model = Model;

            string[] seriesLabels = model.SeriesLabels;
            int      seriesCount  = seriesLabels.Length;

            Color[] seriesColors = model.SeriesColors;

            double[,] yValues = model.YValues;
            double minYValue = model.MinYValue, maxYValue = model.MaxYValue;
            int    nValues = yValues.GetUpperBound(0) + 1;

            double[,] xValues = model.XValues;
            double minXValue = model.MinXValue, maxXValue = model.MaxXValue;

            double          gridBottom = gridHeight + marginTop + yOffset;
            double          dx, dy;
            string          gradientXAML = lf.GetElementGradientXAML();
            MatrixTransform defaultTransform;

            for (int i = 0; i < seriesCount; ++i)
            {
                StringBuilder sb = new StringBuilder();

                for (var j = 0; j < nValues; ++j)
                {
                    dy = gridBottom - gridHeight * (yValues[j, i] - minYValue) / (maxYValue - minYValue);
                    dx = marginLeft + gridWidth * (xValues[j, i] - minXValue) / (maxXValue - minXValue);
                    if (j != nValues - 1)
                    {
                        sb.Append(" M").Append(dx).Append(",").Append(dy);
                        sb.Append(" l").Append(xOffset).Append(",").Append(-yOffset);
                        double nextdy, nextdx;
                        nextdx = marginLeft + gridWidth * (xValues[j + 1, i] - minXValue) / (maxXValue - minXValue);
                        nextdy = gridBottom -
                                 gridHeight * (yValues[j + 1, i] - minYValue) / (maxYValue - minYValue);
                        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);
                    }
                }

                pathElem = CreatePathFromXAMLAndData(pathXAML, sb);

                if (animate)
                {
                    dataElems.Add(pathElem);
                    defaultTransform = new MatrixTransform();
                    Matrix m = new Matrix();
                    m.M11 = 0.0;
                    defaultTransform.Matrix = m;
                    pathElem.SetValue(UIElement.RenderTransformProperty, defaultTransform);
                }

                if (gradientXAML != null)
                {
                    SetGradientOnElement(pathElem, gradientXAML, seriesColors[i], 0xC0);
                }
                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);
            }
        }
Пример #22
0
        private void _drawBars(int mod, int rem)
        {
            bool animate = (this.AnimationDuration > 0);

            double marginLeft = MarginLeft, marginTop = MarginTop;
            double marginRight = MarginRight, marginBottom = MarginBottom;

            double gridWidth  = (ChartCanvas.Width - marginLeft - marginRight);
            double gridHeight = (ChartCanvas.Height - marginTop - marginBottom);

            LookAndFeel      lf       = CurrentLookAndFeel;
            string           rectXAML = lf.GetBarPathXAML();
            Path             rectElem;
            List <UIElement> dataElems        = null;
            MatrixTransform  defaultTransform = null;

            if (animate)
            {
                dataElems = DataElements;
            }

            int  barItemPadding = _BARITEM_PADDING;
            bool isStacked      = (Type == ChartType.HBAR_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;

            // For combo graphs we display every once in mod
            double barDivider  = isStacked ? 1 : ((mod > 1) ? Math.Ceiling(seriesCount / mod) : seriesCount);
            double stackBase   = minValue;
            int    yValueCount = yValues.GetUpperBound(0) + 1;

            double barHeight = (gridHeight / Math.Max(yValueCount, groupCount) - 2 * barItemPadding) / barDivider;
            double dx = marginLeft, dy = gridHeight + marginTop, barWidth;
            string gradientXAML = lf.GetElementGradientXAML();

            for (int i = 0; i < yValueCount; ++i)
            {
                dy -= barItemPadding;
                dx  = marginLeft;
                for (int j = 0; j < seriesCount; ++j)
                {
                    // for combo charts we draw a bar every once in a mod.
                    if ((mod > 1) && (j % mod) != rem)
                    {
                        continue;
                    }

                    // If we use non zero min and it is a stacked graph, we need to remove the min for only
                    // the first series.
                    if (isStacked)
                    {
                        stackBase = (j == 0 ? minValue : 0);
                    }

                    rectElem = XamlReader.Load(rectXAML) as Path;
                    if (animate)
                    {
                        dataElems.Add(rectElem);

                        // FIXTHIS: This is inefficient. However Silverlight currently does not allow sharing transform attribute
                        defaultTransform = new MatrixTransform();
                        Matrix m = new Matrix();
                        m.M11 = 0.0;
                        defaultTransform.Matrix = m;
                        rectElem.SetValue(UIElement.RenderTransformProperty, defaultTransform);
                    }

                    barWidth = gridWidth * (yValues[i, j] - stackBase) / (maxValue - minValue);
                    RectangleGeometry rectGeometry = new RectangleGeometry();
                    rectGeometry.RadiusX = rectGeometry.RadiusY = 2;
                    rectGeometry.Rect    = new Rect(dx, dy - barHeight, barWidth, barHeight);
                    rectElem.SetValue(Path.DataProperty, rectGeometry);

                    if (gradientXAML != null)
                    {
                        SetGradientOnElement(rectElem, gradientXAML, seriesColors[j], 0xe5);
                    }
                    else
                    {
                        SetFillOnElement(rectElem, seriesColors[j]);
                    }

                    rectElem.SetValue(Rectangle.StrokeProperty, new SolidColorBrush(seriesColors[j]));

                    if (isStacked)
                    {
                        dx += barWidth;
                    }

                    SetExpandosOnElement(rectElem, i, j, new Point(dx + barWidth, dy - barHeight / 2.0));

                    if (DisplayToolTip)
                    {
                        rectElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                        rectElem.MouseLeave += new MouseEventHandler(HideToolTip);
                    }

                    rectElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

                    ChartCanvas.Children.Add(rectElem);
                    if (!isStacked)
                    {
                        dy -= barHeight;
                    }
                }
                if (isStacked)
                {
                    dy -= barHeight;
                }
                dy -= barItemPadding;
            }
        }
Пример #23
0
        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]);
             * }*/
        }
Пример #24
0
 internal GaugeChart(ChartType type, ChartModel model) : base(type, model)
 {
 }
Пример #25
0
        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]);
            }
        }
Пример #26
0
        private void _drawPerspectivePoints()
        {
            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           dotXAML    = lf.GetScatterDot3DXAML();
            Path             dotElem;
            List <UIElement> dataElems = null;

            if (animate)
            {
                dataElems = DataElements;
            }

            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 minYValue = model.MinYValue, maxYValue = model.MaxYValue;
            int    nValues = yValues.GetUpperBound(0) + 1;

            double[,] xValues = model.XValues;
            double minXValue = model.MinXValue, maxXValue = model.MaxXValue;

            double barWidth = (gridWidth / (double)(groupCount - 1));
            double gridBottom = gridHeight + marginTop + yOffset;
            double dx, dy, gridCx = 0, gridCy = 0;

            string gradientXAML = lf.GetElementGradientXAML();

            if (animate)
            {
                _cxs   = new double[seriesCount * nValues];
                _cys   = new double[seriesCount * nValues];
                gridCx = gridWidth / 2 + marginLeft + xOffset;
                gridCy = gridHeight / 2 + marginTop;
            }

            for (int i = 0; i < seriesCount; ++i)
            {
                for (int j = 0; j < nValues; ++j)
                {
                    dy = gridBottom - gridHeight * (yValues[j, i] - minYValue) / (maxYValue - minYValue);
                    dx = marginLeft + gridWidth * (xValues[j, i] - minXValue) / (maxXValue - minXValue);

                    dotElem = XamlReader.Load(dotXAML) as Path;

                    EllipseGeometry eg = dotElem.Data as EllipseGeometry;

                    if (animate)
                    {
                        dataElems.Add(dotElem);
                        eg.Center = new Point(gridCx, gridCy);

                        // we will use it during animation
                        int cIndex = (i * nValues + j);
                        _cxs[cIndex] = dx;
                        _cys[cIndex] = dy;
                    }
                    else
                    {
                        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]));

                    SetExpandosOnElement(dotElem, j, i, new Point(dx, dy));

                    if (DisplayToolTip)
                    {
                        dotElem.MouseEnter += new MouseEventHandler(ShowToolTip);
                        dotElem.MouseLeave += new MouseEventHandler(HideToolTip);
                    }

                    dotElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

                    //TODO:
                    // Silverlight does not support Filter effects so use another do as a shadow for it.

                    var shadowElem = XamlReader.Load(dotXAML) as Path;
                    eg = shadowElem.Data as EllipseGeometry;
                    if (animate)
                    {
                        dataElems.Add(shadowElem);
                        eg.Center = new Point(gridCx, gridCy);
                    }
                    else
                    {
                        eg.Center = new Point(dx, dy);
                    }

                    shadowElem.Fill = new SolidColorBrush(Color.FromArgb(0x7f, 0x33, 0x33, 0x33));
                    shadowElem.SetValue(Path.StrokeThicknessProperty, 0.0);

                    TranslateTransform tt = new TranslateTransform();
                    tt.X = tt.Y = 3;
                    shadowElem.SetValue(UIElement.RenderTransformProperty, tt);

                    ChartCanvas.Children.Add(shadowElem);
                    ChartCanvas.Children.Add(dotElem);
                }
            }
        }
Пример #27
0
        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);
            }
        }
Пример #28
0
 public HorizontalBarChart(ChartType type, ChartModel model) : base(type, model)
 {
 }
Пример #29
0
        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;
            }
        }
Пример #30
0
        private void _drawXYValues()
        {
            bool animate = (this.AnimationDuration > 0);

            double marginLeft = MarginLeft, marginTop = MarginTop;
            double marginRight = MarginRight, marginBottom = MarginBottom;

            double           gridWidth  = (ChartCanvas.Width - marginLeft - marginRight);
            double           gridHeight = (ChartCanvas.Height - marginTop - marginBottom);
            LookAndFeel      lf         = CurrentLookAndFeel;
            string           pathXAML   = lf.GetLinePathXAML();
            Path             pathElem;
            List <UIElement> dataElems = null;

            if (animate)
            {
                dataElems = DataElements;
            }

            ChartModel model = Model;

            string[] seriesLabels = model.SeriesLabels;
            int      seriesCount  = seriesLabels.Length;

            Color[] seriesColors = model.SeriesColors;

            double[,] yValues = model.YValues;
            double minYValue = model.MinYValue, maxYValue = model.MaxYValue;
            int    nValues = yValues.GetUpperBound(0) + 1;

            double[,] xValues = model.XValues;
            double minXValue = model.MinXValue, maxXValue = model.MaxXValue;

            double          dx, dy;
            MatrixTransform defaultTransform;

            for (int i = 0; i < seriesCount; ++i)
            {
                StringBuilder sb = new StringBuilder();

                dx = marginLeft;
                dy = gridHeight + marginTop;



                for (int j = 0; j < nValues; ++j)
                {
                    dy = gridHeight + marginTop - gridHeight * (yValues[j, i] - minYValue) / (maxYValue - minYValue);
                    dx = marginLeft + gridWidth * (xValues[j, i] - minXValue) / (maxXValue - minXValue);

                    if (j == 0)
                    {
                        sb.Append("M").Append(dx).Append(",").Append(dy);
                    }
                    else
                    {
                        sb.Append(" L").Append(dx).Append(",").Append(dy);
                    }
                }

                pathElem = CreatePathFromXAMLAndData(pathXAML, sb);

                if (animate)
                {
                    dataElems.Add(pathElem);
                    defaultTransform = new MatrixTransform();
                    Matrix m = new Matrix();
                    m.M11 = 0.0;
                    defaultTransform.Matrix = m;
                    pathElem.SetValue(UIElement.RenderTransformProperty, defaultTransform);
                }

                SetExpandosOnElement(pathElem, -1, i, new Point());

                if (DisplayToolTip)
                {
                    pathElem.MouseMove  += new MouseEventHandler(ShowToolTip);
                    pathElem.MouseLeave += new MouseEventHandler(HideToolTip);
                }

                pathElem.MouseLeftButtonUp += new MouseButtonEventHandler(ChartDataClicked);

                pathElem.SetValue(Path.StrokeProperty, new SolidColorBrush(seriesColors[i]));
                ChartCanvas.Children.Add(pathElem);
            }
        }