Ejemplo n.º 1
0
        /// <inheritdoc />
        public Visual Draw()
        {
            if (Network == null)
                throw new Exception("Network is Null");

            //Create drawing target
            DrawingVisual drawingVisual = new DrawingVisual();
            DrawingContext drawingContext = drawingVisual.RenderOpen();

            //enables clicks to be registered all throughout the drawing (i.e.
            // no holes) but simultaneously remains transparent.
            drawingContext.DrawRectangle(Brushes.Transparent, null, ImgCoords);

            Pen p = new Pen(Brushes.Black,2);
            p.Freeze();

            var busesToSource = Tracing.BusesOnRouteToTarget((Bus)SelectedElement, (Bus)Network.SourceBus);
            var busesFromSelection = Tracing.TraceWithoutCrossingBuses((Bus)SelectedElement, busesToSource);
            var buses = busesToSource.Union(busesFromSelection);

            Dictionary<Bus, double> lengths = new Dictionary<Bus, double>();
            lengths[Network.SourceBus] = 0;
            Collection<Line> lines = new Collection<Line>();

            Tracing.TraceFromWithCallback(Network.SourceBus, buses, (thisBus, line, nextBus) =>
            {
                lengths[nextBus] = (lengths.ContainsKey(thisBus) ? lengths[thisBus] : 0) + line.Length;
                lines.Add(line);
            });

            Limits lengthLimits = new Limits();
            lengthLimits.ProcessData(lengths.Values);
            lengthLimits.LimitMax = ImgCoords.Right - Margin.Right;
            lengthLimits.LimitMin = ImgCoords.Left + Margin.Left;

            Limits voltLimits = new Limits();
            voltLimits.ProcessData(buses.Select(b => -b.VoltagePU.Magnitude));

            //choose grid for volts.
            MagicGridSpacer voltSpacer = new MagicGridSpacer();
            voltSpacer.MinValue = voltLimits.AutoMin;
            voltSpacer.MaxValue = voltLimits.AutoMax;
            voltSpacer.MaxLines = 10; //TODO: change this based on pixels. min(pixelMax, 2)
            var voltSpacings = voltSpacer.GetGridSpacings();
            voltLimits.ProcessData(voltSpacings.LowerLimit);
            voltLimits.ProcessData(voltSpacings.UpperLimit);

            voltLimits.LimitMin = ImgCoords.Top + Margin.Top;
            voltLimits.LimitMax = ImgCoords.Bottom - Margin.Bottom;

            MagicGridSpacer lengthSpacer = new MagicGridSpacer();
            lengthSpacer.MinValue = lengthLimits.AutoMin;
            lengthSpacer.MaxValue = lengthLimits.AutoMax;
            lengthSpacer.MaxLines = 20; //TODO: change this based on pixels.
            var lengthSpacings = lengthSpacer.GetGridSpacings();
            lengthLimits.ProcessData(lengthSpacings.LowerLimit);
            lengthLimits.ProcessData(lengthSpacings.UpperLimit);

            Dictionary<Bus, Point> BusPoints = new Dictionary<Bus, Point>();
            foreach (Bus b in buses)
            {
                BusPoints[b] = new Point(lengthLimits.ValueScaledToLimits(lengths[b]), voltLimits.ValueScaledToLimits(-b.VoltagePU.Magnitude));
            }

            Pen gridPen = new Pen(Brushes.LightGray, 1);
            gridPen.Freeze();

            foreach (double yPos in voltSpacings.GetTicks())
            {
                var y = voltLimits.ValueScaledToLimits(yPos);
                var leftPoint = new Point(ImgCoords.Left + Margin.Left, y);
                drawingContext.DrawLine(gridPen, leftPoint, new Point(ImgCoords.Right - Margin.Right, y));
                var ft = new FormattedText((-yPos).ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(""), 12, Brushes.Black);
                drawingContext.DrawText(ft, leftPoint);
            }

            foreach (double xPos in lengthSpacings.GetTicks())
            {
                var x = lengthLimits.ValueScaledToLimits(xPos);
                var bottomPoint = new Point(x, ImgCoords.Bottom - Margin.Bottom);
                drawingContext.DrawLine(gridPen, bottomPoint, new Point(x,ImgCoords.Bottom - Margin.Bottom - 10));
                var ft = new FormattedText(xPos.ToString(), CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(""), 12, Brushes.Black);
                drawingContext.DrawText(ft, bottomPoint);
            }

            foreach (Line l in lines)
            {
                Bus b1, b2;
                b1 = l.ConnectedTo.OfType<Bus>().First();
                b2 = l.ConnectedTo.OfType<Bus>().Last();

                drawingContext.DrawLine(p, BusPoints[b1], BusPoints[b2]);
            }

            drawingContext.Close();
            return drawingVisual;
        }
        /// <summary>
        /// Draws all the network buses, using the specified value transforms.
        /// </summary>
        /// <param name="Network">The network from which to draw buses.</param>
        /// <param name="colorMap">A map of the colours to use from the specified gradient.</param>
        /// <param name="busSizeLimits">The limits of <see cref="BusSizeTransform"/>,
        /// used for scaling from that space to
        /// [<see cref="BusSizeMin"/>, <see cref="BusSizeMax"/>].</param>
        /// <param name="ringColorPen">A pen for drawing rings.</param>
        /// <param name="drawingContext">The target that we should draw to.</param>
        protected void DrawBuses(NetworkModel Network, AdaptiveGradientMap<Tuple<Brush, Pen>> colorMap, Limits busSizeLimits, Pen ringColorPen, DrawingContext drawingContext)
        {
            //Draw all the buses.
            foreach (var bus in Network.Buses.Values)
            {
                if (!(BusVisibleTransform(bus) && bus.Location.HasValue))
                    continue;
                var bSize = busSizeLimits.ValueScaledToLimits(BusSizeTransform(bus));
                //value-dependant fill, no outline, centre is scaled, radius of 2 (small dots).
                drawingContext.DrawEllipse(
                    colorMap.Map(BusColorTransform(bus)).Item1,
                    null, ScaledLocation(bus.Location.Value), bSize, bSize);

                //Bus Ring
                if (RingEnabledTransform(bus))
                {
                    var ringRadius = RingDistanceFromCenter ?
                        /*true*/ RingDistanceTransform(bus) :
                        /*false*/ bSize + RingDistanceTransform(bus);

                    drawingContext.DrawEllipse(null, ringColorPen,
                        ScaledLocation(bus.Location.Value), ringRadius, ringRadius);
                }
            }
        }