折れ線グラフをつくる

まず、仮データでつくる。

<style>
#line {
 height:200;
 width:750;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.1.4/Chart.min.js"></script>
<div id="line">
<canvas id="myChart" width="750" height="200"></canvas>
</div>
<script>
var ctx = document.getElementById("myChart").getContext('2d');
var myChart = new Chart(ctx, {
   type: 'line',
   data: {
      labels: ["00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12","13","14","15","16","17","18","19","20","21","22","23","24"],
      datasets: [
      {
         label: "Page View",
         borderColor: 'rgb(0, 153, 255)',
         backgroundColor: "#D9E5FF",
         lineTension: 0,
         data: [20, 26, 12, 43, 33, 21, 29, 5, 5, 0, 1,2,2, 3, 4, 5, 5, 5,6, 7, 22, 23, 15, 100, 24],
      },
      ]
   },
   options: {
      responsive: true,
      scales: {
        yAxes: [{
        	ticks: {
            max: 110,
          }
        }]
      }
   }
});
</script>

データラベルが00~24なので、countしたいが、どう組めば一番早い?

新規ユーザーとリターンユーザーを表示する

$visit = json_encode(array_count_values($visit))を配列で渡して、
chart.jsで表示する。

  var visit = JSON.parse('<?php echo $visit; ?>');
  console.log(visit);
  var ctx = document.getElementById("myChart").getContext('2d');
  var myChart = new Chart(ctx, {
  type: 'pie',
  data: {
    labels: ["New", "Returned"],
    datasets: [{
      backgroundColor: [
        "#2ecc71",
        "#3498db",
      ],
      data: [visit['New User'],visit['Returned User']]
    }]
  }
});

ここまではそんなに難しくないんだが、次が問題。
(1)時間ごと、もしくは(2)日付ごとのアクセスを棒グラフで表示する。
まず分けて考えよう。

1.時間ごとの場合
->chart.jsのラベルは24時間
->訪問時間 y:m:d h:m:s の該当するhの数をcountしてjsonにencodeする

2.日付ごとの場合
->ラベルは期間の日付
->訪問時間 y:m:d h:m:s の該当するy:m:dの数をcountしてjsonにencodeする

ややこしいので、時間から作る。

平均滞在時間の計算

array_sumをcountで割った数をh:m:sに変換します。

$avgtime = array_sum($avgtime) / count($avgtime);

$time = s2h($avgtime);
function s2h($avgtime){
  $hours = floor($avgtime / 3600);
  $minutes = floor(($avgtime / 60)%60);
  $seconds = $avgtime % 60;
  $hms = sprintf("%02d:%02d:%02d", $hours, $minutes, $seconds);
  return $hms; 
}

次は、new user とreturn user

analyticsを設計していく

初期画面

<?php

// $date1 = date("Y-m-d H:i:s", strtotime("- 6 day"));
$date1 = date("Y-m-d", strtotime("0 day"));
// $date2 = date("Y-m-d H:i:s", strtotime("- 1 day"));
$date2 = date("Y-m-d H:i:s");


$mng = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$filter =  &#91;
	'date' => [ '$gte' => $date1, '$lte' => $date2]
];
$options = [
  'projection' => ['_id' => 0],
  'sort' => ['_id' => -1],
];
$query = new MongoDB\Driver\Query($filter, $options);
$cursor = $mng->executeQuery('app.na007', $query);

foreach ($cursor as $document) {
  // var_dump($document);
  $pv[] = $document->date;
  $cookie[] = $document->cookie;
  $session[] = $document->session;
  if(!is_null($document->referrer)){
  $referrer[] = $document->referrer;
  }
}
// var_dump($session);
$uu = array_unique($cookie);
$session = array_unique($session);
$bounce = (count($pv) - count($referrer))/ count($pv) * 100;
$exit = (count($pv) - count($session))/ count($pv) * 100;
?>
<style>
.flex-container {
  display: flex;
}
.flex-1{
  flex:1;
}
.flex-2{
  flex:4;
}
</style>
<h1>アナリティクス</h1>
<div class="flex-container">
<div class="flex-1">
  <ul>
    <li><a href="">Audience</a></li>
    <li><a href="">Acuisition</a></li>
    <li><a href="">Behavior</a></li>
  </ul>
</div>
<div class="flex-2">


<?php
echo $date1 ." ~ ".$date2 ."<br>";
echo "<br>Users :".count($uu)."<br>";
echo "Pageviews :".count($pv)."<br>";
echo "Bounce rate :" .sprintf('%.2f',$bounce)."%<br>";
echo "Exit rate:" .sprintf('%.2f',$exit)."%<br>";
?>
</div>
</div>

必要項目
-average session duration
-時間別のユーザー数(折れ線グラフ)
-return userとnew user(円グラフ)

google analyticsのソースを見ると、json.parseして、jsに値を渡しています。

visualizationで、corechartというパッケージをloadしているように見えます。

// TODO(abdussabur): Lazily load gViz instead.
      // NOTE: Due to a conflict with galaxy's copy of gviz, the geochart does not work in GAFE4.
      // See cl/145118637 for more information.
      google.load('visualization', '1', {packages:['corechart', 'table']});
      (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','https://www.google-analytics.com/analytics.js','gaAPI');

      // Tracking codes are being used in tracking-service.js . Please keep them in sync.
      gaAPI('create', 'UA-hoge', 'auto');
      gaAPI('create', 'UA-hoge', 'auto', {'name': 'ta'});
      gaAPI('create', 'UA-hoge', 'auto', {'name': 'tw'});

これのjsはなにしてるんだ?
https://ssl.gstatic.com/analytics/20180419-00/app/js/js.js

monoを使う

昔入れたmono、versionは4.8.0です。

[vagrant@localhost csharp]$ . /opt/mono/env.sh
[vagrant@localhost csharp]$ mono --version
Mono JIT compiler version 4.8.0 (Stable 4.8.0.495/e4a3cf3 Thu Feb 23 18:33:47 UTC 2017)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        LLVM:          yes(3.6.0svn-mono-/)
        GC:            sgen

cs

using System;

class MyApp {

	static void Main(){
		Console.WriteLine("Hello World");
	}
}

compileはmcs

[vagrant@localhost csharp]$ mcs MyApp.cs
[vagrant@localhost csharp]$ ls
MyApp.cs  MyApp.exe
[vagrant@localhost csharp]$ mono MyApp.exe
Hello World
using System;

class MyApp {

	static void Main(){
		string msg = "Hello csharp";
		Console.WriteLine(msg);
	}
}

定数:const string msg = “Hello csharp”;

visual studio

inputとtodoが多すぎて混乱してきた。
1.mongo DBを使ってanalyticsをつくる
2.c# + visual studioでazure cosmosDBに接続する
3.c#でアプリケーションをつくって、azureで公開する

-> c#、visual studioは基本から学ばなければならないので、習得しながら疑似GAの完成までもっていくには恐らく時間がかかりすぎる
-> azure + c# は慣れるまではもっと簡単なテーマ・アプリケーションから作りたい
-> まずは analyticsは VPS + PHP + mongoDB + chart.jsで作り上げる

よし、これで行こう!

cyberduckでazure app serviceにftp接続する

(1)app serviceのデプロイ資格情報でname、passを入力する

(2)概要->発行プロファイルの取得 でpublish settingファイルを取得する

<publishProfile profileName="nanalytics - FTP" publishMethod="FTP" publishUrl="ftp://hoge.ftp.azurewebsites.windows.net/site/wwwroot" ftpPassiveMode="True" userName="hoge" userPWD="hogehoge" destinationAppUrl="http://nanalytics.azurewebsites.net" SQLServerDBConnectionString="" mySQLDBConnectionString="" hostingProviderForumLink="" controlPanelLink="http://windows.azure.com" webSystem="WebSites"><databases /></publishProfile>

(3)ファイル転送ツール等で、サーバーは発行プロファイルのpublishUrl、ユーザー名はuserName、パスワードはuserPWDを入れる。ポートは21でOK

(4)webrootに接続完了! timezoneが-9H(GMT)になってますね。

azureでMongoDB\Driver\Managerの接続が上手くいかない

azureで、php・jsファイルは問題なく動くんだが、MongoDB\Driver\Managerが上手くいなかない。

恐らくapp serviceにphp mongodbのドライバーが入ってないからだと思うのだが(そう思いたい..)

app serviceにライブラリを入れる場合はどうするんでしょうか?
アクティビティログでは、Write DatabaseAccounts 失敗と表示されています。。。

stack overflowで他の方もいってますが、mongodbの接続tutorialはNode.js, .NET、Java、Go、Pythonしかないってところです。

あああ、なるほど、C# & visual studioだったら、簡単にドライバーを入れらるのですね。
ここでC#か~~~~
まぁ、C#でやってみるか~。。。。。。どう頑張ってもNGそうだったら、VPSで構築します。

mondoDBを使いたいのでcosmosDBを作成する

azure cloud shell

az cosmosdb create --name nacosmosdb --resource-group myResourceGroup --kind MongoDB

さーどうしましょう

{
  "additionalProperties": {},
  "capabilities": [],
  "consistencyPolicy": {
    "additionalProperties": {},
    "defaultConsistencyLevel": "Session",
    "maxIntervalInSeconds": 5,
    "maxStalenessPrefix": 100
  },
  "databaseAccountOfferType": "Standard",
  "documentEndpoint": "https://nacosmosdb.documents.azure.com:443/",
  "enableAutomaticFailover": false,
  "failoverPolicies": [
    {
      "additionalProperties": {},
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe"
    }
  ],
  "id": "/subscriptions/hoge/resourceGroups/myResourceGroup/providers/Microsoft.DocumentDB/databaseAccounts/nacosmosdb",
  "ipRangeFilter": "",
  "kind": "MongoDB",
  "location": "West Europe",
  "name": "nacosmosdb",
  "provisioningState": "Succeeded",
  "readLocations": [
    {
      "additionalProperties": {},
      "documentEndpoint": "https://nacosmosdb-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ],
  "resourceGroup": "myResourceGroup",
  "tags": {},
  "type": "Microsoft.DocumentDB/databaseAccounts",
  "writeLocations": [
    {
      "additionalProperties": {},
      "documentEndpoint": "https://nacosmosdb-westeurope.documents.azure.com:443/",
      "failoverPriority": 0,
      "id": "nacosmosdb-westeurope",
      "locationName": "West Europe",
      "provisioningState": "Succeeded"
    }
  ]
}

primary master keyを発行する

az cosmosdb list-keys --name nacosmosdb --resource-group myResourceGroup --query "primaryMasterKey"

接続

'use strict';

module.exports = {
  db: {
    uri: 'mongodb://:@.documents.azure.com:10255/mean-dev?ssl=true&sslverifycertificate=false'
  }
};

ん?

node.jsが入っているのに、npmコマンドが使えない時

# node server.js
module.js:340
Cannot find module ‘lodash’

npm install lodash –save で、npmインストールしようとしたが、できない。

$ sudo yum groupinstall 'Development tools'
$ wget http://nodejs.org/dist/v0.12.0/node-v0.12.0.tar.gz
$ tar xvf node-v0.12.0.tar.gz
$ cd node-v0.12.0/
$ ./configure --prefix=/usr/local
$ make
$ sudo make install

ほぅ

AppServiceからAzure DatabaseにPDOでssl接続する

vagrant環境をmasterにpushするだけです。

$ git commit -am “azure mysql ssl pdo”
$ git push azure master

PDOもOK

次は、ドメインのマウント。
これが出来れば、一通りアプリケーションの公開まではOKになる(はず?)

あ、無料版のサブスクリプションでは購入できませんが、
ドメイン購入のマニュアル読むと、そんなに難しそうではなさそうですね。
https://docs.microsoft.com/ja-jp/azure/app-service/custom-dns-web-site-buydomains-web-app

ということで、一通りOKですね。
では、いよいよazureでmongoDBです。Let’s Go!