public NNResultsVisual(double width, double height, Tuple<Point, double, bool>[] values, bool shouldOutlineNonMatches)
            {
                #region Min/Max Value, Colors

                bool hasNegative = values.Any(o => o.Item2 < 0);
                double maxValue = Math.Max(Math.Abs(values.Min(o => o.Item2)), Math.Abs(values.Max(o => o.Item2)));
                if (maxValue < 1d)      // should never be greater, but leave alone if it is
                {
                    maxValue = 1d;
                }

                Color positiveColor = hasNegative ? Colors.Blue : Colors.Black;
                Color negativeColor = Colors.Red;

                #endregion
                #region XY Scale

                double radius = ((width + height) / 2) / 100;

                bool hasNegativePosition = values.Any(o => o.Item1.X < 0 || o.Item1.Y < 0);
                double maxX = Math.Max(Math.Abs(values.Min(o => o.Item1.X)), Math.Abs(values.Max(o => o.Item1.X)));
                double maxY = Math.Max(Math.Abs(values.Min(o => o.Item1.Y)), Math.Abs(values.Max(o => o.Item1.Y)));

                // If they are somewhat near 1, then cap at 1
                if (maxX > .5 && maxX < 1) maxX = 1;
                if (maxY > .5 && maxY < 1) maxY = 1;

                double offsetX = hasNegativePosition ? (width / 2) : 0;
                double offsetY = hasNegativePosition ? (height / 2) : 0;

                double scaleX = maxX > 0d ? (width - offsetX) / maxX : 1;
                double scaleY = maxY > 0d ? (height - offsetY) / maxY : 1;

                #endregion

                Pen matchPen = new Pen(Brushes.Lime, radius * .32);
                Pen otherPen = shouldOutlineNonMatches ? new Pen(new SolidColorBrush(Color.FromArgb(192, 192, 192, 192)), radius * .18) : null;

                _visual = new DrawingVisual();
                using (DrawingContext dc = _visual.RenderOpen())
                {
                    foreach (var value in values)
                    {
                        Color color = value.Item2 < 0 ? negativeColor : positiveColor;
                        double alpha = Math.Abs(value.Item2) / maxValue;
                        Color finalColor = Color.FromArgb(Convert.ToByte(alpha * 255), color.R, color.G, color.B);

                        Point point = new Point(offsetX + (value.Item1.X * scaleX), offsetY + (value.Item1.Y * scaleY));

                        Pen pen = value.Item3 ? matchPen : otherPen;

                        dc.DrawEllipse(new SolidColorBrush(finalColor), pen, point, radius, radius);
                    }
                }
            }
Example #2
0
 public void DoubleMaxOnTwoTuple()
 {
     var sut = new Tuple<double, double>(1, 2);
       double expected = sut.AsEnumerable().Cast<double>().Max();
       double actual = sut.Max(x => (double) x);
       Assert.AreEqual(expected, actual);
 }
Example #3
0
 public void LongMaxOnTwoTuple()
 {
     var sut = new Tuple<long, long>(1, 2);
       long expected = sut.AsEnumerable().Cast<long>().Max();
       long actual = sut.Max(x => (long) x);
       Assert.AreEqual(expected, actual);
 }
Example #4
0
 public void IntegerMaxOnTwoTuple()
 {
     var sut = new Tuple<int, int>(1, 2);
       int expected = sut.AsEnumerable().Cast<int>().Max();
       int actual = sut.Max(x => (int) x);
       Assert.AreEqual(expected, actual);
 }
Example #5
0
 public void ShortMaxOnTwoTuple()
 {
     var sut = new Tuple<short, short>(1, 2);
       short expected = sut.AsEnumerable().Cast<short>().Max();
       short actual = sut.Max(x => (short) x);
       Assert.AreEqual(expected, actual);
 }
        /// <summary>
        /// This returns a visual of a graph that can be added to a canvas
        /// </summary>
        public static IEnumerable<UIElement> GetGradientGraph(double width, double height, Tuple<double, double>[] gradient, Color fill, Color stroke)
        {
            if (gradient == null || gradient.Length <= 1)       // need at least two for a gradient
            {
                return new UIElement[0];
            }
            else if (width.IsNearZero() || height.IsNearZero())
            {
                return new UIElement[0];
            }

            List<UIElement> retVal = new List<UIElement>();

            double maxPercent = gradient.Max(o => o.Item2);

            if (maxPercent > 1)
            {
                #region 100% line

                // Draw a dashed line at 1 (showing the 100% mark)
                Color color100 = UtilityWPF.AlphaBlend(UtilityWPF.AlphaBlend(stroke, Colors.Gray, .85), Colors.Transparent, .66);

                double y100 = ((maxPercent - 1) / maxPercent) * height;

                Line line100 = new Line()
                {
                    Stroke = new SolidColorBrush(color100),
                    StrokeThickness = 1,
                    StrokeDashArray = new DoubleCollection(new[] { 4d, 2d }),
                    X1 = 0,
                    X2 = width,
                    Y1 = y100,
                    Y2 = y100,
                };

                retVal.Add(line100);

                #endregion
            }

            if (maxPercent < 1)
            {
                // Do this so the graph is to scale (doesn't always go to the top)
                maxPercent = 1;
            }

            double lastGradX = gradient[gradient.Length - 1].Item1;
            if (!Math1D.IsNearZero(lastGradX) && lastGradX > 0)
            {
                Polyline polyLine = new Polyline();
                Polygon polyFill = new Polygon();

                polyLine.Stroke = new SolidColorBrush(stroke);
                polyLine.StrokeThickness = 2;

                polyFill.Fill = new SolidColorBrush(fill);

                //NOTE: gradient must be sorted on Item1
                double xScale = width / lastGradX;

                for (int cntr = 0; cntr < gradient.Length; cntr++)
                {
                    double x = gradient[cntr].Item1 * xScale;
                    double y = ((maxPercent - gradient[cntr].Item2) / maxPercent) * height;

                    polyLine.Points.Add(new Point(x, y));
                    polyFill.Points.Add(new Point(x, y));
                }

                // Circle back fill to make a polygon
                polyFill.Points.Add(new Point(polyFill.Points[polyFill.Points.Count - 1].X, height));
                polyFill.Points.Add(new Point(polyFill.Points[0].X, height));

                retVal.Add(polyFill);
                retVal.Add(polyLine);
            }

            return retVal;
        }
        public static Tuple<int, int, double>[] Normalize(Tuple<int, int, double>[] flattened)
        {
            if (flattened.Length == 0)
            {
                return flattened;
            }

            double maxPercent = flattened.Max(o => o.Item3);
            if (maxPercent.IsNearZero() || maxPercent.IsNearValue(1d))       // if it's zero, then no thrusters are firing.  If one, it's already normalized
            {
                return flattened;
            }

            double scale = 1d / maxPercent;

            return flattened.
                Select(o => Tuple.Create(o.Item1, o.Item2, o.Item3 * scale)).
                ToArray();
        }