I will be doing more with it (when I have less homework), there are some things you can do thus far:
-drag the nodes around
-press x to make the nodes/controls disappear and reappear
-rolling over or dragging a node changes the colour of the edges/curved lines that will be modified
- [UPDATED] right click on node to remove it and immediately connected nodes if it has no further connections.
Randomly chooses amount of nodes.
In the code, in the function deleteNode(Node) in the loop, if you edit out the hasConnections function, the right click will crawl to all connected nodes from the node you select and delete them and their edges.
// forked from NME's Nodes Star 1 - randomly connected
// @author - NME a.k.a. Anthony Pace ap13mo@student.ocadu.ca - Toronto, ON, Canada
//Not done yet, in fact I just started this... doing this when I have a couple minutes here and there, because I have a ton of Homework.
package {
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.utils.Dictionary;
public class FlashTest1 extends Sprite {
public var hoverNodeColour:uint = 0x0000ff;
public var hoverEdgeColour:uint = 0x0000ff;
public var selectedEdgeColour:uint = 0xff0000;
public var unselectedEdgeColour:uint = 0x000000;
public var selectedNodeColour:uint = 0xff0080;
public var unselectedNodeColour:uint = 0x888888;
public var nodeRadius:uint = 4;
public var nodeLayer:Sprite;
public var edgeLayer:Sprite;
public function FlashTest1() {
Wonderfl.disable_capture ();//
init();
}
private function init():void{
removeEventListener(Event.ADDED_TO_STAGE, init);
var offset:Pt = new Pt(stage.stageWidth/2,stage.stageHeight/2);//used as centre of "circle" and as control point for bezier curves
var maxNodes:uint=20+Math.random()*220;//play around here and later in the equation to get nifty constructs
var radius:uint = nodeRadius;
var pix2:Number = Math.PI*2;
var r2d:Number = pix2/180;
var bigRad:uint = 200; //the radius (a.k.a. distance) for the nodes from the centre of the collective 'circle'
var r2dx180_nodes:Number = r2d*(180/maxNodes);
edgeLayer = new Sprite(); //Could have been a shape layer, but I want to draw edges individually
nodeLayer = new Sprite();
var nodes:Vector.<Node> = new Vector.<Node>;//I am only storing references here temporarily in this case, because there isn't a reason, at least right now, to store them this way after they've been generated
//make the nodes, and give them their coordinates
var node1:Node, node2:Node;
var radian:Number;
for(var i:uint=0;i!=maxNodes;i++){
node1 = new Node(i,radius,unselectedNodeColour);
radian = i*r2dx180_nodes;
node1.x = offset.x + Math.cos(radian)*(bigRad);
node1.y = offset.y + Math.sin(radian)*(bigRad);
nodeLayer.addChild(node1);
nodes.push(node1);
}
Edge.anchorPt = offset; //This is where I define the control point that will be static among all Edges
//if you connect this to the mouse, it yields intersting results graphically
//setup the connections between nodes, create the edges
var edge:Edge;
var j:uint,k:uint;
for(i=0;i!=maxNodes;i++){
node1 = nodes[i];
//this is where we establish the connections
k= (i+5*((7*i+5)))%maxNodes;//
node2 = nodes[k];
if(node2.connections[node1.id]===undefined && node2!=node1){
edge = makeEdge(node1,node2);
edge.drawEdge(unselectedEdgeColour);
edgeLayer.addChild(edge);
}
}
for(i=0;i!=maxNodes;i++){
node1 = nodes[i];
if(!hasConnections(node1)){//
deleteNode(node1);
}
}
nodes=null; //clean up to free memory
//make things visible
stage.addChild(edgeLayer);
stage.addChild(nodeLayer);
//these events allow the dragging of elements
nodeLayer.addEventListener(MouseEvent.MOUSE_OVER,mouseOverNLEH);
nodeLayer.addEventListener(MouseEvent.MOUSE_OUT,mouseOutNLEH);
nodeLayer.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownNLEH);
//when the mouse moves faster than image is rendered... listening in a parent layer
//or even globally for movement solves that problem, and it cuts down on the amount of listeners
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpSEH);
stage.addEventListener(MouseEvent.MOUSE_MOVE,mouseMoveSEH);
nodeLayer.addEventListener(MouseEvent.RIGHT_CLICK,mouseRightClickNLEH);
stage.addEventListener(MouseEvent.RIGHT_CLICK,function(me:MouseEvent):void{});
//Keyboard event to make nodes invisible
stage.addEventListener(KeyboardEvent.KEY_DOWN,
function(ke:KeyboardEvent):void{
if(ke.keyCode == 88){
if(nodeLayer.visible){
nodeLayer.visible = false;
stage.removeChild(nodeLayer);
}else {
nodeLayer.visible = true;
stage.addChild(nodeLayer);
}
}
}
);
}
/////////////////////////////////////////////////////////////////
//These variables and functions, are used for dragging the nodes
public var isDragging:Boolean = false;
public var draggedNode:Node; //if you don't know what type of class it will be, you can use Object instead
public function mouseOverNLEH(me:MouseEvent):void{
if (!draggedNode){
var node:Node = me.target as Node;
node.drawDot(nodeRadius,hoverNodeColour);
redrawConnectedEdges(node, hoverEdgeColour);//
}
me.updateAfterEvent();
}
public function mouseOutNLEH(me:MouseEvent):void{//
if (!isDragging){
var node:Node = me.target as Node;
node.drawDot(nodeRadius,unselectedNodeColour);
redrawConnectedEdges(node, unselectedEdgeColour);
draggedNode=null;
}
me.updateAfterEvent();
}
public function mouseDownNLEH(me:MouseEvent):void{
isDragging=true;
draggedNode = me.target as Node;
//this is where would redraw them with the move colour
draggedNode.drawDot(nodeRadius,selectedNodeColour);
redrawConnectedEdges(draggedNode, selectedEdgeColour);//
me.updateAfterEvent();
}
public function mouseUpSEH(me:MouseEvent):void{
if(isDragging){
isDragging=false;
//this is where we would set them back to normal
draggedNode.drawDot(nodeRadius,hoverNodeColour);
redrawConnectedEdges(draggedNode, hoverEdgeColour);
draggedNode=null;
}
me.updateAfterEvent();
}
public function mouseMoveSEH(me:MouseEvent):void{
if(me.buttonDown && isDragging){
draggedNode.x = me.stageX;
draggedNode.y = me.stageY;
redrawConnectedEdges(draggedNode, selectedEdgeColour);
}
me.updateAfterEvent();
}
//right click on a node, to start deleting nodes and their connected edges
public function mouseRightClickNLEH(me:MouseEvent):void{
deleteNode( me.target as Node);
me.updateAfterEvent();
}
//this function is only called when dragging node around
public function redrawConnectedEdges(node:Node,edgeColour:uint):void{//
for each(var edge:Edge in node.edges){
edge.drawEdge(edgeColour);
}
}
//this is called after the generation of the nodes, and connections are being made
public function makeEdge(node1:Node,node2:Node):Edge{
node1.connections[node2.id] = node2;
node2.connections[node1.id] = node1;
var edge:Edge = new Edge(node1,node2);
node1.edges[edge]=edge;
node2.edges[edge]=edge;
return edge;
}
///////////////////////////////////////
//functions required for deleting nodes
public function hasConnections(node:Node):Boolean{
var oc:uint = 0;
for each(var n:Node in node.connections){
oc++;
break;
}
return Boolean(oc);
}
public function deleteNode(node1:Node):void{
//first delete reference to other nodes, and edges
//then removed edges... but that will mean I need to be able to keep track of the edges
var node2:Node;
for each(var edge:Edge in node1.edges){
if(edge.node1 === node1){
node2 = edge.node2;
}else{
node2 = edge.node1;
}
delete node2.edges[edge]; //edge reference to current edge from connected node
delete node2.connections[node1.id] //connection reference to me from connected node
delete node1.connections[node2.id];//my connection reference to the connected node
if(!hasConnections(node2)){//
deleteNode(node2);
}
delete node1.edges[edge]; //primary node's reference to the current edge
edgeLayer.removeChild(edge);
}
nodeLayer.removeChild(node1);
node1 = null;
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.utils.Dictionary;
internal class Pt {
public var x:uint;
public var y:uint;
public function Pt(x:uint,y:uint){
this.x = x;
this.y = y;
}
}
internal class Node extends Sprite{
public var id:uint;
public var connections:Dictionary;//tells you the connections by node id
public var edges:Dictionary; //:Vector.<Edge>;
public function Node(id:uint,radius:uint=1,colour:uint=0){
this.connections = new Dictionary();
this.edges = new Dictionary();//Vector.<Edge>;
this.id=id;
drawDot(radius,colour);
}
public function drawDot(radius:uint=1,colour:uint=0):void{
//I could memoize the results, but I'm doing it this way for... I might do it later when I start playing around later
this.graphics.clear();
this.graphics.beginFill(colour);
this.graphics.drawCircle(0,0,radius);
this.cacheAsBitmap = true;
}
}
internal class Edge extends Sprite{
public var node1:Node;
public var node2:Node;
public static var anchorPt:Pt;
public function Edge (node1:Node,node2:Node){
this.node1 = node1;
this.node2 = node2;
}
public function drawEdge(colour:uint = 0x000000):void{
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(.25,colour);
g.moveTo(node1.x,node1.y);
g.curveTo(anchorPt.x,anchorPt.y,node2.x,node2.y);
}
}