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)); } }
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)); } }
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; } } }
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); }
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); } }
/// <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(); } }
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(); } }
// 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(); } }
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(); } }
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(); } }
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(); } }
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); } }
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); } }
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); }
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; } } }
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); } }
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); } } }
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); } }
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); }
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--; } } } } } }
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); } } }
// 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); }
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); }
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)); } } } }
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; } } } } }