- Timestamp:
- 01/02/13 16:58:21 (11 years ago)
- Location:
- SMC/trunk/SMC/src/web
- Files:
-
- 67 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
SMC/trunk/SMC/src/web/cmd-dep-graph.html
r2364 r2438 21 21 </head> 22 22 <body> 23 <div id="navigate" class="block">navigate < span onclick="toggleNodes(3)" >toggle</span></div>23 <div id="navigate" class="block">navigate </div> 24 24 <div id="notify">notify</div> 25 25 <div id="index-container" class="block">detail</div> -
SMC/trunk/SMC/src/web/scripts/js/cmd-dep-graph.js
r2364 r2438 9 9 10 10 var graph_container_selector = '#infovis'; 11 var navi_container_selector = '#navigate'; 11 12 var graph_container = null; 12 13 var index_container = null; 13 var comp_reg_url = "http://catalog.clarin.eu/ds/ComponentRegistry/"; 14 var source_file = "scripts/cmd-dep-graph-d3.json" 14 15 var input_prefix = "input-"; 16 var select_rect_min_size = 5; 17 var comp_reg_url = "http://catalog.clarin.eu/ds/ComponentRegistry/?item="; 18 /*var source_file = "../scripts/cmd-dep-graph-d3_all_svg.json"*/ 19 var source_file = "file:/C:/Users/m/3/clarin/_repo/SMC/data2/cmd-dep-graph.d3.js" 20 21 22 var opts = {"depth-before": {"value":2, "min":0, "max":10}, "depth-after":{"value":2, "min":0, "max":10}, 23 "link-distance": {"value":30, "min":10, "max":200 }, "charge":{"value":400, "min":10, "max":1000 }}; 15 24 16 25 /** for faster/simpler neighborhood lookup … … 23 32 var links_out = {}; 24 33 25 /** the jquery initialization construct, ensures waiting until all html is loaded, so that it can be safely referenced26 * @name init 34 /** gets the data for the graph and calls rendering of the lists 35 * @name initGraph 27 36 * @function 28 37 */ 29 $(function()38 function initGraph () 30 39 { 31 40 graph_container = $(graph_container_selector); 41 42 fillOpts(navi_container_selector); 32 43 33 44 $('#infovis-wrapper').resizable( { … … 37 48 stop: function(event, ui) { 38 49 graph_container.show(); 39 renderGraph( data_show, graph_container);50 renderGraph(); 40 51 } 41 52 } 42 53 ); 43 54 55 56 $("#navigate .slider").slider(); 57 44 58 // load data 45 59 d3.json(source_file , … … 80 94 }); 81 95 82 render Lists(data_all);96 renderIndex(data_all.nodes); 83 97 //renderGraph(data_all, graph_container); 84 98 }); 85 }); 86 87 88 /** generate the index lists */ 89 function renderLists (data) { 99 } 100 101 102 /** generate the index lists 103 @param nodes - accepts an array of nodes (like in data.nodes) 104 */ 105 function renderIndex (nodes) { 90 106 nest = d3.nest() 91 .key(function(d) { return d.group; }) 92 .entries(data.nodes); 93 107 .key(function(d) { return d.type; }) 108 .sortValues(function(a, b) { return d3.ascending(a.name, b.name); }) 109 .entries(nodes); 110 94 111 index_container = d3.select("#index-container"); 95 // detail_wrapper.selectAll("div").remove();112 index_container.selectAll("div").remove(); 96 113 var group_divs = index_container.selectAll("div").data(nest) 97 114 .enter().append("div") 98 115 .attr("id", function (d) { return "detail-" + d.key }) 116 .classed("cmds-ui-block init-show", 1); 117 118 var group_headers = group_divs.append("div").classed("header", 1) 99 119 .text(function (d) { return d.key}); 100 120 101 var item_li = group_divs.append("ul").selectAll(".node-item") 121 var item_li = group_divs.append("div").classed("content",1) 122 .append("ul").selectAll(".node-item") 102 123 .data(function(d) { return d.values; }) 103 124 .enter().append("li") … … 107 128 .classed("highlight", function (d) { return d.selected }) 108 129 .on("click", function(d) { d.selected= d.selected ? 0 : 1 ; updateSelected() }); 109 //.classed("detail", 1); 130 //.classed("detail", 1); 131 132 handleUIBlock($(".cmds-ui-block")); 133 } 134 135 function filterIndex (search_string){ 136 var filtered_index_nodes = data_all.nodes.filter(function(d, i) { 137 console.log(d.name.indexOf(search_string)); 138 return d.name.indexOf(search_string) > -1; 139 }); 140 console.log(filtered_index_nodes); 141 renderIndex(filtered_index_nodes); 142 } 143 144 145 function renderGraph () { 146 renderGraph(data_show, graph_container); 110 147 } 111 148 112 149 /** render the data as graph into target-container */ 113 function renderGraph (data, target_container) { 150 function renderGraph (data, target_container=graph_container) { 151 152 data = dataToShow(nodes_sel); 114 153 115 154 if (data == null) { … … 126 165 .links(data.links) 127 166 .size([w, h]) 128 .linkDistance( 60)129 .charge( -300)167 .linkDistance(opt("link-distance")) 168 .charge(opt("charge") * -1) 130 169 .on("tick", tick) 131 170 .start(); … … 149 188 .attr("orient", "auto") 150 189 .append("svg:path") 151 .attr("d", "M0,- 5L10,0L0,5");190 .attr("d", "M0,-3L10,0L0,3"); 152 191 153 192 var path = svg.append("svg:g").selectAll("path") … … 158 197 .attr("marker-end", function(d) { return "url(#uses)"; }); 159 198 160 var circle = svg.append("svg:g").selectAll("circle") 199 var circle = svg.append("svg:g") 200 .selectAll("circle") 161 201 .data(force.nodes()) 162 163 .enter().append("svg:circle") 164 .attr("class", function(d) { return (d.group==1) ? 'profile' : 'component' ; }) 202 .enter().append("svg:circle") 165 203 .attr("r", 6) 204 .attr("x", function(d) {return d.init_x;}) 205 .attr("y", function(d) {return d.init_y;}) 166 206 .call(force.drag); 167 207 208 svg.selectAll("circle") 209 .attr("class", function(d) { return "type-" + d.type.toLowerCase()}) 210 .classed("selected", function(d) { return d.selected; }) 211 .on("click", function(d) {d.selected= d.selected ? 0 : 1; updateSelected() }); 212 213 168 214 var textgroup = svg.append("svg:g").selectAll("g") 169 215 .data(data.nodes) 170 .enter().append("svg:g") 216 .enter().append("svg:g") 217 .attr("class", function(d) { return "type-" + d.type.toLowerCase()}) 171 218 .on("click", function(d) {d.selected= d.selected ? 0 : 1; updateSelected() }); 219 172 220 173 221 textgroup.attr("data-key", function (d) { return d.name } ); … … 178 226 .attr("y", ".31em") 179 227 .attr("class", "shadow") 228 180 229 .text(function(d) { return d.name; }); 181 230 … … 188 237 189 238 function tick(e) { 190 var k = 6 * e.alpha; 239 var k = e.alpha; 240 191 241 path.attr("d", function(d) { 192 d.source.x -= k ; 193 d.target.x += k ; 242 /*d.source.x -= k * d.target.sum_level ; 243 d.target.x += k * d.source.sum_level ;*/ 244 /* d.source.y = d.source.init_y ; 245 d.target.y = d.target.init_y;*/ 246 //d.source.x -= d.source.level * 0.2 ; 247 //d.target.x += d.target.level * 0.2; 248 // console.log ("k: " + k + "; source.x:" + d.source.x + "; target.x:" + d.target.x); 194 249 var dx = d.target.x - d.source.x, 195 250 dy = d.target.y - d.source.y, 196 251 dr = Math.sqrt(dx * dx + dy * dy); 197 // console.log ("M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y);252 198 253 return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y; 254 255 256 199 257 }); 200 258 … … 206 264 return "translate(" + d.x + "," + d.y + ")"; 207 265 }); 266 267 /* 268 circle.attr("cx", function(d) { return d.x; }) 269 .attr("cy", function(d) { return d.y; }); 270 271 path.attr("x1", function(d) { return d.source.x; }) 272 .attr("y1", function(d) { return d.source.y; }) 273 .attr("x2", function(d) { return d.target.x; }) 274 .attr("y2", function(d) { return d.target.y; });*/ 208 275 } 209 276 … … 223 290 x1 = Math.max(0, m0[0], m1[0]), 224 291 y1 = Math.max(0, m0[1], m1[1]); 225 292 // console.log("DEBUG: mousedown: " + (x1-x0) + ( y1-y0)); 226 293 selectNodes(data.nodes, x0, y0, x1, y1); 227 294 rect.attr("x", x0).attr("y", y0).attr("width", x1 - x0).attr("height", y1 - y0); 228 updateSelected();295 229 296 }); 230 297 231 298 d3.select(window).on("mouseup", function() { 299 // only change selection, if the rectangle was big enough 300 // (mainly to prevent clearing of the graph on clicks that look like mousemoves to the system) 301 if (rect.attr("width") > select_rect_min_size && rect.attr("height") > select_rect_min_size) { 302 updateSelected(); 303 } 232 304 rect.remove(); 233 305 d3.select(window).on("mousemove", null).on("mouseup", null); … … 237 309 }); 238 310 } // end renderGraph 311 312 313 /** generate the detail lists 314 @param nodes 315 */ 316 function renderDetail (nodes) { 317 /* 318 nest = d3.nest() 319 .key(function(d) { return d.group; }) 320 .sortValues(function(a, b) { return d3.ascending(a.name, b.name); }) 321 .entries(nodes); 322 */ 323 detail_container = d3.select("#detail-container"); 324 detail_container.selectAll("div").remove(); 325 /* 326 var group_divs = detail_container.selectAll("div").data(nest) 327 .enter().append("div") 328 .attr("id", function (d) { return "detail-" + d.key }) 329 .classed("cmds-ui-block init-show", 1); 330 331 var group_headers = group_divs.append("div").classed("header", 1) 332 .text(function (d) { return d.key}); 333 */ 334 var item_li = detail_container.append("div") 335 .append("ul").selectAll(".node-item") 336 .data(nodes) 337 .enter().append("li") 338 .attr("class", "node-item") 339 .attr("id", function (d) { return "n-" + d.name }); 340 item_li.append("span") 341 .text(function (d) { return d.name}) 342 .on("click", function(d) { d.selected= d.selected ? 0 : 1 ; updateSelected() }); 343 var item_detail = item_li.append("div") 344 .append("a") 345 .attr("href",function (d) { if (d.type.toLowerCase()=='datcat') return d.id 346 else return comp_reg_url + d.id }) 347 .text(function (d) { return d.id }); 348 //.classed("detail", 1); 349 350 // handleUIBlock($(".cmds-ui-block")); 351 } 239 352 240 353 … … 258 371 function updateSelected () { 259 372 nodes_sel = data_all.nodes.filter(function (d) { return d.selected }); 260 renderGraph(dataToShow(nodes_sel), graph_container); 261 if (svg!=null) svg.selectAll("circle").style("fill", function(d) { return d.selected ? "red" : null; }); 373 374 renderGraph(); 375 renderDetail(nodes_sel); 376 262 377 index_container.selectAll("li").classed("highlight", function (d) { return d.selected }); 263 378 } … … 269 384 data_show = {}; 270 385 data_show.nodes = nodes; 271 var nodes_add = [], links_add = []; 386 var data_show_collect = {nodes:[],links:[]}; 387 272 388 nodes.forEach(function(n) { 273 nodes_add = nodes_add.concat(neighbours(n,'all')); 274 links_add = links_add.concat(neighbour_links(n,'all')); 275 /* nodes_add = nodes_add.concat(neighbours_out[n.index]);*/ 389 var data_add_in = neighboursWithLinks(n,'in', opt("depth-before")); 390 var data_add_out = neighboursWithLinks(n,'out', opt("depth-after")); 391 data_show_collect.nodes = data_show_collect.nodes.concat(data_add_in.nodes).concat(data_add_out.nodes); 392 data_show_collect.links = data_show_collect.links.concat(data_add_in.links).concat(data_add_out.links); 276 393 }); 277 /*278 links_add = data_all.links.forEach(function(e,n){ console.log(e.source) });279 nodes_add = data_all.nodes.filterlinks280 if (n.source==group) {281 data_show.nodes.push(n)*/282 394 283 data_show.nodes = unique_nodes(nodes.concat(nodes_add)); 284 285 /* filter edges */ 286 data_show.links = unique_links(links_add); 395 /* deduplicate nodes and edges */ 396 data_show.nodes = unique_nodes(nodes.concat(data_show_collect.nodes)); 397 data_show.links = unique_links(data_show_collect.links); 287 398 288 399 /* data_show.nodes.forEach; data_all.links; … … 308 419 (perhaps other key, than index would be less confusing) 309 420 */ 310 function neighbours (n, dir ) {421 function neighbours (n, dir, depth=1) { 311 422 var n_in = neighbours_in[n.key] ? neighbours_in[n.key] : [] ; 312 423 var n_out = neighbours_out[n.key] ? neighbours_out[n.key] : [] ; 313 if (dir == 'in' ) { return n_in; } 314 else if (dir == 'out' ) { return n_out; } 315 else { return n_out.concat(n_in); } 316 317 } 318 319 320 function neighbour_links (n, dir) { 424 var result_n; 425 if (dir == 'in' ) { result_n = n_in; } 426 else if (dir == 'out' ) { result_n = n_out; } 427 else { result_n = n_out.concat(n_in); } 428 var n_nextlevel = []; 429 if (depth > 1) { 430 result_n.forEach (function(n) 431 { var n_neighbours = neighbours(n, dir, depth - 1); 432 n_nextlevel = n_nextlevel.concat(n_neighbours); } 433 ) 434 } 435 return result_n.concat(n_nextlevel); 436 437 } 438 439 function neighboursWithLinks (n, dir, depth=1) { 440 var n_in = neighbours_in[n.key] ? neighbours_in[n.key] : [] ; 441 var n_out = neighbours_out[n.key] ? neighbours_out[n.key] : [] ; 321 442 var l_in = links_in[n.key] ? links_in[n.key] : [] ; 322 443 var l_out = links_out[n.key] ? links_out[n.key] : [] ; 323 if (dir == 'in' ) { return l_in; } 324 else if (dir == 'out' ) { return l_out; } 325 else { return l_out.concat(l_in); } 444 445 var result_n = {nodes:[], links:[]}; 446 if (dir == 'in' ) { result_n.nodes = n_in; result_n.links = l_in; } 447 else if (dir == 'out' ) { result_n.nodes = n_out; result_n.links = l_out; } 448 else { result_n.nodes = n_out.concat(n_in); result_n.links = l_out.concat(l_in); } 449 var n_nextlevel = {nodes:[], links:[]}; 450 if (depth > 1) { 451 result_n.nodes.forEach (function(n) 452 { var n_neighbours = neighboursWithLinks(n, dir, depth - 1); 453 n_nextlevel.nodes = n_nextlevel.nodes.concat(n_neighbours.nodes); 454 n_nextlevel.links = n_nextlevel.links.concat(n_neighbours.links); 455 }) 456 } 457 result_n.nodes = result_n.nodes.concat(n_nextlevel.nodes); 458 result_n.links = result_n.links.concat(n_nextlevel.links); 459 460 return result_n; 461 462 } 463 464 function neighbour_links (nodes, dir) { 465 var l_result = [] 466 467 nodes.forEach (function(n) { 468 var l_in = links_in[n.key] ? links_in[n.key] : [] ; 469 var l_out = links_out[n.key] ? links_out[n.key] : [] ; 470 if (dir == 'in' ) { l_result = l_result.concat(l_in); } 471 else if (dir == 'out' ) { l_result = l_result.concat(l_out); } 472 else { l_result = l_result.concat(l_out.concat(l_in)); } 473 } ); 326 474 475 return l_result; 327 476 } 328 477 … … 360 509 } 361 510 511 /** 512 gets an option, checking with the values in the navigation-UI 513 */ 514 function opt(key) { 515 516 if ($('#' + input_prefix + key) && (opts[key].value != $('#' + input_prefix + key).val())) { 517 opts[key].value = $('#' + input_prefix + key).val(); 518 } else if (opts[key].value) { 519 return opts[key].value 520 } else if (opts[key]) { 521 return opts[key] 522 } else { 523 return "" 524 } 525 } 526 527 function setOpt(input_object) { 528 529 var id = $(input_object).attr("id"); 530 var val = $(input_object).val(); 531 key = id.substring(id.indexOf(input_prefix) + input_prefix.length) 532 opts[key].value = val; 533 return opts[key].value; 534 } 535 536 537 function fillOpts(trg_container) { 538 539 540 for ( var key in opts ) { 541 if ($('#' + input_prefix + key).length) { 542 $('#' + input_prefix + key).value = opts[key].value; 543 } else if (trg_container) { 544 var new_input_label = "<label>" + key + "</label>"; 545 var new_input = $("<input />"); 546 new_input.attr("id", input_prefix + key) 547 .val(opts[key].value) 548 .attr("type", "text") 549 .attr("size", 3); 550 551 var new_slider = $("<div class='slider'></div>"); 552 new_slider.attr("id", "slider-" + key); 553 new_slider.slider( opts[key]); 554 // set both-ways references between the input-field and its slider - necessary for updating 555 new_slider.data("related-input-field",new_input); 556 new_input.data("related-slider",new_slider); 557 558 /* hook changing options + redrawing the graph, when values in navigation changed */ 559 new_slider.bind( "slidechange", function(event, ui) { 560 // console.log(ui.value); 561 $(this).data("related-input-field").val(ui.value); 562 // update the opts-object, but based on the (updated) value of the related input-field 563 setOpt($(this).data("related-input-field")); 564 565 renderGraph(); 566 }); 567 568 new_input.change(function () { 569 setOpt(this); 570 $(this).data("related-slider").slider("option", "value", $(this).val()); 571 renderGraph(); 572 }); 573 574 $(trg_container).append(new_input_label, new_input, new_slider); 575 576 } 577 } 578 579 580 /* 581 d3.select(trg_container).selectAll("input").data(opts[) 582 .enter().append("input") 583 .attr("id", "k") 584 .attr("type", "text") 585 .attr("value", "val") 586 // .attr("value", function (d) { return d } ) 587 ; 588 589 */ 590 } 362 591 363 592 function notify (msg) { -
SMC/trunk/SMC/src/web/scripts/style/cmd-dep-graph.css
r2364 r2438 1 1 2 div#infovis-wrapper {border: 1px solid grey; margin: 20px; padding: 5px; height:450px; width:70%;} 2 /*div#infovis-wrapper {border: 1px solid grey; margin: 20px; padding: 5px; height:450px; width:70%;}*/ 3 3 #infovis {height: 90%; width: 100%;} 4 4 5 #index-container { width:20%; float:right;}5 #index-container { overflow: auto;} 6 6 7 7 .block { 8 8 border: 1px solid #999; 9 background-color: rgba(180,180,240,0.6);9 /* background-color: rgba(180,180,240,0.6); */ 10 10 } 11 11 .detail{ … … 13 13 } 14 14 15 .highlight { 15 .highlight, 16 .selected { 16 17 font-weight: bold; 17 18 background-color: red; 18 19 } 20 21 .slider {width: 80px; display:inline-block; font-size: 70%; margin: 6px 12px 0 2px;} 19 22 20 23 .detaildivs-wrapper { … … 35 38 } 36 39 37 circle.profile { 40 41 circle.type-profile { 38 42 fill: #66a; 39 43 stroke: #339; 44 } 45 46 .type-profile text{ 47 font-size: 12px; 48 font-weight: bold; 49 } 50 51 52 circle.type-datcat { 53 fill: #6a6; 54 stroke: #393; 55 } 56 57 58 circle.selected { 59 fill: #f66; 60 stroke-width: 2px; 40 61 } 41 62 text {
Note: See TracChangeset
for help on using the changeset viewer.