PageSourceSearch

https://terrancelaw.github.io/iDashboard/js/middleTrendView.js

js terrancelaw.github.io collected 2026-10-03 10:06:14 UTC 3,439 bytes, 95 lines download raw bytes

1const MiddleTrendView = {
2	draw: function(isInitialization) {
3		const self = this;
4		let quantitativeAttr = isInitialization ? Database.getQuantitativeAttrList()[1]
5							 : $('#trend-view > .view:nth-child(2) > .header > .attribute[type="quantitative"]').attr('value');
6
7		self.drawHeader(quantitativeAttr);
8		self.drawContent(quantitativeAttr);
9		self.installClickHeaderAttrBehaviour();
10	},
11	showLoader: function() {
12		$('#trend-view > .view:nth-child(2) > .loader')
13			.css('display', 'block');
14	},
15	hideLoader: function() {
16		$('#trend-view > .view:nth-child(2) > .loader')
17			.css('display', 'none');
18	},
19
20	// draw
21
22	drawHeader: function(quantitativeAttr) {
23		let itemName = Database.getItemName();
24		let filterState = MapView.selectedState;
25		let stateAbbr = filterState !== null ? Database.stateToAbbr[filterState] : '';
26		let headerHTML = '';
27
28		headerHTML += '<span class="attribute" type="quantitative" value="' + quantitativeAttr + '">' + quantitativeAttr + '</span>';
29		headerHTML += ' per ' + itemName + (filterState !== null ? ' in ' + stateAbbr : '');
30		$('#trend-view > .view:nth-child(2) > .header').html(headerHTML);
31	},
32	drawContent: function(quantitativeAttr) {
33		let filterState = MapView.selectedState;
34		let containerWidth = $('#trend-view > .view:nth-child(2) > .content').width();
35		let containerHeight = $('#trend-view > .view:nth-child(2) > .content').height();
36		let vegaLiteSpec = {
37			$schema: "https://vega.github.io/schema/vega-lite/v5.json",
38			width: containerWidth - 90, height: containerHeight - 60,
39			data: { values: Database.data },
40			mark: {
41				type: "line",
42				point: { filled: false, fill: "white" }
43			},
44			encoding: {
45				x: { 
46					field: "Year", type: "temporal", timeUnit: "year", 
47					axis: { 
48						labelColor: "gray", labelFontSize: 8,
49						titleColor: "gray", titleFontSize: 9, title: 'Year', titleFontWeight: 'normal',
50						gridDash: [ 2, 2 ], tickCount: 10,
51						labelExpr: "(datum.index === 0 || datum.index === 1) ? null : datum.label"
52					}
53				},
54				y: {
55					field: quantitativeAttr, type: "quantitative", aggregate: "mean",
56					axis: { 
57						labelColor: "gray", labelFontSize: 8,
58						titleColor: "gray", titleFontSize: 9, titleFontWeight: 'normal',
59						gridDash: [ 2, 2 ] 
60					}
61				},
62				tooltip: [
63			      { field: quantitativeAttr, type: "quantitative", aggregate: "mean", format: ".2f" },
64			      { field: "Year", type: "temporal", timeUnit: "year", title: 'Year' }
65			    ]
66			}
67		}
68
69		if (filterState !== null) vegaLiteSpec.transform = [{ filter: { field: "State", equal: filterState } }];
70		vegaEmbed('#trend-view > .view:nth-child(2) > .content', vegaLiteSpec, { actions: false });
71	},
72	installClickHeaderAttrBehaviour: function() {
73		$('#trend-view > .view:nth-child(2) > .header > .attribute')
74			.on('click', onClickHeaderAttribute);
75
76		function onClickHeaderAttribute() {
77			let attributeType = $(this).closest('.attribute').attr('type');
78			let position = $(this).offset();
79			let width = $(this).width();
80			let height = $(this).height();
81			let top = position.top - 8 - 20;
82			let left = position.left + width / 2;
83
84			$('#map-view > .header > .attribute').removeClass('clicking');
85			$('#trend-view > .view > .header > .attribute').removeClass('clicking');
86			$(this).addClass('clicking');
87			
88			DropDownMenu.show({
89				attributeType: attributeType,
90				focusedView: MiddleTrendView,
91				top: top, left: left, isUpArrow: false
92			});
93		}
94	}
95}

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.