--- a/src/hp/settings.py Wed Nov 14 16:35:12 2012 +0100
+++ b/src/hp/settings.py Wed Nov 14 17:26:06 2012 +0100
@@ -163,8 +163,8 @@
}
}
-LDT_DOMAIN = 'http://localhost'
-LDT_BASE_URL = LDT_DOMAIN + '/~ymh/hp_ldt/'
+LDT_DOMAIN = 'http://capsicum'
+LDT_BASE_URL = LDT_DOMAIN + '/pf/'
LDT_URL = LDT_BASE_URL + "ldtplatform/"
LDT_API_URL = LDT_URL + 'api/ldt/1.0/'
LDT_STATIC_URL = LDT_BASE_URL + "static/site/"
--- a/src/hp/static/hp/css/player.css Wed Nov 14 16:35:12 2012 +0100
+++ b/src/hp/static/hp/css/player.css Wed Nov 14 17:26:06 2012 +0100
@@ -11,39 +11,3 @@
.right-column h2 {
text-align: right;
}
-
-.related-video {
- width: 235px; float: left; margin-bottom: 10px;
-}
-
-.related-video:nth-child(even) {
- margin-left: 10px;
-}
-
-.related-video a {
- display: block; clear: both; text-decoration: none;
-}
-
-.related-video img {
- max-width: 120px; max-height: 90px; float: left;
-}
-
-.related-video h3, p {
- margin: 0 0 5px 125px;
-}
-
-.related-video h3 {
- font-size: 14px; font-weight: 600; color: #330099;
-}
-
-.related-video h3:hover {
- text-decoration: underline;
-}
-
-.related-video p {
- font-size: 12px;
-}
-
-.video-duration {
- color: #c00000;
-}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/constants.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,266 @@
+////////// CONSTANTS //////////
+static final int LABEL_LENGTH = 24;
+static final float GAP = 8;
+static final float sigma = 0.01;
+static final float FRAME = 24;
+static final float TICK = 1;//0.5f;
+static final float SPRING_LENGTH = 100;
+static final float SPRING_STRENGTH = 0.4; // 0.2;
+static final float SPRING_DAMPING = 0.4; // 0.2;
+static final float SPACER_STRENGTH = 2000;
+static final float DRAGFACTOR = 0.2; //0.2
+static final float REDUCE = 1;
+static final float MAX_DISTANCE = 600;
+static final float MIN_DISTANCE = 24;//6;
+static final float MAX_VELOCITY = 48;//20; //8;
+
+// mouse event
+static final int MOVED = 1,
+ DRAGGED = 2,
+ CLICKED = 3,
+ RELEASED = 4;
+// touch event
+static final int MOVE = 6,
+ START = 7,
+ END = 8;
+// motion
+static final int HALT = 11,
+ MOVING = 12,
+ DRAGGING = 13,
+ DRAG = 14,
+ UP = 15;
+// action
+static final int NOOP = 20,
+ CLICK = 21,
+ RELEASE = 22,
+ DOUBLECLICK = 23,
+ HOLDING = 24,
+ HOLDED = 25;
+// node menu
+static final int EXPND = 31,
+ ROOT = 32,
+ FIX = 33,
+ FREE = 34,
+ HIDE = 35,
+ INFO = 36,
+ NEWREL = 37,
+ NEWREL2 = 30,
+ SQUEEZE = 38,
+ TOPIC = 39;
+// application menu
+static final int FITALL = 41,
+ ALLFIX = 42,
+ ALLFREE = 43,
+ GROUPSHAPE = 44,
+ ALLSAVE = 45,
+ ALLRETRIEVE = 46,
+ NEWTOPIC = 47,
+ MODE = 48,
+ PEDIA = 49;
+// edge menu
+static final int HIDEEDGE = 51,
+ EDITEDGE = 52,
+ DELETEEDGE = 53;
+
+static final int AliceBlue = #F0F8FF;
+static final int AntiqueWhite = #FAEBD7;
+static final int Aqua = #00FFFF;
+static final int Aquamarine = #7FFFD4;
+static final int Azure = #F0FFFF;
+static final int Beige = #F5F5DC;
+static final int Bisque = #FFE4C4;
+static final int Black = #000000;
+static final int BlanchedAlmond = #FFEBCD;
+static final int Blue = #0000FF;
+static final int BlueViolet = #8A2BE2;
+static final int Brown = #A52A2A;
+static final int BurlyWood = #DEB887;
+static final int CadetBlue = #5F9EA0;
+static final int Chartreuse = #7FFF00;
+static final int Chocolate = #D2691E;
+static final int Coral = #FF7F50;
+static final int CornflowerBlue = #6495ED;
+static final int Cornsilk = #FFF8DC;
+static final int Crimson = #DC143C;
+static final int Cyan = #00FFFF;
+static final int DarkBlue = #00008B;
+static final int DarkCyan = #008B8B;
+static final int DarkGoldenRod = #B8860B;
+static final int DarkGray = #A9A9A9;
+static final int DarkGrey = #A9A9A9;
+static final int DarkGreen = #006400;
+static final int DarkKhaki = #BDB76B;
+static final int DarkMagenta = #8B008B;
+static final int DarkOliveGreen = #556B2F;
+static final int Darkorange = #FF8C00;
+static final int DarkOrchid = #9932CC;
+static final int DarkRed = #8B0000;
+static final int DarkSalmon = #E9967A;
+static final int DarkSeaGreen = #8FBC8F;
+static final int DarkSlateBlue = #483D8B;
+static final int DarkSlateGray = #2F4F4F;
+static final int DarkSlateGrey = #2F4F4F;
+static final int DarkTurquoise = #00CED1;
+static final int DarkViolet = #9400D3;
+static final int DeepPink = #FF1493;
+static final int DeepSkyBlue = #00BFFF;
+static final int DimGray = #696969;
+static final int DimGrey = #696969;
+static final int DodgerBlue = #1E90FF;
+static final int FireBrick = #B22222;
+static final int FloralWhite = #FFFAF0;
+static final int ForestGreen = #228B22;
+static final int Fuchsia = #FF00FF;
+static final int Gainsboro = #DCDCDC;
+static final int GhostWhite = #F8F8FF;
+static final int Gold = #FFD700;
+static final int GoldenRod = #DAA520;
+static final int Gray = #808080;
+static final int Grey = #808080;
+static final int Green = #008000;
+static final int GreenYellow = #ADFF2F;
+static final int HoneyDew = #F0FFF0;
+static final int HotPink = #FF69B4;
+static final int IndianRed = #CD5C5C;
+static final int Indigo = #4B0082;
+static final int Ivory = #FFFFF0;
+static final int Khaki = #F0E68C;
+static final int Lavender = #E6E6FA;
+static final int LavenderBlush = #FFF0F5;
+static final int LawnGreen = #7CFC00;
+static final int LemonChiffon = #FFFACD;
+static final int LightBlue = #ADD8E6;
+static final int LightCoral = #F08080;
+static final int LightCyan = #E0FFFF;
+static final int LightGoldenRodYellow = #FAFAD2;
+static final int LightGray = #D3D3D3;
+static final int LightGrey = #D3D3D3;
+static final int LightGreen = #90EE90;
+static final int LightPink = #FFB6C1;
+static final int LightSalmon = #FFA07A;
+static final int LightSeaGreen = #20B2AA;
+static final int LightSkyBlue = #87CEFA;
+static final int LightSlateGray = #778899;
+static final int LightSlateGrey = #778899;
+static final int LightSteelBlue = #B0C4DE;
+static final int LightYellow = #FFFFE0;
+static final int Lime = #00FF00;
+static final int LimeGreen = #32CD32;
+static final int Linen = #FAF0E6;
+static final int Magenta = #FF00FF;
+static final int Maroon = #800000;
+static final int MediumAquaMarine = #66CDAA;
+static final int MediumBlue = #0000CD;
+static final int MediumOrchid = #BA55D3;
+static final int MediumPurple = #9370D8;
+static final int MediumSeaGreen = #3CB371;
+static final int MediumSlateBlue = #7B68EE;
+static final int MediumSpringGreen = #00FA9A;
+static final int MediumTurquoise = #48D1CC;
+static final int MediumVioletRed = #C71585;
+static final int MidnightBlue = #191970;
+static final int MintCream = #F5FFFA;
+static final int MistyRose = #FFE4E1;
+static final int Moccasin = #FFE4B5;
+static final int NavajoWhite = #FFDEAD;
+static final int Navy = #000080;
+static final int OldLace = #FDF5E6;
+static final int Olive = #808000;
+static final int OliveDrab = #6B8E23;
+static final int Orange = #FFA500;
+static final int OrangeRed = #FF4500;
+static final int Orchid = #DA70D6;
+static final int PaleGoldenRod = #EEE8AA;
+static final int PaleGreen = #98FB98;
+static final int PaleTurquoise = #AFEEEE;
+static final int PaleVioletRed = #D87093;
+static final int PapayaWhip = #FFEFD5;
+static final int PeachPuff = #FFDAB9;
+static final int Peru = #CD853F;
+static final int Pink = #FFC0CB;
+static final int Plum = #DDA0DD;
+static final int PowderBlue = #B0E0E6;
+static final int Purple = #800080;
+static final int Red = #FF0000;
+static final int RosyBrown = #BC8F8F;
+static final int RoyalBlue = #4169E1;
+static final int SaddleBrown = #8B4513;
+static final int Salmon = #FA8072;
+static final int SandyBrown = #F4A460;
+static final int SeaGreen = #2E8B57;
+static final int SeaShell = #FFF5EE;
+static final int Sienna = #A0522D;
+static final int Silver = #C0C0C0;
+static final int SkyBlue = #87CEEB;
+static final int SlateBlue = #6A5ACD;
+static final int SlateGray = #708090;
+static final int SlateGrey = #708090;
+static final int Snow = #FFFAFA;
+static final int SpringGreen = #00FF7F;
+static final int SteelBlue = #4682B4;
+static final int Tan = #D2B48C;
+static final int Teal = #008080;
+static final int Thistle = #D8BFD8;
+static final int Tomato = #FF6347;
+static final int Turquoise = #40E0D0;
+static final int Violet = #EE82EE;
+static final int Wheat = #F5DEB3;
+static final int White = #FFFFFF;
+static final int WhiteSmoke = #F5F5F5;
+static final int Yellow = #FFFF00;
+static final int YellowGreen = #9ACD32;
+
+static final color nodeColor = LightYellow;
+static final color selectColor = Gold;
+static final color selectedColor = SpringGreen;
+static final color rootColor = Darkorange;
+static final color fixedColor = HotPink;
+static final color edgeColor = 0xFF80A0A0;
+
+////////// TO STRING ///////////////////////////////////////////////
+String toStr(int i) {
+ switch(i) {
+// Event
+ case MOVED: return "MOVED";
+ case DRAGGED: return "DRAGGED";
+ case CLICKED: return "CLICKED";
+ case RELEASED: return "RELEASED";
+ case START: return "START";
+ case MOVE: return "MOVE";
+ case END: return "END";
+// Motion
+ case HALT: return "HALT";
+ case MOVING: return "MOVING";
+ case DRAGGING: return "DRAGGING";
+ case DRAG: return "DRAG";
+// Action
+ case NOOP: return "NOOP";
+ case CLICK: return "CLICK";
+ case RELEASE: return "RELEASE";
+ case DOUBLECLICK: return "DOUBLECLICK";
+ case HOLDING: return "HOLDING";
+ case HOLDED: return "HOLDED";
+ default: return "";
+// menu
+ case EXPND: return "EXPAND";
+ case ROOT: return "ROOT";
+ case FIX: return "FIX";
+ case FREE: return "FREE";
+ case HIDE: return "HIDE";
+ case INFO: return "INFO";
+ case NEWREL: return "NEWREL";
+ case NEWREL2: return "NEWREL2";
+ case SQUEEZE: return "SQUEEZE";
+ case TOPIC: return "TOPIC";
+// apmenu
+ case FITALL: return "FITALL";
+ case ALLFIX: return "ALLFIX";
+ case ALLFREE: return "ALLFREE";
+ case GROUPSHAPE: return "GROUPSHAPE";
+ case ALLSAVE: return "ALLSAVE";
+ case ALLRETRIEVE: return "ALLRETRIEVE";
+ case NEWTOPIC: return "NEWTOPIC";
+ }
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/event.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,437 @@
+boolean isMouse=true;
+int mouse_event=0,
+ mouse_motion=HALT,
+ mouse_action=NOOP;
+int touch_event=0,
+ touch_motion=UP,
+ touch_action=NOOP;
+int touch_count;
+boolean is_down;
+boolean touchedH, touchedC, touchedD;
+float startH, startC, startD;
+float elapsedTimeHold, elapsedTimeClick, elapsedTimeDoubleClick;
+float holdX, holdY;
+
+////////// EVENT ACTION /////////////////////////////
+void doMove(float x, float y) {
+ event = "Move";
+ if (menu_active || apmenu_active || edgmenu_active) return;
+ adjustCoordinates(Math.round(x), Math.round(y));
+ pressStartX = pointX;
+ pressStartY = pointY;
+ doSelectEdge();
+ doSelectNode();
+}
+
+void doClick(float x, float y) {
+ event = "Click";
+ adjustCoordinates(Math.round(x), Math.round(y));
+ pressStartX = pointX;
+ pressStartY = pointY;
+ doSelectEdge();
+ doSelectNode();
+ if (mouseButton == RIGHT) {
+ if (selection != null && selected == null && !menu_active)
+ doBeginMenu();
+ else if (sel_edge != null && !edgmenu_active)
+ doBeginEdgMenu();
+ else if (selection == null && !apmenu_active)
+ doBeginApMenu();
+ }
+ else if (from_node == null && selection != null && selected == null) {
+ if (debug) println("doExpandNode");
+ doExpandNode(selection);
+ }
+ else if (from_node != null) {
+ if (debug) println("new_relation("+from_node.name+", "+selection.name+")");
+ String id = from_node.id;
+ String name = from_node.name;
+ String grp = from_node.grp;
+ String proj = from_node.proj;
+ if (grp==null) grp="";
+ String to_id, to_name, to_grp, to_proj;
+ if (selection != null) {
+ to_node = selection;
+ to_id = to_node.id;
+ to_name = to_node.name;
+ to_grp = to_node.grp;
+ to_proj = to_node.proj;
+ if (to_grp==null) to_grp="";
+ to_node = null;
+ }
+ else {
+ to_id = "";
+ to_name = "";
+ to_grp = "";
+ to_proj = "";
+ }
+ from_node = null;
+ if (debug) println("javascript.new_relation2("+id+", "+name+", "+grp+", "+proj+", "+to_id+", "+to_name+", "+to_grp+", "+to_proj+")");
+ javascript.new_relation(id, name, grp, proj, to_id, to_name, to_grp, to_proj);
+ }
+ else if (menu_active && selected != null) {
+ if (debug) println("doMenu " + nls(menu,ln) );
+ doMenu();
+ }
+ else if (edgmenu_active && sel_edge != null) {
+ doEdgMenu();
+ }
+ else if (apmenu_active) {
+ doApMenu();
+ }
+ dragging = false;
+}
+
+void doDoubleClick(float x, float y) {
+ event = "DoubleClick";
+ if (selection != null && selected == null) {
+ rootNode(selection);
+ }
+}
+
+void doHold(float x, float y) {
+ event = "Hold";
+ if (selection != null && selected == null) {
+ doBeginMenu();
+ }
+ else if (sel_edge != null) {
+ doBeginEdgMenu();
+ }
+ else if (selection == null) {
+ doBeginApMenu();
+ }
+}
+
+void doDrag(float x, float y) {
+ event = "Drag";
+ adjustCoordinates(Math.round(x), Math.round(y));
+ if (menu_active == false && apmenu_active == false) {
+ if (selection != null) {
+ doDragNode();
+ dragging = false;
+ }
+ else {
+ dragging = true;
+ }
+ }
+}
+
+void doReleased(float x, float y) {
+ event = "Released";
+ adjustCoordinates(Math.round(x), Math.round(y));
+ if (dragging) {
+ doUpdateNodePosition();
+ }
+ dragging = false;
+ menu = 0;
+ selection = null;
+ previous_selection = null;
+ //javascript.end_select();
+}
+
+////////// MOUSE EVENT DETECTION ///////////////////////////////////
+void mouseMoved() {
+ //if (debug) print("\tmouseMoved");
+ is_down = false;
+ if (!isMouse) return;
+ mouse_event = MOVED;
+ mouse_motion = MOVING;
+ doEvent(mouseX, mouseY);
+}
+
+void mouseDragged() {
+ //if (debug) print("\tmouseDragged");
+ is_down = true;
+ if (!isMouse) return;
+ if (mouse_action==HOLDED) { //Handling wrong dragging status after holding
+ //if (debug) print("\tMoved");
+ is_down = false;
+ mouse_event = MOVED;
+ mouse_motion = MOVING;
+ } else {
+ //if (debug) print("\tDragged");
+ mouse_event = DRAGGED;
+ mouse_motion = DRAGGING;
+ }
+ doEvent(mouseX, mouseY);
+}
+void mouseClicked() {
+ //if (debug) print("\nmouseClicked");
+ is_down = true;
+ if (!isMouse) return;
+ mouse_event = CLICKED;
+ doEvent(mouseX, mouseY);
+}
+void mouseReleased() {
+ //if (debug) print("\nmouseReleased");
+ is_down = false;
+ if (!isMouse) return;
+ mouse_event = RELEASED;
+ doEvent(mouseX, mouseY);
+}
+
+////////// MOUSE EVENT HANDLING ////////////////////////////
+void doEvent(float x, float y) {
+ //if (debug) print( "\ndoEvent event=" + toStr(mouse_event) + "\taction=" + toStr(mouse_action) + "\tmotion=" + toStr(mouse_motion) );
+ switch (mouse_event) {
+ case CLICKED:
+ //if (debug) print("\nCLICKED");
+ checkClickTimer(x, y);
+ checkDoubleClickTimer(x, y);
+ break;
+ case RELEASED:
+ //if (debug) print("\nRELEASED");
+ checkClickTimer(x, y);
+ if (mouse_motion == DRAGGING) { // TO DETECT RELEASE AFTER DRAGGINNG
+ mouse_action = RELEASE;
+ doReleased(x, y);
+ stopClickTimer();
+ stopDoubleClickTimer();
+ stopHoldTimer();
+ } else if (mouse_motion == MOVING) { // TO CATCH CLICK DUE TO NO CLICKED AFTER HOLDING
+ mouse_action = CLICK;
+ doClick(x, y);
+ stopClickTimer();
+ stopDoubleClickTimer();
+ stopHoldTimer();
+ }
+ break;
+ case MOVED:
+ //if (debug) print("\nMOVED");
+ mouse_motion = MOVING;
+ doMove(x, y);
+ stopClickTimer();
+ stopDoubleClickTimer();
+ stopHoldTimer();
+ break;
+ case DRAGGED:
+ //if (debug) print("\nDRAGGED");
+ mouse_motion = DRAGGING;
+ doDrag(x, y);
+ stopClickTimer();
+ stopDoubleClickTimer();
+ stopHoldTimer();
+ break;
+ default:
+ }
+}
+////////// TOUCH EVENT DETECTION ///////////////////////////////////
+// Following functions are used for iPad(iOS)
+
+void touchMove(TouchEvent touchEvent) { //Comment out while debugging. These routines are for iPad.
+ //if (debug) print("\ttouchMove");
+ isMouse=false;
+ is_down = true;
+ touch_event = MOVE;
+ // draw circles at where fingers touch
+ touch_count = touchEvent.touches.length;
+ for (int i = 0; i < touch_count; i++) {
+ int x = touchEvent.touches[i].offsetX;
+ int y = touchEvent.touches[i].offsetY;
+ fill(128,128,128);
+ ellipse(x, y, 10, 10);
+ }
+ if (touch_count > 1) {
+ currtXa = touchEvent.touches[0].offsetX;
+ currtYa = touchEvent.touches[0].offsetY;
+ currtXb = touchEvent.touches[1].offsetX;
+ currtYb = touchEvent.touches[1].offsetY;
+ currt_dist = Math.sqrt((currtXa - currtXb)*(currtXa - currtXb) + (currtYa - currtYb)*(currtYa - currtYb));
+ scl = currt_dist / start_dist;
+ zoom(scl);
+ javascript.setscale(scl);
+ }
+ if (touch_count==1) {
+ touchX = touchEvent.touches[0].offsetX;
+ touchY = touchEvent.touches[0].offsetY;
+ fill(128,64,64);
+ ellipse(touchX, touchY, 10, 10);
+ doTouch(touchX, touchY);
+ }
+}
+
+void touchEnd(TouchEvent touchEvent) {
+ //if (debug) print("\ttouchEnd");
+ touch_event = END;
+ isMouse=false;
+ is_down = false;
+ if (touch_count==1) {
+ doTouch(touchX, touchY);
+ }
+}
+
+void touchStart(TouchEvent touchEvent) {
+ //if (debug) print("\ttouchStart");
+ isMouse=false;
+ is_down = true;
+ // draw circles at where fingers touch
+ touch_count = touchEvent.touches.length;
+ for (int i = 0; i < touch_count; i++) {
+ int x = touchEvent.touches[i].offsetX;
+ int y = touchEvent.touches[i].offsetY;
+ fill(0,128,64);
+ ellipse(x, y, 10, 10);
+ }
+ if (touch_count > 1) {
+ startXa = touchEvent.touches[0].offsetX;
+ startYa = touchEvent.touches[0].offsetY;
+ startXb = touchEvent.touches[1].offsetX;
+ startYb = touchEvent.touches[1].offsetY;
+ start_dist = Math.sqrt((startXa - startXb)*(startXa - startXb) + (startYa - startYb)*(startYa - startYb));
+ }
+ touchX = touchEvent.touches[0].offsetX;
+ touchY = touchEvent.touches[0].offsetY;
+ fill(64,128,255);
+ ellipse(touchX, touchY, 10, 10);
+ touch_event = START;
+ doTouch(touchX, touchY);
+}
+
+////////// TOUCH EVENT HANDLING ////////////////////////////////
+void doTouch(float x, float y) {
+ //if (debug) print("\ndoTouch event=" + toStr(touch_event));
+ switch (touch_event) {
+ case START:
+ dragmode = !dragmode;
+ checkClickTimer(x, y);
+ checkDoubleClickTimer(x, y);
+ break;
+ case END:
+ mouse_motion = (mouse_motion==DRAGGING)? DRAG:UP;
+ checkClickTimer(x, y);
+ if (mouse_motion == DRAG) { // TO DETECT RELEASE AFTER DRAGGINNG
+ mouse_action = RELEASE;
+ doReleased(x, y);
+ }
+ stopClickTimer();
+ stopDoubleClickTimer();
+ stopHoldTimer();
+ break;
+ case MOVE:
+ if (dragmode && selection==null) {
+ mouse_motion = MOVING;
+ doMove(x, y);
+ }
+ else {
+ mouse_motion = DRAGGING;
+ doDrag(x, y);
+ }
+ stopClickTimer();
+ stopDoubleClickTimer();
+ stopHoldTimer();
+ break;
+ default:
+ }
+}
+
+////////// TIMER ///////////////////////////////////////////////
+void checkClickTimer(float x, float y) {
+ float current = millis()/1000F;
+ elapsedTimeClick = current - startC; // Get elapsed time in seconds
+ //if (debug) print("\n"+current+"\tCheck\tClick\ttouched="+touchedC+"\tstart="+startC+"\telapsed="+elapsedTimeClick);
+ if ( !touchedC ) { // IF Not touched
+ startClickTimer();
+ }
+ else if ( touchedC ) {
+ if ( elapsedTimeClick < 1 ) {
+ //if (debug) print("\nCLICK");
+ mouse_motion = HALT;
+ mouse_action = CLICK;
+ if (isMouse) doClick(mouseX, mouseY);
+ else doClick(touchX, touchY);
+ stopClickTimer();
+ }
+ }
+}
+void startClickTimer() {
+ float current = millis()/1000F;
+ touchedC = true;
+ startC = millis()/1000F; // Get current time
+ elapsedTimeClick = 0;
+ //if (debug) print("\n"+current+"\tStart\tClick");
+}
+
+void stopClickTimer() {
+ touchedC = false;
+ elapsedTimeClick = 0;
+}
+
+void checkDoubleClickTimer(float x, float y) { // This routine works only under PC Firefox. Other environment doesn't work.
+ float current = millis()/1000F;
+ elapsedTimeDoubleClick = current - startD; // Get elapsed time in seconds
+ //if (debug) print("\n"+current+"\tCheck\tDoubleClick\ttouched="+touchedD+"\tstart="+startD+"\telapsed="+elapsedTimeDoubleClick);
+ if ( !touchedD ) { // IF Not touched
+ startDoubleClickTimer();
+ }
+ else if ( touchedD ) {
+ if ( elapsedTimeDoubleClick < 1 ) {
+ //if (debug) print("\nDOUBLE CLICK");
+ mouse_motion = HALT;
+ mouse_action = DOUBLECLICK;
+ if (isMouse) doDoubleClick(mouseX, mouseY);
+ else doDoubleClick(touchX, touchY);
+ stopDoubleClickTimer();
+ }
+ }
+}
+
+void startDoubleClickTimer() {
+ float current = millis()/1000F;
+ touchedD = true;
+ startD = millis()/1000F; // Get current time
+ elapsedTimeDoubleClick = 0;
+ //if (debug) print("\n"+current+"\tStart\tDoubleClick");
+}
+
+void stopDoubleClickTimer() { // ditto.
+ touchedD = false;
+ elapsedTimeDoubleClick = 0;
+}
+
+void checkHoldTimer() {
+ float current = millis()/1000F;
+ elapsedTimeHold = current - startH; // Get elapsed time in seconds
+ /*if (Math.round(elapsedTimeHold*10)%10==0)
+ if (debug) print("\n"+current+"\tCheck\tHold\ttouched="+touchedH+"\tstart="+startH+"\telapsed="+elapsedTimeHold);
+ */
+ if ((isMouse && mousePressed && !(mouse_motion==MOVING && mouse_action==HOLDED))
+ || (!isMouse && is_down)) {
+ if ( !touchedH ) { // IF Not touched
+ startHoldTimer();
+ holdX = (isMouse)? mouseX:touchX;
+ holdY = (isMouse)? mouseY:touchY;
+ }
+ else if ( touchedH ) {
+ float currentX = (isMouse)? mouseX:touchX;
+ float currentY = (isMouse)? mouseY:touchY;
+ float dist2 = (currentX - holdX)*(currentX - holdX) + (currentY - holdY)*(currentY - holdY);
+ if ( dist2 < 16 && elapsedTimeHold > 0.5 ) {
+ //if (debug) print("\nHOLD");
+ mouse_motion = HALT;
+ mouse_action = HOLDING;
+ if (isMouse) doHold(mouseX, mouseY);
+ else doHold(touchX, touchY);
+ mouse_action = HOLDED;
+ stopHoldTimer();
+ }
+ }
+ }
+ else {
+ stopHoldTimer();
+ }
+}
+
+void startHoldTimer() {
+ touchedH = true;
+ float current = millis()/1000F;
+ startH = current; // Get current time
+ elapsedTimeHold = 0;
+ //if (debug) print("\n"+current+"\tStart\tHold");
+}
+
+void stopHoldTimer() {
+ touchedH = false;
+ elapsedTimeHold = 0;
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/initialdata.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,10 @@
+//////// LOAD DATA ///////////////////////////////////////////////////////////
+void loadData() {
+
+}
+
+void setNodeShapes() {
+
+}
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/javascript.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,27 @@
+//////// JAVASCRIPT //////////////////////////////////////////////////////////
+interface JavaScript {
+ void adjacentnodes(String id, String pj, String adj, String bd);
+ void selectnode(String id, String pj);
+ void selectedge(String s);
+ void topicnode(String s);
+ void setscale(float s);
+ void group_shapes();
+ void allbackup(String s);
+ void allretrieve(String s);
+ void new_topic();
+ void pedia();
+ void set_mode(String lang, boolean d, boolean p, boolean u, String b, boolean ed);
+ void countassoc(String id, String pj);
+ void new_relation(String id, String name, String grp, String proj, String to_id, String to_name, String to_grp, String to_proj);
+ void new_select(String id, String proj);
+ void startexpand();
+ void endexpand();
+ void username(String uid);
+}
+
+void bindJavascript(JavaScript js) {
+ javascript = js;
+}
+
+JavaScript javascript;
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/menu.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,646 @@
+//////// USER INTERFACE /////////////////////////////////////////////////
+void adjustCoordinates(int x, int y) {
+ scrnX = Math.round( x - WORLD_SIZE_W/2 );
+ scrnY = Math.round( y - WORLD_SIZE_H/2 );
+ pointX = Math.round( scrnX/factor );
+ pointY = Math.round( scrnY/factor );
+}
+
+void doSelectNode() {
+ //func = "select node";
+ Iterator it = nodes.entrySet().iterator();
+ selection = null;
+ while (it.hasNext ()) {
+ Map.Entry e = (Map.Entry)it.next();
+ String k = (String) e.getKey();
+ Node n = (Node) e.getValue();
+ //if (debug) print(n.name + "\t");
+ if ( (! "MARK".equals(n.shape)) && pointerOverRect(n.x, n.y, n.w, n.h) ||
+ "MARK".equals(n.shape) && pointerOverRect(n.x + n.w/factor/2, n.y, n.w, n.h) ) {
+ //func = "select node";
+ sel_edge = null;
+ selection = n;
+ if ( selection == null ||
+ previous_selection == null ||
+ ! previous_selection.id.equals(selection.id) ) {
+ if (nodetrace) println("NEW SELECTION "+ selection.name);
+ previous_selection = selection;
+ if (javascript != null) javascript.new_select(selection.id, selection.proj);
+ }
+ //sel_edge = null;
+ selectNode(selection);
+ //selected = null;
+ }
+ }
+}
+
+void doSelectEdge() {
+ //func = "select edge";
+ if (selection == null) {
+ Iterator it = edges.entrySet().iterator();
+ sel_edge = null;
+ while (it.hasNext ()) {
+ Map.Entry ie = (Map.Entry)it.next();
+ String k = (String) ie.getKey();
+ Edge e = (Edge) ie.getValue();
+ if (pointerOverLine(e.from, e.to) && e.dup==0) {
+ //func = "select edge";
+ //if (debug) println("select edge line "+e.asc_id);
+ sel_edge = e;
+ }
+ else if (pointerOverArc( e )) {
+ //func = "select edge";
+ //if (debug) println("select edge arc "+e.asc_id);
+ sel_edge = e;
+ }
+ }
+ }
+}
+
+void move_vizgroup(int dx, int dy) {
+ if (vizgroup!=null){
+ for (int i = 0; i < vizgroup.size(); i++) {
+ Node n = (Node) vizgroup.get(i);
+ int originalX = n.x;
+ int originalY = n.y;
+ n.position(originalX + dx, originalY + dy);
+ }
+ }
+}
+
+void doUpdateNodePosition() {
+ //func = "update node position";
+ Iterator it = nodes.entrySet().iterator();
+ while (it.hasNext ()) {
+ Map.Entry e = (Map.Entry)it.next();
+ String k = (String) e.getKey();
+ Node n = (Node) e.getValue();
+ n.x += pointX - pressStartX;
+ n.y += pointY - pressStartY;
+ n.position(n.x, n.y);
+ }
+}
+
+boolean pointerOverRect( float x, float y, float w, float h ) {
+ int pX, pY;
+ if (!isMouse) {
+ pX = touchX;
+ pY = touchY;
+ }
+ else {
+ pX = mouseX;
+ pY = mouseY;
+ }
+ adjustCoordinates(pX, pY);
+ boolean isOver = false;
+ if ( pointX >= x - w/factor/2 && pointX <= x + w/factor/2 &&
+ pointY >= y - h/factor/2 && pointY <= y + h/factor/2 ) {
+ isOver = true;
+ }
+ return isOver;
+}
+
+boolean pointerOverLine( Node from, Node to ) {
+ int pX, pY;
+ if (!isMouse) {
+ pX = touchX;
+ pY = touchY;
+ }
+ else {
+ pX = mouseX;
+ pY = mouseY;
+ }
+ adjustCoordinates( pX, pY );
+ boolean isOver = false;
+ Vector2D pFrom = new Vector2D(from.x, from.y);
+ Vector2D pTo = new Vector2D(to.x, to.y);
+ Vector2D pointer = new Vector2D(pointX, pointY);
+ float distance = pointer.distance(pFrom, pTo);
+ if (distance < 2) {
+ isOver = true;
+ }
+ return isOver;
+}
+
+boolean pointerOverArc( Edge e ) {
+ //if (e.dup==0) return false;
+ boolean isOver = false;
+ int ptX, ptY;
+ float sigma = 0.1;
+ if (!isMouse) {
+ ptX = touchX;
+ ptY = touchY;
+ }
+ else {
+ ptX = mouseX;
+ ptY = mouseY;
+ }
+ adjustCoordinates( ptX, ptY );
+ // based on screen coordination. center(0,0) rightbottom(WoORLD_SIZE_W/2, WORLD_SIZE_H/2)
+ if (e.from==null || e.to==null || e.centr==null) return false;
+ fromX = factor * (e.from.x);
+ fromY = factor * (e.from.y);
+ toX = factor * (e.to.x);
+ toY = factor * (e.to.y);
+ cX = factor * (e.centr.x);
+ cY = factor * (e.centr.y);
+ PVector P = new PVector(scrnX, scrnY);
+ PVector Cntr = new PVector(cX, cY);
+ if (P != null) phai = e.theta(Cntr, P);
+ PVector P1 = new PVector(fromX, fromY);
+ if (P1 != null) theta1 = e.theta(Cntr, P1);
+ PVector P2 = new PVector(toX, toY);
+ if (P2 != null) theta2 = e.theta(Cntr, P2);
+ PVector T = PVector.sub(P, Cntr);
+ float D = dist(P1.x, P1.y, Cntr.x, Cntr.y);
+ T.normalize();
+ T.mult(D);
+ T.add(Cntr);
+ T.sub(P);
+ float w = 0;
+ if (sqrt(sq(T.x) + sq(T.y)) < 3) {
+ if (edgetrace) println("initial theta1="+round(degrees(theta1))+" phai="+round(degrees(phai))+" theta2="+round(degrees(theta2)));
+ if (-TWO_PI<theta1 && theta1<0) theta1 += TWO_PI;
+ if (-TWO_PI<theta2 && theta2<0) theta2 += TWO_PI;
+ if (-TWO_PI<phai && phai<0) phai += TWO_PI;
+ float df = theta2 - theta1;
+ if (-TWO_PI<df && df<0) df += TWO_PI;
+ if (df > PI) {
+ w = theta2;
+ theta2 = theta1;
+ theta1 = w;
+ }
+ if((( -TWO_PI < phai-theta1 && phai-theta1 < -PI) ||
+ ( 0 < phai-theta1 && phai-theta1 < PI)) &&
+ (( -TWO_PI < theta2-phai && theta2-phai < -PI) ||
+ ( 0 < theta2-phai && theta2-phai < PI)))
+ isOver = true;
+ }
+ return isOver;
+}
+
+void doBeginMenu() {
+ //func = "begin menu";
+ menu_active = true;
+ menuX = scrnX;
+ menuY = scrnY;
+ selected = selection;
+ selection = null;
+ previous_selection = null;
+ //javascript.end_select();
+}
+
+void doMenu() {
+ if (debug) println( "menu=" + nls(menu,ln) );
+ switch (menu) {
+ case ROOT:
+ rootNode(selected);
+ break;
+ case HIDE:
+ if (!selected.root) hideNode(selected);
+ break;
+ case INFO:
+ infoNode(selected);
+ break;
+ case NEWREL:
+ newRelation(selected);
+ break;
+ case SQUEEZE:
+ squeezeNode(selected);
+ }
+ menu_active = false;
+ selected = null;
+ dragging = false;
+}
+
+void doBeginEdgMenu() {
+ //func = "begin edge menu";
+ edgmenu_active = true;
+ menuX = scrnX;
+ menuY = scrnY;
+ selected_edge = sel_edge;
+}
+
+void doEdgMenu() {
+ if (edgetrace) println( "edge menu=" + nls(edgmenu,ln) );
+ switch (edgmenu) {
+ case HIDEEDGE:
+ hideEdge(sel_edge);
+ break;
+ case EDITEDGE:
+ infoEdge(sel_edge);
+ }
+ edgmenu_active = false;
+ sel_edge = null;
+ dragging = false;
+}
+
+void doBeginApMenu() {
+ //func = "begin ap menu";
+ apmenu_active = true;
+ menuX = scrnX;
+ menuY = scrnY;
+}
+
+void doApMenu() {
+ //func = "execute ap menu";
+ switch (apmenu) {
+ case FITALL:
+ fitAll();
+ break;
+ case ALLFIX:
+ allFix();
+ break;
+ case ALLFREE:
+ allFree();
+ break;
+ case GROUPSHAPE:
+ groupShape();
+ break;
+ case ALLSAVE:
+ allSave();
+ break;
+ case ALLRETRIEVE:
+ allRetrieve();
+ break;
+ case NEWTOPIC:
+ newTopic();
+ break;
+ case PEDIA:
+ pedia();
+ break;
+ case MODE:
+ setMode();
+ }
+ apmenu_active = false;
+}
+
+void setMode() {
+ if (debug) println("setMode");
+ if (javascript!=null) {
+ String lang = ln;
+ boolean d = debug,
+ p = personal,
+ u = showusername,
+ ed = editmode;
+ String b = both;
+ javascript.set_mode( lang, d, p, u, b, ed );
+ }
+}
+
+void saveMode(String lang, String d, String p, String u, String b, String ed){
+ if (debug) println("\t"+lang+" "+d+" "+p+" "+u+" "+b+" "+ed);
+ if (lang!=null) ln = lang;
+ if ("debug".equals(d)) {
+ debug=true;
+ nodetrace=true;
+ edgetrace=true;
+ }
+ else {
+ debug=false;
+ nodetrace=false;
+ edgetrace=false;
+ }
+ if ("personal".equals(p))
+ personal=true; else personal=false;
+ if ("showusername".equals(u))
+ showusername=true; else showusername=false;
+ if ("edit".equals(ed)) {
+ editmode=true;
+ }
+ else {
+ editmode=false;
+ }
+ both = b;
+ if (debug) println("\tdebug="+debug+" personal="+personal+" showusername="+showusername+" both="+both+" editmode="+editmode);
+}
+
+void doExpandNode(Node node) {
+// funcTrace("Expandng...");
+ boolean isfree=true;
+ if(node.fixed) isfree=false;
+ node.fix();
+ expandNode(node, both); // "" means one direction "both" means bidirection expansion
+ selection = null;
+ previous_selection = null;
+}
+
+void doFixNode(Node node) {
+ if (debug) println("doFixNode " + node.name);
+ //func = "fix node";
+ node.fix();
+ selection = null;
+ previous_selection = null;
+}
+
+void doFreeNode(Node node) {
+ if (debug) println("doFreeNode " + node.name);
+ //func = "free node";
+ node.free();
+ selection = null;
+ previous_selection = null;
+}
+
+void doDragNode() {
+ //func = "drag node";
+ draggingnode = true;
+ int dx = pointX - selection.x;
+ int dy = pointY - selection.y;
+ selection.fix();
+ //if (debug) println("mouseDragged " + selection.name + "\t(" + originalX + ",\t" + originalY + ") to (" + pointX + ",\t" + pointY + ")");
+ if (selection.vizgroup == null) {
+ selection.position(pointX, pointY);
+ } else {
+ move_vizgroup(dx, dy);
+ }
+ damper = 1.0;
+}
+
+//////// MENU ///////////////////////////////////////////////////////////
+boolean isOverMenu(float x, float y, int w, int h) {
+ int pX, pY;
+ if (!isMouse) {
+ pX = touchX;
+ pY = touchY;
+ }
+ else {
+ pX = mouseX;
+ pY = mouseY;
+ }
+ adjustCoordinates(pX, pY);
+ if ((scrnX) >= x - w/2 && (scrnX) <= x + w/2 &&
+ (scrnY) >= y - h/2 && (scrnY) <= y + h/2) {
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+Vector2D adjustMenuPosition(int x, int y, int w, int h, int rows) {
+ float WORLD_HALF_SIZE_W = (WORLD_SIZE_W - w)/2;
+ float WORLD_HALF_SIZE_H = (WORLD_SIZE_H - h)/2;
+ float new_x = x;
+ float new_y = y;
+ if ( x < -WORLD_HALF_SIZE_W ) new_x = -WORLD_HALF_SIZE_W;
+ if ( x > WORLD_HALF_SIZE_W ) new_x = WORLD_HALF_SIZE_W;
+ if ( y < -WORLD_HALF_SIZE_H ) new_y = -WORLD_HALF_SIZE_H;
+ if ( y > WORLD_HALF_SIZE_H - rows * h ) new_y = WORLD_HALF_SIZE_H - rows * h;
+ Vector2D newPosition = new Vector2D(new_x, new_y);
+ return newPosition;
+}
+
+void showMenu() {
+ stroke(Silver);
+ strokeWeight(0.1);
+ int w = 100;
+ int h = 25;
+ Vector2D menuPosition;
+ float x0, y0;
+ if (editmode) {
+ menuPosition = adjustMenuPosition( menuX, menuY, w, h, 5);
+ x0 = menuPosition.x;
+ y0 = menuPosition.y;
+ int i = 0;
+ menuItem(x0, y0 + h*i++, w, h, nls(INFO,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(ROOT,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(SQUEEZE,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(HIDE,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(NEWREL,ln) );
+ if (isOverMenu(x0, y0, w, h)) {
+ menuHighlite( x0, y0, w, h, nls(INFO,ln) ); menu = INFO; }
+ else if (isOverMenu(x0, y0 + h, w, h)) {
+ menuHighlite( x0, y0 + h, w, h, nls(ROOT,ln) ); menu = ROOT; }
+ else if (isOverMenu(x0, y0 + h*2, w, h)) {
+ menuHighlite( x0, y0 + h*2, w, h, nls(SQUEEZE,ln) ); menu = SQUEEZE; }
+ else if (isOverMenu(x0, y0 + h*3, w, h)) {
+ menuHighlite( x0, y0 + h*3, w, h, nls(HIDE,ln) ); menu = HIDE; }
+ else if (isOverMenu(x0, y0 + h*4, w, h)) {
+ menuHighlite( x0, y0 + h*4, w, h, nls(NEWREL,ln) ); menu = NEWREL; }
+ else {
+ menu = 0; menu_active = false; selected = null; }
+ }
+ else {
+ menuPosition = adjustMenuPosition( menuX, menuY, w, h, 2);
+ x0 = menuPosition.x;
+ y0 = menuPosition.y;
+ int i = 0;
+ menuItem(x0, y0 + h*i++, w, h, nls(INFO,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(ROOT,ln) );
+ if (isOverMenu( x0, y0, w, h)) {
+ menuHighlite( x0, y0, w, h, nls(INFO,ln) ); menu = INFO; }
+ else if (isOverMenu(x0, y0 + h*1, w, h)) {
+ menuHighlite( x0, y0 + h*1, w, h, nls(ROOT,ln) ); menu = ROOT; }
+ else {
+ menu = 0; menu_active = false; selected = null; }
+ }
+}
+
+void showEdgMenu() {
+ if (menu_active || apmenu_active) return;
+ stroke(Silver);
+ strokeWeight(0.1);
+ int w = 100;
+ int h = 25;
+ Vector2D menuPosition;
+ float x0, y0;
+ if (editmode) {
+ menuPosition = adjustMenuPosition( menuX, menuY, w, h, 2 );
+ x0 = menuPosition.x;
+ y0 = menuPosition.y;
+ menuItem(x0, y0, w, h, nls(EDITEDGE,ln) );
+ //menuItem(x0, y0 + h, w, h, nls(HIDEEDGE,ln) );
+ if (isOverMenu( x0, y0, w, h)) {
+ menuHighlite( x0, y0, w, h, nls(EDITEDGE,ln) ); edgmenu = EDITEDGE; }
+ /*
+ else if (isOverMenu(x0, y0 + h, w, h)) {
+ menuHighlite( x0, y0 + h, w, h, nls(HIDEEDGE,ln) ); edgmenu = HIDEEDGE; }
+ */
+ else {
+ edgmenu = 0; edgmenu_active = false; selected_edge = null;
+ }
+ }
+}
+
+void showApMenu() {
+ if (menu_active) return;
+ stroke(Silver);
+ strokeWeight(0.1);
+ int w = 100;
+ int h = 25;
+ Vector2D menuPosition;
+ float x0, y0;
+ if (editmode) {
+ menuPosition = adjustMenuPosition( menuX, menuY, w, h, 9 );
+ x0 = menuPosition.x;
+ y0 = menuPosition.y;
+ int i = 0;
+ menuItem(x0, y0 + h*i++, w, h, nls(FITALL,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(NEWTOPIC,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(PEDIA,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(ALLFREE,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(ALLFIX,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(GROUPSHAPE,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(ALLSAVE,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(ALLRETRIEVE,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(MODE,ln) );
+ if (isOverMenu( x0, y0 + h*0, w, h)) {
+ menuHighlite( x0, y0 + h*0, w, h, nls(FITALL,ln) ); apmenu = FITALL; }
+ else if (isOverMenu(x0, y0 + h*1, w, h)) {
+ menuHighlite( x0, y0 + h*1, w, h, nls(NEWTOPIC,ln) ); apmenu = NEWTOPIC; }
+ else if (isOverMenu(x0, y0 + h*2, w, h)) {
+ menuHighlite( x0, y0 + h*2, w, h, nls(PEDIA,ln) ); apmenu = PEDIA; }
+ else if (isOverMenu(x0, y0 + h*3, w, h)) {
+ menuHighlite( x0, y0 + h*3, w, h, nls(ALLFREE,ln) ); apmenu = ALLFREE; }
+ else if (isOverMenu(x0, y0 + h*4, w, h)) {
+ menuHighlite( x0, y0 + h*4, w, h, nls(ALLFIX,ln) ); apmenu = ALLFIX; }
+ else if (isOverMenu(x0, y0 + h*5, w, h)) {
+ menuHighlite( x0, y0 + h*5, w, h, nls(GROUPSHAPE,ln) ); apmenu = GROUPSHAPE; }
+ else if (isOverMenu(x0, y0 + h*6, w, h)) {
+ menuHighlite( x0, y0 + h*6, w, h, nls(ALLSAVE,ln) ); apmenu = ALLSAVE; }
+ else if (isOverMenu(x0, y0 + h*7, w, h)) {
+ menuHighlite( x0, y0 + h*7, w, h, nls(ALLRETRIEVE,ln)); apmenu = ALLRETRIEVE; }
+ else if (isOverMenu(x0, y0 + h*8, w, h)) {
+ menuHighlite( x0, y0 + h*8, w, h, nls(MODE,ln)); apmenu = MODE; }
+ else {
+ apmenu = 0; apmenu_active = false; }
+ }
+ else {
+ menuPosition = adjustMenuPosition( menuX, menuY, w, h, 3 );
+ x0 = menuPosition.x;
+ y0 = menuPosition.y;
+ int i = 0;
+ menuItem(x0, y0 + h*i++, w, h, nls(FITALL,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(PEDIA,ln) );
+ menuItem(x0, y0 + h*i++, w, h, nls(MODE,ln) );
+ if (isOverMenu( x0, y0 + h*0, w, h)) {
+ menuHighlite( x0, y0 + h*0, w, h, nls(FITALL,ln) ); apmenu = FITALL; }
+ else if (isOverMenu(x0, y0 + h*1, w, h)) {
+ menuHighlite( x0, y0 + h*1, w, h, nls(PEDIA,ln) ); apmenu = PEDIA; }
+ else if (isOverMenu(x0, y0 + h*2, w, h)) {
+ menuHighlite( x0, y0 + h*2, w, h, nls(MODE,ln)); apmenu = MODE; }
+ else {
+ apmenu = 0; apmenu_active = false; }
+ }
+}
+
+void menuItem(float x, float y, int w, int h, String name) {
+ fill(White);
+ rectMode(CENTER);
+ rect(x, y, w, h);
+ fill(0);
+ textAlign(CENTER, CENTER);
+ textSize(12);
+ text(name, x, y);
+}
+
+void menuHighlite(float x, float y, int w, int h, String name) {
+ fill(192);
+ rectMode(CENTER);
+ rect(x, y, w, h);
+ fill(White);
+ textAlign(CENTER, CENTER);
+ textSize(12);
+ text(name, x, y);
+}
+
+void fitAll() {
+ //func = "fit all";
+ float minX=width/2, maxX=-width/2, minY=height/2, maxY=-height/2;
+ float area_width, area_height, area_centerX, area_centerY;
+ selection = null;
+ previous_selection = null;
+ //javascript.end_select();
+ Iterator it = nodes.entrySet().iterator();
+ while (it.hasNext ()) {
+ Map.Entry e = (Map.Entry)it.next();
+ String k = (String) e.getKey();
+ Node n = (Node) e.getValue();
+ if (n.x < minX) minX = n.x;
+ if (n.x > maxX) maxX = n.x;
+ if (n.y < minY) minY = n.y;
+ if (n.y > maxY) maxY = n.y;
+ }
+ area_width = maxX - minX;
+ area_height = maxY - minY;
+ area_centerX = minX + area_width/2;
+ area_centerY = minY + area_height/2;
+ //if (debug) print("width=" + width + "\theight=" + height + "\tX\tmin=" + minX + "\tmax=" + maxX + "\tY\tmin=" + minY + "\tmax=" + maxY + "\n");
+ //if (debug) print("Area\twidth=" + area_width + "\theight=" + area_height + "\tcentr\tx=" + area_centerX + "\ty=" + area_centerY + "\n");
+
+ Iterator it2 = nodes.entrySet().iterator();
+ while (it2.hasNext ()) {
+ Map.Entry e = (Map.Entry)it2.next();
+ String k = (String) e.getKey();
+ Node n = (Node) e.getValue();
+ n.x -= area_centerX;
+ n.y -= area_centerY;
+ n.position(n.x, n.y);
+ }
+ pressStartX = 0;
+ pressStartY = 0;
+ float sw = width/area_width, sh = height/area_height;
+ float smin = (sw<sh)? sw:sh;
+ float smax = (sw<sh)? sh:sw;
+ scl = smin;
+ if (scl > 4) scl = 3.2;
+ else scl *= 0.8;
+ if (debug) print("scl="+scl+"\tmin="+smin+"\tmax="+smax+"\n");
+ zoom(scl);
+ if (javascript != null) javascript.setscale(scl);
+}
+
+String nls(int i, String ln) {
+ if (ln.equals("ja")){
+ switch(i) {
+ // menu
+ case EXPND: return "展開";
+ case ROOT: return "中心ノード";
+ case HIDE: return "非表示";
+ case INFO: return "情報";
+ case NEWREL: return "関係定義";
+ case SQUEEZE: return "折りたたみ";
+ // apmenu
+ case FITALL: return "全体表示";
+ case ALLFIX: return "全粘着";
+ case ALLFREE: return "全開放";
+ case GROUPSHAPE: return "グループの形";
+ case ALLSAVE: return "退避";
+ case ALLRETRIEVE: return "回復";
+ case NEWTOPIC: return "新規トピック";
+ case MODE: return "実行モード";
+ case PEDIA: return "世界大百科事典";
+ // edgemenu
+ case HIDEEDGE: return "非表示";
+ case EDITEDGE: return "情報";
+ case DELETEEDGE: return "削除";
+ }
+ }
+ else {
+ switch(i) {
+ // menu
+ case EXPND: return "EXPAND";
+ case ROOT: return "ROOT";
+ case HIDE: return "HIDE";
+ case INFO: return "INFO";
+ case NEWREL: return "NEWREL";
+ case SQUEEZE: return "SQUEEZE";
+ // apmenu
+ case FITALL: return "FIT ALL";
+ case ALLFIX: return "ALL FIX";
+ case ALLFREE: return "ALL FREE";
+ case GROUPSHAPE: return "GROUP SHAPE";
+ case ALLSAVE: return "SAVE";
+ case ALLRETRIEVE: return "RETRIEVE";
+ case NEWTOPIC: return "NEW TOPIC";
+ case MODE: return "MODE";
+ case PEDIA: return "ENCYCLOPEDIA";
+ // edgemenu
+ case HIDEEDGE: return "HIDE EDGE";
+ case EDITEDGE: return "EDGE INFO";
+ case DELETEEDGE: return "DELETE EDGE";
+ }
+ }
+ return null;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/model.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,2058 @@
+HashMap<String, UserColor> usercolors = new HashMap<String, UserColor>();
+HashMap<String, Node> nodes = new HashMap<String, Node>();
+HashMap<String, Edge> edges = new HashMap<String, Edge>();
+HashMap<String, NodeShape> nodeshapes = new HashMap<String, NodeShape>();
+HashMap<String, EdgeShape> edgeshapes = new HashMap<String, EdgeShape>();
+HashMap<String, Thumb> thumbs = new HashMap<String, Thumb>();
+HashMap<String, String> connected_edges = new HashMap<String, String>();
+HashMap<String, ImageMap> imageMaps = new HashMap<String, ImageMap>();
+ArrayList<Node> vizgroup = new ArrayList<Node>();
+PImage img;
+int bgColor = White;
+int u_clr; //user color
+
+// ADDED BY IRI TO ACCESS NODES AND EDGES FROM JS
+
+HashMap getNodes() {
+ return nodes;
+}
+
+HashMap getEdges() {
+ return edges;
+}
+
+//////// SAVE & LOAD NODES, EDGED ////////////////////////////////////////////
+void allSave() {
+ String proj, asc_id, a_proj, id, from_proj, name, grp, to_id, to_proj, r_name, r_from, r_to;
+ boolean root, fixed;
+ int x, y, assoc;
+ Node node;
+ Edge edge;
+ String root_str = "";
+ Iterator it = nodes.entrySet().iterator();
+ while (it.hasNext ()) {
+ Map.Entry e = (Map.Entry)it.next();
+ String k = (String) e.getKey();
+ node = (Node) e.getValue();
+ if (node!=null) {
+ id = node.id;
+ proj = node.proj;
+ name = node.name;
+ grp = node.grp;
+ assoc = node.assoc;
+ x = node.x;
+ y = node.y;
+ root = node.root;
+ fixed = node.fixed;
+ if (root)
+ root_str = "\"root\":[{ \"id\":\"" + id + "\", \"proj\":\""+ proj + "\", "
+ + "\"name\":\""+ name + "\", \"grp\":\""+ grp + "\", "
+ + "\"assoc\":" + assoc + ", \"x\":" + x + ", \"y\":" + y +" }]";
+ }
+ }
+ //if (debug) println(root_str);
+ String nodes_str = "\"node\":[ ";
+ it = nodes.entrySet().iterator();
+ while (it.hasNext ()) {
+ Map.Entry e = (Map.Entry)it.next();
+ String k = (String) e.getKey();
+ node = (Node) e.getValue();
+ if (node!=null) {
+ id = node.id;
+ proj = node.proj;
+ name = node.name;
+ grp = node.grp;
+ assoc = node.assoc;
+ x = node.x;
+ y = node.y;
+ root = node.root;
+ fixed = node.fixed;
+ nodes_str += "{ \"id\":\"" + id + "\", \"proj\":\"" + proj + "\", "
+ + "\"name\":\""+ name + "\", \"grp\":\""+ grp + "\", "
+ + "\"assoc\":" + assoc + ", \"x\":" + x + ", \"y\":" + y +" },";
+ }
+ }
+ //nodes_str += " {} ]";
+ nodes_str = nodes_str.substring(0, nodes_str.length()-1) + " ]";
+ //if (debug) println(nodes_str);
+ String edges_str = "\"edge\":[ ";
+ it = edges.entrySet().iterator();
+ while (it.hasNext ()) {
+ Map.Entry e = (Map.Entry)it.next();
+ String k = (String) e.getKey();
+ edge = (Edge) e.getValue();
+ asc_id = edge.asc_id;
+ a_proj = edge.proj;
+ id = edge.from.id;
+ from_proj = edge.from.proj;
+ to_id = edge.to.id;
+ to_proj = edge.to.proj;
+ r_name = edge.r_name;
+ r_from = edge.r_from;
+ r_to = edge.r_to;
+ edges_str += "{ \"asc_id\":\"" + asc_id + "\", \"a_proj\":\""+ a_proj +"\","
+ + " \"id\":\"" + id + "\", \"from_proj\":\""+ from_proj +"\","
+ + " \"to_id\":\"" + to_id + "\", \"to_proj\":\"" + to_proj + "\","
+ + " \"r_name\":\"" + r_name +"\", \"r_from\":\"" + r_from + "\", \"r_to\":\"" + r_to + "\" },";
+ }
+ //edges_str += " {} ]";
+ edges_str = edges_str.substring(0, edges_str.length()-1) + " ]";
+ if (debug)
+ println("{" + root_str + ", " + nodes_str + ", " + edges_str + "}");
+ if (null != javascript) javascript.allbackup("{" + root_str + ", " + nodes_str + ", " + edges_str + "}");
+}
+
+void allRetrieve() {
+ physics.clear();
+ nodes.clear();
+ edges.clear();
+ connected_edges.clear();
+ javascript.allretrieve("");
+}
+
+int cvalue(int hex) {
+ int r = (hex & 0xff0000)>>16;
+ int g = (hex & 0xff00)>>8;
+ int b = hex & 0xff;
+ return r+g+b;
+}
+
+int toInt(String s) {
+ int i = 0;
+ if ("0".equals(s)) i = 0;
+ else if ("1".equals(s)) i = 1;
+ else if ("2".equals(s)) i = 2;
+ else if ("3".equals(s)) i = 3;
+ else if ("4".equals(s)) i = 4;
+ else if ("5".equals(s)) i = 5;
+ else if ("6".equals(s)) i = 6;
+ else if ("7".equals(s)) i = 7;
+ else if ("8".equals(s)) i = 8;
+ else if ("9".equals(s)) i = 9;
+ else if ("a".equals(s)) i = 10;
+ else if ("A".equals(s)) i = 10;
+ else if ("b".equals(s)) i = 11;
+ else if ("B".equals(s)) i = 11;
+ else if ("c".equals(s)) i = 12;
+ else if ("C".equals(s)) i = 12;
+ else if ("d".equals(s)) i = 13;
+ else if ("D".equals(s)) i = 13;
+ else if ("e".equals(s)) i = 14;
+ else if ("E".equals(s)) i = 14;
+ else if ("f".equals(s)) i = 15;
+ else if ("F".equals(s)) i = 15;
+ return i;
+}
+
+int hex2int(String s) {
+ String a = s.substring(0, 1);
+ String b = s.substring(1, 2);
+ int ret = 16 * toInt(a) + toInt(b);
+ //if (debug) println(s + " " + a + " " + b + " " + ret);
+ return ret;
+}
+
+int str2color(String str) {
+ int c;
+ int r = hex2int(str.substring(0, 2));
+ int g = hex2int(str.substring(2, 4));
+ int b = hex2int(str.substring(4, 6));
+ //if (debug) println(str + " " + r + " " + g + " " + b);
+ c = color(r, g, b);
+ return c;
+}
+
+void initNode(String id, String name, String grp, String uid, String proj) {
+ if (debug) println("initNode(id=" + id + " name=" + name + " grp=" + grp + " uid=" + uid + " proj=" + proj + ")");
+ //name = unescapeSTR( name );
+ Node n = findNode(id, proj);
+ if (n == null) n = new Node(id, name, grp, uid, proj);
+ rootNode(n);
+}
+
+//////// GROUP SHAPE & COLOR /////////////////////////////////////////////////
+void groupShape() {
+ if (nodetrace) print("groupShape");
+ javascript.group_shapes();
+}
+
+int hexToColor(String clr) {
+ String s = clr.replaceFirst("^#", "");
+ int c = str2color( s );
+ return c;
+}
+
+int color2int(String clr) {
+ int c = 0;
+ if ( "#".equals(clr.substring(0, 1))) {
+ c = hexToColor(clr);
+ }
+ else if ( "AliceBlue".equals(clr) ) c = AliceBlue;
+ else if ( "AntiqueWhite".equals(clr) ) c = AntiqueWhite;
+ else if ( "Aqua".equals(clr) ) c = Aqua;
+ else if ( "Aquamarine".equals(clr) ) c = Aquamarine;
+ else if ( "Azure".equals(clr) ) c = Azure;
+ else if ( "Beige".equals(clr) ) c = Beige;
+ else if ( "Bisque".equals(clr) ) c = Bisque;
+ else if ( "Black".equals(clr) ) c = Black;
+ else if ( "BlanchedAlmond".equals(clr) ) c = BlanchedAlmond;
+ else if ( "Blue".equals(clr) ) c = Blue;
+ else if ( "BlueViolet".equals(clr) ) c = BlueViolet;
+ else if ( "Brown".equals(clr) ) c = Brown;
+ else if ( "BurlyWood".equals(clr) ) c = BurlyWood;
+ else if ( "CadetBlue".equals(clr) ) c = CadetBlue;
+ else if ( "Chartreuse".equals(clr) ) c = Chartreuse;
+ else if ( "Chocolate".equals(clr) ) c = Chocolate;
+ else if ( "Coral".equals(clr) ) c = Coral;
+ else if ( "CornflowerBlue".equals(clr) ) c = CornflowerBlue;
+ else if ( "Cornsilk".equals(clr) ) c = Cornsilk;
+ else if ( "Crimson".equals(clr) ) c = Crimson;
+ else if ( "Cyan".equals(clr) ) c = Cyan;
+ else if ( "DarkBlue".equals(clr) ) c = DarkBlue;
+ else if ( "DarkCyan".equals(clr) ) c = DarkCyan;
+ else if ( "DarkGoldenRod".equals(clr) ) c = DarkGoldenRod;
+ else if ( "DarkGray".equals(clr) ) c = DarkGray;
+ else if ( "DarkGrey".equals(clr) ) c = DarkGrey;
+ else if ( "DarkGreen".equals(clr) ) c = DarkGreen;
+ else if ( "DarkKhaki".equals(clr) ) c = DarkKhaki;
+ else if ( "DarkMagenta".equals(clr) ) c = DarkMagenta;
+ else if ( "DarkOliveGreen".equals(clr) ) c = DarkOliveGreen;
+ else if ( "Darkorange".equals(clr) ) c = Darkorange;
+ else if ( "DarkOrchid".equals(clr) ) c = DarkOrchid;
+ else if ( "DarkRed".equals(clr) ) c = DarkRed;
+ else if ( "DarkSalmon".equals(clr) ) c = DarkSalmon;
+ else if ( "DarkSeaGreen".equals(clr) ) c = DarkSeaGreen;
+ else if ( "DarkSlateBlue".equals(clr) ) c = DarkSlateBlue;
+ else if ( "DarkSlateGray".equals(clr) ) c = DarkSlateGray;
+ else if ( "DarkSlateGrey".equals(clr) ) c = DarkSlateGrey;
+ else if ( "DarkTurquoise".equals(clr) ) c = DarkTurquoise;
+ else if ( "DarkViolet".equals(clr) ) c = DarkViolet;
+ else if ( "DeepPink".equals(clr) ) c = DeepPink;
+ else if ( "DeepSkyBlue".equals(clr) ) c = DeepSkyBlue;
+ else if ( "DimGray".equals(clr) ) c = DimGray;
+ else if ( "DimGrey".equals(clr) ) c = DimGrey;
+ else if ( "DodgerBlue".equals(clr) ) c = DodgerBlue;
+ else if ( "FireBrick".equals(clr) ) c = FireBrick;
+ else if ( "FloralWhite".equals(clr) ) c = FloralWhite;
+ else if ( "ForestGreen".equals(clr) ) c = ForestGreen;
+ else if ( "Fuchsia".equals(clr) ) c = Fuchsia;
+ else if ( "Gainsboro".equals(clr) ) c = Gainsboro;
+ else if ( "GhostWhite".equals(clr) ) c = GhostWhite;
+ else if ( "Gold".equals(clr) ) c = Gold;
+ else if ( "GoldenRod".equals(clr) ) c = GoldenRod;
+ else if ( "Gray".equals(clr) ) c = Gray;
+ else if ( "Grey".equals(clr) ) c = Grey;
+ else if ( "Green".equals(clr) ) c = Green;
+ else if ( "GreenYellow".equals(clr) ) c = GreenYellow;
+ else if ( "HoneyDew".equals(clr) ) c = HoneyDew;
+ else if ( "HotPink".equals(clr) ) c = HotPink;
+ else if ( "IndianRed ".equals(clr) ) c = IndianRed ;
+ else if ( "Indigo ".equals(clr) ) c = Indigo ;
+ else if ( "Ivory".equals(clr) ) c = Ivory;
+ else if ( "Khaki".equals(clr) ) c = Khaki;
+ else if ( "Lavender".equals(clr) ) c = Lavender;
+ else if ( "LavenderBlush".equals(clr) ) c = LavenderBlush;
+ else if ( "LawnGreen".equals(clr) ) c = LawnGreen;
+ else if ( "LemonChiffon".equals(clr) ) c = LemonChiffon;
+ else if ( "LightBlue".equals(clr) ) c = LightBlue;
+ else if ( "LightCoral".equals(clr) ) c = LightCoral;
+ else if ( "LightCyan".equals(clr) ) c = LightCyan;
+ else if ( "LightGoldenRodYellow".equals(clr) ) c = LightGoldenRodYellow;
+ else if ( "LightGray".equals(clr) ) c = LightGray;
+ else if ( "LightGrey".equals(clr) ) c = LightGrey;
+ else if ( "LightGreen".equals(clr) ) c = LightGreen;
+ else if ( "LightPink".equals(clr) ) c = LightPink;
+ else if ( "LightSalmon".equals(clr) ) c = LightSalmon;
+ else if ( "LightSeaGreen".equals(clr) ) c = LightSeaGreen;
+ else if ( "LightSkyBlue".equals(clr) ) c = LightSkyBlue;
+ else if ( "LightSlateGray".equals(clr) ) c = LightSlateGray;
+ else if ( "LightSlateGrey".equals(clr) ) c = LightSlateGrey;
+ else if ( "LightSteelBlue".equals(clr) ) c = LightSteelBlue;
+ else if ( "LightYellow".equals(clr) ) c = LightYellow;
+ else if ( "Lime".equals(clr) ) c = Lime;
+ else if ( "LimeGreen".equals(clr) ) c = LimeGreen;
+ else if ( "Linen".equals(clr) ) c = Linen;
+ else if ( "Magenta".equals(clr) ) c = Magenta;
+ else if ( "Maroon".equals(clr) ) c = Maroon;
+ else if ( "MediumAquaMarine".equals(clr) ) c = MediumAquaMarine;
+ else if ( "MediumBlue".equals(clr) ) c = MediumBlue;
+ else if ( "MediumOrchid".equals(clr) ) c = MediumOrchid;
+ else if ( "MediumPurple".equals(clr) ) c = MediumPurple;
+ else if ( "MediumSeaGreen".equals(clr) ) c = MediumSeaGreen;
+ else if ( "MediumSlateBlue".equals(clr) ) c = MediumSlateBlue;
+ else if ( "MediumSpringGreen".equals(clr) ) c = MediumSpringGreen;
+ else if ( "MediumTurquoise".equals(clr) ) c = MediumTurquoise;
+ else if ( "MediumVioletRed".equals(clr) ) c = MediumVioletRed;
+ else if ( "MidnightBlue".equals(clr) ) c = MidnightBlue;
+ else if ( "MintCream".equals(clr) ) c = MintCream;
+ else if ( "MistyRose".equals(clr) ) c = MistyRose;
+ else if ( "Moccasin".equals(clr) ) c = Moccasin;
+ else if ( "NavajoWhite".equals(clr) ) c = NavajoWhite;
+ else if ( "Navy".equals(clr) ) c = Navy;
+ else if ( "OldLace".equals(clr) ) c = OldLace;
+ else if ( "Olive".equals(clr) ) c = Olive;
+ else if ( "OliveDrab".equals(clr) ) c = OliveDrab;
+ else if ( "Orange".equals(clr) ) c = Orange;
+ else if ( "OrangeRed".equals(clr) ) c = OrangeRed;
+ else if ( "Orchid".equals(clr) ) c = Orchid;
+ else if ( "PaleGoldenRod".equals(clr) ) c = PaleGoldenRod;
+ else if ( "PaleGreen".equals(clr) ) c = PaleGreen;
+ else if ( "PaleTurquoise".equals(clr) ) c = PaleTurquoise;
+ else if ( "PaleVioletRed".equals(clr) ) c = PaleVioletRed;
+ else if ( "PapayaWhip".equals(clr) ) c = PapayaWhip;
+ else if ( "PeachPuff".equals(clr) ) c = PeachPuff;
+ else if ( "Peru".equals(clr) ) c = Peru;
+ else if ( "Pink".equals(clr) ) c = Pink;
+ else if ( "Plum".equals(clr) ) c = Plum;
+ else if ( "PowderBlue".equals(clr) ) c = PowderBlue;
+ else if ( "Purple".equals(clr) ) c = Purple;
+ else if ( "Red".equals(clr) ) c = Red;
+ else if ( "RosyBrown".equals(clr) ) c = RosyBrown;
+ else if ( "RoyalBlue".equals(clr) ) c = RoyalBlue;
+ else if ( "SaddleBrown".equals(clr) ) c = SaddleBrown;
+ else if ( "Salmon".equals(clr) ) c = Salmon;
+ else if ( "SandyBrown".equals(clr) ) c = SandyBrown;
+ else if ( "SeaGreen".equals(clr) ) c = SeaGreen;
+ else if ( "SeaShell".equals(clr) ) c = SeaShell;
+ else if ( "Sienna".equals(clr) ) c = Sienna;
+ else if ( "Silver".equals(clr) ) c = Silver;
+ else if ( "SkyBlue".equals(clr) ) c = SkyBlue;
+ else if ( "SlateBlue".equals(clr) ) c = SlateBlue;
+ else if ( "SlateGray".equals(clr) ) c = SlateGray;
+ else if ( "SlateGrey".equals(clr) ) c = SlateGrey;
+ else if ( "Snow".equals(clr) ) c = Snow;
+ else if ( "SpringGreen".equals(clr) ) c = SpringGreen;
+ else if ( "SteelBlue".equals(clr) ) c = SteelBlue;
+ else if ( "Tan".equals(clr) ) c = Tan;
+ else if ( "Teal".equals(clr) ) c = Teal;
+ else if ( "Thistle".equals(clr) ) c = Thistle;
+ else if ( "Tomato".equals(clr) ) c = Tomato;
+ else if ( "Turquoise".equals(clr) ) c = Turquoise;
+ else if ( "Violet".equals(clr) ) c = Violet;
+ else if ( "Wheat".equals(clr) ) c = Wheat;
+ else if ( "White".equals(clr) ) c = White;
+ else if ( "WhiteSmoke".equals(clr) ) c = WhiteSmoke;
+ else if ( "Yellow".equals(clr) ) c = Yellow;
+ else if ( "YellowGreen".equals(clr) ) c = YellowGreen;
+ return c;
+}
+
+void newUserColor(String uid, int c, String show) {
+ if (debug) println("newUserColor(" + uid + "," + c + "," + show + ")");
+ boolean s =("show".equals(show))? true:false;
+ UserColor usercolor = new UserColor(uid, uid, c, s);
+ usercolors.put( uid, usercolor );
+ if (javascript != null) javascript.username(uid);
+}
+
+void setUserColor(String uid, String uname) {
+ if (debug) println("setUserColor(" + uid + "," + uname + ")");
+ UserColor usercolor = (UserColor) usercolors.get(uid);
+ if (usercolor != null) {
+ usercolor.uid = uid;
+ usercolor.name = uname;
+ usercolors.put( uid, usercolor );
+ }
+}
+
+public class UserColor {
+ String uid;
+ String name;
+ int c;
+ boolean show;
+
+ UserColor(String uid, String name, int c, boolean show) {
+ this.uid = uid;
+ this.name = name;
+ this.c = c;
+ this.show = show;
+ }
+}
+// NodeShape
+void newNodeShape(String grp, String s, String clr) {
+ if (debug || nodetrace) println("newNodeshape(" + grp + "," + s + "," + clr + ")");
+ int c = color2int(clr);
+ NodeShape nodeshape = new NodeShape(grp, s, c);
+ addNodeShape(nodeshape);
+}
+
+void addNodeShape(NodeShape nodeshape) {
+ if (nodetrace) print("addNodeShape("+nodeshape.grp+","+nodeshape.s+","+hex(nodeshape.c,6)+")");
+ String grp = nodeshape.grp;
+ /*if (nodeshapes.containsKey( grp )) {
+ nodeshapes.remove( grp );
+ } */
+ nodeshapes.put( grp, nodeshape );
+}
+
+NodeShape findNodeShape(String grp) {
+ NodeShape node_shape = (NodeShape) nodeshapes.get(grp);
+ if (nodetrace) {
+ if(node_shape==null)
+ println("\tfindNodeShape grp="+grp+" shape undefined.");
+ else
+ println("\tfindNodeShape grp="+grp+" shape="+node_shape.s+" color="+hex(node_shape.c,6));
+ }
+ return node_shape;
+}
+
+public class NodeShape {
+ String grp;
+ String s;
+ int c;
+
+ NodeShape(String grp, String s, int c) {
+ this.grp = grp;
+ this.s = s;
+ this.c = c;
+ }
+}
+
+// EdgeShape
+void newEdgeShape(String r_name, String s, String clr) {
+ if (edgetrace) println("newEdgeShape(" + r_name + "," + s + "," + clr + ")");
+ int c = color2int(clr);
+ EdgeShape edgeshape = new EdgeShape(r_name, s, c);
+ addEdgeShape(edgeshape);
+}
+
+void addEdgeShape(EdgeShape edgeshape) {
+ if (edgetrace) println("addEdgeShape edgeshape=("+edgeshape.r_name+","+edgeshape.s+","+hex(edgeshape.c,6)+") ");
+ String r_name = edgeshape.r_name;
+ /*if (edgeshapes.containsKey( r_name )) {
+ edgeshapes.remove( r_name );
+ } */
+ edgeshapes.put( r_name, edgeshape );
+}
+
+EdgeShape findEdgeShape(String r_name) {
+ if (edgetrace) println("\tfindEdgeShape("+r_name+")");
+ if (r_name==null || r_name.equals("")) return null;
+ EdgeShape edgeshape = (EdgeShape) edgeshapes.get(r_name);
+ return edgeshape;
+}
+
+public class EdgeShape {
+ String r_name;
+ String s;
+ int c;
+
+ EdgeShape(String r_name, String s, int c) {
+ this.r_name = r_name;
+ this.s = s;
+ this.c = c;
+ }
+}
+
+//////// IMAGE MAP MODEL ///////////////////////////////////////////////
+ImageMap newImageMap(String url) {
+ //if (debug) println("newImageMap(" + url + ")");
+ ImageMap imap = findImageMap(url);
+ if (imap == null) {
+ imap = new ImageMap(url);
+ addImageMap(imap);
+ }
+ return imap;
+}
+
+ImageMap findImageMap(String url) {
+ //if (debug) println("\tfindImageMap("+url+")");
+ if (url==null || url.equals("")) return null;
+ ImageMap imap = (ImageMap) imageMaps.get(url);
+ return imap;
+}
+
+void addImageMap(ImageMap imap) {
+ //if (debug) println("addImage imap=("+imap.url+") ");
+ String url = imap.url;
+ /*if (imageMaps.containsKey( url )) {
+ imageMaps.remove( url );
+ } */
+ imageMaps.put( url, imap );
+}
+
+class ImageMap {
+ String url;
+ PImage img;
+ int w,h;
+
+ ImageMap(String url) {
+ this.url = url;
+ int siz = 80;
+ w = h = 0;
+ this.img = loadImage(url);
+ if(this.img != null) {
+ w = img.width;
+ h = img.height;
+ if (w > h) {
+ h = round(siz * h / w);
+ w = siz;
+ } else {
+ w = round(siz * w / h);
+ h = siz;
+ }
+ img.resize(w, h);
+ }
+ }
+
+ void show(int x, int y) {
+ image(this.img, x - this.w, y - this.h/2);
+ }
+}
+
+//////// THUMBNAIL MODEL ///////////////////////////////////////////////
+void newThumb(String id, int start, int end) {
+ if (debug) println("newThumb(" + id + "," + start + "," + end + ")");
+ Thumb thumb = new Thumb(id, start, end);
+ addThumb(thumb);
+}
+
+void addThumb(Thumb thumb) {
+ if (debug) println("addThumb thumb=("+thumb.start+","+thumb.end+") ");
+ String id = thumb.id;
+ /*if (thumbs.containsKey( id )) {
+ thumbs.remove( id );
+ } */
+ thumbs.put( id, thumb );
+}
+
+Thumb findThumb(String id) {
+ //if (debug) println("\tfindThumb("+id+")");
+ if (id==null || id.equals("")) return null;
+ Thumb thumb = (Thumb) thumbs.get(id);
+ return thumb;
+}
+
+class Thumb {
+ String id;
+ String prefix;
+ int start;
+ int end;
+ String postfix;
+ PImage image;
+
+ Thumb(String id, int start, int end) {
+ this.id = id;
+ this.prefix = "thumbs/";
+ this.start = start;
+ this.end = end;
+ this.postfix = "_in.jpg";
+ }
+}
+
+//////// GRAPH DATA MODEL ///////////////////////////////////////////////
+public class Node {
+ Particle p;
+ int x, y;
+ int mass;
+ String id, proj, uid;
+ String name, grp, abst;
+ String url;
+ String shape;
+ int c;
+ int size;
+ int w, h;
+ //String hide;
+ boolean checked;
+ boolean fixed;
+ boolean root;
+ String isa;
+ int count;
+ int assoc;
+ String freeDirection;
+ String vizgroup;
+
+ Node(String _id, String _name, String _grp, String _uid, String _proj) {
+ this.id = _id;
+ this.name = _name;
+ this.grp = _grp;
+ this.uid = _uid;
+ this.proj = _proj;
+ this.size = 18;
+ this.mass = 1;// MASS;
+ this.x = Math.round( random(-128, 128) );
+ this.y = Math.round( random(-128, 128) );
+ this.p = physics.makeParticle(this.mass, this.x, this.y /*, 0*/);
+ this.checked = false;
+ this.fixed = false;
+ this.root = false;
+ this.isa = "";
+ this.count = 0;
+ this.assoc = 0;
+ String s = "RECTANGLE"; // Default
+ int c = LightSlateGray; // Default
+ NodeShape node_shape = findNodeShape( grp );
+ if (node_shape != null) {
+ s = node_shape.s;
+ c = node_shape.c;
+ }
+ this.shape = s;
+ this.c = c;
+ this.w = 10;
+ this.h = 12;
+ if (nodetrace) println( "\tDEFINE Node( " + id + ", " + name + ", " + grp + ", " + uid + ", " + proj +" )" );
+ }
+
+ void increment() {
+ mass++;
+ }
+
+ void setURL(String url) {
+ this.url = url;
+ }
+
+ void fix() {
+ this.fixed = true;
+ this.p.makeFixed();
+ }
+
+ void free() {
+ this.fixed = false;
+ this.p.makeFree();
+ }
+
+ void position(int x, int y) {
+ this.x = x;
+ this.y = y;
+ this.p.position.x = x;
+ this.p.position.y = y;
+ }
+
+ void update() {
+ this.x = Math.round( p.position.x );
+ this.y = Math.round( p.position.y );
+ }
+
+ void move(float mx, float my) {
+ this.x += mx;
+ this.y += my;
+ this.position(this.x, this.y);
+ damper = 1.0;
+ }
+
+ void affix(int diff, float x, float y, float w, float h, int s) {
+ if (diff > 0) {
+ if (diff>1000) s *= 2;
+ else if (diff>100) s *= 1.5;
+ String unopen = "" + diff;
+ stroke(White);
+ strokeWeight(1);
+ //stroke(edgeColor);
+ stroke(DeepPink);
+ fill(DeepPink);
+ rect(x + w/2, y - h/2, s, s);
+ fill(White);
+ textSize(8);
+ text(unopen, x + w/2, y - h/2);
+ textSize(12);
+ }
+ }
+
+ void drawShape(String label, float dispX, float dispY, boolean highlite) {
+ float sf = sqrt(mass);
+ sf = 1 + (sf-1)/8; // scale factor of each node
+ int tsize = round(10*sf);
+ if (tsize > 48) {
+ textSize(48);
+ } else if (tsize > 12) {
+ textSize(tsize);
+ } else {
+ textSize(12);
+ }
+ w = round( textWidth(label) + 30 );
+ h = round( sf * this.size );
+ if (this.root) fill(rootColor);
+ if ("".equals(this.shape)) {
+ rectMode(CENTER);
+ rect(dispX, dispY, w, h);
+ }
+ else if ("CIRCLE".equals(this.shape)) {
+ ellipseMode(CENTER);
+ ellipse(dispX, dispY, w, w);
+ }
+ else if ("ELLIPSE".equals(this.shape)) {
+ ellipseMode(CENTER);
+ ellipse(dispX, dispY, w + 4, h + 4);
+ }
+ else if ("ROUNDED".equals(this.shape)) {
+ rectMode(CENTER);
+ ellipseMode(CENTER);
+ roundedRect(dispX, dispY, w, h, h/2);
+ }
+ else if ("MARK".equals(this.shape)) {
+ int radius = 18;
+ fill(bgColor, 10);
+ stroke(bgColor, 10);
+ rectMode(CENTER);
+ rect(dispX + w*sf/2 + radius, dispY, w, h);
+ fill(this.c);
+ stroke( (highlite)? selectColor:u_clr );
+ ellipseMode(CENTER);
+ //ellipse(dispX, dispY, h*sf, h*sf);
+ ellipse(dispX, dispY, radius, radius);
+ }
+ else {//Default shape is RECTANGLE
+ rectMode(CENTER);
+ rect(dispX, dispY, w, h);
+ }
+
+ int diff = this.assoc - this.count;
+ String unopen = "";
+ if ( diff > 0 ) unopen += diff;
+ textAlign(CENTER, CENTER);
+ if ("MARK".equals(this.shape)) {
+ fill(Black);
+ text(label, dispX + w*sf/2, dispY);
+ affix(diff, dispX - w*sf/2 + h*sf/2, dispY, w*sf, h*sf, 9);
+ }
+ else {
+ fill(Black);
+ if ( cvalue(this.c) < cvalue(#A0A0A0) ) fill(White);
+ text(label, dispX, dispY);
+ affix(diff, dispX, dispY, w*sf, h*sf, 9);
+ }
+ if (url!=null) {
+ ImageMap imap = newImageMap(url);
+ imap.show(round(dispX - w*sf/2), round(dispY));
+ }
+ }
+
+ void show() {
+ Particle p = this.p;
+ update();
+ if (p!=null) {
+ float dispX = factor * p.position.x;
+ float dispY = factor * p.position.y;
+ String s = "RECTANGLE"; // Default
+ int c = LightSlateGray; // Default
+ NodeShape node_shape = findNodeShape( grp );
+ if (node_shape != null) {
+ s = node_shape.s;
+ c = node_shape.c;
+ }
+ this.shape = s;
+ this.c = c;
+ fill(this.c);
+ UserColor usercolor = (UserColor) usercolors.get(this.uid);
+ strokeWeight(1.5);
+ if (usercolor!=null) {
+ u_clr = usercolor.c;
+ stroke(u_clr);
+ }
+ else {
+ u_clr = color(32*int(random(255)/32), 32*int(random(255)/32), 32*int(random(255)/32));
+ while (u_clr == selectColor){
+ u_clr = color(32*int(random(255)/32), 32*int(random(255)/32), 32*int(random(255)/32));
+ }
+ newUserColor(uid, u_clr, "show");
+ stroke(u_clr);
+ }
+ //textSize(12);
+ String topicname = unescapeSTR(this.name);
+ UserColor uc = (UserColor) usercolors.get(uid);
+ String label = (showusername && uc.name!=null)? "["+uc.name+"] "+topicname:topicname;
+ if ( label.length() > LABEL_LENGTH ) label = label.substring(0, LABEL_LENGTH) + "...";
+ this.drawShape(label, dispX, dispY, false);
+ }
+ }
+
+ void highlight() {
+ Particle p = this.p;
+ float dispX=0, dispY=0;
+ int seq = 0;
+ if (p!=null) {
+ dispX = factor * p.position.x;
+ dispY = factor * p.position.y;
+ stroke(selectColor);
+ strokeWeight(2.0);
+ fill(this.c);
+ //textSize(12);
+ UserColor uc = (UserColor) usercolors.get(uid);
+ String topicname = unescapeSTR(this.name);
+ String label = (showusername && uc.name!=null)? "["+uc.name+"] "+topicname:topicname;
+ this.drawShape(label, dispX, dispY, true);
+ stroke(bgColor);
+ strokeWeight(0.1);
+ /*Thumb thumb = findThumb(id);
+ if (thumb!=null) {
+ int num = thumb.end-thumb.start;
+ num=(num>0)?num:1;
+ String filename =
+ thumb.prefix +
+ (thumb.start + (seq++ / 30) % num) +
+ thumb.postfix;
+ if (debug) println(filename);
+ img = loadImage(filename);
+ if (img!=null) image(img, dispX - 16, dispY + 4);
+ }
+ */
+ }
+ if (nodetrace) {
+ fill(Gray);
+ text(isa, dispX - 30, dispY + 12);
+ text("assoc="+assoc+" count="+count, dispX - 30, dispY + 24);
+ text("fixed="+fixed+" root="+root, dispX - 30, dispY + 36);
+ text(id+"@"+proj+" grp="+grp+" url="+url, dispX - 30, dispY + 48);
+ }
+ }
+}
+
+void roundedRect(float x, float y, float w, float h, float r) {
+ pushMatrix();
+ translate(x, y);
+ beginShape();
+ vertex( w/2 - r, -h/2 );
+ bezierVertex( w/2 - r, -h/2, w/2, -h/2, w/2, -h/2 + r);
+ vertex( w/2, h/2 - r );
+ bezierVertex( w/2, h/2, w/2 - r, h/2, w/2 - r, h/2);
+ vertex( -w/2 + r, h/2 );
+ bezierVertex( - w/2, h/2, -w/2, h/2 - r, -w/2, h/2 - r );
+ vertex( -w/2, -h/2 + r );
+ bezierVertex( -w/2, -h/2, -w/2 + r, -h/2, -w/2 + r, -h/2 );
+ endShape(CLOSE);
+ popMatrix();
+}
+
+public class Edge {
+ Spring s;
+ Node from;
+ Node to;
+ String from_is;
+ String to_is;
+ String proj, uid;
+ String asc_id;
+ String id, to_id, to_name;
+ String r_name, r_from, r_to;
+ float len;
+ int count;
+ int dup; //number of the same node pair
+ String shape;
+ int c;
+ int size;
+ PVector centr, V1, V2, V3;
+ float R;
+ char dir;
+
+ Edge(Node from, Node to, String uid, String proj) {
+ if (edgetrace) print("\tDEFINE Edge("+from.name+", "+to.name+")");
+ if (from==null || to==null) return;
+ this.uid = uid;
+ this.proj = proj;
+ this.from = from;
+ this.to = to;
+ Particle a = from.p;
+ Particle b = to.p;
+ if (a!=null && b!=null) this.s = physics.makeSpring(a, b, SPRING_STRENGTH, SPRING_DAMPING, SPRING_LENGTH);
+ this.id = from.id;
+ this.to_id = to.id;
+ this.len = SPRING_LENGTH;
+ this.count = 0;
+ }
+
+ void setID( String asc_id ) {
+ this.asc_id = asc_id;
+ }
+
+ void setRole( String R, String F, String T ) {
+ this.r_name = R;
+ this.r_from = F;
+ this.r_to = T;
+ String s = "ARROW"; // Default edge shape
+ int c = Silver; // Default edge color
+ EdgeShape edge_shape = findEdgeShape(this.r_name);
+ if (edge_shape != null) {
+ s = edge_shape.s;
+ c = edge_shape.c;
+ }
+ this.shape = s;
+ this.c = c;
+ if (edgetrace) println("\tshape="+s+" color="+hex(c,6));
+ }
+
+ void increment() {
+ count++;
+ }
+
+ PVector vRotate(PVector To, PVector From, float theta, float r) {
+ PVector P = new PVector(From.x, From.y);
+ P.sub(To);
+ float x = cos(theta)*P.x - sin(theta)*P.y;
+ float y = sin(theta)*P.x + cos(theta)*P.y;
+ PVector Q = new PVector(x, y);
+ Q.normalize();
+ Q.mult(r);
+ Q.add(To);
+ return Q;
+ }
+
+ float theta(PVector P, PVector Q) {
+ //float sigma = 0.1;
+ float theta = 0;
+ if (P==null || Q==null) return 0;
+ float deltax = Q.x - P.x;
+ float deltay = Q.y - P.y;
+ float tan = deltay/deltax;
+ theta = atan(tan);
+ if (0 <= deltay) {
+ if (sigma < deltax) theta = theta;
+ if (-sigma <= deltax && deltax <= sigma) theta = HALF_PI;
+ if (deltax < -sigma) theta = PI + theta;
+ }
+ else {
+ if (deltax < -sigma) theta = PI + theta;
+ if (-sigma <= deltax && deltax <= sigma) theta = PI + HALF_PI;
+ if (sigma < deltax) theta = TWO_PI + theta;
+ }
+ return theta;
+ }
+
+ void drawLine(PVector P, PVector Q) {
+ line(P.x, P.y, Q.x, Q.y);
+ }
+/*
+ void fatLine(PVector P, PVector Q, float thickness) {
+ float x1 = P.x, y1 = P.y;
+ float x2 = Q.x, y2 = Q.y;
+ float distance = dist(x1, y1, x2, y2);
+ float angle = 360-atan2((y2-y1),x2-x1) ;
+ pushMatrix();
+ rectMode(CORNER);
+ translate(x1,y1);
+ rotate(360 - angle);
+ rect(0, - (thickness / 2 ), distance, thickness);
+ rectMode(CENTER);
+ popMatrix();
+ }
+*/
+ PVector calcCoord(PVector P) {
+ if (P==null) return null;
+ float x = factor*P.x; //WORLD_SIZE_W/2 + factor*P.x; //Math.round( (P.x - WORLD_SIZE_W/2)/factor );
+ float y = factor*P.y; //WORLD_SIZE_H/2 + factor*P.y; //Math.round( (P.y - WORLD_SIZE_H/2)/factor );
+ PVector Q = new PVector(x, y);
+ return Q;
+ }
+
+ void drawArrow(/*Node from, Node to, int dup*/) {
+ PVector From = new PVector(this.from.x, this.from.y);
+ From.mult(factor);
+ PVector To = new PVector(this.to.x, this.to.y);
+ To.mult(factor);
+ //float sigma = 0.1;
+ int m = 4; // number of control vertex for edge
+ float w = 0.7; // width of arrow
+ float phai = 0;
+ float psi = 0;
+ float L = dist(From.x, From.y, To.x, To.y)/2;
+ PVector Q1;
+ PVector M = new PVector( (To.x + From.x)/2, (To.y + From.y)/2 );
+ this.centr = M;
+ PVector Start, Terminate, P_i, Vi;
+ PVector Outer[] = new PVector[m];
+ PVector Inner[] = new PVector[m];
+ int N = 8;
+ int n = (dup%2==0)? dup/2 : -1*(dup/2)-1;
+ if ( (From.x - To.x < -sigma) ||
+ (-sigma <= From.x - To.x && From.x - To.x < sigma &&
+ From.y - To.y < -sigma) )
+ n *= -1;
+ if (n < 0)
+ Q1 = vRotate(M, From, -HALF_PI, -n*L/N);
+ else
+ Q1 = vRotate(M, From, HALF_PI, n*L/N);
+ float a = dist(M.x, M.y, Q1.x, Q1.y)/L;
+ float b = (1-a*a)/(2*a);
+ if (n < 0) {
+ this.centr = vRotate(M, From, HALF_PI, b*L);
+ psi = theta(centr, To) - theta(centr, From);
+ if (PI < psi) psi -= TWO_PI;
+ if (psi< -PI) psi += TWO_PI;
+ phai = psi/m;
+ }
+ else if (n == 0){
+ this.centr = vRotate(From, M, -HALF_PI, 1);
+ }
+ else if (0 < n){
+ this.centr = vRotate(M,From, -HALF_PI, b*L);
+ psi = theta(centr, To) - theta(centr, From);
+ if (PI < psi) psi -= TWO_PI;
+ if (psi< -PI) psi += TWO_PI;
+ phai = psi/m;
+ }
+ R = dist(centr.x, centr.y, From.x, From.y);
+ if (n == 0) {
+ P_i = vRotate(From, M, 0, GAP);
+ To = vRotate(To, M, 0, GAP);
+ }
+ else {
+ if (0 < phai) {
+ P_i = vRotate(centr, From, GAP/R, R);
+ To = vRotate(centr, To, -GAP/R, R);
+ }
+ else {
+ P_i = vRotate(centr, From, -GAP/R, R);
+ To = vRotate(centr, To, GAP/R, R);
+ }
+ }
+ Vi = new PVector(From.x - centr.x, From.y - centr.y);
+ Vi.normalize();
+ Vi.mult( m*w );
+ Start = PVector.add(P_i, Vi);
+ Terminate = PVector.sub(P_i, Vi);
+ if (m==2) {
+ P_i = Q1;
+ Vi = new PVector(P_i.x - centr.x, P_i.y - centr.y);
+ Vi.normalize();
+ Vi.mult( w );
+ Outer[1]= PVector.add(P_i, Vi);
+ Inner[1]= PVector.sub(P_i, Vi);
+ }
+ else {
+ for (int i=1; i < m; i++) {
+ P_i = vRotate(centr, From, i*phai, R);
+ Vi = new PVector(P_i.x - centr.x, P_i.y - centr.y);
+ Vi.normalize();
+ Vi.mult( (m-i)*w );
+ Outer[i]= PVector.add(P_i, Vi);
+ Inner[i]= PVector.sub(P_i, Vi);
+ }
+ }
+ this.V1 = Outer[1];
+ this.V2 = Q1;
+ this.V3 = Outer[m-1];
+ //strokeJoin(MITER);
+ if (this.shape==null || "ARROW".equals(this.shape)) {
+ beginShape();
+ if ( n == 0 ) {
+ vertex(Start.x, Start.y);
+ vertex(To.x, To.y);
+ vertex(Terminate.x, Terminate.y);
+ vertex(Start.x, Start.y);
+ }
+ else {
+ curveVertex(Start.x, Start.y);
+ curveVertex(Start.x, Start.y);
+ for (int j =1; j < m; j++) {
+ curveVertex(Outer[j].x, Outer[j].y);
+ }
+ curveVertex(To.x, To.y);
+ for (int k = m-1; k > 0; k--) {
+ curveVertex(Inner[k].x, Inner[k].y);
+ }
+ curveVertex(Terminate.x, Terminate.y);
+ curveVertex(Start.x, Start.y);
+ }
+ endShape();
+ }
+ else if ("LINE".equals(this.shape)) {
+ noFill();
+ strokeWeight(4);
+ if ( n == 0 ) {
+ drawLine(From, To);
+ }
+ else {
+ beginShape();
+ curveVertex(From.x, From.y);
+ curveVertex(From.x, From.y);
+ for (int j =1; j < m; j++) {
+ curveVertex((Outer[j].x+Inner[j].x)/2,( Outer[j].y+Inner[j].y)/2);
+ }
+ curveVertex(To.x, To.y);
+ curveVertex(To.x, To.y);
+ endShape();
+ }
+ }
+ this.centr.mult(1/factor);
+ this.V1.mult(1/factor);
+ this.V2.mult(1/factor);
+ this.V3.mult(1/factor);
+ // draw edge degug info
+ strokeWeight(0.5);
+ if (debug) {
+ fill(Pink);
+ if (from_is !=null) text(this.from_is, From.x+20, From.y-30);
+ if (to_is!=null) text(this.to_is, To.x+20, To.y-30);
+ }
+ if (edgetrace) {
+ fill(Red);
+ float pX = factor * (pointX);
+ float pY = factor * (pointY);
+ if (!dragging) ellipse(pX, pY, GAP, GAP);
+
+ fromX = factor * (from.x);
+ fromY = factor * (from.y);
+ toX = factor * (to.x);
+ toY = factor * (to.y);
+ if (dup>0) {
+ cX = factor * (this.centr.x);
+ cY = factor * (this.centr.y);
+ }
+ else {
+ cX = M.x;
+ cY = M.y;
+ }
+ fill(Gray);
+ stroke(Gray);
+ line(cX, cY, fromX, fromY);
+ line(cX, cY, toX, toY);
+ textAlign(CORNER, CENTER);
+ text(asc_id+" dup="+dup+" shape="+this.shape+" color="+hex(c,6), cX, cY);
+ PVector P = new PVector(scrnX, scrnY);
+ PVector Cntr = new PVector(cX, cY);
+ if (P != null) phai = theta(Cntr, P);
+ PVector P1 = new PVector(fromX, fromY);
+ if (P1 != null) theta1 = theta(Cntr, P1);
+ PVector P2 = new PVector(toX, toY);
+ if (P2 != null) theta2 = theta(Cntr, P2);
+ if (dup>0) {
+ text("center x="+round(cX)+" y="+round(cY), cX, cY+10);
+ text("theta1="+round(degrees(theta1))+" theta2="+round(degrees(theta2))+" phai="+round(degrees(phai)), cX, cY+20);
+ }
+ }
+ }
+
+ void show() {
+ UserColor usercolor = (UserColor) usercolors.get(this.uid);
+ strokeWeight(1.5);
+ if (usercolor!=null) {
+ u_clr = usercolor.c;
+ stroke(u_clr);
+ }
+ else {
+ u_clr = color(32*int(random(255)/32), 32*int(random(255)/32), 32*int(random(255)/32));
+ while (u_clr == selectColor){
+ u_clr = color(32*int(random(255)/32), 32*int(random(255)/32), 32*int(random(255)/32));
+ }
+ newUserColor(uid, u_clr, "show");
+ stroke(u_clr);
+ }
+ strokeWeight(0.6);
+ fill(this.c);
+ drawArrow();
+ }
+
+ void highlight() {
+ Node from = this.from;
+ Node to = this.to;
+ if (from==null || to==null) return;
+ float dx = to.x - from.x;
+ float dy = to.y - from.y;
+ float len = sqrt( dx*dx + dy*dy );
+ float cs = GAP * dx/len;
+ float sn = GAP * dy/len;
+ float d = 2;
+ fromX = centerX + factor * (from.x - centerX);
+ fromY = centerY + factor * (from.y - centerX);
+ toX = centerX + factor * (to.x - centerX);
+ toY = centerY + factor * (to.y - centerX);
+ // draw highlighted edge
+ strokeWeight(0.5);
+ if (debug || edgetrace) {
+ fill(Red);
+ float pX = centerX + factor * (pointX - centerX);
+ float pY = centerY + factor * (pointY - centerX);
+ ellipse(pX, pY, GAP, GAP);
+ fill(Gray);
+ stroke(Gray);
+ cX = centerX + factor * (this.centr.x - centerX);
+ cY = centerY + factor * (this.centr.y - centerX);
+ line(cX, cY, fromX, fromY);
+ line(cX, cY, toX, toY);
+ textAlign(CORNER, CENTER);
+ if (dup==0)
+ text(asc_id+" dup="+dup+" shape="+this.shape+" color="+hex(c,6), 20 + (fromX + toX )/2, 10 + (fromY + toY )/2);
+ else
+ text(asc_id+" dup="+dup+" shape="+this.shape+" color="+hex(c,6), cX, cY);
+ }
+ stroke(selectColor);
+ fill(selectColor);
+ drawArrow();
+ //draw label of roles
+ fill(Red);
+ textAlign(CENTER, CENTER);
+ float diffY = toY - fromY;
+ float D = 10;
+ float dY = 0;
+ if ( -D < diffY && diffY <= 0) dY = -D;
+ if ( 0 < diffY && diffY < D ) dY = D;
+ if (dup==0){
+ if (sel_edge.r_from != null)
+ text( sel_edge.r_from, (3*fromX + toX )/4, (3*fromY + toY )/4 - dY );
+ if (sel_edge.r_name != null)
+ text( sel_edge.r_name, (fromX + toX )/2, (fromY + toY )/2 );
+ if (sel_edge.r_to != null)
+ text( sel_edge.r_to, (fromX + 3*toX)/4, (fromY + 3*toY)/4 + dY );
+ }
+ else {
+ text(sel_edge.r_from, factor*V1.x, factor*V1.y);
+ text(sel_edge.r_name, factor*V2.x, factor*V2.y);
+ text(sel_edge.r_to, factor*V3.x, factor*V3.y);
+ }
+ }
+}
+
+void allUpdate() {
+ Iterator itv = nodes.keySet().iterator();
+ while (itv.hasNext ()) {
+ String key = (String) itv.next();
+ Node node = (Node) nodes.get(key);
+ node.update();
+ }
+}
+
+void allFix() {
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ Node node = (Node) nodes.get(key);
+ node.fix();
+ }
+}
+
+void allFree() {
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ Node node = (Node) nodes.get(key);
+ if (!node.root)
+ node.free();
+ }
+ damper = 1.0;
+}
+
+void allMove(float mx, float my) {
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ Node node = (Node) nodes.get(key);
+ node.move(mx, my);
+ }
+}
+
+void setEdgeValue(String asc_id, String r_name, String r_from, String r_to, String s, String clr) {
+ if (edgetrace) println("setEdgeValue("+asc_id+","+r_name+","+r_from+","+r_to+","+s+","+clr+") ");
+ Edge e = edges.get(asc_id);
+ if (e!=null) {
+ e.r_name = r_name;
+ e.r_from = r_from;
+ e.r_to = r_to;
+ if (s!=null && !"".equals(s)) e.shape = s;
+ if (clr!=null && !"".equals(clr)) e.c = hexToColor(clr);
+ if (edgetrace) println("\tEdge UPDATED");
+ }
+}
+
+Edge findEdge(String asc_id, String proj) {
+ if (debug) print("\n\tfindEdge asc_id=" + asc_id + " proj=" + proj);
+ Edge e = null;
+ Iterator it = edges.keySet().iterator();
+ while (it.hasNext ()) {
+ String k = (String) it.next();
+ e = (Edge) edges.get(k);
+ asc_id = asc_id.trim();
+ proj = proj.trim();
+ if(k.equals(asc_id) && e.proj.equals(proj)) {
+ if (debug) {
+ if (debug) println("\tedge FOUND.");
+ }
+ return e;
+ }
+ }
+ if (debug) println("\tedge NOT found.");
+ return null;
+}
+
+void addEdge(String asc_id, String fromId, String fromProj, String toId, String toProj,
+ String r_name, String r_from, String r_to, String uid, String proj) {
+ if (edgetrace) println("================\naddEdge asc_id=" + asc_id +
+ " from id=" + fromId + " proj="+fromProj+" to id=" + toId +" proj="+toProj+ " uid=" + uid+ " proj=" + proj );
+ if("".equals(fromId) || fromId == null || "".equals(toId) || toId == null) return;
+ boolean newedge = false;
+ char dir;
+ String pair, reverse_pair;
+ Node from = findNode(fromId, fromProj);
+ if (from==null) from = newNode(fromId, fromId, "", uid, fromProj);
+ Node to = findNode(toId, toProj);
+ if (to==null) to = newNode(toId, toId, "", uid, toProj);
+ if (edgetrace) println("\tfromId="+fromId+" toId="+toId);
+ if(fromId.hashCode() < toId.hashCode()) {
+ pair = fromId+"#"+toId;
+ reverse_pair = toId+"#"+fromId;
+ }
+ else {
+ pair = toId+"#"+fromId;
+ reverse_pair = fromId+"#"+toId;
+ }
+ if (edgetrace) println("\tpair="+pair+"\tasc_id="+asc_id);
+ from.update();
+ to.update();
+ if ("".equals(asc_id)){
+ newedge = true;
+ asc_id = fromId+"#"+toId;
+ Edge e = findEdge(asc_id, proj);
+ if (e!=null) return;
+ }
+ Edge the_edge = new Edge(from, to, uid, proj);
+ the_edge.asc_id = asc_id;
+ int count_connection = 0;
+ Iterator it = connected_edges.keySet().iterator();
+ while (it.hasNext ()) {
+ String k = (String) it.next();
+ if ( k.indexOf(pair)==0 || k.indexOf(reverse_pair)==0 ) count_connection++;
+ }
+ if (newedge) the_edge.dup = 0; else the_edge.dup = count_connection;
+ the_edge.setRole(r_name, r_from, r_to);
+ if (edgetrace) println("\tthe_edge.setRole("+r_name+","+ r_from+","+ r_to+")");
+ if (edgetrace) println("\taddEdge edges put\t" + asc_id + "\t" + the_edge.from.name + "\t" + the_edge.to.name);
+ edges.put(asc_id, the_edge);
+ if (edgetrace) println("\taddEdge connected_edges put\t" + pair + ":" + count_connection +"\t"+ asc_id);
+ connected_edges.put(pair + ":" + count_connection, asc_id);
+ if (edgetrace) {
+ println("\tconnected_edges size=" + connected_edges.size());
+ it = connected_edges.keySet().iterator();
+ while (it.hasNext()) {
+ String k = (String) it.next();
+ println("\t\tlist\t" + k + "\t" + connected_edges.get(k));
+ }
+ }
+ if (edgetrace) println("================ addEdge");
+}
+
+void addSpacersToNode( Node node ) {
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ Node n = (Node) nodes.get(key);
+ Particle q = n.p;
+ if ( node.p != q ) {
+ physics.makeAttraction( q, node.p, -SPACER_STRENGTH, MIN_DISTANCE );
+ }
+ }
+}
+
+Node newNode(String id, String name, String grp, String uid, String proj) {
+ if (nodetrace) print("----------------\nnewNode\tdefine\tid=" + id + " name=" + name + " grp=" + grp);
+ if (id == null || id.equals("")) return null;
+ if (name == null || name.equals("")) return null;
+ String label = name;//unescapeSTR(name);
+ Node node = findNode(id, proj);
+ if (node == null) node = new Node(id, label, grp, uid, proj);
+ node.name = label;
+ node.grp = grp;
+ if (nodetrace) println("\tdefined\tid=" + node.id + " name=" + node.name + " grp=" + node.grp);
+ addNode(node);
+ if (nodetrace) println("---------------- newNode");
+ return node;
+}
+
+void urlNode(String url, String id, String proj) {
+ if (nodetrace) println("node="+id+" url="+url);
+ Node node = findNode(id, proj);
+ if (node != null && url != null) node.setURL(url);
+}
+void addNode(Node node) {
+ if (nodetrace) print("\t--------\n\taddNode id=" + node.id + " name=" + node.name);
+ String the_id = node.id;
+ String proj = node.proj;
+ Node the_node = findNode( the_id, proj );
+ if (the_node!=null) { // increment used count
+ if (nodetrace) println("\taddNode node Exists.");
+ the_node.count += 1;
+ }
+ else { // add new node
+ if (nodetrace) println("\taddNode ADD node.");
+ nodes.put( the_id, node );
+ addSpacersToNode( node );
+ }
+ if (nodetrace) {
+ println("\tnodes size=" + nodes.size() );
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ Node n = (Node) nodes.get(key);
+ println("\t\tlist\t" + key + "\t" + n.name);
+ }
+ println("\t-------- addNode");
+ }
+}
+
+void printHex(String str) {
+ char chr;
+ int i;
+ println(str);
+ println("length="+str.length());
+ for (i = 0; i < str.length(); i++) {
+ chr = str.charAt(i) ;
+ print(" " + hex((int)chr,4));
+ }
+ print("\n");
+}
+
+Node findNode(String id, String proj) {
+ if (nodetrace) print("\n\tfindNode id=" + id + " proj=" + proj);
+ Node n = null;
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String k = (String) it.next();
+ n = (Node) nodes.get(k);
+ id = id.trim();
+ proj=proj.trim();
+ if(k.equals(id) && n.proj.equals(proj)) {
+ if (nodetrace) {
+ println("\tnode FOUND.");
+ }
+ return n;
+ }
+ }
+ if (nodetrace) println("\tnode NOT found.");
+ return null;
+}
+
+void selectNode(Node node) {
+ if (nodetrace) println("selectNode(" + node.id + ")");
+ String the_id = node.id;
+ topicX = Math.round( node.p.position.x );
+ topicY = Math.round( node.p.position.y );
+ if (node.vizgroup == null)
+ vizgroup.clear();
+ else
+ vizgroupNodes(node);
+}
+
+void infoNode(Node node) {
+ //func = "info node";
+ String the_id = node.id;
+ String the_proj = node.proj;
+ if (nodetrace) println("infoNode name=" + node.name + " id=" + the_id + " proj=" + the_proj);
+ if ( javascript != null ) {
+ javascript.selectnode(the_id, the_proj);
+ }
+}
+
+void topicNode(Node node) {
+ //func = "topic node";
+ String the_id = node.id;
+ if ( javascript != null ) {
+ if (nodetrace) println("topicNode " + node.name + " (" + node.id + ")");
+ javascript.topicnode(the_id);
+ }
+}
+
+void setNodePosition(String id, String proj, int x, int y) {
+ if (nodetrace) println("setNodePosition id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if (node!=null) node.position(x, y);
+}
+
+void fixNode(String id, String proj) {
+ if (nodetrace) println("fixNode id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if (node!=null) node.fix();
+}
+
+void setNodeValue(String id, String proj, String name, String grp, String abst, String uid) {
+ if (nodetrace) println("setNodeValue id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if ( node != null ) {
+ if ( uid != null && !uid.equals("") ) node.uid = uid;
+ if ( name != null && !name.equals("") ) node.name = name;
+ if ( grp != null && !grp.equals("") ) node.grp = grp;
+ if ( abst != null && !abst.equals("") ) node.abst = abst;
+ }
+}
+
+void setNodeName(String id, String proj, String name) {
+ if (nodetrace) println("setNodeName id=" + id + " proj=" + proj + " name=" + name);
+ Node node = findNode(id, proj);
+ if ( node != null ) {
+ if ( name != null && !name.equals("") ) node.name = name;
+ }
+}
+
+void setNodeAssoc(String id, String proj, int assoc) {
+ if (nodetrace) println("setNodeAssoc id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if ( node!=null ) node.assoc = assoc;
+ if ( nodetrace ) println("\tset node "+node.name+"("+id+")"+"\tassoc="+node.assoc);
+}
+
+void setNodeCount(String id, String proj, int count) {
+ if (nodetrace) println("setNodeCount id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if ( node!=null ) node.count = count;
+ if (nodetrace) println("\tset node "+node.name+"("+id+")"+"\tcount="+node.count);
+}
+
+void setNodeMass(String id, String proj, int mass) {
+ if (nodetrace) println("setNodeMass id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if (node!=null) node.mass = mass;
+ if (nodetrace) println("\tset node "+node.name+"("+id+")"+"\tmass="+node.mass);
+}
+
+void setNodeFreeDirection(String id, String proj, String d) {
+ if (nodetrace) println("setNodeFreeDirection id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if ( node!=null ) {
+ node.freeDirection = d;
+ node.p.freeDirection = d;
+ }
+}
+
+void setNodeVizgroup(String id, String proj, String g) {
+ if (nodetrace) println("setNodeVizgroup id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if ( node!=null ) {
+ node.vizgroup = g;
+ }
+}
+
+void setNodeSize(String id, String proj, int size) {
+ if (nodetrace) println("setNodeSize id=" + id + " proj=" + proj);
+ Node node = findNode(id, proj);
+ if ( node!=null ) node.size = size;
+}
+
+void newTopic() {
+ if (debug) println("newTopic");
+ if (javascript!=null) {
+ javascript.new_topic();
+ }
+}
+
+void pedia() {
+ if (debug) println("pedia");
+ if (javascript!=null) {
+ javascript.pedia();
+ }
+}
+/*
+void setTopic(String oldid, String id, String name, String grp) {
+ if (debug) println("setTopic oldid="+oldid+" id=" + id + " name=" + name + " grp=" + grp);
+ //if (debug) println("setTopic id=" + id + " name=" + name + " grp=" + grp);
+ name = name; //unescapeSTR( name );
+ oldid = oldid;
+ id = id;
+ Node n = findNode(id);
+ if (n == null) n = newNode(id, name, grp);
+ if (debug) println( n.id );
+ n.name = name;
+ n.grp = grp;
+ n.fix();
+ n.position(0, 0);
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ Node oldnode = findNode(oldid);
+ if (oldnode!=null) {
+ connected = connectedEdges(oldnode);
+ for (int i = 0; i < connected.size(); i++) {
+ Edge e = (Edge) connected.get(i);
+ if (debug) println("\told:" + oldnode.name + " relation:" + e.from.name + " " + e.to.name);
+ if ( oldnode.id.equals(e.from.id) ) {
+ if (debug) println("\tnew:" + name + " relation:" + name + " " + e.to.name);
+ e.from.id = id;
+ e.from.name = name;
+ e.from.grp = grp;
+ }
+ else if (oldnode.id.equals(e.to.id) ) {
+ if (debug) println("\tnew:" + name + " relation:" + e.from.name + " " + name);
+ e.to.id = id;
+ e.to.name = name;
+ e.to.grp = grp;
+ }
+ }
+ }
+ hideNode(oldnode);
+}
+*/
+void newRelation(Node n) {
+ if (debug) println("newRelation");
+ //func = "new relation";
+ from_node = selected;
+ selection = null;
+ damper = 1.0;
+}
+
+void expandNode(Node node, String both) {
+ //func = "expand node";
+ free = true;
+ connected_edges.clear();
+ String the_id = node.id;
+ String the_proj = node.proj;
+ fixNode(the_id, the_proj);
+ if (javascript!=null) {
+ javascript.startexpand();
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ connected = connectedEdges(node);
+ the_adjacents = "(''";
+ for (int i = 0; i < connected.size(); i++) {
+ Edge e = (Edge) connected.get(i);
+ String ajacent_id = "";
+ if ( node.id.equals(e.from.id) ) {
+ ajacent_id = e.to.id;
+ }
+ else if ( node.id.equals(e.to.id) ) {
+ ajacent_id = e.from.id;
+ }
+ the_adjacents += ",'"+ajacent_id+"'";
+ }
+ the_adjacents += ")";
+ if (debug) println("expandNode name="+node.name+" id="+node.id+" proj="+node.proj+" ajacents="+the_adjacents);
+ javascript.adjacentnodes(the_id, the_proj, the_adjacents, both);
+ javascript.endexpand();
+ }
+ damper = 1.0;
+}
+
+void squeezeNode(Node node) {
+ //func = "squeeze node";
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ String from_is, to_is;
+ from_is = to_is = "";
+ String the_id = node.id;
+ Node self, other;
+ self = other = null;
+ if (debug) println("squeezeNode " + the_id + " " + node.isa);
+ if (!node.isa.equals("leaf")) {
+ connected = connectedEdges(node);
+ if (debug) println(connected.size() + " connected edge(s)");
+ for (int i = 0; i < connected.size(); i++) {
+ Edge e = (Edge) connected.get(i);
+ if (the_id.equals(e.from.id)) {
+ self = e.from;
+ from_is = e.from_is;
+ other = e.to;
+ to_is = e.to_is;
+ }
+ else if (the_id.equals(e.to.id)) {
+ self = e.to;
+ from_is = e.to_is;
+ other = e.from;
+ to_is = e.from_is;
+ }
+ if (debug) println("self=" + self.id + ":" + self.isa + "(" + from_is + ")\t" +
+ "other=" + other.id + ":" + other.isa + "(" + to_is + ")");
+ if ( to_is != null && to_is.equals("leaf") ) {
+ if (other.isa.equals("leaf")) {
+ if (debug) println("remove edge " + e.asc_id + " leaf " + other.id);
+ edges.remove(e.asc_id);
+ nodes.remove(other.id);
+ for (int j = 0; j < physics.numberOfAttractions(); j++) {
+ Attraction attraction = physics.getAttraction(j);
+ if (attraction.getOneEnd() == other.p || attraction.getTheOtherEnd() == other.p) {
+ attraction.turnOff();
+ }
+ }
+ for (int j = 0; j < physics.numberOfAttractions(); j++) {
+ Attraction attraction = physics.getAttraction(j);
+ if ( attraction.isOff() ) physics.removeAttraction(j);
+ }
+ }
+ else if (other.isa.equals("branch")) {
+ if (debug) println("squeeze branch " + other.id);
+ squeezeNode(other);
+ edges.remove(e.asc_id);
+ nodes.remove(other.id);
+ for (int j = 0; j < physics.numberOfAttractions(); j++) {
+ Attraction attraction = physics.getAttraction(j);
+ if (attraction.getOneEnd() == other.p || attraction.getTheOtherEnd() == other.p) {
+ attraction.turnOff();
+ }
+ }
+ for (int j = 0; j < physics.numberOfAttractions(); j++) {
+ Attraction attraction = physics.getAttraction(j);
+ if ( attraction.isOff() ) physics.removeAttraction(j);
+ }
+ }
+ }
+ }
+ }
+}
+
+void deleteTopic(String id, String proj) {
+ if (debug) println("deleteTopic " + id);
+ Node node = findNode(id, proj);
+ if (node!=null) hideNode(node);
+}
+
+void hideNode(Node node) {
+ if (debug) println("hideNode " + node.id + " " + node.isa);
+ //func = "hide node";
+ if (node.vizgroup!=null) return;
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ connected = connectedEdges(node);
+ //if (!node.root) {
+ if (connected.size() > 0) squeezeNode(node);
+ String the_id = node.id;
+ if (debug) println(connected.size() + " connected edge(s)");
+ if (connected !=null) {
+ for (int i=0; i < connected.size(); i++) {
+ Edge e = connected.get(i);
+ edges.remove(e.asc_id);
+ }
+ }
+
+ if (debug) println("\tRemove " + node.id + " " + node.name);
+ nodes.remove(node.id);
+
+ for (int i = 0; i < physics.numberOfAttractions(); i++) {
+ Attraction attraction = physics.getAttraction(i);
+ if (attraction.getOneEnd() == node.p || attraction.getTheOtherEnd() == node.p) {
+ attraction.turnOff();
+ }
+ }
+ for (int i = 0; i < physics.numberOfAttractions(); i++) {
+ Attraction attraction = physics.getAttraction(i);
+ if ( attraction.isOff() ) physics.removeAttraction(i);
+ }
+ //}
+}
+
+void markNode() {
+ //Object k;
+ String k;
+ String key;
+ Node node;
+ Edge edge;
+ int count;
+ Iterator it;
+ ArrayList<Node> adjacent = new ArrayList<Node>();
+ // clear node isa status
+ it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ key = (String) it.next();
+ node = (Node) nodes.get(key);
+ node.isa = "";
+ node.count = 0;
+ nodes.put(key, node);
+ }
+ // reset node conecctioncounts
+ it = edges.keySet().iterator();
+ while (it.hasNext ()) {
+ k = (String) it.next();
+ edge = (Edge) edges.get(k);
+ key = edge.from.id;
+ node = (Node) nodes.get(key);
+ node.count += 1;
+ key = edge.to.id;
+ node = (Node) nodes.get(key);
+ node.count += 1;
+ }
+ it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ key = (String) it.next();
+ node = (Node) nodes.get(key);
+ // A node is leaf iff a node is connected to one edge.
+ count = node.count;
+ if (!node.root && node.isa.equals("") && count == 1) {
+ node.isa = "leaf";
+ //if (debug) print(key + " is leaf.\n");
+ nodes.put(key, node);
+ }
+ // A node is trunk iff a node is root.
+ if (node.root) {
+ node.isa = "trunk";
+ //if (debug) print(key + " is trunk.\n");
+ nodes.put(key, node);
+ // A node is trunk iff a node is connected directry to root node.
+ adjacent = adjacentNodes(node);
+ for (int i = 0; i < adjacent.size(); i++) {
+ Node n = (Node) adjacent.get(i);
+ key = n.id;
+ n.isa = "trunk";
+ //if (debug) print(key + " is trunk connected to root.\n");
+ nodes.put(key, n);
+ }
+ }
+ }
+ // repeat 3 times
+ int repeat = 0;
+ while (repeat++ <= 3) {
+ it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ key = (String) it.next();
+ node = (Node) nodes.get(key);
+ if (node.isa.equals(""));
+ {
+ // A node is branch iff a node is connected directry to n-1 leaf and/or branch nodes.
+ // A node is trunk iff a node is connected directry to more than 2 trunk nodes.
+ adjacent = adjacentNodes(node);
+ int branch_count, trunc_count;
+ branch_count = trunc_count = 0;
+ for (int i = 0; i < adjacent.size(); i++) {
+ Node n = (Node) adjacent.get(i);
+ if (n.isa.equals("leaf") || n.isa.equals("branch")) branch_count++;
+ else if (n.isa.equals("trunk")) trunc_count++;
+ }
+ if (node.isa.equals("") && branch_count == adjacent.size() - 1) {
+ node.isa = "branch";
+ //if (debug) print(key + " is branch.(Step2)\n");
+ nodes.put(key, node);
+ }
+ else if (node.isa.equals("") && trunc_count >= 2) {
+ node.isa = "trunk";
+ //if (debug) print(key + " is trunk.(Step2)\n");
+ nodes.put(key, node);
+ }
+ }
+ }
+ }
+ // A node is trunk if a node is neigther leaf nor branch i.e. "".
+ it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ key = (String) it.next();
+ node = (Node) nodes.get(key);
+ if (node.isa.equals("")) {
+ node.isa = "trunk";
+ //if (debug) print(key + " is trunk.(Step3)\n");
+ nodes.put(key, node);
+ }
+ }
+}
+
+ArrayList<Node> adjacentNodes(Node node) {
+ ArrayList<Node> adjacent = new ArrayList<Node>();
+ String the_id = node.id;
+ Iterator it = edges.keySet().iterator();
+ while (it.hasNext ()) {
+ Object k = it.next();
+ Edge e = (Edge) edges.get(k);
+ Node other = null;
+ if (the_id.equals(e.from.id)) {
+ other = e.to;
+ }
+ else if (the_id.equals(e.to.id)) {
+ other = e.from;
+ }
+ if (other != null) adjacent.add(other);
+ }
+ return adjacent;
+}
+
+void vizgroupNodes(Node node) {
+ vizgroup.clear();
+ String the_vizgroup = node.vizgroup;
+ Iterator it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ Node n = (Node) nodes.get(key);
+ if (the_vizgroup.equals(n.vizgroup)) {
+ if (n != null) vizgroup.add(n);
+ }
+ }
+}
+
+void rootNode(Node node) {
+ if (node == null) {
+ if (debug) println("EMPTY node");
+ return;
+ }
+ if (debug) {
+ println("rootNode " + node.name);
+ }
+ physics.clear();
+ edges.clear();
+ nodes.clear();
+ usercolors.clear();
+ node.root = true;
+ node.fix();
+ node.position(0, 0);
+ node.c = rootColor;
+ addNode(node);
+ if ( javascript != null ) {
+ //javascript.countassoc(node.id, node.proj);
+ }
+}
+
+void markEdge() {
+ Iterator it;
+ Object k;
+ Edge edge;
+ Node node;
+ String key;
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ int count;
+ // clear node isa status
+ it = edges.keySet().iterator();
+ while (it.hasNext ()) {
+ key = (String) it.next();
+ edge = (Edge) edges.get(key);
+ edge.from_is = "";
+ edge.to_is = "";
+ edges.put(key, edge);
+ }
+ it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ k = it.next();
+ node = (Node) nodes.get(k);
+ String the_id = node.id;
+ if (node.isa.equals("leaf")) {
+ checkEdges(node);
+ }
+ }
+ it = nodes.keySet().iterator();
+ while (it.hasNext ()) {
+ k = it.next();
+ node = (Node) nodes.get(k);
+ String the_id = node.id;
+ if (!node.isa.equals("leaf")) {
+ checkEdges(node);
+ }
+ }
+}
+
+void checkEdges(Node node) {
+ String the_id = node.id;
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ connected = connectedEdges(node);
+ for (int i = 0; i < connected.size(); i++) {
+ Edge edge = (Edge) connected.get(i);
+ Node from = edge.from;
+ Node to = edge.to;
+ if (the_id.equals(from.id) && edge.from_is.equals("")) {
+ if (from.isa.equals("leaf")) {
+ edge.from_is = "leaf";
+ edge.to_is = "trunk";
+ }
+ else if (from.isa.equals("branch") &&
+ (to.isa.equals("trunk") || to.isa.equals("root")) ) {
+ edge.from_is = "leaf";
+ edge.to_is = "trunk";
+ }
+ }
+ else if (the_id.equals(to.id) && edge.to_is.equals("")) {
+ if (to.isa.equals("leaf")) {
+ edge.to_is = "leaf";
+ edge.from_is = "trunk";
+ }
+ else if (to.isa.equals("branch") &&
+ (from.isa.equals("trunk") || from.isa.equals("root")) ) {
+ edge.to_is = "leaf";
+ edge.from_is = "trunk";
+ }
+ }
+ }
+ boolean found_trunk = false;
+ boolean found_leaf = false;
+ for (int i = 0; i < connected.size(); i++) {
+ Edge edge = (Edge) connected.get(i);
+ Node from = edge.from;
+ Node to = edge.to;
+ if ( (the_id.equals(from.id) && edge.from_is.equals("leaf")) ||
+ (the_id.equals(to.id) && edge.to_is.equals("leaf")) ) {
+ found_trunk = true;
+ }
+ if ( (the_id.equals(from.id) && edge.from_is.equals("trunk")) ||
+ (the_id.equals(to.id) && edge.to_is.equals("trunk")) ) {
+ found_leaf = true;
+ }
+ }
+ for (int i = 0; i < connected.size(); i++) {
+ Edge edge = (Edge) connected.get(i);
+ Node from = edge.from;
+ Node to = edge.to;
+ if (the_id.equals(from.id) && edge.from_is.equals("")) {
+ if (from.isa.equals("branch") && to.isa.equals("branch")) {
+ if (found_leaf) {
+ edge.from_is = "leaf";
+ edge.to_is = "trunk";
+ }
+ if (found_trunk) {
+ edge.from_is = "trunk";
+ edge.to_is = "leaf";
+ }
+ }
+ }
+ else if (the_id.equals(to.id) && edge.to_is.equals("")) {
+ if (to.isa.equals("branch") && from.isa.equals("branch")) {
+ if (found_leaf) {
+ edge.to_is = "leaf";
+ edge.from_is = "trunk";
+ }
+ if (found_trunk) {
+ edge.to_is = "trunk";
+ edge.from_is = "leaf";
+ }
+ }
+ }
+ }
+}
+
+void infoEdge(Edge e) {
+ if (debug) println("infoEdge " + e.asc_id);
+ //func = "info edge";
+ String asc_id = e.asc_id;
+ if ( javascript != null ) {
+ javascript.selectedge(asc_id);
+ }
+}
+
+void removeEdge(String asc_id) {
+ Edge e = edges.get(asc_id);
+ hideEdge(e);
+}
+
+void hideEdge(Edge e) { //TODO renumber duplicate eges between the same node pair.
+ if (debug) println("hideEdge " + e.asc_id);
+ String asc_id = e.asc_id;
+ Node from = e.from;
+ Node to = e.to;
+ edges.remove(asc_id);
+ Iterator it = edges.keySet().iterator();
+ int count_from=0;
+ int count_to=0;
+ while (it.hasNext ()) {
+ Object k = it.next();
+ Edge edge = (Edge) edges.get(k);
+ if (edge.from.id.equals(from.id) || edge.to.id.equals(from.id)) {
+ count_from++;
+ }
+ if (edge.from.id.equals(to.id) || edge.to.id.equals(to.id)) {
+ count_to++;
+ }
+ }
+ if (count_from == 0) {
+ squeezeNode(from);
+ hideNode(from);
+ }
+ else {
+ from.count = count_from;
+ from.assoc -= 1;
+ }
+ if (count_to == 0) {
+ squeezeNode(to);
+ hideNode(to);
+ }
+ else {
+ to.count = count_to;
+ to.assoc -= 1;
+ }
+}
+
+ArrayList<Edge> connectedEdges(Node node) {
+ ArrayList<Edge> connected = new ArrayList<Edge>();
+ String the_id = node.id;
+ Iterator it = edges.keySet().iterator();
+ while (it.hasNext ()) {
+ Object k = it.next();
+ Edge edge = (Edge) edges.get(k);
+ if (the_id.equals(edge.from.id) || the_id.equals(edge.to.id)) {
+ connected.add(edge);
+ }
+ }
+ return connected;
+}
+
+ArrayList<Node> connectedNodes(Node node) {
+ ArrayList<Node> connected = new ArrayList<Node>();
+ String the_id = node.id;
+ Iterator it = edges.keySet().iterator();
+ while (it.hasNext ()) {
+ Object k = it.next();
+ Edge e = (Edge) edges.get(k);
+ if ( the_id.equals(e.from.id) )
+ connected.add(e.to);
+ else if ( the_id.equals(e.to.id) )
+ connected.add(e.from);
+ }
+ return connected;
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/physics.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,1162 @@
+/*
+This is a cached copy of http://geoviz.googlecode.com/svn
+Search all code Search in http://geoviz.googlecode.com/svn
+http://geoviz.googlecode.com/svn/trunk/touchgraph/src/main/java/geovista/touchgraph/TGLayout.java
+ */
+/*
+ * TouchGraph LLC. Apache-Style Software License
+ *
+ *
+ * Copyright (c) 2002 Alexander Shapiro. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution,
+ * if any, must include the following acknowledgment:
+ * "This product includes software developed by
+ * TouchGraph LLC (http://www.touchgraph.com/)."
+ * Alternately, this acknowledgment may appear in the software itself,
+ * if and wherever such third-party acknowledgments normally appear.
+ *
+ * 4. The names "TouchGraph" or "TouchGraph LLC" must not be used to endorse
+ * or promote products derived from this software without prior written
+ * permission. For written permission, please contact
+ * alex@touchgraph.com
+ *
+ * 5. Products derived from this software may not be called "TouchGraph",
+ * nor may "TouchGraph" appear in their name, without prior written
+ * permission of alex@touchgraph.com.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL TOUCHGRAPH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ====================================================================
+ * Following codes EulerIntegrator are inspired by TGLayout.java.
+ * http://geoviz.googlecode.com/svn/trunk/touchgraph/src/main/java/geovista/touchgraph/TGLayout.java
+ */
+// PHYSICS ////////////////////////////////////////////
+/*
+* May 29, 2005
+* @author jeffrey traer bernstein
+* moified by ns 2012
+*/
+public interface Force {
+ public void turnOn();
+ public void turnOff();
+ public boolean isOn();
+ public boolean isOff();
+ public void apply();
+}
+
+public interface Integrator {
+ public void step( float t );
+}
+
+public class EulerIntegrator implements Integrator {
+ ParticleSystem s;
+
+ public EulerIntegrator( ParticleSystem s ) {
+ this.s = s;
+ }
+
+ public void step( float t ) {
+ s.clearForces();
+ s.applyForces();
+
+ for ( int i = 0; i < s.numberOfParticles(); i++ ) {
+ float lastMaxMotion = maxMotion;
+ maxMotion = 0;
+ motionRatio = 1.0;
+ Particle p = (Particle)s.getParticle( i );
+ if ( p.isFree() ) {
+ p.velocity.add( p.force.x/(p.mass * t), p.force.y/(p.mass * t) );
+
+ float squared = p.velocity.x*p.velocity.x + p.velocity.y*p.velocity.y;
+ float len = (float) sqrt( squared );
+ maxMotion = max( maxMotion, len );
+ if (maxMotion>0) motionRatio = lastMaxMotion/maxMotion - 1; //subtract 1 to make a positive value mean that
+ else motionRatio = 0; //things are moving faster
+ if ( motionRatio <= 0.001 ) {
+ if ((maxMotion<0.2 || (maxMotion>1 && damper<0.9)) && damper > 0.01) damper -= 0.005;
+ //If we've slowed down significanly, damp more aggresively (then the line two below)
+ else if (maxMotion<0.4 && damper > 0.003) damper -= 0.003;
+ //If max motion is pretty high, and we just started damping, then only damp slightly
+ else if (damper>0.0001) damper -=0.0001;
+ }
+ if ( maxMotion<0.001 ) {
+ damper=0;
+ }
+ p.velocity.multiplyBy( damper );
+
+ float dx = p.velocity.x/t;
+ float dy = p.velocity.y/t;
+ dx = max(-MAX_VELOCITY, min(MAX_VELOCITY, dx));
+ dy = max(-MAX_VELOCITY, min(MAX_VELOCITY, dy));
+ p.position.add(dx, dy );
+ }
+ }
+ }
+}
+
+public class RungeKuttaIntegrator implements Integrator {
+ ArrayList originalPositions;
+ ArrayList originalVelocities;
+ ArrayList k1Forces;
+ ArrayList k1Velocities;
+ ArrayList k2Forces;
+ ArrayList k2Velocities;
+ ArrayList k3Forces;
+ ArrayList k3Velocities;
+ ArrayList k4Forces;
+ ArrayList k4Velocities;
+
+ ParticleSystem s;
+
+ public RungeKuttaIntegrator( ParticleSystem s ) {
+ this.s = s;
+
+ originalPositions = new ArrayList();
+ originalVelocities = new ArrayList();
+ k1Forces = new ArrayList();
+ k1Velocities = new ArrayList();
+ k2Forces = new ArrayList();
+ k2Velocities = new ArrayList();
+ k3Forces = new ArrayList();
+ k3Velocities = new ArrayList();
+ k4Forces = new ArrayList();
+ k4Velocities = new ArrayList();
+ }
+
+ final void allocateParticles() {
+ while ( s.particles.size () > originalPositions.size() ) {
+ originalPositions.add( new Vector2D() );
+ originalVelocities.add( new Vector2D() );
+ k1Forces.add( new Vector2D() );
+ k1Velocities.add( new Vector2D() );
+ k2Forces.add( new Vector2D() );
+ k2Velocities.add( new Vector2D() );
+ k3Forces.add( new Vector2D() );
+ k3Velocities.add( new Vector2D() );
+ k4Forces.add( new Vector2D() );
+ k4Velocities.add( new Vector2D() );
+ }
+ }
+
+ public final void step( float deltaT ) {
+ allocateParticles();
+ /////////////////////////////////////////////////////////
+ // save original position and velocities
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ if ( p.isFree() ) {
+ ((Vector2D)originalPositions.get( i )).set( p.position );
+ ((Vector2D)originalVelocities.get( i )).set( p.velocity );
+ }
+ p.force.clear(); // and clear the forces
+ }
+
+ ////////////////////////////////////////////////////////////
+ // get all the k1 values
+ s.applyForces();
+
+ // save the intermediate forces
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ if ( p.isFree() ) {
+ ((Vector2D)k1Forces.get( i )).set( p.force );
+ ((Vector2D)k1Velocities.get( i )).set( p.velocity );
+ }
+ p.force.clear();
+ }
+
+ ////////////////////////////////////////////////////////////
+ // get k2 values
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ String freeDirection = p.freeDirection;
+ if ( p.isFree() ) {
+ Vector2D originalPosition = (Vector2D)originalPositions.get( i );
+ Vector2D k1Velocity = (Vector2D)k1Velocities.get( i );
+
+ if(freeDirection.indexOf("x")>=0)
+ p.position.x = originalPosition.x + k1Velocity.x * deltaT;
+ if(freeDirection.indexOf("y")>=0)
+ p.position.y = originalPosition.y + k1Velocity.y * deltaT;
+ //p.position.z = originalPosition.z + k1Velocity.z * deltaT;
+
+ Vector2D originalVelocity = (Vector2D)originalVelocities.get( i );
+ Vector2D k1Force = (Vector2D)k1Forces.get( i );
+
+ if(freeDirection.indexOf("x")>=0)
+ p.velocity.x = originalVelocity.x + k1Force.x * deltaT / p.mass;
+ if(freeDirection.indexOf("y")>=0)
+ p.velocity.y = originalVelocity.y + k1Force.y * deltaT / p.mass;
+ // p.velocity.z = originalVelocity.z + k1Force.z * deltaT / p.mass;
+ }
+ }
+
+ s.applyForces();
+
+ // save the intermediate forces
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ if ( p.isFree() ) {
+ ((Vector2D)k2Forces.get( i )).set( p.force );
+ ((Vector2D)k2Velocities.get( i )).set( p.velocity );
+ }
+ p.force.clear(); // and clear the forces now that we are done with them
+ }
+
+ /////////////////////////////////////////////////////
+ // get k3 values
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ String freeDirection = p.freeDirection;
+ if ( p.isFree() ) {
+ Vector2D originalPosition = (Vector2D)originalPositions.get( i );
+ Vector2D k2Velocity = (Vector2D)k2Velocities.get( i );
+
+ if(freeDirection.indexOf("x")>=0)
+ p.position.x = originalPosition.x + k2Velocity.x * deltaT;
+ if(freeDirection.indexOf("y")>=0)
+ p.position.y = originalPosition.y + k2Velocity.y * deltaT;
+ //p.position.z = originalPosition.z + k2Velocity.z * deltaT;
+
+ Vector2D originalVelocity = (Vector2D)originalVelocities.get( i );
+ Vector2D k2Force = (Vector2D)k2Forces.get( i );
+
+ if(freeDirection.indexOf("x")>=0)
+ p.velocity.x = originalVelocity.x + k2Force.x * deltaT / p.mass;
+ if(freeDirection.indexOf("y")>=0)
+ p.velocity.y = originalVelocity.y + k2Force.y * deltaT / p.mass;
+ //p.velocity.z = originalVelocity.z + k2Force.z * deltaT / p.mass;
+ }
+ }
+
+ s.applyForces();
+
+ // save the intermediate forces
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ if ( p.isFree() ) {
+ ((Vector2D)k3Forces.get( i )).set( p.force );
+ ((Vector2D)k3Velocities.get( i )).set( p.velocity );
+ }
+ p.force.clear(); // and clear the forces now that we are done with them
+ }
+
+ //////////////////////////////////////////////////
+ // get k4 values
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ String freeDirection = p.freeDirection;
+ if ( p.isFree() ) {
+ Vector2D originalPosition = (Vector2D)originalPositions.get( i );
+ Vector2D k3Velocity = (Vector2D)k3Velocities.get( i );
+
+ if(freeDirection.indexOf("x")>=0)
+ p.position.x = originalPosition.x + k3Velocity.x * deltaT;
+ if(freeDirection.indexOf("y")>=0)
+ p.position.y = originalPosition.y + k3Velocity.y * deltaT;
+ //p.position.z = originalPosition.z + k3Velocity.z * deltaT;
+
+ Vector2D originalVelocity = (Vector2D)originalVelocities.get( i );
+ Vector2D k3Force = (Vector2D)k3Forces.get( i );
+
+ if(freeDirection.indexOf("x")>=0)
+ p.velocity.x = originalVelocity.x + k3Force.x * deltaT / p.mass;
+ if(freeDirection.indexOf("y")>=0)
+ p.velocity.y = originalVelocity.y + k3Force.y * deltaT / p.mass;
+ //p.velocity.z = originalVelocity.z + k3Force.z * deltaT / p.mass;
+ }
+ }
+
+ s.applyForces();
+
+ // save the intermediate forces
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ if ( p.isFree() ) {
+ ((Vector2D)k4Forces.get( i )).set( p.force );
+ ((Vector2D)k4Velocities.get( i )).set( p.velocity );
+ }
+ }
+
+ /////////////////////////////////////////////////////////////
+ // put them all together and what do you get?
+ float lastMaxMotion = maxMotion;
+ maxMotion = 0;
+ motionRatio = 1.0;
+ for ( int i = 0; i < s.particles.size(); ++i ) {
+ Particle p = (Particle)s.particles.get( i );
+ String freeDirection = p.freeDirection;
+ p.age += deltaT;
+ if ( p.isFree() ) {
+ // update position
+ Vector2D originalPosition = (Vector2D)originalPositions.get( i );
+ Vector2D k1Velocity = (Vector2D)k1Velocities.get( i );
+ Vector2D k2Velocity = (Vector2D)k2Velocities.get( i );
+ Vector2D k3Velocity = (Vector2D)k3Velocities.get( i );
+ Vector2D k4Velocity = (Vector2D)k4Velocities.get( i );
+
+ Vector2D dPosition = new Vector2D();
+ if(freeDirection.indexOf("x")>=0)
+ dPosition.x = deltaT / 6.0f * ( k1Velocity.x + 2.0f * k2Velocity.x + 2.0f * k3Velocity.x + k4Velocity.x );
+ if(freeDirection.indexOf("y")>=0)
+ dPosition.y = deltaT / 6.0f * ( k1Velocity.y + 2.0f * k2Velocity.y + 2.0f * k3Velocity.y + k4Velocity.y );
+ //dPosition.z = deltaT / 6.0f * ( k1Velocity.z + 2.0f * k2Velocity.z + 2.0f * k3Velocity.z + k4Velocity.z );
+
+ float squared = dPosition.x*dPosition.x + dPosition.y*dPosition.y /*+ dPosition.z*dPosition.z*/;
+ float len = (float) Math.sqrt( squared );
+ maxMotion = Math.max( maxMotion, len );
+ if (maxMotion>0) motionRatio = lastMaxMotion/maxMotion - 1; //subtract 1 to make a positive value mean that
+ else motionRatio = 0; //things are moving faster
+ if ( motionRatio <= 0.001 ) {
+ //This is important. Only damp when the graph starts to move faster
+ //When there is noise, you damp roughly half the time. (Which is a lot)
+ //If things are slowing down, then you can let them do so on their own,
+ //without damping.
+ //If max motion<0.2, damp away
+ //If by the time the damper has ticked down to 0.9, maxMotion is still>1, damp away
+ //We never want the damper to be negative though
+// if ((maxMotion<0.1 || (maxMotion>1 && damper<0.3)) && damper > 0.01) damper -= 0.01;
+ if ((maxMotion<0.2 || (maxMotion>1 && damper<0.7)) && damper > 0.01) damper -= 0.01;
+ //If we've slowed down significanly, damp more aggresively (then the line two below)
+ else if (maxMotion<0.4 && damper > 0.003) damper -= 0.003;
+ //If max motion is pretty high, and we just started damping, then only damp slightly
+ else if (damper>0.0001) damper -=0.0001;
+ }
+ if ( maxMotion<0.001 ) {
+ damper=0;
+ }
+
+ dPosition.multiplyBy( damper );
+
+ if (len > MAX_DISTANCE) {
+ dPosition.multiplyBy( MAX_DISTANCE/len );
+ }
+
+ if(freeDirection.indexOf("x")>=0)
+ p.position.x = originalPosition.x + dPosition.x;
+ if(freeDirection.indexOf("y")>=0)
+ p.position.y = originalPosition.y + dPosition.y;
+ //p.position.z = originalPosition.z + dPosition.z;
+
+ // update velocity
+ Vector2D originalVelocity = (Vector2D)originalVelocities.get( i );
+ Vector2D k1Force = (Vector2D)k1Forces.get( i );
+ Vector2D k2Force = (Vector2D)k2Forces.get( i );
+ Vector2D k3Force = (Vector2D)k3Forces.get( i );
+ Vector2D k4Force = (Vector2D)k4Forces.get( i );
+ Vector2D dVelocity = new Vector2D();
+
+ if(freeDirection.indexOf("x")>=0)
+ dVelocity.x = deltaT / ( 6.0f * p.mass ) * ( k1Force.x + 2.0f * k2Force.x + 2.0f * k3Force.x + k4Force.x );
+ if(freeDirection.indexOf("y")>=0)
+ dVelocity.y = deltaT / ( 6.0f * p.mass ) * ( k1Force.y + 2.0f * k2Force.y + 2.0f * k3Force.y + k4Force.y );
+ //dVelocity.z = deltaT / ( 6.0f * p.mass ) * ( k1Force.z + 2.0f * k2Force.z + 2.0f * k3Force.z + k4Force.z );
+
+ squared = dVelocity.x*dVelocity.x + dVelocity.y*dVelocity.y /*+ dVelocity.z*dVelocity.z*/;
+ len = (float) Math.sqrt(squared);
+ if (len > MAX_VELOCITY) {
+ if(freeDirection.indexOf("x")>=0)
+ dVelocity.x *= MAX_VELOCITY/len;
+ if(freeDirection.indexOf("y")>=0)
+ dVelocity.y *= MAX_VELOCITY/len;
+ //dVelocity.z *= MAX_VELOCITY/len;
+ }
+
+ if(freeDirection.indexOf("x")>=0)
+ p.velocity.x = originalVelocity.x + dVelocity.x;
+ if(freeDirection.indexOf("y")>=0)
+ p.velocity.y = originalVelocity.y + dVelocity.y;
+ //p.velocity.z = originalVelocity.z + dVelocity.z;
+ }
+ }
+ }
+}
+
+public class Attraction implements Force {
+ Particle a;
+ Particle b;
+ float k;
+ boolean on;
+ float distanceMin;
+ float distanceMinSquared;
+
+ public Attraction( Particle a, Particle b, float k, float distanceMin ) {
+ this.a = a;
+ this.b = b;
+ this.k = k;
+ on = true;
+ this.distanceMin = distanceMin;
+ this.distanceMinSquared = distanceMin*distanceMin;
+ }
+
+ public void setA( Particle p ) {
+ a = p;
+ }
+
+ public void setB( Particle p ) {
+ b = p;
+ }
+
+ public final float getMinimumDistance() {
+ return distanceMin;
+ }
+
+ public final void setMinimumDistance( float d ) {
+ distanceMin = d;
+ distanceMinSquared = d*d;
+ }
+
+ public final void turnOff() {
+ on = false;
+ }
+
+ public final void turnOn() {
+ on = true;
+ }
+
+ public final void setStrength( float k ) {
+ this.k = k;
+ }
+
+ public final Particle getOneEnd() {
+ return a;
+ }
+
+ public final Particle getTheOtherEnd() {
+ return b;
+ }
+
+ public void apply() {
+ if ( on && ( a.isFree() || b.isFree() ) ) {
+ float a2bX = a.position.x - b.position.x;
+ float a2bY = a.position.y - b.position.y;
+ float a2bDistanceSquared = a2bX*a2bX + a2bY*a2bY;
+
+ if ( a2bDistanceSquared < distanceMinSquared ) {
+ a2bX = random(-distanceMin,distanceMin);
+ a2bY = random(-distanceMin,distanceMin);
+ }
+
+ float force = k * a.mass * b.mass / a2bDistanceSquared;
+
+ float length = (float)Math.sqrt( a2bDistanceSquared );
+
+ // make unit vector
+ a2bX /= length;
+ a2bY /= length;
+
+ // multiply by force
+ a2bX *= force;
+ a2bY *= force;
+
+ // apply
+ if (length < 600) {
+ if ( a.isFree() )
+ a.force.add( -a2bX, -a2bY );
+ if ( b.isFree() )
+ b.force.add( a2bX, a2bY );
+ }
+ }
+ }
+
+ public final float getStrength() {
+ return k;
+ }
+
+ public final boolean isOn() {
+ return on;
+ }
+
+ public final boolean isOff() {
+ return !on;
+ }
+}
+
+public class Particle {
+ public Vector2D position;
+ public Vector2D velocity;
+ public Vector2D force;
+ public float mass;
+ public float age;
+ public boolean dead;
+ public boolean fixed;
+ public String freeDirection;
+
+ public Particle( float m ) {
+ position = new Vector2D();
+ velocity = new Vector2D();
+ force = new Vector2D();
+ mass = m;
+ age = 0;
+ dead = false;
+ fixed = false;
+ freeDirection = "xy";
+ }
+
+ public final float distanceTo( Particle p ) {
+ return this.position.distanceTo( p.position );
+ }
+
+ public final void makeFixed() {
+ fixed = true;
+ velocity.clear();
+ }
+
+ public final boolean isFixed() {
+ return fixed;
+ }
+
+ public final boolean isFree() {
+ return !fixed;
+ }
+
+ public final void makeFree() {
+ fixed = false;
+ }
+
+ public final Vector2D position() {
+ return position;
+ }
+
+ public final Vector2D velocity() {
+ return velocity;
+ }
+
+ public final float mass() {
+ return mass;
+ }
+
+ public final void setMass( float m ) {
+ mass = m;
+ }
+
+ public final Vector2D force() {
+ return force;
+ }
+
+ public final float age() {
+ return age;
+ }
+
+ public void reset() {
+ age = 0;
+ dead = false;
+ position.clear();
+ velocity.clear();
+ force.clear();
+ mass = 1f;
+ }
+}
+
+public class ParticleSystem {
+ public static final color RUNGE_KUTTA = 0;
+ public static final color EULER = 1;
+ public static final color MODIFIED_EULER = 2;
+
+ public static final float DEFAULT_GRAVITY = 0;
+ public static final float DEFAULT_DRAG = 0.001f;
+
+ ArrayList particles;
+ ArrayList springs;
+ ArrayList attractions;
+ ArrayList customForces = new ArrayList();
+
+ Integrator integrator;
+
+ Vector2D gravity;
+ float drag;
+
+ boolean hasDeadParticles = false;
+
+ public final void setIntegrator( int integrator ) {
+ switch ( integrator ) {
+ case RUNGE_KUTTA:
+ this.integrator = new RungeKuttaIntegrator( this );
+ break;
+ case EULER:
+ this.integrator = new EulerIntegrator( this );
+ break;
+ }
+ }
+
+ public final void setGravity( float x, float y/*, float z*/ ) {
+ gravity.set( x, y );
+ }
+
+ // default down gravity
+ public final void setGravity( float g ) {
+ gravity.set( 0, g );
+ }
+
+ public final void setDrag( float d ) {
+ drag = d;
+ }
+
+ public final void tick() {
+ tick( 1 );
+ }
+
+ public final void tick( float t ) {
+ integrator.step( t );
+ }
+
+ public final Particle makeParticle( float mass, float x, float y/*, float z*/ ) {
+ Particle p = new Particle( mass );
+ p.position.set( x, y );
+ particles.add( p );
+ return p;
+ }
+
+ public final Particle makeParticle() {
+ return makeParticle( 1.0f, 0f, 0f );
+ }
+
+ public final Spring makeSpring( Particle a, Particle b, float ks, float d, float r ) {
+ Spring s = new Spring( a, b, ks, d, r );
+ springs.add( s );
+ return s;
+ }
+
+ public final Attraction makeAttraction( Particle a, Particle b, float k, float minDistance ) {
+ Attraction m = new Attraction( a, b, k, minDistance );
+ attractions.add( m );
+ return m;
+ }
+
+ public final void clear() {
+ particles.clear();
+ springs.clear();
+ attractions.clear();
+ }
+
+ public ParticleSystem( float g, float somedrag ) {
+ integrator = new RungeKuttaIntegrator( this );
+ particles = new ArrayList();
+ springs = new ArrayList();
+ attractions = new ArrayList();
+ gravity = new Vector2D( 0, g );
+ drag = somedrag;
+ }
+
+ public ParticleSystem( float gx, float gy, float gz, float somedrag ) {
+ integrator = new RungeKuttaIntegrator( this );
+ particles = new ArrayList();
+ springs = new ArrayList();
+ attractions = new ArrayList();
+ gravity = new Vector2D( gx, gy );
+ drag = somedrag;
+ }
+
+ public ParticleSystem() {
+ integrator = new RungeKuttaIntegrator( this );
+ particles = new ArrayList();
+ springs = new ArrayList();
+ attractions = new ArrayList();
+ gravity = new Vector2D( 0, ParticleSystem.DEFAULT_GRAVITY );
+ drag = ParticleSystem.DEFAULT_DRAG;
+ }
+
+ public final void applyForces() {
+ if ( !gravity.isZero() ) {
+ for ( int i = 0; i < particles.size(); ++i ) {
+ Particle p = (Particle)particles.get( i );
+ p.force.add( gravity );
+ }
+ }
+
+ for ( int i = 0; i < particles.size(); ++i ) {
+ Particle p = (Particle)particles.get( i );
+ p.force.add( p.velocity.x * -drag, p.velocity.y * -drag );
+ }
+
+ for ( int i = 0; i < springs.size(); i++ ) {
+ Spring f = (Spring)springs.get( i );
+ f.apply();
+ }
+
+ for ( int i = 0; i < attractions.size(); i++ ) {
+ Attraction f = (Attraction)attractions.get( i );
+ f.apply();
+ }
+
+ for ( int i = 0; i < customForces.size(); i++ ) {
+ Force f = (Force)customForces.get( i );
+ f.apply();
+ }
+ }
+
+ public final void clearForces() {
+ Iterator i = particles.iterator();
+ while ( i.hasNext () ) {
+ Particle p = (Particle)i.next();
+ p.force.clear();
+ }
+ }
+
+ public final int numberOfParticles() {
+ return particles.size();
+ }
+
+ public final int numberOfSprings() {
+ return springs.size();
+ }
+
+ public final int numberOfAttractions() {
+ return attractions.size();
+ }
+
+ public final Particle getParticle( int i ) {
+ return (Particle)particles.get( i );
+ }
+
+ public final Spring getSpring( int i ) {
+ return (Spring)springs.get( i );
+ }
+
+ public final Attraction getAttraction( int i ) {
+ return (Attraction)attractions.get( i );
+ }
+
+ public final void addCustomForce( Force f ) {
+ customForces.add( f );
+ }
+
+ public final int numberOfCustomForces() {
+ return customForces.size();
+ }
+
+ public final Force getCustomForce( int i ) {
+ return (Force)customForces.get( i );
+ }
+
+ public final Force removeCustomForce( int i ) {
+ return (Force)customForces.remove( i );
+ }
+
+ public final void removeParticle( Particle p ) {
+ particles.remove( p );
+ }
+
+ public final Spring removeSpring( int i ) {
+ return (Spring)springs.remove( i );
+ }
+
+ public final Attraction removeAttraction( int i ) {
+ return (Attraction)attractions.remove( i );
+ }
+
+ public final void removeAttraction( Attraction s ) {
+ attractions.remove( s );
+ }
+
+ public final void removeSpring( Spring a ) {
+ springs.remove( a );
+ }
+
+ public final void removeCustomForce( Force f ) {
+ customForces.remove( f );
+ }
+}
+
+public class Spring implements Force {
+ float springConstant;
+ float damping;
+ float restLength;
+ Particle a, b;
+ boolean on;
+
+ public Spring( Particle A, Particle B, float ks, float d, float r ) {
+ springConstant = ks;
+ damping = d;
+ restLength = r;
+ a = A;
+ b = B;
+ on = true;
+ }
+
+ public final void turnOff() {
+ on = false;
+ }
+
+ public final void turnOn() {
+ on = true;
+ }
+
+ public final boolean isOn() {
+ return on;
+ }
+
+ public final boolean isOff() {
+ return !on;
+ }
+
+ public final Particle getOneEnd() {
+ return a;
+ }
+
+ public final Particle getTheOtherEnd() {
+ return b;
+ }
+
+ public final float currentLength() {
+ return a.position.distanceTo( b.position );
+ }
+
+ public final float restLength() {
+ return restLength;
+ }
+
+ public final float strength() {
+ return springConstant;
+ }
+
+ public final void setStrength( float ks ) {
+ springConstant = ks;
+ }
+
+ public final float damping() {
+ return damping;
+ }
+
+ public final void setDamping( float d ) {
+ damping = d;
+ }
+
+ public final void setRestLength( float l ) {
+ restLength = l;
+ }
+
+ public final void apply() {
+ if ( on && ( a.isFree() || b.isFree() ) ) {
+ float a2bX = a.position.x - b.position.x;
+ float a2bY = a.position.y - b.position.y;
+
+ float a2bDistance = (float)Math.sqrt( a2bX*a2bX + a2bY*a2bY );
+
+ if ( a2bDistance == 0 ) {
+ a2bX = 0;
+ a2bY = 0;
+ //a2bZ = 0;
+ }
+ else {
+ a2bX /= a2bDistance;
+ a2bY /= a2bDistance;
+ }
+
+ // spring force is proportional to how much it stretched
+ float springForce = -( a2bDistance - restLength ) * springConstant;
+
+ // want velocity along line b/w a & b, damping force is proportional to this
+ float Va2bX = a.velocity.x - b.velocity.x;
+ float Va2bY = a.velocity.y - b.velocity.y;
+
+
+ float dampingForce = -damping * ( a2bX*Va2bX + a2bY*Va2bY );
+
+ // forceB is same as forceA in opposite direction
+ float r = springForce + dampingForce;
+
+ a2bX *= r;
+ a2bY *= r;
+
+ if (a2bDistance < MIN_DISTANCE) {
+ if ( a.isFree() )
+ a.force.add( a2bX, a2bY );
+ if ( b.isFree() )
+ b.force.add( -a2bX, -a2bY );
+ }
+ else {
+ if ( a.isFree() )
+ a.force.add( a2bX/10, a2bY/10 );
+ if ( b.isFree() )
+ b.force.add( -a2bX/10, -a2bY/10 );
+ }
+
+ }
+ }
+
+ public void setA( Particle p ) {
+ a = p;
+ }
+
+ public void setB( Particle p ) {
+ b = p;
+ }
+}
+
+public class Vector2D {
+ float x;
+ float y;
+
+ public Vector2D( float X, float Y ) {
+ x = X;
+ y = Y;
+ }
+
+ public Vector2D( ) {
+ x = 0;
+ y = 0;
+ }
+
+ public Vector2D( Vector2D p ) {
+ x = p.x;
+ y = p.y;
+ }
+
+ public final void set( float X, float Y ) {
+ x = X;
+ y = Y;
+ }
+
+ public final void set( Vector2D p ) {
+ x = p.x;
+ y = p.y;
+ }
+
+ public final void add( Vector2D p ) {
+ x += p.x;
+ y += p.y;
+ }
+ public final void subtract( Vector2D p ) {
+ x -= p.x;
+ y -= p.y;
+ }
+
+ public final void add( float a, float b ) {
+ x += a;
+ y += b;
+ }
+ public final void subtract( float a, float b ) {
+ x -= a;
+ y -= b;
+ }
+
+ public final Vector2D multiplyBy( float f ) {
+ x *= f;
+ y *= f;
+ return this;
+ }
+
+ public final float distanceTo( Vector2D p ) {
+ return (float)Math.sqrt( distanceSquaredTo( p ) );
+ }
+
+ public final float distanceSquaredTo( Vector2D p ) {
+ float dx = x-p.x;
+ float dy = y-p.y;
+ return dx*dx + dy*dy;
+ }
+
+ public final float distanceTo( float x, float y ) {
+ float dx = this.x - x;
+ float dy = this.y - y;
+ return (float)Math.sqrt( dx*dx + dy*dy );
+ }
+
+ public final float length() {
+ return (float)Math.sqrt( x*x + y*y );
+ }
+
+ public final float lengthSquared() {
+ return x*x + y*y;
+ }
+
+ public final void clear() {
+ x = 0;
+ y = 0;
+ }
+
+ public final String toString() {
+ return new String( "(" + x + ", " + y + ")" );
+ }
+
+ public boolean isZero() {
+ return x == 0 && y == 0;
+ }
+
+ float dot( Vector2D p ) {
+ return x * p.x + y * p.y;
+ }
+
+ float cross( Vector2D p ) {
+ float c = (x * p.y - y * p.x);
+ return (float) Math.sqrt( c * c );
+ }
+
+ float abs() {
+ return (float) Math.sqrt( x * x + y * y );
+ }
+
+ float distance( Vector2D a, Vector2D b) {
+ float EPS = 0.001f;
+ Vector2D b_a = new Vector2D( b.x - a.x, b.y - a.y );
+ Vector2D p_a = new Vector2D( x - a.x, y - a.y );
+ Vector2D a_b = new Vector2D( a.x - b.x, a.y - b.y );
+ Vector2D p_b = new Vector2D( x - b.x, y - b.y );
+ if ( b_a.dot(p_a) < EPS ) return p_a.abs();
+ else if ( a_b.dot(p_b) < EPS ) return p_b.abs();
+ else return ( b_a.cross(p_a) / b_a.abs() );
+ }
+}
+
+public class Vector3D {
+ float x;
+ float y;
+ float z;
+
+ public Vector3D( float X, float Y, float Z ) {
+ x = X;
+ y = Y;
+ z = Z;
+ }
+
+ public Vector3D() {
+ x = 0;
+ y = 0;
+ z = 0;
+ }
+
+ public Vector3D( Vector3D p ) {
+ x = p.x;
+ y = p.y;
+ z = p.z;
+ }
+
+ public final float z() {
+ return z;
+ }
+
+ public final float y() {
+ return y;
+ }
+
+ public final float x() {
+ return x;
+ }
+
+ public final void setX( float X ) {
+ x = X;
+ }
+
+ public final void setY( float Y ) {
+ y = Y;
+ }
+
+ public final void setZ( float Z ) {
+ z = Z;
+ }
+
+ public final void set( float X, float Y, float Z ) {
+ x = X;
+ y = Y;
+ z = Z;
+ }
+
+ public final void set( Vector3D p ) {
+ x = p.x;
+ y = p.y;
+ z = p.z;
+ }
+
+ public final void add( Vector3D p ) {
+ x += p.x;
+ y += p.y;
+ z += p.z;
+ }
+ public final void subtract( Vector3D p ) {
+ x -= p.x;
+ y -= p.y;
+ z -= p.z;
+ }
+
+ public final void add( float a, float b, float c ) {
+ x += a;
+ y += b;
+ z += c;
+ }
+ public final void subtract( float a, float b, float c ) {
+ x -= a;
+ y -= b;
+ z -= c;
+ }
+
+ public final Vector3D multiplyBy( float f ) {
+ x *= f;
+ y *= f;
+ z *= f;
+ return this;
+ }
+
+ public final float distanceTo( Vector3D p ) {
+ return (float)Math.sqrt( distanceSquaredTo( p ) );
+ }
+
+ public final float distanceSquaredTo( Vector3D p ) {
+ float dx = x-p.x;
+ float dy = y-p.y;
+ float dz = z-p.z;
+ return dx*dx + dy*dy + dz*dz;
+ }
+
+ public final float distanceTo( float x, float y, float z ) {
+ float dx = this.x - x;
+ float dy = this.y - y;
+ float dz = this.z - z;
+ return (float)Math.sqrt( dx*dx + dy*dy + dz*dz );
+ }
+
+ public final float dot( Vector3D p ) {
+ return x*p.x + y*p.y + z*p.z;
+ }
+
+ public final float length() {
+ return (float)Math.sqrt( x*x + y*y + z*z );
+ }
+
+ public final float lengthSquared() {
+ return x*x + y*y + z*z;
+ }
+
+ public final void clear() {
+ x = 0;
+ y = 0;
+ z = 0;
+ }
+
+ public final String toString() {
+ return new String( "(" + x + ", " + y + ", " + z + ")" );
+ }
+
+ public final Vector3D cross( Vector3D p ) {
+ return new Vector3D(
+ this.y * p.z - this.z * p.y,
+ this.x * p.z - this.z * p.x,
+ this.x * p.y - this.y * p.x );
+ }
+
+ public boolean isZero() {
+ return x == 0 && y == 0 && z == 0;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/preload.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,1 @@
+/* @pjs preload="/blog/wp-content/uploads/2012/05/genbakunoko.jpg"; */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/hp/static/hp/tmgraph/tmgraph.pde Wed Nov 14 17:26:06 2012 +0100
@@ -0,0 +1,370 @@
+String title = "17 June, 2012 ver.02";
+PFont font;
+
+String ln = "en";// "ja" "fr"
+boolean personal = true;
+boolean editmode = true;
+boolean debug = false;
+boolean nodetrace = false;
+boolean edgetrace = false;
+boolean eventtrace = false;
+boolean attractiontrace = false;
+boolean load = false;
+boolean showusername = false;
+
+ParticleSystem physics;
+Node selection,
+ selected,
+ previous_selection,
+ from_node, to_node,
+ dragnode;
+Edge sel_edge,
+ selected_edge;
+int edgeCount = 0;
+int topicCount = 0;
+
+boolean touch = false;
+boolean free = true;
+boolean dragging = false;
+boolean draggingnode = false;
+boolean menu_active = false;
+boolean apmenu_active = false;
+boolean edgmenu_active = false;
+boolean mouseMode = false;
+boolean dowbleclick = false;
+boolean touched = false;
+boolean holding = false;
+boolean dragmode = false;
+
+int menu = 0;
+int edgmenu = 0;
+int apmenu = 0;
+int centerX,
+ centerY;
+int touchX,
+ touchY;
+int menuX,
+ menuY;
+int scrnX,
+ scrnY;
+int pressStartX,
+ pressStartY;
+int pointX,
+ pointY;
+int topicX,
+ topicY;
+
+float start = 0;
+float elapsedTimeMillis = 0;
+float elapsedTimeSec = 0.0;
+float factor = 1.0;
+float damper = 1.0;
+float maxMotion = 0;
+float motionRatio;
+float start_dist,
+ currt_dist;
+float scl;
+float theta1,
+ phai,
+ theta2;
+float fromX,
+ fromY,
+ toX,
+ toY,
+ cX,
+ cY;
+
+String both = "both";
+String msg = "";
+String str = "";
+String event= "";
+String func = "";
+
+String unescapeSTR(String text) {
+ String str=text;
+ if (str == null || str.equals("")) return "";
+ str = str.replaceAll("&","&");
+ str = str.replaceAll(""","\"");
+ str = str.replaceAll("'","'");
+ str = str.replaceAll(""","\"");
+ str = str.replaceAll("<","<");
+ str = str.replaceAll(">",">");
+ str = str.replaceAll("<br>","\n");
+ return str;
+}
+
+String trimSTR(String text) {
+ String str=text;
+ if (str == null || str.equals("")) return "";
+ str = str.replaceAll("\n","");
+ str = str.replaceAll("\f","");
+ str = str.replaceAll(" ","");
+ str = str.replaceAll(" ","");
+ str = str.replaceAll("\r","");
+ return str;
+}
+
+void setDebugmode(){
+ debug = true;
+}
+
+//////// PROCESSING //////////////////////////////////////////////////////////
+int WORLD_SIZE_W, WORLD_SIZE_H;
+
+void setSize(int w, int h) {
+ if (javascript != null) {
+ WORLD_SIZE_W = w;
+ WORLD_SIZE_H = h;
+ size(w, h);
+ }
+}
+
+void setup() {
+ WORLD_SIZE_W = 600;
+ WORLD_SIZE_H = 600;
+ size(WORLD_SIZE_W, WORLD_SIZE_H);
+ //size(600, 600);
+
+ physics = new ParticleSystem( 0, DRAGFACTOR/* 0.1*/ );
+ // Runge-Kutta, the default integrator is stable and snappy,
+ // but slows down quickly as you add particles.
+ // Try this to see how Euler is faster, but borderline unstable.
+ // physics.setIntegrator( ParticleSystem.EULER );
+ // Now try this to see make it more damped, but stable.
+ physics.setDrag( DRAGFACTOR );
+ physics.clear();
+
+ setNodeShapes();
+ if (load) loadData();
+
+ frameRate(FRAME);
+ smooth();
+
+ selected = null;
+ selection = null;
+ menu_active = false;
+ apmenu_active = false;
+ mouseMode = false;
+ damper = 1.0f;
+
+ if( debug || load || nodetrace || edgetrace || eventtrace || attractiontrace || editmode ) setMode();
+ stopDoubleClickTimer();
+}
+
+void draw() {
+ physics.tick(TICK);
+ if (dragmode)
+ bgColor = MintCream;
+ else
+ bgColor = White;
+ background(bgColor);
+ smooth();
+
+ translate( WORLD_SIZE_W/2, WORLD_SIZE_H/2);
+ if (dragging == true) {
+ pushMatrix();
+ translate((pointX - pressStartX) * factor,
+ (pointY - pressStartY) * factor);
+ }
+
+ drawNetwork();
+
+ if (dragging == true) popMatrix();
+ if (menu_active) showMenu();
+ else if (apmenu_active) showApMenu();
+ else if (edgmenu_active) showEdgMenu();
+ translate( -WORLD_SIZE_W/2, -WORLD_SIZE_H/2);
+ debugTrace();
+ checkHoldTimer();
+}
+
+void zoom(float value) {
+ factor = round(value*10)/10;
+}
+
+void drawNetwork() {
+ noStroke();
+ // draw attractions
+ if (attractiontrace) {
+ Iterator ita = physics.attractions.iterator();
+ while (ita.hasNext ()) {
+ Attraction attraction = (Attraction) ita.next();
+ if ( attraction.isOn() ) {
+ strokeWeight(1);
+ stroke(LightPink);
+ line(factor*attraction.getOneEnd().position.x, factor*attraction.getOneEnd().position.y,
+ factor*attraction.getTheOtherEnd().position.x, factor*attraction.getTheOtherEnd().position.y);
+ }
+ }
+ }
+ // draw edges
+ Iterator ite = edges.entrySet().iterator();
+ while (ite.hasNext ()) {
+ Map.Entry ee = (Map.Entry)ite.next();
+ String k = (String) ee.getKey();
+ Edge edge = (Edge) ee.getValue();
+ edge.show();
+ }
+ if (sel_edge != null) sel_edge.highlight();
+ // draw vertices
+ Iterator itv = nodes.entrySet().iterator();
+ while (itv.hasNext ()) {
+ Map.Entry ev = (Map.Entry)itv.next();
+ String k = (String) ev.getKey();
+ Node node = (Node) ev.getValue();
+ node.update();
+ if(node != selection && node != selected) node.show();
+ }
+ if ( selection != null) {
+ selection.highlight();
+ highlite_vizgroup();
+ }
+ if ( selected != null ) selected.highlight();
+ if ( from_node != null ) from_node.highlight();
+ if ( sel_edge != null ) sel_edge.highlight();
+ markNode();
+ markEdge();
+}
+
+void highlite_vizgroup() {//Displays selected group topics
+ if (vizgroup!=null){
+ for (int i = 0; i < vizgroup.size(); i++) {
+ Node n = (Node) vizgroup.get(i);
+ n.highlight();
+ }
+ }
+}
+
+//////// DEBUG TRACE /////////////////////////////////////////////////////////
+void funcTrace(String f) {
+ func = f;
+ fill(Gray);
+ textSize(12);
+ textAlign(RIGHT, TOP);
+ text(f, WORLD_SIZE_W - 20, 10);
+}
+
+void debugTrace() {
+ funcTrace(func);
+ fill(Gray);
+ textSize(12);
+ textAlign(LEFT, TOP);
+ str = "scale:" + factor; text(str, 10, 10);
+ str = (personal)?"personal":"team";
+ str += " work";
+ text(str, 70, 10);
+
+ Iterator it = usercolors.keySet().iterator();
+ int i=0,loc=10,h=10;
+ while (it.hasNext ()) {
+ String key = (String) it.next();
+ UserColor usercolor = (UserColor) usercolors.get(key);
+ stroke(usercolor.c);
+ strokeWeight(3);
+ line (loc,WORLD_SIZE_H-h,loc+20,WORLD_SIZE_H-h);
+ text(usercolor.name,loc+25,WORLD_SIZE_H-h-10);
+ loc += textWidth(usercolor.name)+35;
+ if (loc > WORLD_SIZE_W - 100) {
+ loc=10; h -= 10;
+ }
+ }
+
+ //str = "motion:" + toStr(mouse_motion); text(str, 10, 10);
+ if (debug) {
+ if (!isMouse) {
+ str = "touch menu active:" + menu_active; text(str, 10, 20);
+ str = "apmenu active:" + apmenu_active; text(str, 150, 20);
+ str = "menu:" + toStr(menu); text(str, 10, 30);
+ str = "apmenu:" + toStr(apmenu); text(str, 150, 30);
+ str = "tuoch x=" + touchX + " y=" + touchY; text(str, 10, 40);
+ str = "screen x=" + scrnX + " y=" + scrnY; text(str, 140, 40);
+ str = "point x=" + pointX + " y=" + pointY; text(str, 270, 40);
+ str = "screen x=" + scrnX + " y=" + scrnY; text(str, 400, 40);
+ str = "start x=" + pressStartX + " y=" + pressStartY; text(str, 530, 40);
+ str = (selection != null)? selection.name : "";
+ str = "selection:\t" + str; text(str, 10, 50);
+ str = (selected != null)? selected.name : "";
+ str = "selected:\t" + str; text(str, 10, 60);
+ str = event; text(str, 10, 70);
+ str = "dragging=" + dragging; text(str, 140, 70);
+ str = "dragging node=" + draggingnode; text(str, 270, 70);
+ str = "func=" + func; text(str, 400, 70);
+ str = "touch count=" + touch_count; text(str, 10, 80);
+ //str = "start time(ms)=" + start; text(str, 140, 80);
+ //str = "elapsed time=" + elapsedTimeSec; text(str, 270, 80);
+ //str = "holding=" + holding; text(str, 400, 80);
+ //str = "touched=" + touched; text(str, 530, 80);
+ }
+ else {
+ str = "menu active:" + menu_active; text(str, 10, 20);
+ str = "apmenu active:" + apmenu_active; text(str, 150, 20);
+ str = "menu:" + toStr(menu); text(str, 10, 30);
+ str = "apmenu:" + toStr(apmenu); text(str, 150, 30);
+ str = "mouse x=" + mouseX + " y=" + mouseY; text(str, 10, 40);
+ str = "point x=" + pointX + " y=" + pointY; text(str, 150, 40);
+ str = "screen x=" + scrnX + " y=" + scrnY; text(str, 290, 40);
+ str = "start x=" + pressStartX + " y=" + pressStartY;text(str, 430, 40);
+ str = (selection != null)? selection.name : "";
+ str = "selection:\t" + str; text(str, 10, 50);
+ str = (from_node != null)? from_node.name : "";
+ str = "from:\t" + str; text(str, 150, 50);
+ str = (selection != null)? selection.shape : "";
+ str = "shape:\t" + str; text(str, 290, 50);
+ str = (selected != null)? selected.name : "";
+ str = "selected:\t" + str; text(str, 10, 60);
+ str = (to_node != null)? to_node.name : "";
+ str = "to:\t" + str; text(str, 150, 60);
+ str = event; text(str, 10, 70);
+ str = "mouse=" + mouseMode; text(str, 150, 70);
+ str = "dragging=" + dragging; text(str, 290, 70);
+ str = "func=" + func; text(str, 430, 70);
+ str = "start=" + start; text(str, 570, 70);
+ str = (sel_edge != null)? sel_edge.from.name : "";
+ str = "edge from:\t" + str; text(str, 10, 80);
+ str = (sel_edge != null)? sel_edge.to.name : "";
+ str = "to:\t" + str; text(str, 150, 80);
+ str = (sel_edge != null)? sel_edge.asc_id : "";
+ str = "asc_id:\t" + str; text(str, 290, 80);
+ str = (sel_edge != null)? "" + sel_edge.dup : "";
+ str = "dup:\t" + str; text(str, 430, 80);
+ str = (previous_selection != null)? "" + previous_selection.name : "";
+ str = "previous_selection=" + str; text(str, 10, 90);
+ //str = "theta1=" + degrees(theta1); text(str, 10, 90);
+ //str = "phai=" + degrees(phai); text(str, 150, 90);
+ //str = "theta2=" + degrees(theta2); text(str, 290, 90);
+ }
+}
+
+if (eventtrace) {
+ str = "mouse :" + toStr(mouse_event); text(str, 10, 110);
+ str = "touch :" + toStr(touch_event); text(str, 10, 120);
+ str = "motion:" + toStr(mouse_motion); text(str, 10, 130);
+ str = "action:" + toStr(mouse_action); text(str, 10, 140);
+ str = "time:" + millis()/1000F; text(str, 10, 150);
+ str = "Ct:" + touchedC; text(str, 10, 160);
+ str = "startC:" + startC; text(str, 10, 170);
+ str = "CTimer:" + elapsedTimeClick; text(str, 10, 180);
+ str = "Dt:" + touchedD; text(str,100, 160);
+ str = "startD:" + startD; text(str,100, 170);
+ str = "DTimer:" + elapsedTimeDoubleClick; text(str,100, 180);
+ str = "Ht:" + touchedH; text(str,180, 160);
+ str = "startH:" + startH; text(str,180, 170);
+ str = "HTimer:" + elapsedTimeHold; text(str,180, 180);
+ str = "pressed:" + mousePressed; text(str,120, 110);
+ str = "is down:" + is_down; text(str,120, 120);
+ str = "start__:" + start_dist; text(str, 10, 190);
+ str = "current:" + currt_dist; text(str, 10, 200);
+ str = "scale__:" + scl/100; text(str, 10, 210);
+ }
+}
+/*
+void setParams(float frame, float spring_length, float spring_strength, float spring_damping, float spacer_strength, float drag, int mass) {
+ FRAME = frame;
+ SPRING_LENGTH = spring_length;
+ SPRING_STRENGTH = spring_strength; // 0.2;
+ SPRING_DAMPING = spring_damping; // 0.2;
+ SPACER_STRENGTH = spacer_strength;// 1000;
+ DRAGFACTOR = drag; //0.2
+ //MASS = mass;
+}
+*/
--- a/src/hp/templates/hp/partial/embed_player.html Wed Nov 14 16:35:12 2012 +0100
+++ b/src/hp/templates/hp/partial/embed_player.html Wed Nov 14 17:26:06 2012 +0100
@@ -2,15 +2,18 @@
{% load i18n %}
{% load thumbnail %}
{% load staticfiles %}
-<div>
-<div id="{{ player_id }}_embed" class="iri_player_embed">
+
+<div id="LdtPlayer" class="iri_player_embed">
</div>
<script type="text/javascript" src="{{LDT_STATIC_URL}}ldt/metadataplayer/LdtPlayer-core.js"></script>
<script type="text/javascript">
- IriSP.libFiles.defaultDir = "libs/";
+ IriSP.libFiles.defaultDir = "{{LDT_STATIC_URL}}ldt/js";
+ IriSP.libFiles.locations.jwPlayerSWF = "{{LDT_STATIC_URL}}ldt/swf/player.swf";
+ IriSP.libFiles.locations.zeroClipboardSwf = "{{LDT_STATIC_URL}}ldt/swf/ZeroClipboard10.swf";
+ IriSP.libFiles.locations.cssjQueryUI = "{{LDT_STATIC_URL}}ldt/css/jq-css/themes/base/jquery-ui.css"
IriSP.language = '{{LANGUAGE_CODE}}';
- IriSP.widgetsDir = "metadataplayer";
+ IriSP.widgetsDir = "{{LDT_STATIC_URL}}ldt/metadataplayer";
var _metadata = {
url: '{{LDT_URL}}ldt/cljson/id/{{project_id}}?callback=?',
format: 'ldt'
@@ -42,7 +45,6 @@
{ type: "Controller" },
{ type: "Polemic" },
{ type: "Segments" },
- { type: "Arrow" },
{
type: "Annotation",
search_on_tag_click: false,
@@ -52,16 +54,18 @@
{
type: "KnowledgeConcierge",
container: "KcContainer",
- proxy: "{% url kc_proxy '' %}",
+ kc_api_root: "{% url kc_proxy '' %}",
width: 480,
height: 420,
+ sketch_path: '{% static "hp/tmgraph" %}',
project_id: "{{kc_id}}",
- topic_id: "{{topic_id}}"
+ topic_id: "{{topic_id}}",
+ related_api_endpoint: '{% url videos_recommended %}',
+ video_url_base: '{% url hp.views.show_video_details "" %}'
}
]
};
var _myPlayer = new IriSP.Metadataplayer(_config);
</script>
-</div>
{% endspaceless %}
--- a/src/hp/templates/hp/video_player.html Wed Nov 14 16:35:12 2012 +0100
+++ b/src/hp/templates/hp/video_player.html Wed Nov 14 17:26:06 2012 +0100
@@ -20,14 +20,11 @@
<div class="main row">
<div class="column left-column">
<h2>{% trans 'Watch' %} "{{content.title}}"</h2>
- <div class="ldt_player" id="wrapper_{{player_id}}">
{% include "hp/partial/embed_player.html" %}
- </div>
</div>
<div class="column right-column">
<h2>{% trans 'Explore topics' %}</h2>
<div id="KcContainer"></div>
- <h2>{% trans 'Related videos' %}</h2>
</div>
</div>