From e8597bcbeb79fec8441bb40e89549121b9758069 Mon Sep 17 00:00:00 2001 From: Alex de Mulder Date: Tue, 4 Feb 2014 17:04:04 +0100 Subject: [PATCH] WIP manipulate dataset for graph --- Jakefile.js | 1 + dist/UI_icons/addNodeIcon.png | Bin 0 -> 20998 bytes dist/UI_icons/backIcon.png | Bin 0 -> 20802 bytes dist/UI_icons/connectIcon.png | Bin 0 -> 20764 bytes dist/UI_icons/deleteIcon.png | Bin 0 -> 20981 bytes dist/vis.js | 222 ++++++++++++++++++++++++++---- examples/graph/20_UI_example.html | 83 +++++++++++ src/graph/Graph.js | 66 ++++++--- src/graph/Node.js | 4 +- src/graph/SelectionMixin.js | 24 ++-- src/graph/manipulationMixin.js | 128 +++++++++++++++++ 11 files changed, 468 insertions(+), 60 deletions(-) create mode 100644 dist/UI_icons/addNodeIcon.png create mode 100644 dist/UI_icons/backIcon.png create mode 100644 dist/UI_icons/connectIcon.png create mode 100644 dist/UI_icons/deleteIcon.png create mode 100644 src/graph/manipulationMixin.js diff --git a/Jakefile.js b/Jakefile.js index a4795eab..a4a9aa54 100644 --- a/Jakefile.js +++ b/Jakefile.js @@ -82,6 +82,7 @@ task('build', {async: true}, function () { './src/graph/Popup.js', './src/graph/Groups.js', './src/graph/Images.js', + './src/graph/manipulationMixin.js', './src/graph/SectorsMixin.js', './src/graph/ClusterMixin.js', './src/graph/SelectionMixin.js', diff --git a/dist/UI_icons/addNodeIcon.png b/dist/UI_icons/addNodeIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..6fa30613f9b3d97508534c69421eca60f1126746 GIT binary patch literal 20998 zcmeI42{@GN`^R4qLa3}sXGpd%t6|1i$C@oWl^8Q)Ow5d!vJ}x`tCJ+z9WC~yqR3W6 zR78|yiAqumr&N^fKT?y^an5gk%YVDBnd=&Jd*1v0KF|Akp68zXedoH~=xtUetNGUR z0RXVt%+%19@hP$J=H+JmeHx%W#rRm|YwF?;0Q~C~-W)(m8pDInnvBJ6+vY{1)BL?? zz92I!7Ub(k^CbHa0U)p^-Hv2$_gYMQvj2mDc~sbGbDFIvFUZ#5SeQthyt2$H;jK|J zXS+ph>ed(;aY^0IjN&|TBJ8-Rjfy}F-(#K^GUrYlJ|7ixclz1>^WKlDCtu#1yV|8Q zTsV~5#`8?13>GDQHFq*7Esvc7-IxDLjVy^^9B^~ zSQUVnIeD4_m&$?KR$=}UfL8#3*hC#w0=V`A?zcB>3IvWM10u%noiOjV6blb4Ge{+u zU@GKLM&UbnRrl~XIjL<_Y&8?#B7(%Nz@_M^-3&^WgoPu7o=&s?KxUjM<7_8p16u`) zTU(JQ$^_k1M{aP>%X)YW&JDE{`04?`GkR$IoC>&feV7(^7-jC<<}og>UHqAQCy#lS z2gmmv4;EP)+D@%H;?egq)?}ufe||>#foy}BM}@Pp$e_*IJtquPj!(d{WTOpE zDc#!KF;93tpfb&=GoTJ!+O5N}KTb8*70>y}TtV2GUi*9!0Nz*8>K-cca)x;we%2N+ zKdw7#lDQcO^E5lP2LN^%%Bk7kE!Az}1pvd$aOF$-QXlFhRBE|5)UE8R zxM?74z()w%;ODMXc*sC8;@%}`Wq0sHJ!wR(jaNjxub|pZhiih`zCvGcycubl>J;=dS`n|T_3RL7y zbR9O{|Z@w&BC{WP2{*q%MXI1n^eB0#!uC?JtwX2X^ z0R|x4MtxIf3umjxrn#UEa)>oOt29<|9a+@I%k85t z(qGiSfWMG>A@hC*U%H3ho(ofU&lPR&?%panBs_!|;wC1+^c~Kp*gnZUYrjT4cDq5* z*)rRUHj%mO5PMTl_YRAhnP(N9OL(x}OWbRceDM{%a?O*3jaG^GojRIdo4iVV#rYvX zV0DD(;if2(qGYNBj|53FK;mMOMYiOFW0Fnw5Dn;?q~TE_Idf)`ThC)4igT|_OW@p>_Uo-9pH9@d8;0tDR9V7-}c5%%8rz$l^dB)%B9)s zUI=xWjplZ#x2U(qUa-l$>^4~42;#>}mIkWGc&{#q*c-0iAb}0NLSy>AOme1~e zmn>(8?XIQ9Md?MGA5|4q<*do6u!^@T$aqAmzx1x`PFY^Lh4>n^J}g-2Z<4ZR}H

|#V-x46+1BId1SnF`o)!|KGJUGs&sOwUB zRzUtFZd_dFlaAkSgF1s4jec0ai(89EZTao;X6t%dhTG8r?7>a*g!$n4b|5EgGY5$? zI$S?|$BOBx-~%!@PUxb0iJwZkNA-_qR_KfB#~vy=G*nk4<8}M($s(D_;iT5MR-6;L=DdDJOF_k?eh^ZIsZqIy7kAJ%`s@QdLY!~Rqf)EaeBb*s9v zPQKc1Opit-qEfd}&C{i&(>dMQ%*T8KN=>;KN%grtFf%$4`8@qO|KNV{B=Bul-=MRt zH$NQB5zA9stAakGXAxzkdHQ#KVdY%0qt$y; zWy|1GZ{w=fgXC_(vs8vEjws}vthQKf@gxCf#;5Q>B+*CE~9I?jEYU%HjQn-+^!FXvmwsu2ENOXRyn_Ros_|bSWLt=$K-W zUhzcHgO3&a0*9m`X?JfV_np3ySI|&FX!GpweEqUtHDib1nf%0;iGtMC-91-U4>(>K z{rJhK7o2!cvA61Q8Mfm54a~J_V$Pk`ds@2o7wkXSf3Zi7bv(I>>zbmrk4f#X{)Bkj z*}J29a#rWg^+PU5uLbm^pSadiIcsWa0Q*CH#*p3x@G4$fJgO@d`z6%RY5 zJGAX>V;^mKVHS404S{h9+B#u>hurh}(1Uo=`?llh z3F#rBYM=Yud(V~aAI7&1>=vSpR|?agbr{Vb8`i4UYTfz%8vT7q@6bA@YfdQ_(QcFx z`Uqw&{(*HYcg*!Y9`8H2yEY(mqP@>#lKbf4wz;^E zu|n9DvB|N`5vwEKWN7N3P|tP!W?#?bVA}|7@)_cD=jNJ=#l^s(Q=M+|K0cK36p z<0a$c=eanOCT8$()m{M57bM#|)156X(0Cd}4M(7P5Y+-HzKlW?05H0NzBs%$kq+`8 zlE_qT+3~6yvLG@+Th>Y45@P9#C3=xfgZ+qh!B+P8U~fE%AgimxhY3V81Smv04irf7 zq57i(wPnBRq8au=Ggub%)rIb@EvvuKA;{Ts8wgADBZAb`)K&2i7!;&|QiG}^P*A7} z2nK<|!B7YohEjz>(FhGR6bbtFlGWj3SQtNoC)(D~_*-|3|FmVj=yYE+7#t7~pcVjE zqxq4*P!tLUhQPoum@30V)jxOKwPj@& zI%2-QofpNI*%8(M8#@L?a3IbX3{``GmkT1`nK8b5{d~R-jerLeeTWnymF~}ogDxA# zKx%2p3|+Q63T4?yf4b2=#uzZ1eY7B!q8tX^I(P@76 zG@6gj;&T0QA;!24Q*f_KCZN>`>K+gz0ivqz z34^F=;t&W`9Gqc!dP1RaI0AyuKzMw`VQINE{7=$`H2mI$z4J|)z>qf5*FeIIQAiDh zCfo=Pg`yCe28K|$5zN3y1BKFuewSSm`X^ayKQbfd;e3|(ER1|XUIT7`gz4)WqM&~- zzl_A6x-ljDGZt6Sl10Z@dS5e|9dXYeTfZOhA%D$GzBoUB;=;z&mi@kSnW>DKsTN|s zCIB=JzmU^(@C&P%NWg&q(E4Lo%*bzHkoh{tNiw3)u*&iH2x=&m;dk_G)2RE1e*a9SW8_mDqdX=0`RjQ4(I_CCudfdok6Xx^;C)oWxB8A*ntGeMAGYB)b;7?=F)j{lN$7IQ zw11~)TPi61?EC%y#ik`e{OOipMl&4=b^Nh1(-81=w%%}X?Y9A^Bkv~BTcB^`fT z69bT$5f%wWA(5&uHAc<6tltuyg)1*KqvmDQU|+MQ4kPAIZ9n@vFVwC+d%xDE8ZZb1 z1z}w4GhW|9mmdB()aCC(mmdB(^hcxvl}y)xee3O~<|R=Jmxqf`?HIR2hzqCobJNe> z+sJ`LA7?`{GUziowRk3MHlw8y6D=D+U`EE0mZ%Y+OtftQc%utWaY5uyHX_uwt-ru|kRI!^Xu# z!HU7g#R?^+4;vQ~1uF&{7b}#QK5Se}6s#C*T&z%H`mk{^QLtjLaj`;)>BGjwM8S%| z#>EOHrVkqz69p><8y72-m_BS=OcbmbY+S5RV*0RgF;TE$uyL_MiRr_}#YDl1!N$c3 zC8iG>7ZU|51{)VEl$btjTucGUzit)F&_aHMRr?~)AdpVY1@nJk8=NI2DPE);xh>d12?K`1Ues{O)lsTQFJ z77tsU>p>4}IcMY0JyyL(E~n=b8ldhcA}G58KG+a5>tJ`>Sgh7P^FZsD)(#i% z1Lo3OR&)njB>^9fUVm8J=WXuIe}#}y*?T%tLWHAJ7gK&7dOgM+!rN21cMD^<@WH9O zvsD6(8|B^i8fTTu2TWdF`6O1E9S@~rgR&xdn{#-P?dMpa!I`}bOJ(BtFdbHBQM zPxV_p^;PQ)!z{=0kI~e0`o=D`#xyEaBK#U{LWXWRtaf`?gb5lR6e!QoI*n_t{B5`8 zvEr1PI`Om(v2*)pcFRZItt{=~tl%7|5&6|v=JV&zUM_nf(#P%OYMZ;Y)W){cYqhkS zpG9juqKv-jdJ+P8wT)00NPieAbAM#J773py{{;&uZr%U##Hx-sB_EgG(cQEIB>{Vq zk|l-T5;z>&Lh7c!oD1nUA!}+sd?8@m^!C`PiD_`cz~?u1cg(+FVcvxo;Zz93s&5d3mYO2OtzI0BX0~V zN?jAyOi)nq7FmTcJU;XA+!|o2>$ZytrO7(uAVfV*?gGdsoP*OqnWI)%cvb({tX+jH z$F1C8+EZGb>p;+(UxJiAZxSne$}vSILeeabtAyxF0R6A>!O4(~azi;{lO<#~2sBAz z;^WbJ;AHCCcM3`&9X?r)=OD$g2ggFIXtX=mH=D$UOISR&Hw-(u)%O+uN3^KY29>GY zq23mU(x+Y0vD5SCt@+EJoDk5I6p&fDIYvYxRKE3<(By8aw#J7G+D+s919V5%JQWhG z^L(Z|kVJFStj5>9k^WWth8s+H%v_^XK>{iRk?^Ou%QDRy^~(C1(;%9H=-OA2jYGQhFBzQjiWe>InzSB>tc$Yt{$(1`Mu-3MtdoQkgil$@Hr8cux8Va4JhrZA zIxat-^)ha%b}}HgTYhy`;+BZ+ov_iBVWsu=GD6(OK69J;=(Sj7$G?Wg|MGhNSWd`? zLnfwrnKg!7^0JsNNA(stb*`Hx<^3+9nbYO-oF$l|7G1k6uKifoVsYIa6-D5_(Ud&f zL(R74GY=GK(z~}?WgB|mt(J-e^!WJsq4-9D7gJ|kNA8S-ojm=7cURkt@qgI7UWuF-<)?i-Qn}&TolNZqXNC@Ty3V%+ZQtjs65JL%RWRG!%Cnu{ zCwXsUr=y3n=BmHP;~C?>X~&o%l6Q z*0M6oWB>q=wY4F;f}bjax3nbq_gRR^DEKii$i|BY0P~duZwVkH3-pk2W?5LQS>wmy zb9jE7Ac(Dn1tf^e@nr=t03h^fwj0ykt#^sZNXL7UeO%;0dyea3X^1Onf8?TM9X-u? z@^*2Wxlb0m)F@b5&QZO2G;VfcVr0T%7ySkMWFAX(Y33zHAB)>}d+ho4WBv~-M_%2X zxbTSBb80BNv`MO3dO@mzJC zUInd|x&laq-k&cGR6Ax?Bh_Lj7rr5-Z;*)GBT>yyHnNwFTm+bfCz4J8W>ylB*@t!9 zfTME&?*^LBOJEHQ@LsX&)qNl`do+E!1hD>~=3PGqb=K$#i0MaEcW+gCZJK%j&ODh!ElMXDhdgp2Uc2$Xd zj~+-W{hV>RHr_I7y)hFF{@83{ry+1=3sGWwGOS=DZT9c>E95Es>K7vb@UDVW^NX(Z z>`1@p=S?A#gQnxwN0$SUzP1Op0>CD+Hr)MoscF450FaMH>76lGeP5%ZUoELtGq%H>SZj$cayJyt(yb-^csbi{L{Pv~<$-%FAT#_>hTKJJF zol~P*88vT?`Aumhs^-%;37>rwtwd?%^q5i28k;$a`?Vpr;ug6;?UM~{P_FyjAs#mB z?@YL}@Ua`LE+?+FNOjIv91%#pIU-7c9yPaLe{s<;}lG=c6)`mK@Ez$34Hy zBmtY-bFav6;nO6dMLn|mwThI%^#CNiu9kGxNPk`mt>G;6)PkbAWoOo&nq3h;OlvwD zGDk7WvU(nNP6!D?)iAfAI8dA(+Y~_5v@r@#=i%nf-s5s@1vI6={=Cj*g%8(Ne9)*^ zijBV3L&YQ|g#7k6i|aUT#dr(!it?Xk*`EE`y+yIbs)g;U)vJFp6JxVXE9KTxy8k&T z{6T%ls+%!g*bB|*guI&Z6 z?h1xU>qy19Wv-`PVhfZo+cNNXqnFs)A1}^3bbpzjvfl{n^lScQh4w=lPHFc%TN-+; zU#GpE{XS%Y?B2!E^>IwyrI{*HD$J!JDyI)SoLG8)|I&JQBo5VgxF>yKI>&>eSEjdP zaq?}MLw1LB4yo!P+)oysDC{Vl?=j@j;GT4HliSV`D-Q#=mnY}_l3L_Zn7yXYP1TKg za&v&GLYN6&74Sy=~}Pg`0Vs;}uUTeNpul;L%qvv;5D z2-d4OJg#1`-=y$lF5bex&cL(Ob?Bh4snpBETSv3_PV;(n^V5bR_H`^8T=`<9>IsZP zIf}8tzc4i|l~QC=UFbUfvVyWp z4BK;E>rQwLlvT20*5SR5Q#{sfEVU}mE?)kyqPQYoA-~)y#i=OgA+z?(+p=3_Coe8N z)BRYowWKVtY$uiJqs+W`qoj5qr7C6T<()r{n@GvVK9MU@U#A|yJI`H2SWD>0Xv`Wg z-Ff4EYA=FGX_9YxZ1A#7sbS@HR<>K_eQTyNvz!+_6t_R#es=>rjR?vxy$S#k2GN(Who_Dn*~l8j(TAligb zg^E6q{L@xap{8R>8S@SEm2YsvDMrk>i5u+w7ZDnVq;C0_{&Z@t7fhy%bmF!9I^9Ql zQsVPDI<*CV&UkBB ztIW&Ab64$MD|yQJ(!Mgizz5Dn{hnzh5mh?jj{Z@bYHshYxgg=+H{V01J7#BJ+oS%C z&J=`K=LPD=z1gb7#qs+}7PTs;E#CE5w=J|=HI{SxYI@tj^Cye0m(!bkTYP(8b-;4g z%cT~ky-Jf~%RYH}Ubb`X`TpVGEn5+3cXeAUqRTAGk6kssRLRJ{)p&Qcsr%3F@7+JT zV+UH=FHj$ivYQ7~w^#m-`Sn5T`pS`U;;k#K9ugjo4}2dm#%#w*M@&oN3wuXX#{xGN zI|Xj-ub+xe&-3zTCa#&aI z$h^)G4Ozm|;Dqg`o=e^TAy}QMj@UxVc$Z<7>6S6J-e>(~=R3sahi^K=kA=%s5Th9QcO+#&{y-zH@y=Rz*fh`3C>;f$*ve+kHoRRdaBS?eD9? z-Y%JZ_#g*w(q1(b&KbEeGTgbOJ%YPpys@F;Nyv(U;!5Yr&F{_n&7WAb$38G!KhgGh zux;0t>X4&D&282rk}=Uu6UoC#3oYg*r6)D)mEGHyV?@N`Uzl>odq3q{G|`)Ma+D|X zCK^hVmmnfWAM`zHY(CtaoAxd(jS$vLwR4}GE;z*+&oT#n^V;ZqzP2sBP0oJ!~T zFyNtqL0};Y0LG@FK~$PQgAegxFj;I9=wQWFD1=2ffqEJ`A{~P)7=A39a4y3w+{v95 z?oY$hp{7I`<4^)95Xj(DA)$c*Y#t%h1o~N*0NR3P1Qhbwh3{_yH5YUUp*XIASa7%u zh#}k%Mnj@e5F8$kGQ{9fD18VTi84T-kO(v$hC&fAI06a_`SOAiWkAcAOZO$XlC8dU z2mWUQ_2ct{2na+-NC-T{0M6ku5hy$!k3gakXfzD;fbqiEd}=6+&C{9^`Km)^@Mv6C z5TC_iLj<~1AI>(u2^1>mNcj44UV%Zvj@Y~}>_Cc$P-+kY1xF%g3Zm15F+tn70iTCP zry&>tj6epP&jaI7Gsb~P9UXp){>4B9NB%O55z6|DFu{?ju+M91 zYO0Mv>I4fegUaV{-8q~9;?#2eb|D5{hv|B<*mO<^Z>2Hfd+%>+=9>_MOyx6(;F`w3 zkSG`$?T*3|&=`UtY84ViKq9A!OnH8%;Rx;@I+ahIrhA0UF8qH-|KMb zEZ;DZRK9sm)1cD`z8r2Kl}}^^Qke`y5SwX?_|`bh^Yg+b*s^(iDx1czB@@90IEzIm z_+Wi7NVFjxo_`bJSPaX`z3Tb>_0boJS3q<|7!nKptm6 z!lKR1$#~S?%g-S3r*3RmJaBP^OARDzh#34lPQ333{dCRoi3x-sGpt>18PLW)o%4{NI{18iyUs;Qlk24$P-iusmgOc|>0>ClEpn3JPG+sDiAC2xim2)OW(t z1j6S)rhWHK5t^p)Ke#~Y3@+=RNh;GuDZ~W%e|FCQb{Z9}{Fs_n@uq}KeIx#{Ciz-M z{ket_)VpBWMxI)jR)Xy$_(J{1B@0+}fY%I!X~4ghi=rmc@52AE4Zo<<|CNeyYGBhs zXHw?;J4NGE4>L%7>**`;X<(<7D8|C%M6lolaJY^fI)ez-12Z*G)BJWA{9S3y)Xz#p zo~tzpVryxEMd7hn7#a@N%rp8;(-B;G5x|-ktie8KO(Gccr?&6?DT3NHVB6=~6o*D4 z@ksDmAAEfYoqqWHP_MraoqqWH&~K3*Y!;u0{?glb&C{X;mxohO-N0KS48f^=-}Jrr z8dfMHfI?=0*Csqc<&DOCiTVD(jDcQ%6*%p{m%yp5Iqk;9=Or=K3f>k0@5ms8w`8WR z7Gb6TpEtgp(SKfBs3`74h(Z)Yj7tS26eZ;tgC`2*DxJ02O^bz9{q7cOp;}V6E z&_|3*h(Z)Yj7t&L4=q09fBc5G)tTfaE9Xi<-_}5uDeWvEYu3I_ zLDi`+e+x{mR~SLprf_uh4?|GKw-QkM>6%tLtBU1T+eNMltXbmb$Fa}t)OcurxPkuB zp3T0JGBn;;UVgO`-}N?h4TT~Ncqc@mBmoHYXV;U8&^N$6E3zS(UehV9&^!oeNQ~N^ zeq{YtB2GGvr#9H2zwP=vD47d(9Xld;}@T^+7b{oIpxZ*p%d48hP+nj=oCuu zm0U(zT3QyDK55H0)ZPPZtPE9%iHY$}&{UJ#Wlc6A?}?UL7;d7`MECOYn)QRZ?jk)E z4UOO{J3h3ekL9h`NjWJ6to8J)>3j1A(tw60-&|ZrLC_Wy7Z=mg;2W29mh+gBt<~O0 zdK>#Vku60VaJ8l>MT1O$b zs%pISmSL80SW5#wR@)YLzn6cKOjgfWhdJbDbKLb)O|+DprHg)dcXuwYr_nLMvzm@x zt}YkbG&thPEPW!kk_lBa3i94$zi$0{+Q>jVPij`wJ~GsWOr}sMXSOyrcXV6{RH$et zPQH0iw59RG*7&$A@}AqbZ>siYE9baC-v17FJd3jJBTSY7utEQ-szLbW{ynBn;l;brvHs*}1TeE4?m3t2# z{+?G>hE+?d@6OHDEGXPE8uW93NzDw2|t_Z~bLwl6v3_4KJZME;Dtf}A?xeO_tl z5bj5_(~p=X8!NC!e>^aGt-T_o2@ZpK#Yt!JP6G zuXj1v4$c>1i@$$uJlUr{dv!>o-GTR~b1!W(Qd9tktGn#SC0#Ex2e{>l=sLaPwSBF% zu?tsO9YdjUxQqT_VPTKDy6A_RdJKBHyO-ymIB}(=Z+O**4U!)%vvfd8GXVGvL^km@2*2}uao6pTaJ!D;B}NsM3N zoMSXQD$-yinxmu;>gJ|oXJ>byu&^%f_2{Qhl^z}s6582GJM=zWzkdA@p0N=Iheu@C z9j{hZRn5KMd-PG?k)lGG#t#aXE~k=h==B{{+m*Kw+Ux4$l;ZaoqtUK|BV&Es>`wHu zAFIfF_ypO@5#xk?`}S3<%`~7b9`3BXd|76tM$%+$d=~HKIpcc#)nupqt4+S8*`&C&Q0}b9 zusxCTK2dR%q_`vCq+SK*77F#-ur4apIPt0^5WvH~?e?vd5=td1 zA&RmTLQ*e^MA`l`sY$)w_cy=gzg^eNb&a{5=f1z^JfCyUJ@@m>bv*~|Y)r*P=3HQXI)nj(xKFqpv<0Sw@AQu%tT32!kAq4u?y}u2xqPS!fZZbgo&( z{*Dw5C!p})Y!rWVbodb&dyNH$L|+JXE1i$tdm-x3qw&s=3p<-iN8i*;U3-q{%^6N9 ztP?61UU13`VXqawAk%2MRL9<`iptJz&GiwYD`~(&;Xfb9=dR04s0iGZ}pkc-~OwRsDB)mfwxujm!8 zMBySf34?uwTwFAltJRt>Su3rLpNCIcuX#5pQ4St~lZddyh4SI+1jD_j&aWB}@Z2hP)_?S{#}&!- z*MPHqEiS_}HXGczW5vzQJ>A_eEGmpP;UBr|nj+ubR_-$C^(9PiVsxbA*6WoK@GTLh z0%IL_AAhpCw5;y9$UgVBH!-FY*TtqM6rUuiG`o`7!NUK*0_SUq~!CV+(=*v!&`nS4R2kQ2-b!q276>Cd?o1xwo^9IX!4F zX?k`Q5bj}q+!p}08n4uJdQ@moB@6(@XCu@L3>7}zS*lSkxa`jSwmV`I+qL%@t*p3f zw9rVD7{1JJ`2uLM1elD1d2jMXxOIUI5VIh!dC>HEz?9oTGg zGj`nr0KR8pf2k?#M8p+){bviVVT&_#;EQ&n7?dyDG1LMEhLtlWb4P zmKY4S3R?blsSu*V3#wUp&*-wQhDaQt`m%D)g6vB9f(<$RB?m_cb(fg}iz0C4BH98> zBM^SMp_!|dtIZ3u4A8QbNU0VP9TEP0_IFj4<1#F-uD&VtrDCZ&9CpCfOhctCk;n16kw@s*}OR zFt^Erf^PS$?%855+Mm6=t*f*WBu0=c4AfBCDW1LGKSHZw_2ru8&;a$4gh|Dc!}?j7 z=TKOL1;VA!VfciHflyb1@7QUEjYzLrdi-$Mp;yv_YhJHWNJCl`!$_NVW}S*Z<(h4l zZJ%xWzDzr>KRqR_3|Hbd9wA{^WudxR)s!4lJ3pn@vDxuux@fwrwLW?zPcv)hC53Y( z#?0G3=>rL=x3-3-T2a$q1(o%FUA7A{=``v6HGRZ%fvaHQf|Y`;3u>3@-PiJ^>M261 zT0h!jx7=Hgy@WrBkMGs!HUEY=6l^0eEu2x!YY5mT6Aj!eH zIBiYZI;(Y7RW*-m&et?0Y9;H#p2K^Sdy}6hw_o4BF>s?sQAW`XlKGYHjcINJMWsHG z8&PhTT%9*=DKyDV$z9b{l3S84m0oNUXOo@UM7~$>vFKq@=5@J(o)?0xc}3nuyYOW9 zCFJY(^X?7AmBsD4x$EepzL5BVW{GUYjf!FPtA5hx4d_=%wWkLRcHRGUst-bTty@_4 z0?}2pxOzfi1`f2Hd5k=>Ce;l=e{$~uw!^-s-azckN$Ae@oG@FgZ3OvRuL^_!iFL_+ zUU2;qGiww-xCHYV<9DVD)1{~L3jWG%+hd*b>kqD1+uoz5Zi{Tk?pB#5P6tod1L@(b z_{jVRBMc)p%^M#J4pq7xZGdhieZJD%Z+PTvv7wA%%%0pmJ$G`IJRkgVELUl?H=#DR zmLd^p7xuR4i4gt`{_wr91*(w;B3NdOuTx%&b%iWRfIQej z3p!VO_furLY^LTS4fLt?R#7&(Cq5W1RL_t-vTA5Cb5*ox&|Ss5WMxRbc74}K`l zHbZ9W*1^aBh%MC$T6rIFNu#HDpK9i@QY&$*m&xc<*`xrFH(VcG2HSf)_L#3xmXdW` z5&0eYjYmLr4k_}=)P0}B*CESK3O(Fecr0hW8(6f+DDAD&Mz!baLRZKn7mwRD2OptM zWv8yK>3>}KsP&l6>A^G8{fq7{>O5X_X}_flSkd)OS zkvVuMPr7wUyv*(wYHfi%3J0i#xSE+=QB17!Xz=KJ^9r20N#ayi{F`_QAMxgv ztK#h&uJ(_7#AM`P2_6 zgp__p{?XXFsdRJ_^YB)yGoQ0{qemlY+K^9Y#q*NhZmTN#mQ`H{G;-jHz#W_bPb8v~`8#X{4T8kj1dmLrP2Eo~Lo- zp}Hd}CsTHXX?|(j-g>?$q?b_JzC)5acyl46vjI1KxOZLYy4uY{HyA@#T6-3|+;B}b!uOJDhv83JKfZniqd~sHXKYH zy+1nAF8eafPj#}kx}=$@I*?mxTe|Jj`hLS^?8^g<2AihZUJSPF-cimxJ6zvpIw}~s zw{9wSBt{ZDKPEAzdcXMo_o=!V6za8s-(=rJI<}5jw>ovn)cL9Eyd|=bu(8JX&ui-w z>d(aw#mC+D4!tz_uKc}Rerx63%H_8n1|ncvKW!NAzr$=}Dh^&~m$dB;1?^Uw_WW{r z#PLb`c${2Z+_V6H!tewE0d55VLkWtLE5p^=3QeGTYvPGicamnHH;q+@0)U=DAPrC0 zNn(K9No0zTzVcwnZDkOJsITmzWev5aVM(48vtU1xW3Y`AA$TVNMN~Gxi0TERSpwc9 z1|AgX?d3y92kI+-(?zpvb~8j7^v#8_Q(xJT-66=;+75)J`jJ3dnp$826b=LFpfq7x zNE8gF0fIwe2nY-cfuq1M7#gXAhG~PozmzeeEKARi=z(@HHu>Hi>py*EPX>dAhCrB1 zrX~}iN%bQ`U?>y{0)<21a4^dQOb_y5-~+)vbd?#AA3DY)I>C=ZV^F9*Ahs^vo$Alf zS5{_s#Cd%`FK-&BBOm&Ab}WjJKs*fs(}Y6i3L+9XF*JWauWv&m5+Ecmk~hhRL1)Fm z=8R(@wYKJj&e@%}_neV*1}=bg2H%Oy8A*2vqLCmDBs$gKk3hl&utuUX*Wl?42hvZt zTu8Cp=Ma>hdaSgXgCtB z1zQV+p`p-OA~T-9X;`!N4-wD6&r*Sdp-3kf5{=MBYw65Z`Nj8l9V(IH5yX|sPtREz zL;~7_>gSDTU?|>rG6_QSA?rbYHqP?=ws6trK6D1&hd?qn#;_VRDHI|a<>9Ucg=!(e zcpY6B7)C_uf>9(C39O|}BBBVoBzGNx_BR~X*0aO^ByCJ3__O!UcWEL^8fU1Z4L3n) z>mYRzI0OuaLh2eB!w@*Q5l#n%GKBq*ofY~gSzA8}E9c?8X8Ev3&X(6f7-_=|4UJK- zzn7mw;!oX}QRuA26*Oznv6kMqjOIx4{k8SS0WZq8%tXWc(Mjx$tFQcH=WIT(tyGybqZ~#6W(W)sKe% zPcx=NBI4n2BoqwCBVk|!3CYTN1Z@P^T?gTgXVoRFOo#t*e*f&O&6)lG6SMZqHyby5 z=Kt2D5vV=^B)@+q)3Nd?o>iWb{OA}DKdLtfPosHJ2zYkZgar5yzt?x1(gehyf@Xd9 z%@CTU@jtjgi6lSDKa*5ujgo^2^#AOf|Lru&UHLIHt-MVMn)ycjwI=ydM*X>lVb{B? zvdwsAVVbbF6Z;GGAD1kws)KdSfSv{XN4dyt68$awmu>i6o%pX*j57n96*`wP_1`HP zXL^`J;%84kh|dB$t3=V`BqubM>P7XlrV>dQRy{CR^DNDuhgrWX+0Fc{grPf_8iCAl zSZx?eTN@15WYx@b`pwc|UwNTfH7~0M`<68^te8Kw{qFC|u3f$SztyHXa3~Z7WnJsD zUf)A!AO1bm?e9ZpAO1b`XQZ$V8%jtqozOJ>$;;Z*wn zdE@69{pYngio8xZD7Z0rxVWLj@!{d(py0;f;o^o8$A^cDgMu4_hl?9Z93LJo4hn7z z9xiSuaeR2VI4HO=c(}Ns#PQ+b;-KKh;Njwi632&!i-Uq2gNKV7N*o^^E)EKA3?43S zC~9xe_FZVVnSZYXhl zc(^zyxG{LRxS_=H;o;(-;KtzL;)W8(hlh)Uf*XT}iyKNDA093a3T_M@E^a7se0aDx zD7Z0rxVWLj@!{d(py0;f;o^o8$A^cDgMu4_hl?9Z93LJo4hn9Jzr`i`^C1T$AJ&r% zn5;(_Xi^n0tj8aK2xbn}01&(i0K)eIz?W&(XCDCgLjmC3b^t&p0KgLJ@oo1_0AN1Y z+}O}5u;s|9-CoZ|8hABl7N( z3&-9Pl$bX-{rb@q{uV*mNd2TyQc}`~;4(*=ROhu-$wq=j$`g;e`GJ}}y0m#4hCv`p zev5ll+uOstjrth!6fduf1qC0_p?#G#NtbY|gtja`Ul^dhOR{eJ*zz-$plJG5nIdJXN^LVe8^G18+13PV^uR9IrFOsDA5R@eQ z8kN3Qt~O&vJD!W~IU@sE9)@i4RgQbuEl>mr$u#cB5S^INj2=ui9q%s}+MiH34Hx@7 zQuyKanu*qdGy)QPlW!zt0R)-C0kT;LH~H=^g}4#eyelibJCq{U8}HkviO=0xC8^2aq~9esn8`c%N07e zUf3S)VEIR9Gs9*4U|D1Jp;ciw+i#sI5;LE$4ZSDW8-DJwVw2K)8CS*g!yX@=2?U3p z2oa0)+7*@mZm_#elDvq2tR`sr2i=4fAPH#xv5Fy3${CYPrT0y1?NrMjHGg`QgTz>V zuEH@yJQ;h+8|0b;!v?#rJBbt^%hyk}#(31P4bRGRAX~XckZ{IS|IAneCcCs=y+&L z(d2Ocy_Nu`qe3!htVe54 zWk-&YH>@|UYN@ZQ)M?mxoBp$azWIdCK26Rbu0JcR#p94+4 zcH%>~=0}@k7DL_Ao)S*TMfzVl-R7U#@}hCsME`jHJ*vm#nhDjeXG{4AJ^H)6&uS?@ z@|m9$LRa+d)DUdEv*N3(l=L&ZU|q{7?e+c9V%Ma zpqwYIp13KZi&7c_x%@|=nq)?}?yHIBj&u7nV~d%CTjxapS%_6`^TkumzrIoRpmWaeUH|*0^~e zY=2XSBh$4pJ>`ML1x+u-9+UYpU!6U#Kf?PCl=-WySYW+-s2dz>_Te@k5Zw6g?VX!D REZGm4F~`{$=NWC^^ItUJ)cF7a literal 0 HcmV?d00001 diff --git a/dist/UI_icons/deleteIcon.png b/dist/UI_icons/deleteIcon.png new file mode 100644 index 0000000000000000000000000000000000000000..540256479106ed2f9263ec5df22fd7f0c75231e4 GIT binary patch literal 20981 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 literal 0 HcmV?d00001 diff --git a/dist/vis.js b/dist/vis.js index 5c4efb78..5dc6d8e6 100644 --- a/dist/vis.js +++ b/dist/vis.js @@ -8956,8 +8956,8 @@ Node.prototype.setProperties = function(properties, constants) { } } - this.xFixed = this.xFixed || (properties.x !== undefined); - this.yFixed = this.yFixed || (properties.y !== undefined); + this.xFixed = this.xFixed || (properties.x !== undefined && properties.fixed); + this.yFixed = this.yFixed || (properties.y !== undefined && properties.fixed); this.radiusFixed = this.radiusFixed || (properties.radius !== undefined); if (this.shape == 'image') { @@ -10604,6 +10604,134 @@ Images.prototype.load = function(url) { return img; }; +/** + * Created by Alex on 2/4/14. + */ + +var manipulationMixin = { + + _createManipulatorBar : function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + // add the icons to the manipulator div + this.manipulationDiv.innerHTML = "" + + "Add Node" + + "

" + + "Connect Node" + + "
" + + "Delete selected"; + + // bind the icons + var addButton = document.getElementById("manipulate-addNode"); + addButton.onclick = this._createAddToolbar.bind(this); + var connectButton = document.getElementById("manipulate-connectNode"); + connectButton.onclick = this._createConnectToolbar.bind(this); + var deleteButton = document.getElementById("manipulate-delete"); + deleteButton.onclick = this._deleteSelected.bind(this); + }, + + _createAddToolbar : function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + + this.manipulationDiv.innerHTML = "" + + "Back" + + "
" + + "Click in an empty space to place a new node"; + + // bind the icon + var backButton = document.getElementById("manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); + + + var me = this; + events.addListener(me, 'select', me._addNode.bind(me)); + }, + + + _createConnectToolbar : function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + var message = "hello"; + if (!this._selectionIsEmpty()) { + message = "Select the node you want to connect to other nodes"; + } + + this.manipulationDiv.innerHTML = "" + + "Back" + + "
" + + ""+message+""; + + // bind the icon + var backButton = document.getElementById("manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); + + var self = this; + events.addListener(self, 'select', function(params) {alert(self.selectForConnect)}); + }, + + _continueConnect : function() { + if (this._clusterInSelection()) { + this._unselectAll(); + this._createConnectToolbar("Select the node you want to connect (Clusters are not allowed)."); + return true; + } + else if (!this._selectionIsEmpty()) { + this._connectNodes(); + return true; + } + else { + var manipulatorLabel = document.getElementById['manipolatorLabel']; + manipulatorLabel + return false; + } + }, + + + /** + * Adds a node on the specified location + * + * @param {Object} pointer + */ + _addNode : function(pointer) { + console.log("HERE",this) + if (this._selectionIsEmpty()) { + var positionObject = this._pointerToPositionObject(pointer); + this.nodesData.add({id:util.randomUUID(),x:positionObject.left,y:positionObject.top,label:"new",fixed:false}); + this.moving = true; + this.start(); + } + }, + + _connectNodes : function() { + console.log(this.selectionObj) + }, + + + /** + * delete everything in the selection + * + * @private + */ + _deleteSelected : function() { + if (!this._clusterInSelection()) { + var selectedNodes = this.getSelectedNodes(); + var selectedEdges = this.getSelectedEdges(); + this._removeEdges(selectedEdges); + this._removeNodes(selectedNodes); + this._redraw(); + } + else { + alert("Clusters cannot be deleted.") + } + } + + + +} /** * Creation of the SectorMixin var. * @@ -12413,6 +12541,19 @@ var SelectionMixin = { return true; }, + _clusterInSelection : function() { + for(var objectId in this.selectionObj) { + if(this.selectionObj.hasOwnProperty(objectId)) { + if (this.selectionObj[objectId] instanceof Node) { + if (this.selectionObj[objectId].clusterSize > 1) { + return true; + } + } + } + } + return false; + }, + /** * select the edges connected to the node that is being selected * @@ -12583,9 +12724,7 @@ var SelectionMixin = { */ getSelection : function() { var nodeIds = this.getSelectedNodes(); - var edgeIds = this.getSelectedEdges(); - return {nodes:nodeIds, edges:edgeIds}; }, @@ -12625,15 +12764,6 @@ var SelectionMixin = { return idArray }, - /** - * - * retrieve the currently selected nodes as objects - * @return {Objects} selection An array with the ids of the - * selected nodes. - */ - getSelectionObjects : function() { - return this.selectionObj; - }, /** * select zero or more nodes @@ -13048,21 +13178,31 @@ function Graph (container, data, options) { this.yIncrement = 0; this.zoomIncrement = 0; + // create a frame and canvas this._create(); // load the sector system. (mandatory, fully integrated with Graph) this._loadSectorSystem(); - // apply options - this.setOptions(options); - // load the cluster system. (mandatory, even when not using the cluster system, there are function calls to it) this._loadClusterSystem(); // load the selection system. (mandatory, required by Graph) this._loadSelectionSystem(); + // load the data manipulation system + this._loadManipulationSystem(); + + // apply options + this.setOptions(options); + + + + + + + // other vars var graph = this; this.freezeSimulation = false;// freeze the simulation @@ -13457,6 +13597,7 @@ Graph.prototype._create = function () { this.frame.className = 'graph-frame'; this.frame.style.position = 'relative'; this.frame.style.overflow = 'hidden'; + this.frame.style.zIndex = "1"; // create the graph canvas (HTML canvas element) this.frame.canvas = document.createElement( 'canvas' ); @@ -13492,6 +13633,7 @@ Graph.prototype._create = function () { // add the frame to the container element this.containerElement.appendChild(this.frame); + }; @@ -13527,14 +13669,6 @@ Graph.prototype._createKeyBinds = function() { this.mousetrap.bind("pagedown",this._zoomOut.bind(me),"keydown"); this.mousetrap.bind("pagedown",this._stopZoom.bind(me), "keyup"); } - /* - this.mousetrap.bind("=",this.decreaseClusterLevel.bind(me)); - this.mousetrap.bind("-",this.increaseClusterLevel.bind(me)); - this.mousetrap.bind("s",this.singleStep.bind(me)); - this.mousetrap.bind("h",this.updateClustersDefault.bind(me)); - this.mousetrap.bind("c",this._collapseSector.bind(me)); - this.mousetrap.bind("f",this.toggleFreeze.bind(me)); - */ } /** @@ -13580,7 +13714,7 @@ Graph.prototype._onDragStart = function () { drag.nodeId = node.id; // select the clicked node if not yet selected if (!node.isSelected()) { - this._selectNode(node,false); + this._selectObject(node,false); } // create an array with the selected nodes and their original location and status @@ -13682,6 +13816,7 @@ Graph.prototype._onDragEnd = function () { Graph.prototype._onTap = function (event) { var pointer = this._getPointer(event.gesture.touches[0]); this._handleTap(pointer); + }; @@ -14032,6 +14167,8 @@ Graph.prototype.setSize = function(width, height) { this.frame.canvas.width = this.frame.canvas.clientWidth; this.frame.canvas.height = this.frame.canvas.clientHeight; + this.manipulationDiv.style.width = this.frame.canvas.clientWidth; + if (this.constants.navigationUI.enabled == true) { this._relocateUI(); } @@ -14096,7 +14233,7 @@ Graph.prototype._addNodes = function(ids) { var node = new Node(data, this.images, this.groups, this.constants); this.nodes[id] = node; // note: this may replace an existing node - if (!node.isFixed()) { + if (!node.isFixed() && this.createNodeOnClick != true) { // TODO: position new nodes in a smarter way! var radius = this.constants.edges.length * 2; var count = ids.length; @@ -14112,6 +14249,7 @@ Graph.prototype._addNodes = function(ids) { this._updateNodeIndexList(); this._reconnectEdges(); this._updateValueRange(this.nodes); + this.updateLabels(); }; /** @@ -14376,7 +14514,7 @@ Graph.prototype._redraw = function() { this._doInAllSectors("_drawAllSectorNodes",ctx); this._doInAllSectors("_drawEdges",ctx); - this._doInAllSectors("_drawNodes",ctx); + this._doInAllSectors("_drawNodes",ctx,true); // restore original scaling and translation ctx.restore(); @@ -14867,9 +15005,9 @@ Graph.prototype.start = function() { } }; - - - +/** + * Debug function, does one step of the graph + */ Graph.prototype.singleStep = function() { if (this.moving) { this._initializeForceCalculation(); @@ -14958,6 +15096,30 @@ Graph.prototype._loadSelectionSystem = function() { } + +/** + * Mixin the navigationUI (User Interface) system and initialize the parameters required + * + * @private + */ +Graph.prototype._loadManipulationSystem = function() { + // load the manipulator HTML elements. All styling done in css. + this.manipulationDiv = document.createElement('div'); + this.manipulationDiv.className = 'graph-manipulationDiv'; + this.containerElement.insertBefore(this.manipulationDiv, this.frame); + + + // load the manipulation functions + for (var mixinFunction in manipulationMixin) { + if (manipulationMixin.hasOwnProperty(mixinFunction)) { + Graph.prototype[mixinFunction] = manipulationMixin[mixinFunction]; + } + } + + this._createManipulatorBar(); + +} + /** * Mixin the navigationUI (User Interface) system and initialize the parameters required * diff --git a/examples/graph/20_UI_example.html b/examples/graph/20_UI_example.html index f3bdc458..89e620a6 100644 --- a/examples/graph/20_UI_example.html +++ b/examples/graph/20_UI_example.html @@ -31,6 +31,89 @@ div.table_description { width:100px; } + div.graph-manipulationDiv { + border-width:0px; + border-bottom: 1px; + border-style:solid; + border-color: #d6d9d8; + background: #ffffff; /* Old browsers */ + background: -moz-linear-gradient(top, #ffffff 0%, #f3f3f3 50%, #ededed 51%, #ffffff 100%); /* FF3.6+ */ + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#ffffff), color-stop(50%,#f3f3f3), color-stop(51%,#ededed), color-stop(100%,#ffffff)); /* Chrome,Safari4+ */ + background: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%); /* Chrome10+,Safari5.1+ */ + background: -o-linear-gradient(top, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%); /* Opera 11.10+ */ + background: -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%); /* IE10+ */ + background: linear-gradient(to bottom, #ffffff 0%,#f3f3f3 50%,#ededed 51%,#ffffff 100%); /* W3C */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#ffffff',GradientType=0 ); /* IE6-9 */ + width: 600px; + height:30px; + z-index:10; + position:absolute; + } + + span.manipulationUI { + -moz-border-radius: 15px; + border-radius: 15px; + display:inline-block; + background-position: 4px 0px; + background-repeat:no-repeat; + height:24px; + margin: -14px 0px 0px 10px; + vertical-align:middle; + cursor: pointer; + padding: 0px 8px 0px 8px; + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + } + + span.manipulationUI:hover { + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.20); + } + + span.manipulationUI:active { + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.50); + } + + span.manipulationUI.back { + background-image: url("../../dist/UI_icons/backIcon.png"); + } + + span.manipulationUI.none:hover { + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0); + cursor: default; + } + span.manipulationUI.none:active { + box-shadow: 1px 1px 8px rgba(0, 0, 0, 0.0); + } + + span.manipulationUI.add { + background-image: url("../../dist/UI_icons/addNodeIcon.png"); + } + + span.manipulationUI.connect { + background-image: url("../../dist/UI_icons/connectIcon.png"); + } + + span.manipulationUI.delete { + background-image: url("../../dist/UI_icons/deleteIcon.png"); + } + /* top right bottom left */ + span.manipulationLabel { + margin: 0px 0px 0px 25px; + line-height: 25px; + } + + div.seperatorLine { + display:inline-block; + width:1px; + height:20px; + background-color: #bdbdbd; + margin: 5px 7px 0px 15px; + + } diff --git a/src/graph/Graph.js b/src/graph/Graph.js index e36e15d8..1f0c1ee0 100644 --- a/src/graph/Graph.js +++ b/src/graph/Graph.js @@ -110,21 +110,31 @@ function Graph (container, data, options) { this.yIncrement = 0; this.zoomIncrement = 0; + // create a frame and canvas this._create(); // load the sector system. (mandatory, fully integrated with Graph) this._loadSectorSystem(); - // apply options - this.setOptions(options); - // load the cluster system. (mandatory, even when not using the cluster system, there are function calls to it) this._loadClusterSystem(); // load the selection system. (mandatory, required by Graph) this._loadSelectionSystem(); + // load the data manipulation system + this._loadManipulationSystem(); + + // apply options + this.setOptions(options); + + + + + + + // other vars var graph = this; this.freezeSimulation = false;// freeze the simulation @@ -519,6 +529,7 @@ Graph.prototype._create = function () { this.frame.className = 'graph-frame'; this.frame.style.position = 'relative'; this.frame.style.overflow = 'hidden'; + this.frame.style.zIndex = "1"; // create the graph canvas (HTML canvas element) this.frame.canvas = document.createElement( 'canvas' ); @@ -554,6 +565,7 @@ Graph.prototype._create = function () { // add the frame to the container element this.containerElement.appendChild(this.frame); + }; @@ -589,14 +601,6 @@ Graph.prototype._createKeyBinds = function() { this.mousetrap.bind("pagedown",this._zoomOut.bind(me),"keydown"); this.mousetrap.bind("pagedown",this._stopZoom.bind(me), "keyup"); } - /* - this.mousetrap.bind("=",this.decreaseClusterLevel.bind(me)); - this.mousetrap.bind("-",this.increaseClusterLevel.bind(me)); - this.mousetrap.bind("s",this.singleStep.bind(me)); - this.mousetrap.bind("h",this.updateClustersDefault.bind(me)); - this.mousetrap.bind("c",this._collapseSector.bind(me)); - this.mousetrap.bind("f",this.toggleFreeze.bind(me)); - */ } /** @@ -642,7 +646,7 @@ Graph.prototype._onDragStart = function () { drag.nodeId = node.id; // select the clicked node if not yet selected if (!node.isSelected()) { - this._selectNode(node,false); + this._selectObject(node,false); } // create an array with the selected nodes and their original location and status @@ -744,6 +748,7 @@ Graph.prototype._onDragEnd = function () { Graph.prototype._onTap = function (event) { var pointer = this._getPointer(event.gesture.touches[0]); this._handleTap(pointer); + }; @@ -1094,6 +1099,8 @@ Graph.prototype.setSize = function(width, height) { this.frame.canvas.width = this.frame.canvas.clientWidth; this.frame.canvas.height = this.frame.canvas.clientHeight; + this.manipulationDiv.style.width = this.frame.canvas.clientWidth; + if (this.constants.navigationUI.enabled == true) { this._relocateUI(); } @@ -1158,7 +1165,7 @@ Graph.prototype._addNodes = function(ids) { var node = new Node(data, this.images, this.groups, this.constants); this.nodes[id] = node; // note: this may replace an existing node - if (!node.isFixed()) { + if (!node.isFixed() && this.createNodeOnClick != true) { // TODO: position new nodes in a smarter way! var radius = this.constants.edges.length * 2; var count = ids.length; @@ -1174,6 +1181,7 @@ Graph.prototype._addNodes = function(ids) { this._updateNodeIndexList(); this._reconnectEdges(); this._updateValueRange(this.nodes); + this.updateLabels(); }; /** @@ -1438,7 +1446,7 @@ Graph.prototype._redraw = function() { this._doInAllSectors("_drawAllSectorNodes",ctx); this._doInAllSectors("_drawEdges",ctx); - this._doInAllSectors("_drawNodes",ctx); + this._doInAllSectors("_drawNodes",ctx,true); // restore original scaling and translation ctx.restore(); @@ -1929,9 +1937,9 @@ Graph.prototype.start = function() { } }; - - - +/** + * Debug function, does one step of the graph + */ Graph.prototype.singleStep = function() { if (this.moving) { this._initializeForceCalculation(); @@ -2020,6 +2028,30 @@ Graph.prototype._loadSelectionSystem = function() { } + +/** + * Mixin the navigationUI (User Interface) system and initialize the parameters required + * + * @private + */ +Graph.prototype._loadManipulationSystem = function() { + // load the manipulator HTML elements. All styling done in css. + this.manipulationDiv = document.createElement('div'); + this.manipulationDiv.className = 'graph-manipulationDiv'; + this.containerElement.insertBefore(this.manipulationDiv, this.frame); + + + // load the manipulation functions + for (var mixinFunction in manipulationMixin) { + if (manipulationMixin.hasOwnProperty(mixinFunction)) { + Graph.prototype[mixinFunction] = manipulationMixin[mixinFunction]; + } + } + + this._createManipulatorBar(); + +} + /** * Mixin the navigationUI (User Interface) system and initialize the parameters required * diff --git a/src/graph/Node.js b/src/graph/Node.js index 3aea901d..924be40f 100644 --- a/src/graph/Node.js +++ b/src/graph/Node.js @@ -188,8 +188,8 @@ Node.prototype.setProperties = function(properties, constants) { } } - this.xFixed = this.xFixed || (properties.x !== undefined); - this.yFixed = this.yFixed || (properties.y !== undefined); + this.xFixed = this.xFixed || (properties.x !== undefined && properties.fixed); + this.yFixed = this.yFixed || (properties.y !== undefined && properties.fixed); this.radiusFixed = this.radiusFixed || (properties.radius !== undefined); if (this.shape == 'image') { diff --git a/src/graph/SelectionMixin.js b/src/graph/SelectionMixin.js index 4b6bebd5..42b58d56 100644 --- a/src/graph/SelectionMixin.js +++ b/src/graph/SelectionMixin.js @@ -233,6 +233,19 @@ var SelectionMixin = { return true; }, + _clusterInSelection : function() { + for(var objectId in this.selectionObj) { + if(this.selectionObj.hasOwnProperty(objectId)) { + if (this.selectionObj[objectId] instanceof Node) { + if (this.selectionObj[objectId].clusterSize > 1) { + return true; + } + } + } + } + return false; + }, + /** * select the edges connected to the node that is being selected * @@ -403,9 +416,7 @@ var SelectionMixin = { */ getSelection : function() { var nodeIds = this.getSelectedNodes(); - var edgeIds = this.getSelectedEdges(); - return {nodes:nodeIds, edges:edgeIds}; }, @@ -445,15 +456,6 @@ var SelectionMixin = { return idArray }, - /** - * - * retrieve the currently selected nodes as objects - * @return {Objects} selection An array with the ids of the - * selected nodes. - */ - getSelectionObjects : function() { - return this.selectionObj; - }, /** * select zero or more nodes diff --git a/src/graph/manipulationMixin.js b/src/graph/manipulationMixin.js new file mode 100644 index 00000000..9ba8f20f --- /dev/null +++ b/src/graph/manipulationMixin.js @@ -0,0 +1,128 @@ +/** + * Created by Alex on 2/4/14. + */ + +var manipulationMixin = { + + _createManipulatorBar : function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + // add the icons to the manipulator div + this.manipulationDiv.innerHTML = "" + + "Add Node" + + "
" + + "Connect Node" + + "
" + + "Delete selected"; + + // bind the icons + var addButton = document.getElementById("manipulate-addNode"); + addButton.onclick = this._createAddToolbar.bind(this); + var connectButton = document.getElementById("manipulate-connectNode"); + connectButton.onclick = this._createConnectToolbar.bind(this); + var deleteButton = document.getElementById("manipulate-delete"); + deleteButton.onclick = this._deleteSelected.bind(this); + }, + + _createAddToolbar : function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + + this.manipulationDiv.innerHTML = "" + + "Back" + + "
" + + "Click in an empty space to place a new node"; + + // bind the icon + var backButton = document.getElementById("manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); + + + var me = this; + events.addListener(me, 'select', me._addNode.bind(me)); + }, + + + _createConnectToolbar : function() { + while (this.manipulationDiv.hasChildNodes()) { + this.manipulationDiv.removeChild(this.manipulationDiv.firstChild); + } + var message = "hello"; + if (!this._selectionIsEmpty()) { + message = "Select the node you want to connect to other nodes"; + } + + this.manipulationDiv.innerHTML = "" + + "Back" + + "
" + + ""+message+""; + + // bind the icon + var backButton = document.getElementById("manipulate-back"); + backButton.onclick = this._createManipulatorBar.bind(this); + + var self = this; + events.addListener(self, 'select', function(params) {alert(self.selectForConnect)}); + }, + + _continueConnect : function() { + if (this._clusterInSelection()) { + this._unselectAll(); + this._createConnectToolbar("Select the node you want to connect (Clusters are not allowed)."); + return true; + } + else if (!this._selectionIsEmpty()) { + this._connectNodes(); + return true; + } + else { + var manipulatorLabel = document.getElementById['manipolatorLabel']; + manipulatorLabel + return false; + } + }, + + + /** + * Adds a node on the specified location + * + * @param {Object} pointer + */ + _addNode : function(pointer) { + console.log("HERE",this) + if (this._selectionIsEmpty()) { + var positionObject = this._pointerToPositionObject(pointer); + this.nodesData.add({id:util.randomUUID(),x:positionObject.left,y:positionObject.top,label:"new",fixed:false}); + this.moving = true; + this.start(); + } + }, + + _connectNodes : function() { + console.log(this.selectionObj) + }, + + + /** + * delete everything in the selection + * + * @private + */ + _deleteSelected : function() { + if (!this._clusterInSelection()) { + var selectedNodes = this.getSelectedNodes(); + var selectedEdges = this.getSelectedEdges(); + this._removeEdges(selectedEdges); + this._removeNodes(selectedNodes); + this._redraw(); + } + else { + alert("Clusters cannot be deleted.") + } + } + + + +} \ No newline at end of file