PageSourceSearch

https://www.sironaconsulting.com/graph-calc.js

js sironaconsulting.com collected 2026-10-03 21:37:37 UTC 3,934 bytes, 130 lines download raw bytes

1function getEventX(event) {
2	var posx = 0;
3	if (event.pageX || event.pageY) {
4		posx =  event.pageX;
5	}
6	else if (event.clientX || event.clientY) 	{
7		posx = event.clientX + document.body.scrollLeft
8			+ document.documentElement.scrollLeft;
9	}
10	return posx;
11}
12function getElementX(obj) {
13	var x = 0;
14	if (obj.offsetParent) {
15		do {
16			x += obj.offsetLeft;
17		} while (obj = obj.offsetParent);
18	}
19	return x;
20}
21function zeroPad(v, len) {
22  v = v.toString();
23  return v.length >= len ? v : "00000000".substring(0, len - v.length) + v;
24}
25
26/**
27 * Check if the difference between the max and the min non zero capture numbers
28 * is larger than 3 orders of magnitude. If yes, we need to scale.
29**/
30function capturegraph_scale_is_required(captures) {
31    var max = 0;
32    var min = 1000;
33    for (var i = 0; i < captures.length; i++) {
34	var year = captures[i];
35        max = Math.max(max, Math.max.apply(null, year[1]));
36        min = Math.min(min, Math.min.apply(null,
37                                           year[1].filter(Boolean)));
38    }
39    return (Math.log1p(max) - Math.log1p(min) > 3);
40}
41
42/**
43 * Scale captugraph counts and max maxcount using log1p if necessary.
44 */
45function capturegraph_scale(captures) {
46    var maxcount = 0;
47    for (var i = 0; i < captures.length; i++) {
48	maxcount = Math.max(maxcount, Math.max.apply(null, captures[i][1]));
49    }
50    if (capturegraph_scale_is_required(captures)) {
51	var scaled = [];
52	for (var i = 0; i < captures.length; i++) {
53	    var year = captures[i];
54	    // XXX map may not be available on all platforms
55	    scaled.push([year[0], year[1].map(Math.log1p)]);
56	}
57	captures = scaled;
58	maxcount = Math.log1p(maxcount);
59    }
60    return [captures, maxcount];
61}
62
63/**
64 * Draw years, highlight current year, draw capture frequency per month
65 */
66function sparkline(captures, width, height, canvas, start_year,
67                   cur_year, cur_month) {
68    var ctx = canvas.getContext("2d");
69    if (!ctx) return;
70    ctx.fillStyle = "#FFF";
71    var end_year = new Date().getUTCFullYear();
72    var year_width = width / (end_year - start_year + 1);
73
74    var scaled = capturegraph_scale(captures.years);
75    var years = scaled[0];
76    var maxcount = scaled[1];
77
78    var yscale = height / maxcount;
79
80    function year_left(year) {
81	return Math.ceil((year - start_year) * year_width) + 0.5;
82    }
83
84    if (cur_year >= start_year) {
85	var x = year_left(cur_year);
86	ctx.fillStyle = "#FFFFA5";
87	ctx.fillRect(x, 0, year_width, height);
88    }
89    for (var year = start_year; year <= end_year; year++) {
90	var x = year_left(year);
91        ctx.beginPath();
92        ctx.moveTo(x, 0);
93        ctx.lineTo(x, height);
94        ctx.lineWidth = 1;
95        ctx.strokeStyle = "#CCC";
96        ctx.stroke();
97    }
98    cur_month = parseInt(cur_month) - 1;
99    var month_width = (year_width - 1) / 12;
100    for (var i = 0; i < years.length; i++) {
101	var year = years[i][0];
102	var months = years[i][1];
103	var left = year_left(year) + 1.0;
104        for (var month = 0; month < 12; month++) {
105            var count = months[month];
106            if (count > 0) {
107                var h = Math.ceil(count * yscale);
108		if (year == cur_year && month == cur_month) {
109                    ctx.fillStyle = "#EC008C";
110                } else {
111                    ctx.fillStyle = "#000";
112                }
113                // must note that when I use width=Math.round(month_width+1),
114                // the replay toolbar looks more accurate whereas the
115                // bubble calendar looks somehow different.
116                ctx.fillRect(Math.round(left), Math.ceil(height - h),
117                             Math.ceil(month_width), Math.round(h));
118            }
119            left += month_width;
120        }
121    }
122}
123
124function clear_canvas(canvas_id) {
125    var c = document.getElementById(canvas_id);
126    if (!c || !c.getContext) return;
127    var ctx = c.getContext("2d");
128    if (!ctx) return;
129    ctx.clearRect(0, 0, c.width, c.height);
130}

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.