Exemple #1
0
        /// <summary>
        /// Return projected string for some item.
        /// </summary>
        /// <param name="cachingGraph"></param>
        /// <param name="item">Iitem to be projected.</param>
        /// <param name="left">Item is on left side of dependency</param>
        /// <returns>Projected item; or <c>null</c> if item does not
        /// match projection</returns>
        public Item Match(WorkingGraph cachingGraph, [NotNull] Item item, bool left)
        {
            if (left && !_forLeftSide || !left && !_forRightSide)
            {
                return(null);
            }
            else
            {
                var matchResultGroups = ItemMatch.Matches(item);

                if (!matchResultGroups.Success)
                {
                    return(null);
                }
                else
                {
                    IEnumerable <string> targets = _targetSegments;
                    for (int i = 0; i < matchResultGroups.Groups.Length; i++)
                    {
                        int matchResultIndex = i;
                        targets = targets.Select(s => s.Replace("\\" + (matchResultIndex + 1), matchResultGroups.Groups[matchResultIndex]));
                    }
                    _matchCount++;
                    return(cachingGraph.CreateItem(_targetItemType, targets.Select(t => GlobalContext.ExpandHexChars(t)).ToArray()));
                }
            }
        }
Exemple #2
0
            public void Traverse(IEnumerable <TDependency> dependencies, ItemMatch pathAnchor,
                                 bool pathAnchorIsCountMatch, AbstractPathMatch <TDependency, TItem>[] expectedPathMatches)
            {
                Dictionary <TItem, TDependency[]> incidentDependencies = _backwards
                    ? AbstractItem <TItem> .CollectIncomingDependenciesMap(dependencies)
                    : AbstractItem <TItem> .CollectOutgoingDependenciesMap(dependencies);

                _seenInnerPathStarts.Clear();
                Paths.Clear();
                Counts.Clear();
                _onPath.Clear();

                TItem[] uniqueStartItems = (pathAnchor == null
                    ? incidentDependencies.Keys
                    : incidentDependencies.Keys.Where(i => pathAnchor.Matches(i).Success)).ToArray();
                AbstractPathMatch <TDependency, TItem> endMatch;

                AbstractPathMatch <TDependency, TItem>[] innerMatches;
                int n = expectedPathMatches.Length;

                if (n == 0)
                {
                    endMatch     = null;
                    innerMatches = expectedPathMatches;
                }
                else
                {
                    endMatch     = expectedPathMatches[n - 1];
                    innerMatches = expectedPathMatches.Take(n - 1).ToArray();
                }

                foreach (var item in uniqueStartItems.OrderBy(i => i.Name))
                {
                    if (_seenInnerPathStarts.Add(item))
                    {
                        List <PathNode <TItem, TDependency> > up = Traverse(root: item,
                                                                            incidentDependencies: incidentDependencies, expectedInnerPathMatches: innerMatches,
                                                                            endMatch: endMatch, down: new DownInfo(pathAnchorIsCountMatch ? item : null));
                        if (up != null)
                        {
                            Paths.Add(item, up);
                        }
                    }
                }
            }
Exemple #3
0
 public override bool IsMatch(TDependency nextDep, TItem newTail)
 {
     return(_itemMatch.Matches(newTail).Success);
 }
Exemple #4
0
        protected override void PlaceObjects([NotNull, ItemNotNull] IEnumerable <Dependency> dependencies)
        {
            // ASCII-art sketch of what I want to accomplish:
            //   +-----+
            //   |     |--------------------------------------------->|
            //   | VKF |--------->|                                   |
            //   +-----+          |                                   |
            //                    |                                   |
            //   +-----+          |                                   |
            //   |     |--------------------------------------------->|
            //   | WLG |--------------------->|                       |
            //   +-----+          |           |                       |
            //                    |           |                       |
            //   +-----+          |           |                       |
            //   |     |--------------------------------->|           |
            //   | KST |--------------------->|           |           |
            //   |     |--------->|           |           |           |
            //   +-----+          |           |           |           |
            //                +-------+   +-------+   +-------+   +-------+
            //                | IMP.A |   | IMP.B |   | IMP.C |   | IMP.D |
            //                +-------+   +-------+   +-------+   +-------+
            //

            // The itemtype is expected to have 1 or 2 fields Name[:HtmlRef]
            // In the example diagram above, we would have items about like the following:
            //        BAC:
            //        WLG:
            //        KST:
            //        IMP.A:
            //        IMP.B:
            //        IMP.C:
            //        IMP.D:

            Arrow(F(0, 0), F(100, 0), 1, Color.Chartreuse, "100px", textFont: _lineFont);
            Box(F(-20, -20), _title + "(" + DateTime.Now + ")", boxAnchoring: BoxAnchoring.UpperRight);

            List <Item> yItems = dependencies.Select(e => e.UsingItem).Distinct().ToList();
            List <Item> xItems = dependencies.Select(e => e.UsedItem).Distinct().
                                 Where(i => _bottomItemMatch == null || _bottomItemMatch.Matches(i).Success).
                                 ToList();

            Dependency[] relevantDependencies = dependencies.Where(d => yItems.Contains(d.UsingItem) && xItems.Contains(d.UsedItem)).ToArray();
            if (_showOnlyReferencedOnBottom)
            {
                xItems.RemoveAll(ix => !relevantDependencies.Any(d => d.UsedItem.Equals(ix)));
            }
            if (_showOnlyReferencingOnLeft)
            {
                yItems.RemoveAll(iy => !relevantDependencies.Any(d => d.UsingItem.Equals(iy)));
            }

            _orderSupport.SortWithEdgeCount(xItems, relevantDependencies, (i, d) => d.UsedItem.Equals(i));
            _orderSupport.SortWithEdgeCount(yItems, relevantDependencies, (i, d) => d.UsingItem.Equals(i));

            double x      = 100;
            var    xBoxes = new Dictionary <Item, IBox>();

            foreach (var ix in xItems)
            {
                string name = GetName(ix);
                var    xPos = new VariableVector(name + ".POS", Solver);
                IBox   box  = Box(xPos, boxAnchoring: BoxAnchoring.LowerLeft, text: name, borderWidth: 3, boxColor: Color.LemonChiffon, boxTextPlacement: BoxTextPlacement.LeftUp,
                                  textFont: _boxFont, drawingOrder: 1, fixingOrder: 4, htmlRef: GetXHtmlRef(ix));
                xPos.SetX(x).SetY(-box.TextBox.Y);
                xBoxes[ix] = box;

                x += 40;
            }

            const int       DELTA_Y_MAIN = 12;
            NumericVariable y            = Solver.CreateConstant("y", 10);

            foreach (var iy in yItems)
            {
                string name = GetName(iy);
                var    yPos = new VariableVector(name + ".POS", Solver);
                IBox   box  = Box(yPos, boxAnchoring: BoxAnchoring.LowerRight, text: name, borderWidth: 3, boxColor: Color.Coral,
                                  boxTextPlacement: BoxTextPlacement.Left, textFont: _boxFont, drawingOrder: 1, fixingOrder: 4,
                                  htmlRef: GetYHtmlRef(iy) ?? GetXHtmlRef(iy));
                yPos.SetX(0).SetY(y);

                double minBoxHeight = 45;
                foreach (var d in relevantDependencies.Where(d => iy.Equals(d.UsingItem)))
                {
                    IBox usedBox = xBoxes[d.UsedItem];
                    yPos += F(0, 3);
                    Arrow(yPos, new VariableVector(name + "->...", usedBox.LowerLeft.X, yPos.Y), width: 2,
                          color: d.NotOkCt > 0 ? Color.Red : d.QuestionableCt > 0 ? Color.Blue : Color.Black,
                          text: "#=" + d.Ct, placement: LineTextPlacement.Left, textLocation: -85,
                          edgeInfo: d.ExampleInfo, drawingOrder: 1);
                    usedBox.UpperRight.MinY(yPos.Y + 5);
                    yPos         += F(0, DELTA_Y_MAIN);
                    minBoxHeight += DELTA_Y_MAIN;
                    box.UpperRight.MinY(yPos.Y);
                }
                box.Diagonal.MinY(minBoxHeight);
                //Console.WriteLine(name + ".LR.Y=" + y + " .H>=" + minBoxHeight + "  H.ShortName=" + box.Diagonal.Y.ShortName);
                y += minBoxHeight + 10;
            }

            //string countText = "\n<" + SumAsString(dependencies, d => d.UsingItem.Equals(i) && !d.UsedItem.Equals(i))
            //                   + " =" + SumAsString(dependencies, d => d.UsingItem.Equals(i) && d.UsedItem.Equals(i))
            //                   + " >" + SumAsString(dependencies, d => !d.UsingItem.Equals(i) && d.UsedItem.Equals(i));
            // TODO: Add option and computation to split this into .,?,!
        }