javascriptでunixtimeを取得

ga.jsだと、new Date()は9か所で書かれてます。大体、new Date()と.getTime()が続けて書かれています。

+(new Date((new Date).getTime()+f)).toGMTString()+"; ")

a=Math.min(a,1E3*Be+a-(new Date).getTime());

this.set(ab,Math.round((new Date).getTime()/1E3));
this.set(y,Math.round((new Date).getTime()/1E3));
if("event"===a.get(sc)){var b=(new Date).getTime(),c=a.b(dc,0),d=a.b(Zb,0);

1E3 とは、10^3 つまり1000のようです。

ga.jsの真似をして1E3で書いてみます。

var date = Math.floor((new Date()).getTime()/1E3);
document.write(date);

おお、少しプログラミングが上達した錯覚を起こしますね。んな訳ない、桑原桑原。

javascriptでランダムな英数字10桁と数字10桁

console.time('timer1');
var char = "abcdefghijklmnopqrstuvwxyz123456789"
var id = "";
for(var i=0; i<10; i++){
	id += char[Math.floor(Math.random()*35)];
}
document.write(id);
console.timeEnd('timer1');

0.24609375ms
timer1: 0.411865234375ms ※2回目
timer1: 0.324951171875ms ※3回目

min:1000000000 ~ max 9999999999 の10桁の数字の場合

var id = Math.floor(Math.random() * 9000000000)+ 1000000000;
document.write(id);

timer1: 0.329833984375ms
timer1: 0.248779296875ms ※2回目
timer1: 0.24462890625ms ※3回目

感覚的に、1回の演算処理に較べて10回のforループを回す場合、レジストリの演算処理が10倍に増えるので、処理時間も約10倍位になるかと思いきや、計算してみるとforループでも処理時間はほとんど変わらない(2倍以下)ですね。multiplyとplusのCPUの処理はそんなに時間がかからない、ということなんでしょうか。よくわかりませんね。

gaがデータを送信しているように見えるdoubleclick.netとは?

doubleclick.net 
アクセスすると、doubleclickbygoogle にリダイレクトされます。。よくわからないですね。トラッキングのデータがすべて入ってくるので、広告関係をやっているのでしょうか?サイトを見ると、adコンテンツばかりです。
googleの検索アルゴリズムと、double clickが無関係(な訳ないか)なのか、どう連携しているのかも気になるところですが、運営がgoogleになっている。。
https://www.doubleclickbygoogle.com/

再び、ga.jsですが、どうやってデータを送っているのか、よくわかりません。この変だと思うのですが。。。

return"https:"==J.location.protocol||M.G?"https://ssl.google-analytics.com":"http://www.google-analytics.com"},
														Ce=function(a){
															this.name="len";this.message=a+"-8192"},
															De=function(a){
																this.name="ff2post";
																this.message=a+"-2036"},Sa=function(a,b,c,d){b=b||Fa;if(d||2036>=a.length)gf(a,b,c);
																	else if(8192>=a.length){
																		if(0<=W.navigator.userAgent.indexOf("Firefox")&&![].reduce)throw new De(a.length);

cookieの読み込み

document.cookieでcookieを全て取得します。

console.log(GetCookie('key1'));
function GetCookie(name){
	var result = null;

	var cookieName = name + '=';
	var allcookies = document.cookie;

	var position = allcookies.indexOf(cookieName);
	if(position != -1){
		var startIndex = position + cookieName.length;
		var endIndex = allcookies.indexOf(';', startIndex);
		if(endIndex == -1){
			endIndex == allcookies.length;
		}

		result = decodeURIComponent(allcookies.substring(startIndex, endIndex));
	}
	return result;
}

indexOfは全文検索。allcookieの中で、key3=のポジションを取得
indexOf(‘hoge’, n) は、nの位置から、hogeを全文検索
つまり、indexOf(‘;’, 308)は、308以降の次の’;’を検索
allcookie.substring()で、valueを切り抜いています。

console.log(document.cookie);
console.log(document.cookie.indexOf('key3=')); //position
console.log(308); // start index 
console.log(document.cookie.indexOf(';', 308)); // end index 311
console.log(document.cookie.substring(308, 311));

アフィリエイトタグとコンバージョンタグの仕組みについて

例えば、VCで広告を作成すると、以下のようなタグは発行される
sidは個人のidで固定, pidは広告の種類によって異なるので、おそらく広告ごとのid?
リンク先がurlでパラメーターとして送られているので、getで取得してsid, pidを保存、setCookieして、設定されたURLリダイレクトさせて、コンバージョンページに行ったら、jsで処理しているのか??

<script language="javascript" src="//ad.jp.ap.valuecommerce.com/servlet/jsbanner?sid=xxxxxxx&pid=yyyyyyyyy"></script><noscript><a href="//ck.jp.ap.valuecommerce.com/servlet/referral?sid=xxxxxxx&pid=yyyyyyyyy" target="_blank" rel="nofollow"><img src="//ad.jp.ap.valuecommerce.com/servlet/gifbanner??sid=xxxxxxx&pid=yyyyyyyyy" border="0"></a></noscript>

gaタグの挙動を理解する

最初gaタグは以下のような記述になっているかと思います。

<script type="text/javascript">
    var _gaq = _gaq || [];
    _gaq.push(['_setAccount', 'UA-xxxxx-x']);
    _gaq.push(['_trackPageview']);
    (function() {

        var ga = document.createElement('script');
        ga.type = 'text/javascript';
        ga.async = true;
        ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(ga, s);
    })();
</script>

ga.jsのダミーとして同じディレクトリにtest.jsを作ります。
test.js

console.log(obj[0]);

test.php
objの配列にidを入れて、test.phpからtest.jsを呼び込みます。

<script type="text/javascript">
    var obj = obj || [];
    obj.push('id:1');
    (function() {
        var sa = document.createElement('script');
        sa.type = 'text/javascript';
        sa.async = true;
        sa.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://') + '192.168.33.10:8000/test.js';
        var s = document.getElementsByTagName('script')[0];
        s.parentNode.insertBefore(sa, s);
    })();
</script>

配列のid:1がtest.jsに渡されて、console.logが実行されます。

test.jsの中身を以下に書き換えると

console.log(obj[0]);
console.log(location.pathname);

test.phpのlocation.pathnameが表示されます。

つまり、setAccountとtrackPageviewを配列としてga.jsに渡して、対象ページのユーザー情報、挙動やcookieをga.jsでcollectしているということですね。
  _gaq.push([‘_setAccount’, ‘UA-xxxxxx-x’]);
_gaq.push([‘_trackPageview’]);

あれ、もしかして、アフィリエイトのコンバージョンタグも同じ仕組み?? マジ?

Google Analyticsでip情報を取得する方法

Google Analytics -> 管理 -> プロパティ -> カスタム定義 -> カスタムディメンション をクリック
「+新しいカスタムディメンション」を押下

カスタム ディメンションを追加 で名前を追加
JavaScript(ユニバーサルアナリティクスのプロパティのみで有効)から、
ga(‘set’, ‘dimension1’, dimensionValue); をコピー

GA JSにdimension1 とphpのREMOTE_ADDRの情報を送る

<script>
  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');

  ga('create', 'UAxxxxxx-xx', 'auto');
  ga('set', 'dimension1', <?php echo $_SERVER&#91;‘REMOTE_ADDR’&#93;; ?>);
  ga('send', 'pageview');

</script>

あとは、セカンダリディメンション・カスタムディメンションで指定した名前を見れば、ipアドレスを閲覧できますね。

ga.jsでは、タグから送られてきたdimension1とipアドレスを配列に入れて、processingしてgaにレポーティングいるだけですな。
なるほど!ga.jsはまだ途上だが、仕組み自体は少しづつ分かってきた!

javascriptでユーザー情報を取得

<script type="text/javascript">
document.write("HOST : " + location.host + "<br>");
document.write("HOSTNAME : " + location.hostname + "<br>");
document.write("PORT : " + location.port + "<br>");
document.write("REQUEST : " + location.pathname + "<br>");
document.write("CODE : " + navigator.appCodeName + "<br>");
document.write("BROWSER : " + navigator.appName + "<br>");
document.write("VERSION : " + navigator.appVersion + "<br>");
document.write("LANG : " + navigator.language + "<br>");
document.write("PLATFORM : " + navigator.platform + "<br>");
document.write("USERAGENT : " + navigator.userAgent + "<br>");
document.write("REFERER : " + document.referrer + "<br>");
document.write("DOMAIN : " + document.domain + "<br>");
document.write("SCREEN.W : " + screen.width + "<br>");
document.write("SCREEN.H : " + screen.height + "<br>");
document.write("SCREEN.COL : " + screen.colorDepth + "Bit" + "<br>");
</script>

ipアドレスがありませんね。
ga.jsでipに関する記述を見てみると、
line10: Xa=Va(“anonymizeIp”)
くらいしかみつけられません。

Google analyticsのユーザー エクスプローラはipアドレスではなく、ユーザー固有の数字のようです。

予約数と予約時間を2軸でchart.jsで表示する

php側
1.DBから取得した予約データで、時間は+=,予約数は++で連想配列をつくる
2.array_multisortで時間の多い順に連想配列をソート
3.jsに値を渡す

$i = 0; 
while($result = $stmt->fetch(PDO::FETCH_ASSOC)){
	if($year == substr($result['day'], 0, 4) && $month == substr($result['day'], 7, 2)){
		$charge = $result['charge'];
		$book[$charge]['course'] += $result['course'];
		$book[$charge]['count']++;
		$total += $result['course'];
		$i++;
	} 
}

foreach($book as $key => $value){
	$time[$key]["course"] = $value["course"];
}
array_multisort($time, SORT_DESC, $book);

foreach($book as $key => $value){
	$name_list[] = $key;
	$time_list[] = $value["course"];
	$count_list[] = $value["count"];
}

chart.js
オプションで、左右の軸を指定する
tickのmaxは配列の中の最も大きい数 x N とする
Math.max.apply(null, array)*N

ただし、javascriptの IEEE 754の計算だと、誤差が生じることがある
例 Math.max.apply(null, array)*1.1 = 90.00000000000001(!?)
IEEE 754は、2進法計算だかららしい。※wikipediaを読んだが、何故二進法だと誤差が出るのかは私の頭では理解不能


そのため、 Math.floor(Math.max.apply(null, array)*N) として、小数点以下切り捨て

var name_arr = JSON.parse('<?php echo $name_l; ?>');
var time_arr = JSON.parse('<?php echo $time_l; ?>');
var count_arr = JSON.parse('<?php echo $count_l; ?>');
var ctx = document.getElementById("BarChart");
var BarChart = new Chart(ctx, {
	type: 'bar',
	data:{
		labels:name_arr,
		datasets:[{
			label:'予約時間',
			data: time_arr,
			backgroundColor: "rgba(255,136,86,0.8)",
			yAxisID: "y-axis-1",
		},{
			label:'予約数',
			data: count_arr,
			backgroundColor: "rgba(54,264,235,0.4)",
			yAxisID: "y-axis-2",
		}]
		},
		options:{
			responsive: true,
			scales:{
				yAxes:[{
					id: "y-axis-1",
					type: "linear",
					position: "left",
					ticks:{
						max: Math.floor(Math.max.apply(null, time_arr)*1.1),
						min:0,
						stepSize: 30
					}
				},{
					id: "y-axis-2",
					type: "linear",
					position: "right",
					ticks:{
						max: Math.max.apply(null, count_arr)+1,
						min:0,
						stepSize: 1
					}
				}],
				
			}
		}
		
});

結果:今月

翌月

予約日(datepicker)が今日の場合は、現在時刻以降のselectを表示

onSelectのところで、dateTextが今日を選択された場合、idと現在時刻の分を比較して、idが現在時刻より前(値が小さければ)、display noneに変更する。

onSelect: function(dateText, inst) {
                    $("#date_val").val(dateText);
                    if(today == dateText){
                    	for(var i = 0; i < timelist.length; i++){
                    		if(timelist[i] < time){
                    			document.getElementById(timelist[i]).style.display = "none";
                    		}
                    	}
                    	
                    } else{
                    	for(var i = 0; i < timelist.length; i++){
                    			document.getElementById(timelist[i]).style.display = "";
                    	}
                    }              
        }

デフォルト

今日の日付が選択された場合
->現在時刻以降しか選択できない

きた!

if(timelist[i] < time + 60) とすれば、現在時刻から、1時間後以降しか選べなくなりますね♪♪♪