Example #1
0
    public GameObject ReplaceNodeWithNewPrefab(WMG_Node theNode, Object prefabNode)
    {
        // Used to swap prefabs of a node
        GameObject newNode  = CreateNode(prefabNode, theNode.transform.parent.gameObject);
        WMG_Node   newNode2 = newNode.GetComponent <WMG_Node>();

        newNode2.numLinks   = theNode.numLinks;
        newNode2.links      = theNode.links;
        newNode2.linkAngles = theNode.linkAngles;
        newNode2.SetID(theNode.id);
        newNode2.name = theNode.name;
        newNode.transform.position = theNode.transform.position;

        // Update link from / to node references
        for (int i = 0; i < theNode.numLinks; i++)
        {
            WMG_Link aLink = theNode.links[i].GetComponent <WMG_Link>();
            WMG_Node fromN = aLink.fromNode.GetComponent <WMG_Node>();
            if (fromN.id == theNode.id)
            {
                aLink.fromNode = newNode;
            }
            else
            {
                aLink.toNode = newNode;
            }
        }
        nodesParent.Remove(theNode.gameObject);
        Destroy(theNode.gameObject);

        return(newNode);
    }
    private void TooltipLegendLinkMouseEnter(WMG_Series aSeries, WMG_Link aLink, bool state)
    {
        if (isTooltipObjectNull()) return;
        if (!aSeries.hidePoints) return;
        if (state) {
            // Set the text
            changeLabelText(theGraph.toolTipLabel, aSeries.seriesName);

            // Resize this control to match the size of the contents
            changeSpriteWidth(theGraph.toolTipPanel, Mathf.RoundToInt(getSpriteWidth(theGraph.toolTipLabel)) + 24);

            // Ensure tooltip is in position before showing it so it doesn't appear to jump
            repositionTooltip();

            // Display the base panel
            showControl(theGraph.toolTipPanel);
            bringSpriteToFront(theGraph.toolTipPanel);

            performTooltipAnimation(aLink.transform, new Vector3(2,1.05f,1));
        }
        else {
            hideControl(theGraph.toolTipPanel);
            sendSpriteToBack(theGraph.toolTipPanel);

            performTooltipAnimation(aLink.transform, new Vector3(1,1,1));
        }
    }
Example #3
0
    private void TooltipLegendLinkMouseEnter(WMG_Series aSeries, WMG_Link aLink, bool state)
    {
        if (isTooltipObjectNull())
        {
            return;
        }
        if (!aSeries.hidePoints)
        {
            return;
        }
        if (state)
        {
            // Set the text
            changeLabelText(theGraph.toolTipLabel, aSeries.seriesName);

            // Resize this control to match the size of the contents
            changeSpriteWidth(theGraph.toolTipPanel, Mathf.RoundToInt(getSpriteWidth(theGraph.toolTipLabel)) + 24);

            // Ensure tooltip is in position before showing it so it doesn't appear to jump
            repositionTooltip();

            // Display the base panel
            showControl(theGraph.toolTipPanel);
            bringSpriteToFront(theGraph.toolTipPanel);

            performTooltipAnimation(aLink.transform, new Vector3(2, 1.05f, 1));
        }
        else
        {
            hideControl(theGraph.toolTipPanel);
            sendSpriteToBack(theGraph.toolTipPanel);

            performTooltipAnimation(aLink.transform, new Vector3(1, 1, 1));
        }
    }
Example #4
0
 void ActivateNeighbors(WMG_Node fromNode)
 {
     for (int i = 0; i < fromNode.numLinks; i++)
     {
         WMG_Link aLink = fromNode.links[i].GetComponent <WMG_Link>();
         if (!theMap.activeInHierarchy(aLink.gameObject))
         {
             // Activate and animate links expanding from source node to end node
             activatingNodesStart = fromNode;
             theMap.SetActive(aLink.gameObject, true);
             UIWidget aLinkW    = aLink.objectToScale.GetComponent <UIWidget>();
             int      origScale = Mathf.RoundToInt(aLinkW.height);
             float    p1y       = fromNode.transform.localPosition.y + (fromNode.radius) * Mathf.Sin(Mathf.Deg2Rad * fromNode.linkAngles[i]);
             float    p1x       = fromNode.transform.localPosition.x + (fromNode.radius) * Mathf.Cos(Mathf.Deg2Rad * fromNode.linkAngles[i]);
             Vector3  origPos   = aLink.transform.localPosition;
             Vector3  newPos    = new Vector3(p1x, p1y, origPos.z);
             aLink.transform.localPosition = newPos;
             TweenPosition.Begin(aLink.gameObject, 1, origPos);
             aLinkW.height = 0;
             TweenHeight tSca = TweenHeight.Begin(aLinkW, 1, origScale);
             tSca.callWhenFinished = "endActivatingNeighbors";
             tSca.eventReceiver    = this.gameObject;
         }
     }
 }
Example #5
0
    public WMG_Series seriesRef;     // Used for series legend event delegates

    public GameObject CreateLink(GameObject target, Object prefabLink, int linkId, GameObject parent, bool repos)
    {
        // Creating a link between two nodes populates all needed references and automatically repositions and scales the link based on the nodes
        GameObject objLink      = Instantiate(prefabLink) as GameObject;
        Vector3    linkLocalPos = objLink.transform.localPosition;
        GameObject theParent    = parent;

        if (parent == null)
        {
            theParent = target.transform.parent.gameObject;
        }
        changeSpriteParent(objLink, theParent);
//		objLink.transform.parent = target.transform.parent;
        objLink.transform.localScale    = Vector3.one;
        objLink.transform.localPosition = linkLocalPos;
        WMG_Link theLink = objLink.GetComponent <WMG_Link>();

        links.Add(objLink);
        linkAngles.Add(0);
        WMG_Node theTarget = target.GetComponent <WMG_Node>();

        theTarget.links.Add(objLink);
        theTarget.linkAngles.Add(0);
        theTarget.numLinks++;
        numLinks++;
        theLink.Setup(this.gameObject, target, linkId, repos);         // automatically repositions and scales the link based on the nodes
        return(objLink);
    }
Example #6
0
 private void animateLinkCallbackEnd(WMG_Series aSeries)
 {
     for (int i = 0; i < aSeries.getLines().Count; i++)
     {
         WMG_Link theLine = aSeries.getLines()[i].GetComponent <WMG_Link>();
         theLine.Reposition();
     }
 }
    public void CreateLink(WMG_Node fromNode, WMG_Node toNode)
    {
        WMG_Link aLink = GetLink(fromNode, toNode);

        if (aLink == null)
        {
            CreateLink(fromNode, toNode.gameObject, this.LinkPrefab, this.gameObject);
        }
    }
Example #8
0
 /// <summary>
 /// Update the position of this node. Also repositions and rotates its links to correctly correspond with the new node position.
 /// </summary>
 /// <param name="x">The x coordinate.</param>
 /// <param name="y">The y coordinate.</param>
 public virtual void Reposition(float x, float y)
 {
     changeSpritePositionTo(this.gameObject, new Vector3(x, y, 1));
     for (int i = 0; i < numLinks; i++)
     {
         WMG_Link theLink = links[i].GetComponent <WMG_Link>();
         theLink.Reposition();
     }
 }
Example #9
0
 public void Reposition(float x, float y)
 {
     // Updates the local position of this node and all associated links
     changeSpritePositionTo(this.gameObject, new Vector3(x, y, 1));
     for (int i = 0; i < numLinks; i++)
     {
         WMG_Link theLink = links[i].GetComponent <WMG_Link>();
         theLink.Reposition();
     }
 }
Example #10
0
    // Only Used in Editor -
    public void RepositionRelativeToNode(WMG_Node fromNode, bool fixAngle, int degreeStep, float lengthStep)
    {
        // This is used to reposition the node and associated links based on a fixed angle or fixed length step relative to another node
        float posXdif = (this.transform.localPosition.x - fromNode.transform.localPosition.x);
        float posYdif = (this.transform.localPosition.y - fromNode.transform.localPosition.y);

        float angle = Mathf.Atan2(posYdif, posXdif) * Mathf.Rad2Deg;

        if (angle < 0)
        {
            angle += 360;
        }

        float length = Mathf.Sqrt(Mathf.Pow(posYdif, 2) + Mathf.Pow(posXdif, 2));

        if (length < 0)
        {
            length = 0;
        }

        float newAngle = angle;

        if (fixAngle)
        {
            newAngle = 0;
            for (int i = 0; i < 360 / degreeStep; i++)
            {
                if (angle >= i * degreeStep - 0.5f * degreeStep && angle < (i + 1) * degreeStep - 0.5f * degreeStep)
                {
                    newAngle = i * degreeStep;
                }
            }
        }
        else
        {
            float mod = length % lengthStep;
            length -= mod;
            if (lengthStep - mod < lengthStep / 2)
            {
                length += lengthStep;
            }
        }

        this.transform.localPosition = new Vector3(fromNode.transform.localPosition.x + length * Mathf.Cos(Mathf.Deg2Rad * (newAngle)),
                                                   fromNode.transform.localPosition.y + length * Mathf.Sin(Mathf.Deg2Rad * (newAngle)),
                                                   this.transform.localPosition.z);

        for (int i = 0; i < numLinks; i++)
        {
            WMG_Link theLink = links[i].GetComponent <WMG_Link>();
            theLink.Reposition();
        }
    }
Example #11
0
    public void UpdateLegendEntry()
    {
        if (legendEntryLinkSpacingChanged)
        {
            // Update legend entry lines based on legendEntryLinkSpacing
            theGraph.changeSpritePositionRelativeToObjBy(legendEntryNodeLeft, legendEntryNode, new Vector3(-legendEntryLinkSpacing, 0, 0));
            theGraph.changeSpritePositionRelativeToObjBy(legendEntryNodeRight, legendEntryNode, new Vector3(legendEntryLinkSpacing, 0, 0));

            WMG_Link theLine = legendEntryLink.GetComponent <WMG_Link>();
            theLine.Reposition();
        }
    }
Example #12
0
    private void animateLinkCallback(WMG_Series aSeries, GameObject aGO)
    {
        WMG_Node aNode   = aGO.GetComponent <WMG_Node>();
        WMG_Link theLine = aNode.links[aNode.links.Count - 1].GetComponent <WMG_Link>();

        theLine.Reposition();
        if (aSeries.connectFirstToLast)           // One extra link to animate for circles / close loop series
        {
            aNode   = aSeries.getPoints()[0].GetComponent <WMG_Node>();
            theLine = aNode.links[0].GetComponent <WMG_Link>();
            theLine.Reposition();
        }
    }
Example #13
0
 void ActivateNeighborNodes(WMG_Node fromNode)
 {
     for (int i = 0; i < fromNode.numLinks; i++)
     {
         WMG_Link aLink   = fromNode.links[i].GetComponent <WMG_Link>();
         WMG_Node aLinkTo = aLink.toNode.GetComponent <WMG_Node>();
         if (aLinkTo.id == fromNode.id)
         {
             aLinkTo = aLink.fromNode.GetComponent <WMG_Node>();
         }
         theMap.SetActive(aLinkTo.gameObject, true);
     }
 }
	private void animateLinkCallback(WMG_Series aSeries, GameObject aGO, bool isLast) {
		WMG_Node aNode = aGO.GetComponent<WMG_Node>();
		if (aNode.links.Count != 0) {
			WMG_Link theLine = aNode.links[aNode.links.Count-1].GetComponent<WMG_Link>();
			theLine.Reposition();
		}
		if (isLast) {
			aSeries.updateAreaShading(null);
		}
		if (aSeries.connectFirstToLast) { // One extra link to animate for circles / close loop series
			aNode = aSeries.getPoints()[0].GetComponent<WMG_Node>();
			WMG_Link theLine = aNode.links[0].GetComponent<WMG_Link>();
			theLine.Reposition();
		}
	}
Example #15
0
 public void UpdateLineColor()
 {
     if (lineColorChanged)
     {
         // Series line colors
         for (int i = 0; i < lines.Count; i++)
         {
             WMG_Link theLine = lines[i].GetComponent <WMG_Link>();
             theGraph.changeSpriteColor(theLine.objectToColor, lineColor);
         }
         // Legend line colors
         WMG_Link theLeftLine = legendEntryLink.GetComponent <WMG_Link>();
         theGraph.changeSpriteColor(theLeftLine.objectToColor, lineColor);
     }
 }
Example #16
0
 public void UpdateLineScale()
 {
     if (lineScaleChanged)
     {
         // Series line widths
         for (int i = 0; i < lines.Count; i++)
         {
             WMG_Link theLine = lines[i].GetComponent <WMG_Link>();
             theLine.objectToScale.transform.localScale = new Vector3(lineScale, theLine.objectToScale.transform.localScale.y, theLine.objectToScale.transform.localScale.z);
         }
         // Legend line widths
         WMG_Link theLeftLine = legendEntryLink.GetComponent <WMG_Link>();
         theLeftLine.objectToScale.transform.localScale = new Vector3(lineScale, theLeftLine.objectToScale.transform.localScale.y, theLeftLine.objectToScale.transform.localScale.z);
     }
 }
Example #17
0
 public WMG_Link GetLink(WMG_Node fromNode, WMG_Node toNode)
 {
     foreach (GameObject link in fromNode.links)
     {
         WMG_Link aLink = link.GetComponent <WMG_Link>();
         WMG_Node toN   = aLink.toNode.GetComponent <WMG_Node>();
         if (toN.id != toNode.id)
         {
             toN = aLink.fromNode.GetComponent <WMG_Node>();
         }
         if (toN.id == toNode.id)
         {
             return(aLink);
         }
     }
     return(null);
 }
Example #18
0
    public void DeleteLink(WMG_Link theLink)
    {
        // Deleting a link updates references in the to and from nodes and swaps IDs with the largest link ID in the list
        WMG_Node fromN = theLink.fromNode.GetComponent <WMG_Node>();
        WMG_Node toN   = theLink.toNode.GetComponent <WMG_Node>();

        for (int i = 0; i < fromN.numLinks; i++)
        {
            WMG_Link aLink = fromN.links[i].GetComponent <WMG_Link>();
            if (aLink.id == theLink.id)
            {
                fromN.numLinks--;
                fromN.links[i] = fromN.links[fromN.numLinks];
                break;
            }
        }
        for (int i = 0; i < toN.numLinks; i++)
        {
            WMG_Link aLink = toN.links[i].GetComponent <WMG_Link>();
            if (aLink.id == theLink.id)
            {
                toN.numLinks--;
                toN.links[i] = toN.links[toN.numLinks];
                break;
            }
        }

        int idToDelete = theLink.id;

        foreach (GameObject child in linksParent)
        {
            WMG_Link aLink = child.GetComponent <WMG_Link>();
            if (aLink != null && aLink.id == linksParent.Count - 1)
            {
                aLink.SetId(idToDelete);
                linksParent.Remove(theLink.gameObject);
                DestroyImmediate(theLink.gameObject);
                fromN.links.RemoveAt(fromN.numLinks);
                fromN.linkAngles.RemoveAt(fromN.numLinks);
                toN.links.RemoveAt(toN.numLinks);
                toN.linkAngles.RemoveAt(toN.numLinks);
                return;
            }
        }
    }
Example #19
0
 void SetNodeAngles(float angle, WMG_Node fromN, WMG_Node toN)
 {
     for (int i = 0; i < fromN.numLinks; i++)
     {
         WMG_Link fromNlink = fromN.links[i].GetComponent <WMG_Link>();
         if (fromNlink.id == this.id)
         {
             fromN.linkAngles[i] = angle - 90;
         }
     }
     for (int i = 0; i < toN.numLinks; i++)
     {
         WMG_Link toNlink = toN.links[i].GetComponent <WMG_Link>();
         if (toNlink.id == this.id)
         {
             toN.linkAngles[i] = angle + 90;
         }
     }
 }
 private void TooltipLegendLinkMouseEnter(WMG_Series aSeries, WMG_Link aLink, bool state)
 {
     if (isTooltipObjectNull())
     {
         return;
     }
     if (!aSeries.hidePoints)
     {
         return;
     }
     if (state)
     {
         MouseEnterCommon(aSeries.seriesName, aLink.gameObject, new Vector3(2, 1.05f, 1));
     }
     else
     {
         MouseExitCommon(aLink.gameObject);
     }
 }
Example #21
0
    void CreateOrDeleteLink(WMG_Node fromNode, WMG_Node toNode, bool noVertHoriz)
    {
        WMG_Link aLink = GetLink(fromNode, toNode);

        if (aLink == null)
        {
            if (createLinks && !noVertHoriz)
            {
                gridLinks.Add(CreateLink(fromNode, toNode.gameObject, linkPrefab, this.gameObject));
            }
        }
        else
        {
            if (!createLinks || noVertHoriz)
            {
                gridLinks.Remove(aLink.gameObject);
                DeleteLink(aLink);
            }
        }
    }
Example #22
0
 void TooltipLegendLinkMouseEnter(WMG_Series aSeries, WMG_Link aLink, bool state)
 {
     if (isTooltipObjectNull())
     {
         return;
     }
     if (!aSeries.hidePoints)
     {
         return;
     }
     if (state)
     {
         MouseEnterCommon(aSeries.seriesName, aLink.gameObject);
         performTooltipAnimation(aLink.transform, new Vector3(2, 1.05f, 1), theGraph.tooltipAnimationsDuration, 0, theGraph.tooltipAnimationsEasetype);
     }
     else
     {
         MouseExitCommon();
         performTooltipAnimation(aLink.transform, Vector3.one, theGraph.tooltipAnimationsDuration, 0, theGraph.tooltipAnimationsEasetype);
     }
 }
Example #23
0
    public void DeleteNode(WMG_Node theNode)
    {
        // Deleting a node also deletes all of its link and swaps IDs with the largest node ID in the list
        int idToDelete = theNode.id;

        foreach (GameObject node in nodesParent)
        {
            WMG_Node aNode = node.GetComponent <WMG_Node>();
            if (aNode != null && aNode.id == nodesParent.Count - 1)
            {
                aNode.SetID(idToDelete);
                while (theNode.numLinks > 0)
                {
                    WMG_Link aLink = theNode.links[0].GetComponent <WMG_Link>();
                    DeleteLink(aLink);
                }
                nodesParent.Remove(theNode.gameObject);
                DestroyImmediate(theNode.gameObject);
                return;
            }
        }
    }
    public List <GameObject> GenerateGraphFromNode(WMG_Node fromNode)
    {
        // Given a starting node, generate a graph of nodes around the starting node
        // Returns the list of nodes and links composing the resulting graph
        List <GameObject> returnResults = new List <GameObject>();

        returnResults.Add(fromNode.gameObject);

        // Initialize various variables used in the algorithm
        GameObject[] nodes             = new GameObject[numNodes];
        bool[]       nodesProcessed    = new bool[numNodes];
        GameObject   curObj            = fromNode.gameObject;
        int          procNodeNum       = 0;
        int          numNodesProcessed = 0;
        int          numNodesStarting  = theGraph.NodesParent.Count - 1;

        nodes[procNodeNum] = curObj;

        // Each while loop processes a node by attempting to create neighbors and links to neighbors from the node.
        // The loop ends when all nodes have been processed or when the number of nodes specified have been created.
        // A node is processed if all of its neighbors were successfully created or if not all neighbors were created, but maxNeighborAttempts was reached.
        // maxNeighborAttempts (a failed neighbor creation attempt) can get incremented for the following reasons:
        // 1. When a randomly generated angle falls between existing neighbors that is less than minAngle.
        // 2. If noLinkIntersection is true, a randomly generated angle and length would create a link that would cross an existing link in this manager's links parent.
        // 3. If noNodeIntersection is true, a randomly generated angle and length would create a node that that would circle interesect an existing node in this manager's nodes parent.
        // 3 cont. The same as above but noNodeIntersectionRadiusPadding > 0, performs the circle intersections check with the nodes' radii increased by the specified padding.
        // 4. If noLinkNodeIntersection is true, a randomly generated node would intersect with an existing link or a randomly generated link would intersect with an existing node.
        // 4 cont. The same as above but noLinkNodeIntersectionRadiusPadding > 0, performas the circle - line intersections with the node radius increased by the specified padding.
        while (theGraph.NodesParent.Count - numNodesStarting < numNodes)
        {
            WMG_Node procNode     = nodes[procNodeNum].GetComponent <WMG_Node>();
            int      numNeighbors = Random.Range(minRandomNumberNeighbors, maxRandomNumberNeighbors);
            if (debugRandomGraph)
            {
                Debug.Log("Processesing Node: " + procNode.id + " with " + numNeighbors + " neighbors.");
            }
            // Attempt to create a neighbor for the specified random number of neighbors
            for (int i = 0; i < numNeighbors; i++)
            {
                int curNeighborAttempt = 0;
                // For each neighbor, attempt to create the neighbor based on the maxNeighborAttempts
                while (curNeighborAttempt < maxNeighborAttempts)
                {
                    // For this attempt, randomly generate an angle and length based on the specified parameters
                    float neighborAngle  = Random.Range(minAngleRange, maxAngleRange);
                    float neighborLength = Random.Range(minRandomLinkLength, maxRandomLinkLength);
                    bool  failedAttempt  = false;

                    if (debugRandomGraph)
                    {
                        Debug.Log("Neighbor: " + i + " Attempt: " + curNeighborAttempt + " angle: " + Mathf.Round(neighborAngle));
                    }

                    // Check to see that the randomly generated neighbor would not be too close to an existing neighbor (failure possibility #1)
                    if (minAngle > 0)
                    {
                        for (int j = 0; j < procNode.numLinks; j++)
                        {
                            float angleDif = Mathf.Abs(procNode.linkAngles[j] - neighborAngle);
                            if (angleDif > 180)
                            {
                                angleDif = Mathf.Abs(angleDif - 360);
                            }
                            if (angleDif < minAngle)
                            {
                                failedAttempt = true;
                                break;
                            }
                        }
                    }

                    if (failedAttempt)
                    {
                        // Failed because random angle was smaller than the minAngle on either side of an existing neighbor
                        if (debugRandomGraph)
                        {
                            Debug.Log("Failed: Angle within minAngle of existing neighbor");
                        }
                        curNeighborAttempt++;
                        continue;
                    }
                    // Check if the randomly generated link intersects an existing link (failure possibility #2)
                    if (noLinkIntersection)
                    {
                        float p1y = procNode.transform.localPosition.y + (neighborLength + procNode.radius) * Mathf.Sin(Mathf.Deg2Rad * neighborAngle);
                        float p1x = procNode.transform.localPosition.x + (neighborLength + procNode.radius) * Mathf.Cos(Mathf.Deg2Rad * neighborAngle);
                        float p2y = procNode.transform.localPosition.y + procNode.radius * Mathf.Sin(Mathf.Deg2Rad * neighborAngle);
                        float p2x = procNode.transform.localPosition.x + procNode.radius * Mathf.Cos(Mathf.Deg2Rad * neighborAngle);
                        foreach (GameObject child in theGraph.LinksParent)
                        {
                            WMG_Link childLink = child.GetComponent <WMG_Link>();
                            if (childLink.id == -1)
                            {
                                continue;                                                 // Dummy editor link
                            }
                            WMG_Node childLinkFrom = childLink.fromNode.GetComponent <WMG_Node>();
                            WMG_Node childLinkTo   = childLink.toNode.GetComponent <WMG_Node>();
                            float    p3y           = childLinkFrom.transform.localPosition.y;
                            float    p3x           = childLinkFrom.transform.localPosition.x;
                            float    p4y           = childLinkTo.transform.localPosition.y;
                            float    p4x           = childLinkTo.transform.localPosition.x;
                            if (PointInterArea(p1x, p1y, p2x, p2y, p3x, p3y) * PointInterArea(p1x, p1y, p2x, p2y, p4x, p4y) < 0 &&
                                PointInterArea(p3x, p3y, p4x, p4y, p1x, p1y) * PointInterArea(p3x, p3y, p4x, p4y, p2x, p2y) < 0)                                   // Links intersect
                            {
                                if (debugRandomGraph)
                                {
                                    Debug.Log("Failed: Link intersected with existing link: " + childLink.id);
                                }
                                failedAttempt = true;
                                break;
                            }
                        }
                    }
                    if (failedAttempt)
                    {
                        // Failed because random link intersected an existing link
                        curNeighborAttempt++;
                        continue;
                    }
                    // Check if the randomly generated node intersects an existing node (failure possibility #3)
                    if (noNodeIntersection)
                    {
                        float p1y = procNode.transform.localPosition.y + (neighborLength) * Mathf.Sin(Mathf.Deg2Rad * neighborAngle);
                        float p1x = procNode.transform.localPosition.x + (neighborLength) * Mathf.Cos(Mathf.Deg2Rad * neighborAngle);
                        foreach (GameObject child in theGraph.NodesParent)
                        {
                            WMG_Node aNode = child.GetComponent <WMG_Node>();
                            if (aNode.id == -1)
                            {
                                continue;                                             // Dummy editor node
                            }
                            // Circles intersect if (R0-R1)^2 <= (x0-x1)^2+(y0-y1)^2 <= (R0+R1)^2
                            if (Mathf.Pow((p1x - child.transform.localPosition.x), 2) + Mathf.Pow((p1y - child.transform.localPosition.y), 2) <= Mathf.Pow(2 * (procNode.radius + noNodeIntersectionRadiusPadding), 2))
                            {
                                if (debugRandomGraph)
                                {
                                    Debug.Log("Failed: Node intersected with existing node: " + aNode.id);
                                }
                                failedAttempt = true;
                                break;
                            }
                        }
                    }
                    if (failedAttempt)
                    {
                        // Failed because random node intersected an existing node
                        curNeighborAttempt++;
                        continue;
                    }
                    // Check if the randomly generated link intersects an existing node
                    if (noLinkNodeIntersection)
                    {
                        float p1y = procNode.transform.localPosition.y + (neighborLength + procNode.radius) * Mathf.Sin(Mathf.Deg2Rad * neighborAngle);
                        float p1x = procNode.transform.localPosition.x + (neighborLength + procNode.radius) * Mathf.Cos(Mathf.Deg2Rad * neighborAngle);
                        float p2y = procNode.transform.localPosition.y + procNode.radius * Mathf.Sin(Mathf.Deg2Rad * neighborAngle);
                        float p2x = procNode.transform.localPosition.x + procNode.radius * Mathf.Cos(Mathf.Deg2Rad * neighborAngle);
                        foreach (GameObject child in theGraph.NodesParent)
                        {
                            WMG_Node aNode = child.GetComponent <WMG_Node>();
                            if (procNode.id == aNode.id)
                            {
                                continue;                                                      // Ignore the processesing node
                            }
                            if (LineInterCircle(p1x, p1y, p2x, p2y, child.transform.localPosition.x, child.transform.localPosition.y, aNode.radius + noLinkNodeIntersectionRadiusPadding))
                            {
                                if (debugRandomGraph)
                                {
                                    Debug.Log("Failed: Link intersected with existing node: " + aNode.id);
                                }
                                failedAttempt = true;
                                break;
                            }
                        }
                    }
                    if (failedAttempt)
                    {
                        // Failed because random link intersected an existing node
                        curNeighborAttempt++;
                        continue;
                    }

                    // Check if the randomly generated node intersects an existing link
                    if (noLinkNodeIntersection)
                    {
                        float cy = procNode.transform.localPosition.y + (neighborLength + 2 * procNode.radius) * Mathf.Sin(Mathf.Deg2Rad * neighborAngle);
                        float cx = procNode.transform.localPosition.x + (neighborLength + 2 * procNode.radius) * Mathf.Cos(Mathf.Deg2Rad * neighborAngle);
                        foreach (GameObject child in theGraph.LinksParent)
                        {
                            WMG_Link childLink = child.GetComponent <WMG_Link>();
                            if (childLink.id == -1)
                            {
                                continue;                                                 // Dummy editor link
                            }
                            WMG_Node childLinkFrom = childLink.fromNode.GetComponent <WMG_Node>();
                            WMG_Node childLinkTo   = childLink.toNode.GetComponent <WMG_Node>();
                            float    p1y           = childLinkFrom.transform.localPosition.y;
                            float    p1x           = childLinkFrom.transform.localPosition.x;
                            float    p2y           = childLinkTo.transform.localPosition.y;
                            float    p2x           = childLinkTo.transform.localPosition.x;
                            if (LineInterCircle(p1x, p1y, p2x, p2y, cx, cy, procNode.radius + noLinkNodeIntersectionRadiusPadding))
                            {
                                if (debugRandomGraph)
                                {
                                    Debug.Log("Failed: Node intersected with existing link: " + childLink.id);
                                }
                                failedAttempt = true;
                                break;
                            }
                        }
                    }
                    if (failedAttempt)
                    {
                        // Failed because random node intersected an existing link
                        curNeighborAttempt++;
                        continue;
                    }

                    // The attempt did not fail, so create the node and the link and break out of the while attempt < maxAttempts loop
                    curObj = theGraph.CreateNode(nodePrefab, fromNode.transform.parent.gameObject);
                    returnResults.Add(curObj);
                    nodes[theGraph.NodesParent.Count - numNodesStarting - 1] = curObj;

//					curObj.transform.parent = fromNode.transform.parent;

                    float dx = Mathf.Cos(Mathf.Deg2Rad * neighborAngle) * neighborLength;
                    float dy = Mathf.Sin(Mathf.Deg2Rad * neighborAngle) * neighborLength;
                    curObj.transform.localPosition = new Vector3(procNode.transform.localPosition.x + dx, procNode.transform.localPosition.y + dy, 0);

                    returnResults.Add(theGraph.CreateLink(procNode, curObj, linkPrefab, null));
                    break;
                }
                if (theGraph.NodesParent.Count - numNodesStarting == numNodes)
                {
                    break;                                                                            // Max number nodes specified was reached, we are done generating the graph
                }
            }
            // Set the node as processed and increment the processed node counter
            nodesProcessed[procNodeNum] = true;
            numNodesProcessed++;
            // Process the oldest node added as the next node to process
            if (centerPropogate)
            {
                procNodeNum++;
            }
            // Pick a random node as the next node to process from the nodes that have been created from this algorithm
            else
            {
                int numPossibleProcNodes = theGraph.NodesParent.Count - numNodesStarting - numNodesProcessed;
                if (numPossibleProcNodes > 0)
                {
                    int[] possibleProcNodes = new int[numPossibleProcNodes];
                    int   j = 0;
                    for (int i = 0; i < numNodes; i++)
                    {
                        if (!nodesProcessed[i] && i < theGraph.NodesParent.Count - numNodesStarting)
                        {
                            possibleProcNodes[j] = i;
                            j++;
                        }
                    }
                    procNodeNum = possibleProcNodes[Random.Range(0, j - 1)];
                }
            }

            // This happens (algorithm ends prematurely) when maxNeighborAttempts was reached for the starting node or all the nodes created
            if (theGraph.NodesParent.Count - numNodesStarting == numNodesProcessed)               // Case where all nodes have been processed, but number nodes specfied were not created
            {
                Debug.Log("WMG - Warning: Only generated " + (theGraph.NodesParent.Count - numNodesStarting - 1) + " nodes with the given parameters.");
                break;
            }
        }


        return(returnResults);
    }
Example #25
0
    public void updateLegend()
    {
        if (backgroundEnabled() && !theGraph.activeInHierarchy(background))
        {
            theGraph.SetActive(background, true);
        }
        if (!backgroundEnabled() && theGraph.activeInHierarchy(background))
        {
            theGraph.SetActive(background, false);
        }
        if (!hideLegend && !theGraph.activeInHierarchy(entriesParent))
        {
            theGraph.SetActive(entriesParent, true);
        }
        if (hideLegend && theGraph.activeInHierarchy(entriesParent))
        {
            theGraph.SetActive(entriesParent, false);
        }
        if (hideLegend)
        {
            return;
        }

        float maxPointSize = 0;

        Vector2 entriesAnchor = Vector2.zero;
        Vector2 entriesPivot  = Vector2.zero;
        Vector2 entriesOffset = Vector2.zero;

        if (axisGraph != null)
        {
            maxPointSize = axisGraph.getMaxPointSize();
        }
        if (pieGraph != null)
        {
            maxPointSize = pieSwatchSize;
        }

        if (legendType == legendTypes.Bottom)
        {
            if (oppositeSideLegend)
            {
                entriesAnchor = new Vector2(0.5f, 1);
                entriesPivot  = entriesAnchor;
                entriesOffset = new Vector2(0, -offset);
            }
            else
            {
                entriesAnchor = new Vector2(0.5f, 0);
                entriesPivot  = entriesAnchor;
                entriesOffset = new Vector2(0, offset);
            }
        }
        else if (legendType == legendTypes.Right)
        {
            if (oppositeSideLegend)
            {
                entriesAnchor = new Vector2(0, 0.5f);
                entriesPivot  = entriesAnchor;
                entriesOffset = new Vector2(offset, 0);
            }
            else
            {
                entriesAnchor = new Vector2(1, 0.5f);
                entriesPivot  = entriesAnchor;
                entriesOffset = new Vector2(-offset, 0);
            }
        }

        // For pie graphs anchor the legend to the edge of the pie
        if (pieGraph != null)
        {
            entriesOffset = new Vector2(-1 * entriesOffset.x, -1 * entriesOffset.y);
            if (legendType == legendTypes.Bottom)
            {
                entriesPivot = new Vector2(entriesPivot.x, 1 - entriesPivot.y);
            }
            else
            {
                entriesPivot = new Vector2(1 - entriesPivot.x, entriesPivot.y);
            }
        }

        changeSpriteWidth(this.gameObject, LegendWidth);
        changeSpriteHeight(this.gameObject, LegendHeight);

        setAnchor(this.gameObject, entriesAnchor, entriesPivot, entriesOffset);

        Vector2 entriesParentOffset = new Vector2(legendEntryLinkSpacing + backgroundPadding + maxPointSize / 2f,
                                                  -legendEntryHeight / 2f + LegendHeight / 2f - backgroundPadding);

        setAnchor(entriesParent, new Vector2(0, 0.5f), new Vector2(0, 0.5f), entriesParentOffset);



        int numEntries       = NumEntries;
        int maxInRowOrColumn = MaxInRowOrColumn;         // Max elements in a row for horizontal legends

        if (numRowsOrColumns < 1)
        {
            _numRowsOrColumns = 1;                               // Ensure not less than 1
        }
        if (numRowsOrColumns > numEntries)
        {
            _numRowsOrColumns = numEntries;                                        // Ensure cannot exceed number series
        }
        int extras = 0;

        if (numEntries > 0)
        {
            extras = numEntries % numRowsOrColumns; // When the number series does not divide evenly by the num rows setting, then this is the number of extras
        }
        int  origExtras       = extras;             // Save the original extras, since we will need to decrement extras in the loop
        int  cumulativeOffset = 0;                  // Used to offset the other dimension, for example, elements moved to a lower row (y), need to also move certain distance (x) left
        int  previousI        = 0;                  // Used to determine when the i (row for horizontal) has changed from the previous i, which is used to increment the cumulative offset
        bool useSmaller       = false;              // Used to determine whether we need to subtract 1 from maxInRowOrColumn when calculating the cumulative offset

        if (maxInRowOrColumn == 0)
        {
            return;                                // Legend hidden / all entries deactivated
        }
        // Calculate the position of the legend entry for each line series
        for (int j = 0; j < legendEntries.Count; j++)
        {
            WMG_Legend_Entry legendEntry = legendEntries[j];

            if (axisGraph != null)
            {
                if (legendEntry.swatchNode == null)
                {
                    foreach (GameObject seriesGO in axisGraph.lineSeries)
                    {
                        seriesGO.GetComponent <WMG_Series>().CreateOrDeleteSpritesBasedOnPointValues();
                    }
                }

                theGraph.changeSpritePositionRelativeToObjBy(legendEntry.nodeLeft, legendEntry.swatchNode, new Vector3(-legendEntryLinkSpacing, 0, 0));
                theGraph.changeSpritePositionRelativeToObjBy(legendEntry.nodeRight, legendEntry.swatchNode, new Vector3(legendEntryLinkSpacing, 0, 0));

                WMG_Link theLine = legendEntry.line.GetComponent <WMG_Link>();
                theLine.Reposition();
            }
            else
            {
                changeSpriteWidth(legendEntry.swatchNode, Mathf.RoundToInt(pieSwatchSize));
                changeSpriteHeight(legendEntry.swatchNode, Mathf.RoundToInt(pieSwatchSize));
            }

            if (axisGraph != null)
            {
                theGraph.changeSpritePositionToX(legendEntry.label, legendEntrySpacing);
            }
            else
            {
                theGraph.changeSpritePositionToX(legendEntry.label, legendEntrySpacing + pieSwatchSize / 2);
            }

            // Legend text
            if (axisGraph != null)
            {
                string theText = legendEntry.seriesRef.seriesName;

                if (labelType == WMG_Enums.labelTypes.None)
                {
                    theText = "";
                }
                changeLabelText(legendEntry.label, theText);
            }
            changeLabelFontSize(legendEntry.label, legendEntryFontSize);
            changeSpriteColor(legendEntry.label, labelColor);
            // Font Style
            changeLabelFontStyle(legendEntry.label, legendEntryFontStyle);
            // Font
            if (legendEntryFont != null)
            {
                changeLabelFont(legendEntry.label, legendEntryFont);
            }

            // i is the row for horizontal legends, and the column for vertical
            int i = Mathf.FloorToInt(j / maxInRowOrColumn);
            if (origExtras > 0)
            {
                i = Mathf.FloorToInt((j + 1) / maxInRowOrColumn);
            }

            // If there were extras, but no longer any more extras, then need to subtract 1 from the maxInRowOrColumn, and recalculate i
            if (extras == 0 && origExtras > 0)
            {
                i = origExtras + Mathf.FloorToInt((j - origExtras * maxInRowOrColumn) / (maxInRowOrColumn - 1));
                if ((j - origExtras * maxInRowOrColumn) > 0)
                {
                    useSmaller = true;
                }
            }

            // When there are extras decrease i for the last element in the row
            if (extras > 0)
            {
                if ((j + 1) % maxInRowOrColumn == 0)
                {
                    extras--;
                    i--;
                }
            }

            // Increment cumulative offset when i changes, use offset to position other dimension correctly.
            if (previousI != i)
            {
                previousI = i;
                if (useSmaller)
                {
                    cumulativeOffset += (maxInRowOrColumn - 1);
                }
                else
                {
                    cumulativeOffset += maxInRowOrColumn;
                }
            }

            // Set the position based on the series index (j), i (row index for horizontal), and cumulative offset
            if (legendType == legendTypes.Bottom)
            {
                theGraph.changeSpritePositionTo(legendEntry.gameObject, new Vector3(j * legendEntryWidth - legendEntryWidth * cumulativeOffset, -i * legendEntryHeight, 0));
            }
            else if (legendType == legendTypes.Right)
            {
                theGraph.changeSpritePositionTo(legendEntry.gameObject, new Vector3(i * legendEntryWidth, -j * legendEntryHeight + legendEntryHeight * cumulativeOffset, 0));
            }
        }

        // This needs to be called after label text is set
        if (setWidthFromLabels)
        {
            if (axisGraph != null && (axisGraph.graphType == WMG_Axis_Graph.graphTypes.line || axisGraph.graphType == WMG_Axis_Graph.graphTypes.line_stacked))
            {
                legendEntryWidth = Mathf.Max(legendEntryLinkSpacing, maxPointSize / 2) + legendEntrySpacing + getMaxLabelWidth() + 5;
            }
            else
            {
                legendEntryWidth = maxPointSize + legendEntrySpacing + getMaxLabelWidth() + 5;
            }
        }

        if (autofitEnabled)
        {
            if (legendType == legendTypes.Bottom)
            {
                if (LegendWidth > getSpriteWidth(theGraph.gameObject))
                {
                    if (numRowsOrColumns < NumEntries)
                    {
                        numRowsOrColumns++;
                    }
                }
                else
                {
                    if (numRowsOrColumns > 1)
                    {
                        _numRowsOrColumns--;                                   // temporarily decrease without callback
                        if (LegendWidth > getSpriteWidth(theGraph.gameObject)) // if new temporary width exceeds border, then dont do anything
                        {
                            _numRowsOrColumns++;
                        }
                        else                           // new width doesn't exceed the border, actually decrease
                        {
                            _numRowsOrColumns++;
                            numRowsOrColumns--;
                        }
                    }
                }
            }
            else
            {
                if (LegendHeight > getSpriteHeight(theGraph.gameObject))
                {
                    if (numRowsOrColumns < NumEntries)
                    {
                        numRowsOrColumns++;
                    }
                }
                else
                {
                    if (numRowsOrColumns > 1)
                    {
                        _numRowsOrColumns--;                                     // temporarily decrease without callback
                        if (LegendHeight > getSpriteHeight(theGraph.gameObject)) // if new temporary width exceeds border, then dont do anything
                        {
                            _numRowsOrColumns++;
                        }
                        else                           // new width doesn't exceed the border, actually decrease
                        {
                            _numRowsOrColumns++;
                            numRowsOrColumns--;
                        }
                    }
                }
            }
        }
    }
Example #26
0
    public void CreateOrDeleteSpritesBasedOnPointValues()
    {
        // Real Time Update
        if (realTimeRunning)
        {
            DoRealTimeUpdate();
        }
        if (pointValuesChanged)
        {
            // Create points based on pointValues data
            for (int i = 0; i < pointValues.Count; i++)
            {
                if (points.Count <= i)
                {
                    GameObject curObj = theGraph.CreateNode(nodePrefab, nodeParent);

                    theGraph.addNodeClickEvent(curObj);
                    theGraph.addNodeMouseEnterEvent(curObj);
                    theGraph.addNodeMouseLeaveEvent(curObj);

                    curObj.GetComponent <WMG_Node>().radius = -1 * linePadding;
                    theGraph.SetActive(curObj, false);
                    points.Add(curObj);
                    if (i > 0)
                    {
                        WMG_Node fromNode = points[i - 1].GetComponent <WMG_Node>();
                        curObj = theGraph.CreateLink(fromNode, curObj, theGraph.linkPrefabs[linkPrefab], linkParent);

                        theGraph.addLinkClickEvent(curObj);
                        theGraph.addLinkMouseEnterEvent(curObj);
                        theGraph.addLinkMouseLeaveEvent(curObj);

                        theGraph.SetActive(curObj, false);
                        lines.Add(curObj);
                    }
                }
            }
            // If there are more points than pointValues data, delete the extras
            for (int i = points.Count - 1; i >= 0; i--)
            {
                if (points[i] != null && i >= pointValues.Count)
                {
                    WMG_Node thePoint = points[i].GetComponent <WMG_Node>();
                    foreach (GameObject child in thePoint.links)
                    {
                        lines.Remove(child);
                    }
                    theGraph.DeleteNode(thePoint);
                    points.RemoveAt(i);
                }
                // Delete existing connect first to last
                if (i > 1 && i < pointValues.Count - 1)
                {
                    WMG_Node firstNode = points[0].GetComponent <WMG_Node>();
                    WMG_Node toNode    = points[i].GetComponent <WMG_Node>();
                    WMG_Link delLink   = theGraph.GetLink(firstNode, toNode);
                    if (delLink != null)
                    {
                        lines.Remove(delLink.gameObject);
                        theGraph.DeleteLink(delLink);
                    }
                }
            }
            // Connect first to last
            if (points.Count > 2)
            {
                WMG_Node firstNode = points[0].GetComponent <WMG_Node>();
                WMG_Node toNode    = points[points.Count - 1].GetComponent <WMG_Node>();
                WMG_Link delLink   = theGraph.GetLink(firstNode, toNode);
                if (connectFirstToLast && delLink == null)
                {
                    GameObject curObj = theGraph.CreateLink(firstNode, toNode.gameObject, theGraph.linkPrefabs[linkPrefab], linkParent);

                    theGraph.addLinkClickEvent(curObj);
                    theGraph.addLinkMouseEnterEvent(curObj);
                    theGraph.addLinkMouseLeaveEvent(curObj);

                    theGraph.SetActive(curObj, false);
                    lines.Add(curObj);
                }
                if (!connectFirstToLast && delLink != null)
                {
                    lines.Remove(delLink.gameObject);
                    theGraph.DeleteLink(delLink);
                }
            }
            // Create the legend if it doesn't exist
            if (legendEntryNode == null)
            {
                legendEntryNode = theGraph.CreateNode(nodePrefab, legendEntryParent);

                theGraph.addNodeClickEvent_Leg(legendEntryNode);
                theGraph.addNodeMouseEnterEvent_Leg(legendEntryNode);
                theGraph.addNodeMouseLeaveEvent_Leg(legendEntryNode);

                WMG_Node cNode = legendEntryNode.GetComponent <WMG_Node>();
                theGraph.changeSpritePivot(cNode.objectToColor, WMG_Graph_Manager.WMGpivotTypes.Center);
                cNode.Reposition(0, 0);

                legendEntryLink = theGraph.CreateLink(legendEntryNodeRight.GetComponent <WMG_Node>(), legendEntryNodeLeft, theGraph.linkPrefabs[linkPrefab], legendEntryParent);

                theGraph.addLinkClickEvent_Leg(legendEntryLink);
                theGraph.addLinkMouseEnterEvent_Leg(legendEntryLink);
                theGraph.addLinkMouseLeaveEvent_Leg(legendEntryLink);

                theGraph.bringSpriteToFront(legendEntryNode);
            }
        }
    }
Example #27
0
    // Given two nodes return one or more shortest paths between the nodes based on the number of links (unweighted)
    public List <WMG_Link> FindShortestPathBetweenNodes(WMG_Node fromNode, WMG_Node toNode)
    {
        List <WMG_Link> linksBetweenToAndFrom = new List <WMG_Link>();

        // Reset BFS data needed for this algorithm
        foreach (GameObject node in nodesParent)
        {
            WMG_Node aNode = node.GetComponent <WMG_Node>();
            if (aNode != null)
            {
                aNode.BFS_mark  = false;
                aNode.BFS_depth = 0;
            }
        }

        Queue <WMG_Node> mapSysQ = new Queue <WMG_Node>();

        // This calculates and stores the depth of every node between the starting and ending nodes
        // This is exactly the BFS (Breadth-first search) algorithm
        mapSysQ.Enqueue(fromNode);
        fromNode.BFS_mark = true;
        while (mapSysQ.Count > 0)
        {
            WMG_Node temp = mapSysQ.Dequeue();
            if (toNode.id == temp.id)
            {
                break;                                   // Reached the target node so we are done
            }
            // Add the current node neighbors to the queue if they haven't been added in the past and calculate the depth
            for (int i = 0; i < temp.numLinks; i++)
            {
                WMG_Link aLink = temp.links[i].GetComponent <WMG_Link>();
                WMG_Node temp2 = aLink.toNode.GetComponent <WMG_Node>();
                if (temp2.id == temp.id)
                {
                    temp2 = aLink.fromNode.GetComponent <WMG_Node>();
                }
                if (!temp2.BFS_mark)
                {
                    temp2.BFS_mark  = true;
                    temp2.BFS_depth = temp.BFS_depth + 1;
                    mapSysQ.Enqueue(temp2);
                }
            }
        }

        // If all we cared about was the shortest distance between the two nodes we could end here, but we might also want the links themselves
        // This finds the shortest path of links between the starting and ending nodes using the previously calculated depths
        mapSysQ.Clear();
        mapSysQ.Enqueue(toNode);
        while (mapSysQ.Count > 0)
        {
            WMG_Node temp = mapSysQ.Dequeue();
            if (fromNode.id == temp.id)
            {
                break;
            }
            for (int i = 0; i < temp.numLinks; i++)
            {
                WMG_Link aLink = temp.links[i].GetComponent <WMG_Link>();
                WMG_Node temp2 = aLink.toNode.GetComponent <WMG_Node>();
                if (temp2.id == temp.id)
                {
                    temp2 = aLink.fromNode.GetComponent <WMG_Node>();
                }
                if (temp.BFS_depth == temp2.BFS_depth + 1)
                {
                    if (temp2.BFS_depth == 0 && temp2.id != fromNode.id)
                    {
                        continue;
                    }
                    linksBetweenToAndFrom.Add(aLink);
                    if (!mapSysQ.Contains(temp2))
                    {
                        mapSysQ.Enqueue(temp2);
                    }
                }
            }
        }
        return(linksBetweenToAndFrom);
    }
Example #28
0
    public void UpdateSprites(List <GameObject> prevPoints)
    {
        if (pointValuesChanged)
        {
            // Auto set xDistBetween based on the axis length and point count
            if (AutoUpdateXDistBetween)
            {
                if (theGraph.orientationType == WMG_Axis_Graph.orientationTypes.vertical)
                {
                    xDistBetweenPoints = theGraph.xAxisLength / points.Count;
                }
                else
                {
                    xDistBetweenPoints = theGraph.yAxisLength / points.Count;
                }
                cachedXDistBetweenPoints = xDistBetweenPoints;
            }
            // Update point positions
            for (int i = 0; i < points.Count; i++)
            {
                if (i >= pointValues.Count)
                {
                    break;
                }
                float newX = 0;
                float newY = 0;
                // If using xDistBetween then point positioning based on previous point point position
                if (UseXDistBetweenToSpace)
                {
                    if (i > 0)                       // For points greater than 0, use the previous point position plus xDistBetween
                    {
                        if (theGraph.orientationType == WMG_Axis_Graph.orientationTypes.vertical)
                        {
                            newX = theGraph.getSpritePositionX(points[i - 1]) + xDistBetweenPoints + theGraph.getSpriteOffsetX(points[i]);
                            newY = (pointValues[i].y - theGraph.yAxisMinValue) / (theGraph.yAxisMaxValue - theGraph.yAxisMinValue) * theGraph.yAxisLength;
                        }
                        else
                        {
                            newX = (pointValues[i].y - theGraph.xAxisMinValue) / (theGraph.xAxisMaxValue - theGraph.xAxisMinValue) * theGraph.xAxisLength;
                            newY = theGraph.getSpritePositionY(points[i - 1]) + xDistBetweenPoints - (theGraph.getSpriteFactorY(points[i]) - 1) * theGraph.barWidth;
                        }
                    }
                    else                       // For point 0, one of the positions is just 0
                    {
                        if (theGraph.orientationType == WMG_Axis_Graph.orientationTypes.vertical)
                        {
                            newY = (pointValues[i].y - theGraph.yAxisMinValue) / (theGraph.yAxisMaxValue - theGraph.yAxisMinValue) * theGraph.yAxisLength;
                        }
                        else
                        {
                            newX = (pointValues[i].y - theGraph.xAxisMinValue) / (theGraph.xAxisMaxValue - theGraph.xAxisMinValue) * theGraph.xAxisLength;
                        }
                    }
                }
                else                   // Not using xDistBetween, so use the actual x values in the Vector2 list
                {
                    if (i < pointValues.Count)
                    {
                        if (theGraph.orientationType == WMG_Axis_Graph.orientationTypes.vertical)
                        {
                            newX = (pointValues[i].x - theGraph.xAxisMinValue) / (theGraph.xAxisMaxValue - theGraph.xAxisMinValue) * theGraph.xAxisLength;
                            newY = (pointValues[i].y - theGraph.yAxisMinValue) / (theGraph.yAxisMaxValue - theGraph.yAxisMinValue) * theGraph.yAxisLength;
                        }
                        else
                        {
                            newX = (pointValues[i].y - theGraph.xAxisMinValue) / (theGraph.xAxisMaxValue - theGraph.xAxisMinValue) * theGraph.xAxisLength;
                            newY = (pointValues[i].x - theGraph.yAxisMinValue) / (theGraph.yAxisMaxValue - theGraph.yAxisMinValue) * theGraph.yAxisLength;
                        }
                    }
                }

                // For bar graphs, need to update sprites width and height based on positions
                if (theGraph.graphType != WMG_Axis_Graph.graphTypes.line)
                {
                    // For stacked percentage, need to set a y position based on the percentage of all series values combined
                    if (theGraph.graphType == WMG_Axis_Graph.graphTypes.bar_stacked_percent && theGraph.TotalPointValues.Count > i)
                    {
                        if (theGraph.orientationType == WMG_Axis_Graph.orientationTypes.vertical)
                        {
                            newY = (pointValues[i].y - theGraph.yAxisMinValue) / theGraph.TotalPointValues[i] * theGraph.yAxisLength;
                        }
                        else
                        {
                            newX = (pointValues[i].y - theGraph.xAxisMinValue) / theGraph.TotalPointValues[i] * theGraph.xAxisLength;
                        }
                    }
                    // Update sprite dimensions and increase position using previous point position
                    // Previous points is null for side by side bar, but should not be empty for stacked and stacked percentage for series after the first series
                    WMG_Node thePoint = points[i].GetComponent <WMG_Node>();
                    if (theGraph.orientationType == WMG_Axis_Graph.orientationTypes.vertical)
                    {
//						theGraph.changeSpritePivot(thePoint.objectToColor, WMG_GUI_Functions.WMGpivotTypes.Bottom);
                        theGraph.changeSpriteHeight(thePoint.objectToColor, Mathf.RoundToInt(newY));
                        theGraph.changeSpriteWidth(thePoint.objectToColor, Mathf.RoundToInt(theGraph.barWidth));
                        newY -= theGraph.getSpriteOffsetY(points[i]);
                        newY -= (theGraph.getSpriteFactorY(points[i]) - 1) * -theGraph.getSpriteHeight(points[i]);                         // new
                        if (prevPoints != null && i < prevPoints.Count)
                        {
                            newY += theGraph.getSpritePositionY(prevPoints[i]);
                            newY += (theGraph.getSpriteFactorY(points[i]) - 1) * -theGraph.getSpriteHeight(prevPoints[i]);                             // new
                        }
                    }
                    else
                    {
//						theGraph.changeSpritePivot(thePoint.objectToColor, WMG_GUI_Functions.WMGpivotTypes.Left);
                        theGraph.changeSpriteHeight(thePoint.objectToColor, Mathf.RoundToInt(theGraph.barWidth));
                        theGraph.changeSpriteWidth(thePoint.objectToColor, Mathf.RoundToInt(newX));
                        newX  = 0;
                        newY -= theGraph.barWidth;
                        if (prevPoints != null && i < prevPoints.Count)
                        {
                            newX += theGraph.getSpritePositionX(prevPoints[i]);
                            newX += theGraph.getSpriteWidth(prevPoints[i]);
                        }
                    }
                }
                // Finally, set the positions calculated above
                theGraph.changeSpritePositionTo(points[i], new Vector3(newX, newY, 0));
            }
            // Reposition existing lines based on the new point positions
            for (int i = 0; i < lines.Count; i++)
            {
                WMG_Link theLine = lines[i].GetComponent <WMG_Link>();
                theLine.Reposition();
            }
        }
    }
    // Given two nodes return one or more shortest paths between the nodes based on the link weights (weighted), and also node radii if include radii is true
    public List <WMG_Link> FindShortestPathBetweenNodesWeighted(WMG_Node fromNode, WMG_Node toNode, bool includeRadii)
    {
        List <WMG_Link> linksBetweenToAndFrom = new List <WMG_Link>();
        List <WMG_Node> Dijkstra_nodes        = new List <WMG_Node>();

        // Reset data needed for this algorithm
        foreach (GameObject node in nodesParent)
        {
            WMG_Node aNode = node.GetComponent <WMG_Node>();
            if (aNode != null)
            {
                if (aNode.id == fromNode.id)
                {
                    aNode.Dijkstra_depth = 0;
                }
                else
                {
                    aNode.Dijkstra_depth = Mathf.Infinity;
                }
                Dijkstra_nodes.Add(aNode);
            }
        }
        Dijkstra_nodes.Sort(delegate(WMG_Node x, WMG_Node y) { return(x.Dijkstra_depth.CompareTo(y.Dijkstra_depth)); });

        // This is exactly Dijkstra's algorithm
        while (Dijkstra_nodes.Count > 0)
        {
            WMG_Node temp = Dijkstra_nodes[0];
            Dijkstra_nodes.RemoveAt(0);
            if (toNode.id == temp.id)
            {
                break;                                   // Reached the target node so we are done
            }
            if (temp.Dijkstra_depth == Mathf.Infinity)
            {
                break;
            }
            for (int i = 0; i < temp.numLinks; i++)
            {
                WMG_Link aLink = temp.links[i].GetComponent <WMG_Link>();
                WMG_Node temp2 = aLink.toNode.GetComponent <WMG_Node>();
                if (temp2.id == temp.id)
                {
                    temp2 = aLink.fromNode.GetComponent <WMG_Node>();
                }
                float alt = temp.Dijkstra_depth + aLink.weight;
                if (includeRadii)
                {
                    alt += temp.radius + temp2.radius;
                }
                if (alt < temp2.Dijkstra_depth)
                {
                    temp2.Dijkstra_depth = alt;
                    Dijkstra_nodes.Sort(delegate(WMG_Node x, WMG_Node y) { return(x.Dijkstra_depth.CompareTo(y.Dijkstra_depth)); });
                }
            }
        }

        /*
         *             // If all we cared about was the shortest distance between the two nodes we could end here, but we might also want the links themselves
         *             // This finds the shortest path of links between the starting and ending nodes using the previously calculated depths
         *             Queue<WMG_Node> mapSysQ = new Queue<WMG_Node>();
         *             mapSysQ.Enqueue(toNode);
         *             while (mapSysQ.Count > 0) {
         *                     WMG_Node temp = mapSysQ.Dequeue();
         *                     if (fromNode.id == temp.id) break;
         *                     for (int i = 0; i < temp.numLinks; i++) {
         *                             WMG_Link aLink = temp.links[i].GetComponent<WMG_Link>();
         *                             WMG_Node temp2 = aLink.toNode.GetComponent<WMG_Node>();
         *                             if (temp2.id == temp.id) temp2 = aLink.fromNode.GetComponent<WMG_Node>();
         *                             float alt = temp2.Dijkstra_depth + aLink.weight;
         *                             if (includeRadii) alt += temp.radius + temp2.radius;
         *                             if (Mathf.Approximately(temp.Dijkstra_depth, alt)) {
         *                                     linksBetweenToAndFrom.Add(aLink);
         *                                     if (!mapSysQ.Contains(temp2)) mapSysQ.Enqueue(temp2);
         *                             }
         *                     }
         *             }
         *
         */

        return(linksBetweenToAndFrom);
    }
Example #30
0
    public void updateLegend()
    {
        if (legendTypeChanged || legendChanged)
        {
            if (!hideLegend && showBackground && !theGraph.activeInHierarchy(background))
            {
                theGraph.SetActive(background, true);
            }
            if ((hideLegend || !showBackground) && theGraph.activeInHierarchy(background))
            {
                theGraph.SetActive(background, false);
            }
            if (!hideLegend && !theGraph.activeInHierarchy(entriesParent))
            {
                theGraph.SetActive(entriesParent, true);
            }
            if (hideLegend && theGraph.activeInHierarchy(entriesParent))
            {
                theGraph.SetActive(entriesParent, false);
            }
            if (hideLegend)
            {
                return;
            }

            // Swap parent offsets when changing the legend type
            if (legendTypeChanged)
            {
                theGraph.SwapVals <float>(ref offsetX, ref offsetY);
            }

            WMG_Axis_Graph axisGraph    = theGraph.GetComponent <WMG_Axis_Graph>();
            WMG_Pie_Graph  pieGraph     = theGraph.GetComponent <WMG_Pie_Graph>();
            float          graphY       = 0;
            float          graphX       = 0;
            float          maxPointSize = 0;
            if (axisGraph != null)
            {
                graphY       = axisGraph.yAxisLength;
                graphX       = axisGraph.xAxisLength;
                maxPointSize = axisGraph.getMaxPointSize();
            }
            if (pieGraph != null)
            {
                graphY       = pieGraph.pieSize + pieGraph.explodeLength;
                graphX       = graphY;
                maxPointSize = pieSwatchSize;
            }
            int numEntries = legendEntries.Count;
            for (int j = 0; j < legendEntries.Count; j++)
            {
                if (!activeInHierarchy(legendEntries[j].gameObject))
                {
                    numEntries--;
                }
            }
            int maxInRowOrColumn = Mathf.CeilToInt(1f * numEntries / numRowsOrColumns);             // Max elements in a row for horizontal legends

            float oppositeSideOffset = 0;
            if (legendType == legendTypes.Bottom)
            {
                if (autoCenterLegend)
                {
                    offsetX = (-maxInRowOrColumn * legendEntryWidth) / 2f + legendEntryLinkSpacing + 5;
                }
                if (oppositeSideLegend)
                {
                    oppositeSideOffset = 2 * offsetY + graphY;
                }
                changeSpritePositionTo(this.gameObject, new Vector3(graphX / 2 + offsetX, -offsetY + oppositeSideOffset, 0));
            }
            else if (legendType == legendTypes.Right)
            {
                if (autoCenterLegend)
                {
                    offsetY = (-(maxInRowOrColumn - 1) * legendEntryHeight) / 2f;
                }
                if (oppositeSideLegend)
                {
                    oppositeSideOffset = -2 * offsetX - graphX - legendEntryWidth + 2 * legendEntryLinkSpacing;
                }
                changeSpritePositionTo(this.gameObject, new Vector3(graphX + offsetX + oppositeSideOffset, graphY / 2 - offsetY, 0));
            }
            if (pieGraph != null)
            {
                Vector2 offset = pieGraph.getPaddingOffset();
                changeSpritePositionRelativeToObjBy(this.gameObject, this.gameObject, new Vector3(-graphX / 2f - offset.x, -graphY / 2f - offset.y));
            }

            int numRows = maxInRowOrColumn;
            int numCols = numRowsOrColumns;

            if (legendType == legendTypes.Right)
            {
                theGraph.SwapVals <int>(ref numRows, ref numCols);
            }

            changeSpriteWidth(background, Mathf.RoundToInt(legendEntryWidth * numRows + 2 * backgroundPadding + legendEntryLinkSpacing));
            changeSpriteHeight(background, Mathf.RoundToInt(legendEntryHeight * numCols + 2 * backgroundPadding));
            changeSpritePositionTo(background, new Vector3(-backgroundPadding - legendEntryLinkSpacing - maxPointSize / 2f, backgroundPadding + legendEntryHeight / 2f));

            if (numRowsOrColumns < 1)
            {
                numRowsOrColumns = 1;                                   // Ensure not less than 1
            }
            if (numRowsOrColumns > numEntries)
            {
                numRowsOrColumns = numEntries;                                            // Ensure cannot exceed number series
            }
            int extras = 0;
            if (numEntries > 0)
            {
                extras = numEntries % numRowsOrColumns; // When the number series does not divide evenly by the num rows setting, then this is the number of extras
            }
            int  origExtras       = extras;             // Save the original extras, since we will need to decrement extras in the loop
            int  cumulativeOffset = 0;                  // Used to offset the other dimension, for example, elements moved to a lower row (y), need to also move certain distance (x) left
            int  previousI        = 0;                  // Used to determine when the i (row for horizontal) has changed from the previous i, which is used to increment the cumulative offset
            bool useSmaller       = false;              // Used to determine whether we need to subtract 1 from maxInRowOrColumn when calculating the cumulative offset

            if (maxInRowOrColumn == 0)
            {
                return;                                    // Legend hidden / all entries deactivated
            }
            // Calculate the position of the legend entry for each line series
            for (int j = 0; j < legendEntries.Count; j++)
            {
                WMG_Legend_Entry legendEntry = legendEntries[j];

                if (axisGraph != null)
                {
                    theGraph.changeSpritePositionRelativeToObjBy(legendEntry.nodeLeft, legendEntry.swatchNode, new Vector3(-legendEntryLinkSpacing, 0, 0));
                    theGraph.changeSpritePositionRelativeToObjBy(legendEntry.nodeRight, legendEntry.swatchNode, new Vector3(legendEntryLinkSpacing, 0, 0));

                    WMG_Link theLine = legendEntry.line.GetComponent <WMG_Link>();
                    theLine.Reposition();
                }
                else
                {
                    changeSpriteWidth(legendEntry.swatchNode, Mathf.RoundToInt(pieSwatchSize));
                    changeSpriteHeight(legendEntry.swatchNode, Mathf.RoundToInt(pieSwatchSize));
                }

                theGraph.changeSpritePositionToX(legendEntry.label, legendEntrySpacing);

                // Legend text
                if (axisGraph != null)
                {
                    string theText = legendEntry.seriesRef.seriesName;

                    if (labelType == WMG_Enums.labelTypes.None)
                    {
                        theText = "";
                    }
                    changeLabelText(legendEntry.label, theText);
                }
                legendEntry.label.transform.localScale = new Vector3(legendEntryFontSize, legendEntryFontSize, 1);

                // i is the row for horizontal legends, and the column for vertical
                int i = Mathf.FloorToInt(j / maxInRowOrColumn);
                if (origExtras > 0)
                {
                    i = Mathf.FloorToInt((j + 1) / maxInRowOrColumn);
                }

                // If there were extras, but no longer any more extras, then need to subtract 1 from the maxInRowOrColumn, and recalculate i
                if (extras == 0 && origExtras > 0)
                {
                    i = origExtras + Mathf.FloorToInt((j - origExtras * maxInRowOrColumn) / (maxInRowOrColumn - 1));
                    if ((j - origExtras * maxInRowOrColumn) > 0)
                    {
                        useSmaller = true;
                    }
                }

                // When there are extras decrease i for the last element in the row
                if (extras > 0)
                {
                    if ((j + 1) % maxInRowOrColumn == 0)
                    {
                        extras--;
                        i--;
                    }
                }

                // Increment cumulative offset when i changes, use offset to position other dimension correctly.
                if (previousI != i)
                {
                    previousI = i;
                    if (useSmaller)
                    {
                        cumulativeOffset += (maxInRowOrColumn - 1);
                    }
                    else
                    {
                        cumulativeOffset += maxInRowOrColumn;
                    }
                }

                // Set the position based on the series index (j), i (row index for horizontal), and cumulative offset
                if (legendType == legendTypes.Bottom)
                {
                    theGraph.changeSpritePositionTo(legendEntry.gameObject, new Vector3(j * legendEntryWidth - legendEntryWidth * cumulativeOffset, -i * legendEntryHeight, 0));
                }
                else if (legendType == legendTypes.Right)
                {
                    theGraph.changeSpritePositionTo(legendEntry.gameObject, new Vector3(i * legendEntryWidth, -j * legendEntryHeight + legendEntryHeight * cumulativeOffset, 0));
                }
            }
        }
    }
Example #31
0
    void OnEngineTreeClick(GameObject go)
    {
        if (!treeAnimating && !engineClicked)
        {
            engineClicked = !engineClicked;
            treeAnimating = true;
            Quaternion newRot = engineTree.transform.localRotation;
            newRot.eulerAngles = new Vector3(0, 0, 270);
            TweenRotation.Begin(engineTree, treeClickAnimDuration, newRot);
            TweenPosition tpos = TweenPosition.Begin(engineTree, treeClickAnimDuration, new Vector3(0, 100, -350));
            tpos.method = UITweener.Method.EaseIn;
            TweenAlpha.Begin(go, treeClickAnimDuration, 70 / 255f);

            foreach (Transform child in engineTree.transform)
            {
                WMG_Link aLink = child.GetComponent <WMG_Link>();
                if (aLink != null)
                {
                    newRot.eulerAngles = new Vector3(0, 0, 180);
                    TweenRotation tro = TweenRotation.Begin(aLink.objectToScale, treeClickAnimDuration, newRot);
                    tro.method = UITweener.Method.BounceIn;
                }
            }
            TweenAlpha.Begin(shieldTree, treeClickAnimDuration, 0);
            TweenAlpha.Begin(weaponTree, treeClickAnimDuration, 0);

            tpos.callWhenFinished = "endEngineTreeClicked";
            tpos.eventReceiver    = this.gameObject;
        }
        if (!treeAnimating && engineClicked)
        {
            engineClicked = !engineClicked;
            treeAnimating = true;
            Quaternion newRot = engineTree.transform.localRotation;
            newRot.eulerAngles = new Vector3(0, 345, 0);
            TweenRotation.Begin(engineTree, treeClickAnimDuration, newRot);
            TweenPosition tpos = TweenPosition.Begin(engineTree, treeClickAnimDuration, new Vector3(0, 0, 0));
            TweenAlpha.Begin(go, treeClickAnimDuration, 100 / 255f);

            foreach (Transform child in engineTree.transform)
            {
                WMG_Link aLink = child.GetComponent <WMG_Link>();
                if (aLink != null)
                {
                    newRot.eulerAngles = new Vector3(0, 0, 0);
                    TweenRotation.Begin(aLink.objectToScale, treeClickAnimDuration, newRot);
                }
            }
            TweenAlpha.Begin(shieldTree, treeClickAnimDuration, 1);
            TweenAlpha.Begin(weaponTree, treeClickAnimDuration, 1);

            tpos.callWhenFinished = "endTreeClickAnim";
            tpos.eventReceiver    = this.gameObject;

            foreach (Transform child in engineTree.transform)
            {
                WMG_Node aNode = child.GetComponent <WMG_Node>();
                if (aNode != null)
                {
                    BoxCollider aCol = child.GetComponent <BoxCollider>();
                    if (aCol != null)
                    {
                        aCol.enabled = false;
                    }
                }
            }
        }
    }