1const container = "#dv2"; 2const font_size = 10; 3 4// const filter_item = 100; 5 6const shiftx_article = 30; 7const wiki_link = "https://en.wikipedia.org/wiki/"; 8const variation_line_opacity = 0.7; 9 10let limit_y_min = 500 11let limit_y_max = 15000 12let max_update = 0 13let min_update = 0 14 15const stroke_dash = "3,3"; 16 17const log_exponent = 0.5; 18 19let y_axis_value = 0 20 21function dv2(the_sort) { 22 23 // size constants 24 let window_w = document.getElementById("dv2").offsetWidth; 25 window_h = document.getElementById("dv2").offsetHeight; 26 27 let margin = {top: 20, left: 0, bottom: 20, right: 60}, 28 width = window_w - (margin.right + margin.right), 29 height = window_h - (margin.top + margin.bottom); 30 31 if (width <= 768){ 32 translate_articles = 10 33 reduction = 30 34 } 35 else { 36 translate_articles = shiftx_article 37 reduction = 100 38 } 39 40 // load data 41 d3.tsv("assets/data/voci.tsv") 42 .then(loaded) 43 44 function loaded(data) { 45 // console.log(data) 46 47 data = format_data(data) 48 filtered_data = data 49 50 statistics(data) 51 52 // svg 53 // --------------------------- 54 let svg = d3.select(container) 55 .append("svg") 56 .attr("width", width + (margin.right + margin.right)) 57 .attr("height",height + (margin.top + margin.bottom)) 58 .attr("id", "svg") 59 60 // scale 61 // --------------------------- 62 63 let min = 0 64 let max = filtered_data.length 65 66 let y_max = 0 67 68 let r_max = d3.max(filtered_data, function(d) { 69 return Math.sqrt(d.size/3.14); 70 }) 71 72 let r = d3.scaleLinear() 73 .range([min_circle_size, max_circle_size]) 74 .domain([0,r_max]) 75 76 let y = d3.scaleLinear() // scaleSymlog() > it works 77 // .domain([0,y_max + (y_max/100*10)]) 78 // .range([height - (margin.top * 10), 0]) 79 80 let x = d3.scaleLinear() 81 .domain([min,max]) 82 .range([0,width - reduction]) 83 84 // grid and plot 85 // --------------------------- 86 87 let grid = svg.append("g") 88 .attr("id","grid") 89 .attr("transform", "translate(-1," + margin.top*2 + ")") 90 .call(make_y_gridlines() 91 .tickSize(-width-margin.left-margin.right-60) 92 ) 93 94 let plot = svg.append("g") 95 .attr("id", "d3_plot") 96 .attr("transform", "translate(" + margin.right + "," + margin.top + ")"); 97 98 // axis and grid 99 // --------------------------- 100 101 let yAxis_margin = 10; 102 if (window_w < 700){ 103 yAxis_margin = 0; 104 } 105 106 let yAxis = plot.append("g") 107 .attr("id","yAxis") 108 .attr("transform", "translate(" + yAxis_margin + "," + (margin.top) +")") 109 .call(d3.axisLeft(y)) 110 .selectAll("text") 111 .attr("y", -10) 112 113 function make_y_gridlines() { 114 return d3.axisLeft(y) 115 } 116 117 let tooltip = get_tooltip('dv2') 118 plot.call(tooltip); 119 120 const duration = 0 121 function handleMouseOver(){ 122 123 // hide circles 124 d3.selectAll(".article_circles,.line_prev,.circle_prev") 125 .transition() 126 .duration(duration) 127 .attr("opacity",0.2) 128 129 // highlight 130 d3.select(this) 131 .transition() 132 .duration(duration) 133 .attr("opacity",1) 134 135 d3.select(this.previousSibling).select(".circle_prev,.line_prev") 136 .transition() 137 .duration(duration) 138 .attr("opacity",1) 139 } 140 141 function handleMouseOut(){ 142 d3.selectAll(".article_circles") 143 .transition() 144 .duration(duration) 145 .attr("opacity",1) 146 147 d3.selectAll(".variation").select(".circle_prev") 148 .transition() 149 .duration(duration) 150 .attr("opacity",0) 151 152 d3.selectAll(".variation").select(".line_prev") 153 .transition() 154 .duration(duration) 155 .attr("opacity",variation_line_opacity) 156 } 157 158 let articles = plot.append("g") 159 .attr("id","articles") 160 .attr("transform","translate(" + translate_articles + "," + (margin.top) + ")") 161 162 plot.call(tooltip) 163 164 // update the top bar filters 165 // -------------- 166 167 const min_pageviews = document.getElementById("min_pageviews") 168 const max_pageviews = document.getElementById("max_pageviews") 169 170 min_pageviews.value = limit_y_min; 171 max_pageviews.value = limit_y_max; 172 173 const filter_instance = document.getElementById("filter_instance"); 174 175 // remove categoris with count < 2 176 const counts = filtered_data.reduce((acc, d) => { 177 acc[d.instance_of] = (acc[d.instance_of] || 0) + 1; 178 return acc; 179 }, {}); 180 181 const sortedCategories = Object.entries(counts) 182 .filter(([cat, count]) => count >= 1) 183 .sort((a, b) => { 184 // First sort by count descending 185 if (b[1] !== a[1]) return b[1] - a[1]; 186 187 // Then sort alphabetically ascending 188 return a[0].localeCompare(b[0]); 189 }); 190
191 sortedCategories.forEach(([cat, count]) => { 192 const option = document.createElement("option"); 193 option.value = cat; 194 option.textContent = `${cat} (${count})`; // Optional: show count 195 filter_instance.appendChild(option); 196 }); 197 198 function display_data(instance, the_sort, limit_y_min, limit_y_max, y_axis_value){ // region, category, 199 200 the_sort = parseInt(the_sort) 201 202 if (d3.selectAll('.article')){ 203 d3.selectAll('.article').remove() 204 } 205 206 // filter data by region and category 207 // --------------------------- 208 209 the_data = data.sort((a, b) => a.article.localeCompare(b.article)); 210 211 if (instance == 'all'){ 212 filtered_data = the_data.filter(item => 213 item.avg_pv > limit_y_min 214 && 215 item.avg_pv < limit_y_max 216 ) 217 } 218 else { 219 filtered_data = the_data.filter(item => 220 item.instance_of == instance 221 && 222 item.avg_pv > limit_y_min 223 && 224 item.avg_pv < limit_y_max 225 ) 226 } 227 228 // review the elements attributes 229 // --------------------------- 230 231 if (the_sort == 1) { 232 min = 0 233 max = filtered_data.length - 1 234 } 235 else if (the_sort == 2){ 236 min = d3.min(filtered_data, function(d) { 237 return d.days; 238 }) 239 max = d3.max(filtered_data, function(d) { 240 return d.days; 241 }) 242 } 243 else if (the_sort == 3){ 244 min = d3.min(filtered_data, function(d) { 245 return d.size; 246 }) 247 max = d3.max(filtered_data, function(d) { 248 return d.size; 249 }) 250 } 251 else if (the_sort == 4){ 252 min = d3.min(filtered_data, function(d) { 253 return d.discussion_size; 254 }) 255 max = d3.max(filtered_data, function(d) { 256 return d.discussion_size; 257 }) 258 } 259 else if (the_sort == 5){ 260 min = d3.min(filtered_data, function(d) { 261 return d.incipit_size; 262 }) 263 max = d3.max(filtered_data, function(d) { 264 return d.incipit_size; 265 }) 266 } 267 else if (the_sort == 6){ 268 min = d3.min(filtered_data, function(d) { 269 return d.issues; 270 }) 271 max = d3.max(filtered_data, function(d) { 272 return d.issues; 273 }) 274 } 275 else if (the_sort == 7){ 276 min = d3.min(filtered_data, function(d) { 277 return d.images; 278 }) 279 max = d3.max(filtered_data, function(d) { 280 return d.images; 281 }) 282 } 283 else if (the_sort == 8){ 284 min = d3.min(filtered_data, function(d) { 285 return d.edits_editors_ratio 286 }) 287 max = d3.max(filtered_data, function(d) { 288 return d.edits_editors_ratio 289 }) 290 } 291 else if (the_sort == 9){ 292 min = d3.min(filtered_data, function(d) { 293 return d.linguistic_versions 294 }) 295 max = d3.max(filtered_data, function(d) { 296 return d.linguistic_versions 297 }) 298 } 299 // console.log(min, max) 300 301 if (y_axis_value == 0){ 302 y_min = d3.min(filtered_data, function(d) { 303 return d.total_views; 304 }) 305 306 y_max = d3.max(filtered_data, function(d) { 307 return d.total_views; 308 }) 309 } 310 else if (y_axis_value == 1){ 311 y_min = d3.min(filtered_data, function(d) { 312 return d.avg_pv; 313 }) 314 315 y_max = d3.max(filtered_data, function(d) { 316 return d.avg_pv; 317 }) 318 } 319 else if (y_axis_value == 2){ 320 y_min = d3.min(filtered_data, function(d) { 321 return d.editors; 322 }) 323 324 y_max = d3.max(filtered_data, function(d) { 325 return d.editors; 326 }) 327 } 328 else { 329 y_min = d3.min(filtered_data, function(d) { 330 return d.incoming_links; 331 }) 332 333 y_max = d3.max(filtered_data, function(d) { 334 return d.incoming_links; 335 }) 336 } 337 // console.log(y_max) 338 339 x = d3.scaleLinear() 340 .domain([min,max]) 341 .range([0,width-100]) 342 343 y = d3.scaleLinear() 344 .domain([0,y_max+(y_max/100*10)]) 345 .range([height - (margin.top * 1.6),0]) 346 347 toltip = tooltip.offset(function (d,i){ 348 let direction = '' 349 let off = [0,0] // [top, left] 350 351 if (y_axis_value == 0){ 352 y_value = d.total_views 353 354 y_max = d3.max(filtered_data, function(d) { 355 return d.total_views; 356 }) 357 } 358 else if (y_axis_value == 1){ 359 y_value = d.avg_pv 360 361 y_max = d3.max(filtered_data, function(d) { 362 return d.avg_pv; 363 }) 364 } 365 else if (y_axis_value == 2){ 366 y_value = d.editors 367 368 y_max = d3.max(filtered_data, function(d) { 369 return d.editors; 370 }) 371 } 372 else { 373 y_value = d.incoming_links 374 375 y_max = d3.max(filtered_data, function(d) { 376 return d.incoming_links; 377 }) 378 } 379 380 if (the_sort == 1) { // title 381 direction = tooltip_direction(i, min, max, y_value, y_max, false) 382 } 383 else if (the_sort == 2){ 384 direction = tooltip_direction(d.days, min, max, y_value, y_max, true) 385 } 386 else if (the_sort == 3){ 387 direction = tooltip_direction(d.size, min, max, y_value, y_max, false) 388 } 389 else if (the_sort == 4){ 390 direction = tooltip_direction(d.discussion_size, min, max, y_value, y_max, false) 391 } 392 else if (the_sort == 5){ 393 direction = tooltip_direction(d.incipit_size, min, max, y_value, y_max, false) 394 } 395 else if (the_sort == 6){ 396 direction = tooltip_direction(d.issues, min, max, y_value, y_max, false) 397 } 398 else if (the_sort == 7){ 399 direction = tooltip_direction(d.images, min, max, y_value, y_max, false) 400 } 401 else if (the_sort == 8){ 402 direction = tooltip_direction(d.edits_editors_ratio, min, max, y_value, y_max, false) 403 } 404 else if (the_sort == 9){ 405 direction = tooltip_direction(d.linguistic_versions, min, max, y_value, y_max, false) 406 } 407 // console.log(the_sort, y_axis_value, y_value, y_max) 408 409 if (direction == 'nw'){ 410 off = [-10,-10] 411 } 412 else if (direction == 'n'){ 413 off = [-10,0] 414 } 415 else if (direction == 'ne'){ 416 off = [-10,-10] 417 } 418 419 return off 420 }) 421 .direction(function (d,i) { 422 423 if (y_axis_value == 0){ 424 y_value = d.total_views 425 426 y_max = d3.max(filtered_data, function(d) { 427 return d.total_views; 428 }) 429 } 430 else if (y_axis_value == 1){ 431 y_value = d.avg_pv 432 433 y_max = d3.max(filtered_data, function(d) { 434 return d.avg_pv; 435 }) 436 } 437 else if (y_axis_value == 2){ 438 y_value = d.editors 439 440 y_max = d3.max(filtered_data, function(d) { 441 return d.editors; 442 }) 443 } 444 else if (y_axis_value == 3) { 445 y_value = d.incoming_links 446 447 y_max = d3.max(filtered_data, function(d) { 448 return d.incoming_links; 449 }) 450 } 451 // console.log(y_axis_value, y_value, y_max) 452 453 let direction = '' 454 if (the_sort == 1) { // title 455 // console.log(y_value) 456 457 direction = tooltip_direction(i, min, max, y_value, y_max, false) 458 } 459 else if (the_sort == 2){ 460 direction = tooltip_direction(d.days, min, max, y_value, y_max, true) 461 } 462 else if (the_sort == 3){ 463 direction = tooltip_direction(d.size, min, max, y_value, y_max, false) 464 } 465 else if (the_sort == 4){ 466 direction = tooltip_direction(d.discussion_size, min, max, y_value, y_max, false) 467 } 468 else if (the_sort == 5){ 469 direction = tooltip_direction(d.incipit_size, min, max, y_value, y_max, false) 470 } 471 else if (the_sort == 6){ 472 direction = tooltip_direction(d.issues, min, max, y_value, y_max, false) 473 } 474 else if (the_sort == 7){ 475 direction = tooltip_direction(d.images, min, max, y_value, y_max, false) 476 } 477 else if (the_sort == 8){ 478 direction = tooltip_direction(d.edits_editors_ratio, min, max, y_value, y_max, false) 479 } 480 else if (the_sort == 9){ 481 direction = tooltip_direction(d.linguistic_versions, min, max, y_value, y_max, false) 482 } 483 // console.log(the_sort, y_axis_value, y_value, y_max, 'b') 484 485 return direction 486 }) 487 488 svg.select("#yAxis") 489 .transition() 490 .duration(200) 491 .call(d3.axisLeft(y)) 492 493 d3.select('#grid') 494 .transition() 495 .duration(200) 496 .call(d3.axisLeft(y)
497 .tickSize(-width-margin.left-margin.right-60) 498 ) 499 500 // plot data 501 // --------------------------- 502 503 article = articles.selectAll("g") 504 .data(filtered_data) 505 .enter() 506 .append("g") 507 .attr("class","article") 508 .attr("id", function(d,i){ 509 return i 510 }) 511 .attr("data-article", function(d,i){ 512 return d.article 513 }) 514 .attr("data-subject", function(d,i){ 515 return d.subject 516 }) 517 .attr("transform", function(d,i){ 518 if (the_sort == 1) { // "article" 519 x_position = x(i) 520 } 521 else if (the_sort == 2){ 522 x_position = x(d.days) 523 } 524 else if (the_sort == 3){ 525 x_position = x(d.size) 526 } 527 else if (the_sort == 4){ 528 x_position = x(d.discussion_size) 529 } 530 else if (the_sort == 5){ 531 x_position = x(d.incipit_size) 532 } 533 else if (the_sort == 6){ 534 x_position = x(d.issues) 535 } 536 else if (the_sort == 7){ 537 x_position = x(d.images) 538 } 539 else if (the_sort == 8){ 540 x_position = x(d.edits_editors_ratio) 541 } 542 else if (the_sort == 9){ 543 x_position = x(d.linguistic_versions) 544 } 545 else { 546 x_position = x(i) 547 } 548 return "translate(" + (x_position + 50) + "," + 0 + ")" 549 }) 550 .on("mouseover", tooltip.show) 551 .on("mouseout", tooltip.hide) 552 553 // articles 554 let article_circles = article.append("g") 555 .attr("class","article_circles") 556 .attr("transform",function (d,i) { 557 558 let output = '' 559 if (y_axis_value == 0){ 560 output = "translate(" + 0 + "," + y(d.total_views) + ")" 561 } 562 else if (y_axis_value == 1){ 563 output = "translate(" + 0 + "," + y(d.avg_pv) + ")" 564 } 565 else if (y_axis_value == 2){ 566 output = "translate(" + 0 + "," + y(d.editors) + ")" 567 } 568 else { 569 output = "translate(" + 0 + "," + y(d.incoming_links) + ")" 570 } 571 572 return output 573 }) 574 .attr("id", function(d,i){ 575 return 'id_' + d.wikidata_id 576 }) 577 .on("mouseover", handleMouseOver) 578 .on("mouseout", handleMouseOut) 579 .append("a") 580 .attr("xlink:href", function(d,i){ 581 return wiki_link + d.article 582 }) 583 .attr("target","_blank") 584 585 let circles = article_circles.append("circle") 586 .transition() 587 .duration(500) 588 .delay(function(d,i){ 589 return i * 2 590 }) 591 .attr("cx",0) 592 .attr("cy",0) 593 .attr("fill", d => categoryColors[d.instance_of] || categoryColors.default) 594 .attr("opacity",0.5) 595 .attr("r",0) 596 .transition() 597 .ease(d3.easeLinear) 598 .duration(500) 599 .attr("r", function(d,i){ 600 return r(Math.sqrt(d.size/3.14)) 601 }) 602 .attr("data-size", function(d,i){ 603 return d.size 604 }) 605 606 let incipit = article_circles.append("circle") 607 .transition() 608 .duration(500) 609 .delay(function(d,i){ 610 return i * 2 611 }) 612 .attr("cx",0) 613 .attr("cy",0) 614 .attr("fill", d => categoryColors[d.instance_of] || categoryColors.default) 615 .attr("opacity",0.5) 616 .attr("r", function(d,i){ 617 return r(Math.sqrt(d.incipit_size/3.14)) 618 }) 619 .attr("data-incipit", function(d,i){ 620 return d.incipit_size 621 }) 622 623 let discussion = article_circles.append("circle") 624 .transition() 625 .duration(500) 626 .delay(function(d,i){ 627 return i * 2 628 }) 629 .attr("cx",0) 630 .attr("cy",0) 631 .attr("stroke", d => categoryColors[d.instance_of] || categoryColors.default) 632 .attr("fill","transparent") 633 .attr("stroke-width",0.5) 634 .attr("opacity",0.9) 635 .attr("r",0) 636 .transition() 637 .delay(1000) 638 .ease(d3.easeLinear) 639 .duration(500) 640 .attr("r", function(d,i){ 641 return r(Math.sqrt(d.discussion_size/3.14)) 642 }) 643 .attr("data-discussion", function(d,i){ 644 return d.discussion_size 645 }) 646 647 // restrictions 648 const padlock_width = 6 649 const padlock_animation = 500 650 let padlock = article_circles.append('g') 651 .attr('transform', function(d,i){ 652 const x = r(Math.sqrt(d.size/3.14)) + 5 + (padlock_width/2) 653 return "translate(" + x + "," + 0 + ")" 654 }) 655 656 let padlock_a = padlock.append("circle") 657 .transition() 658 .duration(500) 659 .delay(function(d,i){ 660 return i * 2 + padlock_animation 661 }) 662 .ease(d3.easeLinear) 663 .duration(padlock_animation) 664 .attr('stroke-width',1) 665 .attr("r",0) 666 .attr("fill", "transparent") 667 .attr("stroke", function (d){ 668 if (d.restrictions != ''){ 669 return "gray" 670 } 671 else { 672 return "transparent" 673 } 674 }) 675 .attr("r",padlock_width/2 - 1) 676 677 let padlock_b = padlock.append("rect") 678 .transition() 679 .duration(500) 680 .delay(function(d,i){ 681 return i * 2 + padlock_animation 682 }) 683 .ease(d3.easeLinear) 684 .duration(padlock_animation) 685 .attr("width",0) 686 .attr("height",0) 687 .attr('x',-padlock_width/2) 688 .attr('y',0) 689 .attr("stroke", function (d){ 690 if (d.restrictions != ''){ 691 return "gray" 692 } 693 else { 694 return "transparent" 695 } 696 }) 697 .attr("fill", function (d){ 698 if (d.restrictions != ''){ 699 return "white" 700 } 701 else { 702 return "transparent" 703 } 704 }) 705 .attr("width",padlock_width) 706 .attr("height",padlock_width/5*4) 707 708 709 sidebar(2,filtered_data,the_sort) 710 711 // sort data 712 // --------------------------- 713 const sort_box = document.getElementById('sort_article') 714 sort_box.addEventListener("change", function() { 715 716 let new_sort = this.value; 717 // let new_region = region_box.options[region_box.selectedIndex].value; 718 719 // console.log(y_axis_value) 720 update_sort(new_sort) 721 }); 722 723 function update_sort(the_sort){ // region 724 725 the_sort = parseInt(the_sort) 726 727 if (the_sort == 1) { 728 min = 0 729 max = filtered_data.length 730 } 731 else if (the_sort == 2){ 732 min = d3.min(filtered_data, function(d) { 733 return d.days; 734 }) 735 max = d3.max(filtered_data, function(d) { 736 return d.days; 737 }) 738 } 739 else if (the_sort == 3){ 740 min = d3.min(filtered_data, function(d) { 741 return d.size; 742 }) 743 max = d3.max(filtered_data, function(d) { 744 return d.size; 745 }) 746 } 747 else if (the_sort == 4){ 748 min = d3.min(filtered_data, function(d) { 749 return d.discussion_size; 750 }) 751 max = d3.max(filtered_data, function(d) { 752 return d.discussion_size; 753 }) 754 } 755 else if (the_sort == 5){ 756 min = d3.min(filtered_data, function(d) { 757 return d.incipit_size; 758 }) 759 max = d3.max(filtered_data, function(d) { 760 return d.incipit_size; 761 }) 762 } 763 else if (the_sort == 6){ 764 min = d3.min(filtered_data, function(d) { 765 return d.issues; 766 }) 767 max = d3.max(filtered_data, function(d) { 768 return d.issues; 769 }) 770 } 771 else if (the_sort == 7){ 772 min = d3.min(filtered_data, function(d) { 773 return d.images; 774 }) 775 max = d3.max(filtered_data, function(d) { 776 return d.images; 777 }) 778 } 779 else if (the_sort == 8){ 780 min = d3.min(filtered_data, function(d) { 781 return d.edits_editors_ratio 782 }) 783 max = d3.max(filtered_data, function(d) { 784 return d.edits_editors_ratio 785 }) 786 } 787 else if (the_sort == 9){ 788 min = d3.min(filtered_data, function(d) { 789 return d.linguistic_versions 790 }) 791 max = d3.max(filtered_data, function(d) { 792 return d.linguistic_versions 793 }) 794 } 795 796 if (the_sort == 2){ 797 x = d3.scaleLinear() 798 .domain([max,min]) 799 .range([0,width-100]) 800 } 801 else { 802 x = d3.scaleLinear() 803 .domain([min,max]) 804 .range([0,width-100]) 805 } 806 // console.log(filtered_data) 807 808 let sort = [ 809 "article", // 1 810 "publication", // 2 811 "size", // 3 812 "discussion", // 4 813 "incipit", // 5 814 "issue", // 6 815 "images" // 7 816 ] 817 818 svg.selectAll(".article") 819 .transition() 820 .attr("transform", function(d,i){ 821 822 x_position = 0 823 824 if (the_sort == 1) { // "article" 825 x_position = x(i) 826 } 827 else if (the_sort == 2){ 828 x_position = x(d.days) 829 } 830 else if (the_sort == 3){ 831 x_position = x(d.size) 832 } 833 else if (the_sort == 4){ 834 x_position = x(d.discussion_size) 835 } 836 else if (the_sort == 5){ 837 x_position = x(d.incipit_size) 838 } 839 else if (the_sort == 6){ 840 x_position = x(d.issues) 841 } 842 else if (the_sort == 7){ 843 x_position = x(d.images) 844 } 845 else if (the_sort == 8){ 846 x_position = x(d.edits_editors_ratio) 847 } 848 else if (the_sort == 9){ 849 x_position = x(d.linguistic_versions) 850 } 851 else { 852 x_position = x(i) 853 } 854 // console.log(d.article,min,max,d.size,width,x_position) 855 return "translate(" + (x_position + 50) + "," + 0 + ")" 856 }) 857 858 tooltip = tooltip.direction(function (d,i) { 859 860 if (y_axis_value == 0){ 861 y_value = d.total_views 862 863 y_max = d3.max(filtered_data, function(d) { 864 return d.total_views; 865 }) 866 } 867 else if (y_axis_value == 1){ 868 y_value = d.avg_pv 869 870 y_max = d3.max(filtered_data, function(d) { 871 return d.avg_pv; 872 }) 873 } 874 else if (y_axis_value == 2){ 875 y_value = d.editors 876 877 y_max = d3.max(filtered_data, function(d) { 878 return d.editors; 879 }) 880 } 881 else { 882 y_value = d.incoming_links 883 884 y_max = d3.max(filtered_data, function(d) { 885 return d.incoming_links; 886 }) 887 } 888 889 let direction = '' 890 if (the_sort == 1) { // title 891 direction = tooltip_direction(i, min, max, y_value, y_max, false) 892 } 893 else if (the_sort == 2){ 894 direction = tooltip_direction(d.days, min, max, y_value, y_max, false) 895 } 896 else if (the_sort == 3){ 897 direction = tooltip_direction(d.size, min, max, y_value, y_max, false) 898 } 899 else if (the_sort == 4){ 900 direction = tooltip_direction(d.discussion_size, min, max, y_value, y_max, false) 901 } 902 else if (the_sort == 5){ 903 direction = tooltip_direction(d.incipit_size, min, max, y_value, y_max, false) 904 } 905 else if (the_sort == 6){ 906 direction = tooltip_direction(d.issues, min, max, y_value, y_max, false) 907 } 908 else if (the_sort == 7){ 909 direction = tooltip_direction(d.images, min, max, y_value, y_max, false) 910 } 911 else if (the_sort == 8){ 912 direction = tooltip_direction(d.edits_editors_ratio, min, max, y_value, y_max, false) 913 } 914 else if (the_sort == 9){ 915 direction = tooltip_direction(d.linguistic_versions, min, max, y_value, y_max, false) 916 } 917 return direction 918 }) 919 sidebar(2, filtered_data, the_sort) 920 } 921 } 922 display_data('all', the_sort, limit_y_min, limit_y_max, y_axis_value) // region, category, 923 924 // yaxis label 925 let yaxis_label_box = plot.append("g") 926 .attr("class","yaxis_label") 927 .attr("transform","translate(7," + (height - 10) + ")") 928 .attr("class","hover") 929 .on("mouseover", y_axis_mouseover) 930 .on("mouseout", y_axis_mouseout) 931 .on("click", y_axis_switch) 932 933 let yaxis_label_rect = yaxis_label_box.append("rect") 934 .attr("width", 175) 935 .attr("height", 25) 936 .attr("transform","translate(0,-30)") 937 .attr("stroke", "gray") 938 .attr("fill","white") 939 .attr("opacity",0.8) 940 .attr("rx",5) 941 .attr("ry",5) 942 943 let yaxis_label = yaxis_label_box.append("text") 944 .attr("class","lang_switch") 945 .text("total visits (1 of 4)") 946 .attr("data-it","visite toali (1 di 4)") 947 .attr("data-en","total visits (1 of 4)") 948 .attr("id","yaxis_label") 949 .attr("y", -14) 950 .attr("x", 10) 951 .attr("font-size",font_size) 952 953 function y_axis_mouseover(){ 954 d3.select(this) 955 .transition() 956 .duration(duration) 957 .attr("opacity",1) 958 } 959 960 function y_axis_mouseout(){ 961 d3.select(this) 962 .transition() 963 .duration(duration) 964 .attr("opacity",0.8) 965 } 966 967 scale = 'linear' 968 969 function y_axis_switch(){ 970 971 // 0 total visit 972 // 1 average visit 973 // 2 editor
974 // 3 incoming links 975 976 if (y_axis_value == 0){ 977 y_axis_value = 1 978 979 d3.select(this).select('text') 980 .text("average daily visits (2 of 4)") 981 } 982 else if (y_axis_value == 1) { 983 y_axis_value = 2 984 985 d3.select(this).select('text') 986 .text("number of editor (3 of 4)") 987 } 988 else if (y_axis_value == 2) { 989 y_axis_value = 3 990 991 d3.select(this).select('text') 992 .text("number of incoming links (4 of 4)") 993 } 994 else { 995 y_axis_value = 0 996 997 d3.select(this).select('text') 998 .text("total visits (1 of 4)") 999 } 1000 1001 // console.log(y_axis_value) 1002 update_scale(scale, y_axis_value, false) 1003 } 1004 1005 // chart scale 1006 // --------------------------- 1007 1008 function update_scale(scale, y_axis_value, switch_log){ 1009 // console.log(scale, y_axis_value, switch_log) 1010 1011 y = d3.scaleLinear() 1012 1013 // if (switch_log == false){ 1014 1015 if (y_axis_value == 0){ 1016 y_min = d3.min(filtered_data, function(d) { 1017 return d.total_views; 1018 }) 1019 1020 y_max = d3.max(filtered_data, function(d) { 1021 return d.total_views; 1022 }) 1023 } 1024 else if (y_axis_value == 1){ 1025 y_min = d3.min(filtered_data, function(d) { 1026 return d.avg_pv; 1027 }) 1028 1029 y_max = d3.max(filtered_data, function(d) { 1030 return d.avg_pv; 1031 }) 1032 } 1033 else if (y_axis_value == 2){ 1034 y_min = d3.min(filtered_data, function(d) { 1035 return d.editors; 1036 }) 1037 1038 y_max = d3.max(filtered_data, function(d) { 1039 return d.editors; 1040 }) 1041 } 1042 else { 1043 y_min = d3.min(filtered_data, function(d) { 1044 return d.incoming_links; 1045 }) 1046 1047 y_max = d3.max(filtered_data, function(d) { 1048 return d.incoming_links; 1049 }) 1050 } 1051 // } 1052 // console.log(y_axis_value, y_min, y_max) 1053 1054 if (scale == "linear"){ 1055 y = d3.scaleLinear() 1056 .domain([0,y_max+(y_max/100*10)]) 1057 .range([height - (margin.top * 1.6),0]) 1058 } 1059 else if (scale == "log"){ 1060 y = d3.scaleSymlog(10) 1061 .domain([0,y_max+(y_max/100*10)]) 1062 .range([height - (margin.top * 1.6),0]) 1063 } 1064 1065 // articles 1066 svg.selectAll(".article_circles") 1067 .transition() 1068 .duration(200) 1069 .attr("transform",function (d,i) { 1070 let output = '' 1071 if (y_axis_value == 0){ 1072 output = "translate(" + 0 + "," + y(d.total_views) + ")" 1073 } 1074 else if (y_axis_value == 1){ 1075 output = "translate(" + 0 + "," + y(d.avg_pv) + ")" 1076 } 1077 else if (y_axis_value == 2){ 1078 output = "translate(" + 0 + "," + y(d.editors) + ")" 1079 } 1080 else { 1081 output = "translate(" + 0 + "," + y(d.incoming_links) + ")" 1082 } 1083 return output 1084 }) 1085 1086 // y axis ticks text 1087 svg.select("#yAxis") 1088 .transition() 1089 .duration(200) 1090 .call(d3.axisLeft(y)) // it works 1091 1092 d3.select('#grid') 1093 .transition() 1094 .duration(200) 1095 .call(d3.axisLeft(y) 1096 .tickSize(-width-margin.left-margin.right-60) 1097 ) 1098 } 1099 1100 function chart_scale(){ 1101 1102 function to_log(){ 1103 update_scale("log", y_axis_value, true) 1104 1105 the_path = load_path() 1106 scale_icon.style.background = "url(" + the_path + "assets/img/scale_linear.svg) center center / 55% no-repeat" 1107 scale = "log" 1108 1109 tootip_linear.style.display = 'none' 1110 tootip_log.style.display = 'block' 1111 } 1112 1113 function to_linear(){ 1114 update_scale("linear", y_axis_value, true) 1115 1116 the_path = load_path() 1117 scale_icon.style.background = "url(" + the_path + "assets/img/scale_log.svg) center center / 55% no-repeat" 1118 scale = "linear" 1119 1120 tootip_log.style.display = 'none' 1121 tootip_linear.style.display = 'block' 1122 } 1123 1124 let scale = "linear" 1125 const switch_scale = document.getElementById("scale_button") 1126 const scale_icon = document.getElementById("scale_button_icon") 1127 const tootip_linear = document.getElementById("scale_tooltip_linear") 1128 const tootip_log = document.getElementById("scale_tooltip_logarithmic") 1129 1130 switch_scale.addEventListener('click', (event) => { 1131 if (scale == "linear"){ 1132 to_log() 1133 } 1134 else if (scale == "log") { 1135 to_linear() 1136 } 1137 }) 1138 1139 // filter by page views an by instane 1140 // -------------------- 1141 1142 const display_filter = document.getElementById("display_filter") 1143 const filter_instance = document.getElementById("filter_instance") 1144 1145 display_filter.addEventListener('click', (event) => { 1146 update_filter() 1147 }) 1148 1149 filter_instance.addEventListener('change', function() { 1150 update_filter() 1151 }) 1152 1153 function update_filter(){ 1154 const min_pageviews = document.getElementById("min_pageviews") 1155 const max_pageviews = document.getElementById("max_pageviews") 1156 const the_instance = document.getElementById("filter_instance") 1157 const sort_box = document.getElementById('sort_article') 1158 1159 let new_sort = sort_box.value; 1160 1161 const new_limit_y_min = parseInt(min_pageviews.value) 1162 const new_limit_y_max = parseInt(max_pageviews.value) 1163 const instance = the_instance.value 1164 1165 // console.log(y_axis_value) 1166 display_data(instance, new_sort, new_limit_y_min, new_limit_y_max, y_axis_value) 1167 } 1168 } 1169 chart_scale() 1170 1171 // make the visualization responsive 1172 // --------------------------- 1173 function responsive_chart(width){ 1174 1175 if (width <= 768){ 1176 translate_articles = 10 1177 reduction = 30 1178 1179 } 1180 else { 1181 translate_articles = shiftx_article 1182 reduction = 100 1183 } 1184 1185 svg
1186 .attr("width", width + (margin.right + margin.right)) 1187 1188 grid 1189 .call(make_y_gridlines() 1190 .tickSize(-width-margin.left-margin.right-60) 1191 ) 1192 1193 x = d3.scaleLinear() 1194 .domain([min,max]) 1195 .range([0,width - reduction]) 1196 1197 articles.attr("transform","translate(" + translate_articles + "," + margin.top + ")") 1198 1199 svg.selectAll(".article") 1200 .transition() 1201 .attr("transform", function(d,i){ 1202 x_position = 0 1203 1204 if (the_sort == 1) { // "article" 1205 x_position = x(i) 1206 } 1207 else if (the_sort == 2){ 1208 x_position = x(d.days) 1209 } 1210 else if (the_sort == 3){ 1211 x_position = x(d.size) 1212 } 1213 else if (the_sort == 4){ 1214 x_position = x(d.discussion_size) 1215 } 1216 else if (the_sort == 5){ 1217 x_position = x(d.incipit_size) 1218 } 1219 else if (the_sort == 6){ 1220 x_position = x(d.issues) 1221 } 1222 else if (the_sort == 7){ 1223 x_position = x(d.images) 1224 } 1225 else if (the_sort == 7){ 1226 x_position = x(d.images) 1227 } 1228 else if (the_sort == 8){ 1229 x_position = x(d.edits_editors_ratio) 1230 } 1231 else if (the_sort == 9){ 1232 x_position = x(d.linguistic_versions) 1233 } 1234 else { 1235 x_position = x(i) 1236 } 1237 // console.log(d.article,min,max,d.size,width,x_position) 1238 return "translate(" + x_position + "," + 0 + ")" 1239 }) 1240 } 1241 1242 window.addEventListener("resize", (event) => { 1243 window_w = document.getElementById("dv2").offsetWidth; 1244 width = window_w - (margin.right + margin.right) 1245 1246 responsive_chart(width) 1247 }); 1248 1249 function show_no_data(){ 1250 1251 const lineData = [ 1252 {y: 1}, 1253 {y: 2}, 1254 {y: 3}, 1255 {y: 4}, 1256 {y: 5}, 1257 {y: 6}, 1258 {y: 7} 1259 ] 1260 1261 const line_height = (height - (margin.top * 1.5)) / lineData.length 1262 1263 group = articles.append("g") 1264 .attr("class","article") 1265 .attr("transform","translate(" + (-90) + ",0)") 1266 1267 lines = group.append("g") 1268 .attr("class","lines") 1269 .selectAll("lines") 1270 .data(lineData) 1271 .enter() 1272 .append("line") 1273 .attr("x1", 0) 1274 .attr("y1", d => d.y * line_height) 1275 .attr("x2", window_w) 1276 .attr("y2", d => d.y * line_height) 1277 .attr("stroke", "#e9e4e4") 1278 .attr("stroke-width", 1); 1279 1280 text_box = group.append("g") 1281 .attr("class","text") 1282 .attr("transform","translate(" + 0 + ",-20)") 1283 1284 text_a = text_box.append("text") 1285 .text("Purtroppo qui non ci sono dati.") 1286 .attr("x",window_w / 2) 1287 .attr("y",height / 2) 1288 .attr("text-anchor","middle") 1289 1290 text_b = text_box.append("text") 1291 .text("Prova a cambiare la selezione.") 1292 .attr("x",window_w / 2) 1293 .attr("y",height / 2 + 20) 1294 .attr("text-anchor","middle") 1295 } 1296 } 1297} 1298 1299function tooltip_direction(the_x, x_min, x_max, y_value, y_max, invert){ 1300 1301 x = parseInt(the_x) 1302 x_min = parseInt(x_min) 1303 x_max = parseInt(x_max) 1304 y_max = parseInt(y_max) 1305 1306 let n_s = '' 1307 let w_e = '' 1308 1309 if (y_value > (y_max/3*2) ){ 1310 n_s = 's' 1311 } 1312 else { 1313 n_s = 'n' 1314 } 1315 1316 if (invert == false){ 1317 let range = x_max - x_min 1318 if (x < (x_min + range / 3)){ 1319 w_e = 'e' 1320 } 1321 else if ( x > (x_min + range / 3 * 2) ) { 1322 w_e = 'w' 1323 } 1324 } 1325 else { 1326 let range = x_max - x_min 1327 if (x > (x_min + range / 3)){ 1328 w_e = 'e' 1329 } 1330 else if ( x < (x_min + range / 3 * 2) ) { 1331 w_e = 'w' 1332 } 1333 } 1334 1335 const direction = n_s + w_e 1336 // console.log(y_value, y_max, direction, y_axis_value) 1337 1338 return direction 1339} 1340 1341window.onload = function() { 1342 dv2(1); 1343}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.