PageSourceSearch

https://giovannipro.github.io/wikipedia-climate-change/assets/script/dv2.js

js giovannipro.github.io collected 2026-10-03 09:14:43 UTC 32,726 bytes, 1,343 lines download raw bytes

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.