end0tknr's kipple - 新web写経開発

http://d.hatena.ne.jp/end0tknr/ から移転しました

install mongodb ver.4.2.0 from src

gcc ver.8.3.0の準備もできたので、 mongodb に付属の docs/building.md と https://shoken.hatenablog.com/entry/2015/07/13/162548 を参考に実施。

download & build & install

https://www.mongodb.com/download-center/community

$ wget https://fastdl.mongodb.org/src/mongodb-src-r4.2.0.tar.gz
$ tar -xvf mongodb-src-r4.2.0.tar.gz
$ cd mongodb-src-r4.2.0
$ less docs/building.md

$ sudo /usr/local/python3/bin/pip3 install -r etc/pip/compile-requirements.txt

# ↓私の環境では3時間程、かかりました
$ /usr/local/python3/bin/python3 buildscripts/scons.py core

$ sudo /usr/local/python3/bin/python3 buildscripts/scons.py \
  --prefix=/usr/local/mongodb install

設定

$ wget https://raw.githubusercontent.com/mongodb/mongo/master/rpm/mongod.conf
$ vi mongod.conf
  old)  dbPath: /var/lib/mongo
  new)  dbPath: /home/mongod/data

$ sudo mv mongod.conf /etc/mongod.conf

$ sudo mkdir /var/log/mongodb
$ sudo mkdir /var/run/mongodb
$ sudo mkdir /home/mongo/data

で、試しに rootで起動 & 接続.

(色々とwarningが表示されますが、最後に「>」が表示され起動されたことが確認できます)

(この起動により root権限で /home/mongod/data 以下に様々なfileが作成されますので mongod 停止後、sudo rm -rf /home/mongod/data/* します)

起動
$ sudo /usr/local/mongodb/bin/mongod -f /etc/mongod.conf

接続確認
$ /usr/local/mongodb/bin/mongo
MongoDB shell version v4.2.0
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("3a4e52bf-3401-4324-be73-22efc394d473") }
MongoDB server version: 4.2.0
Welcome to the MongoDB shell.
For interactive help, type "help".
For more comprehensive documentation, see
    http://docs.mongodb.org/
Questions? Try the support group
    http://groups.google.com/group/mongodb-user
  :
2019-08-14T03:12:55.595+0900 I  CONTROL  [initandlisten] **        We suggest setting it to 'never'
2019-08-14T03:12:55.595+0900 I  CONTROL  [initandlisten] 
---
Enable MongoDB's free cloud-based monitoring service, which will then receive and display
metrics about your deployment (disk utilization, CPU, operation statistics, etc).

The monitoring data will be available on a MongoDB website with a unique URL accessible to you
and anyone you share the URL with. MongoDB may use this information to make product
improvements and to suggest MongoDB products and deployment options to you.

To enable free monitoring, run the following command: db.enableFreeMonitoring()
To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

> 

停止
$ sudo kill `cat /var/run/mongodb/mongod.pid`
$ sudo rm /var/lib/mongo/mongod.lock

掃除
$ sudo rm -rf /home/mongod/data/*

自動起動設定

$ sudo /usr/sbin/groupadd -r mongod
$ sudo /usr/sbin/useradd -r -g mongod mongod

$ sudo chown -R mongod:mongod /usr/local/mongodb
$ sudo chown -R mongod:mongod /var/log/mongodb
$ sudo chown -R mongod:mongod /var/run/mongodb

$ wget https://raw.githubusercontent.com/mongodb/mongo/master/rpm/mongod.service
$ vi mongod.service
 old) ExecStart=/usr/bin/mongod $OPTIONS
 new) ExecStart=/usr/local/mongodb/bin/mongod $OPTIONS

$ sudo mv mongod.service /usr/lib/systemd/system/
$ cd /usr/lib/systemd/system/
$ sudo systemctl enable mongod
$ sudo systemctl start mongod.service
$ sudo systemctl status mongod.service

install gcc ver.8.3.0 from source to centos 7

mongo db を srcから installしようとしましたが、centos 7付属のgccが古かった為、 gcc ver.8.3.0 をsrcから install

$ wget http://ftp.tsukuba.wide.ad.jp/software/gcc/releases/gcc-8.3.0/gcc-8.3.0.tar.gz
$ tar -xvf gcc-8.3.0.tar.gz
$ cd gcc-8.3.0cd
# 以下にて必要なライブラリ?がダウンロードされます
$ ./contrib/download_prerequisites 

$ mkdir build
$ cd build
$ ../configure \
    --prefix=/usr/local/gcc8 \
    --disable-bootstrap \
    --disable-multilib \
    --enable-languages=c,c++
$ make
$ sudo make install

g++: internal compiler error: Killed (program cc1plus) のエラー

上記の configureでは、いくつかoptionを指定していますが、 このoptionなしで、makeを実行したところ、以下のようなエラーとなりました。

g++: internal compiler error: Killed (program cc1plus)

インターネットで検索しましたが、メモリ不足が原因のようでしたので 上記のoption指定や、不要なdaemonを停止、更には make -jでなく単なる「make」によりgccのbuildができました

既存のgccをmvでバックアップ後、ln -s で配備

今回の gcc ver.8.30は /usr/local/gcc8 へ installし /usr/bin/gcc や /usr/bin/g++ 、/lib64/libstdc++.so.6 はmvでバックアップし ln -s で置き換え?しています。

$ sudo mv /usr/bin/gcc /usr/bin/gcc.20190810
$ sudo mv /usr/bin/g++ /usr/bin/g++.20190810
$ sudo ln -s /usr/local/gcc8/bin/gcc /usr/bin/gcc
$ sudo ln -s /usr/local/gcc8/bin/g++ /usr/bin/g++

$ sudo mv /lib64/libstdc++.so.6 /lib64/libstdc++.so.6.20190810
$ sudo ln -s /usr/local/gcc8/lib64/libstdc++.so.6.0.25 libstdc++.so.6

ちなみに libstdc++.so.6 の ln -s を行う前は、mongod 起動時に 次のエラーが表示されていました。

$ sudo /usr/local/mongodb/bin/mongod -f /etc/mongod.conf
/usr/local/mongodb/bin/mongod: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by /usr/local/mongodb/bin/mongod)
/usr/local/mongodb/bin/mongod: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.22' not found (required by /usr/local/mongodb/bin/mongod)
/usr/local/mongodb/bin/mongod: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.20' not found (required by /usr/local/mongodb/bin/mongod)
/usr/local/mongodb/bin/mongod: /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/local/mongodb/bin/mongod)

また、 ln -s libstdc++.so.6 後、GLIBCXX_3.4.20 等が含まれることの確認は 次のように strings + grep で行っています。

$ strings /usr/lib64/libstdc++.so.6 | grep GLIBCXX

Vue.js の練習

https://jp.vuejs.org/

先程のエントリでは Reactでしたが、Vue.jsも触れたことがない為、dotinstall.com にて写経。

ReactはJSXで実装しますが、Vue.jsはjavascriptで実装できる為、 こちらの方が入門しやすい印象です。

以下は、写経した 2つのサンプルで、詳細はsrcを読めば分かります。

写経 その1 - TODO管理

html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Vue.jsの練習</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>

  <div id="app" class="container">
    <h1>
      <button @click="purge">完了TODOを一括削除</button>
      TODO一覧
      <span class="info">({{ remaining.length }}/{{ todos.length }})</span>
    </h1>
    <ul>
      <li v-for="(todo, index) in todos">
        <input type="checkbox" v-model="todo.isDone">
        <span :class="{done: todo.isDone}">{{ todo.title }}</span>
        <span @click="deleteItem(index)" class="command">[x]</span>
      </li>
      <li v-show="!todos.length">残っているTODOはありません!</li>
    </ul>
    <form @submit.prevent="addItem">
      <input type="text" v-model="newItem">
      <input type="submit" value="追加">
    </form>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="js/main.js"></script>
</body>
</html>

javascript

(function() {
    'use strict';
    
    var vm = new Vue({
    el: '#app', // vueを実体化するelementの指定
    data: {
        newItem: '',
        todos: []
    },
    computed: {
        remaining: function() {
        return this.todos.filter(function(todo) {
            return !todo.isDone;
        });
        }
    },
    watch: {
        todos: { // todoに変更があった場合、localStorageに保存
        handler: function() {
            localStorage.setItem('todos', JSON.stringify(this.todos));
        },
        deep: true // hash内部をdeepにwatch
        }
    },
    // 起動直後に localStorage から load
    mounted: function() {
        this.todos = JSON.parse(localStorage.getItem('todos')) || [];
    },
    methods: {
        addItem: function() {
        var item = {
            title: this.newItem,
            isDone: false
        };
        this.todos.push(item);
        this.newItem = '';
        },
        deleteItem: function(index) {
        if (confirm('削除してよろしいですか?')) {
            this.todos.splice(index, 1);
        }
        },
        purge: function() {
        if (!confirm('削除してよろしいですか?')) {
            return;
        }
        this.todos = this.remaining;
        }
    }
    });
})();

css

body {}

.container {
  width: 400px;
  margin: auto;
}

#app h1 {
  font-size: 20px;
  border-bottom: 1px solid #888;
}

#app li {}

#app input[type="text"] {}

.command {
  font-size: 12px;
  cursor: pointer;
  color: #08c;
}

#app ul {
  padding: 0;
  list-style: none;
}

#app li > span.done {
  text-decoration: line-through;
}

.info {
  color: #888;
  font-weight: normal;
}

#app h1 > button {
  float: right;
}

写経 その2 - ボタンクリック カウンタ

html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Vue.jsの練習 2</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>

  <div id="app">
    <p>総合計: {{ total }}</p>
    <like-component message="Like"    @increment="incrementTotal"></like-component>
    <like-component message="Awesome" @increment="incrementTotal"></like-component>
    <like-component message="Great"   @increment="incrementTotal"></like-component>
    <like-component @increment="incrementTotal"></like-component>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue"></script>
  <script src="js/main.js"></script>
</body>
</html>

javascript

(function() {
    'use strict';

    var likeComponent = Vue.extend({
    props: {
        message: {
        type: String,
        default: 'Like'
        }
    },
    data: function() {
        return {
        count: 0
        }
    },
    template: '<button @click="countUp">{{ message }} {{ count }}</button>',
    methods: {
        countUp: function() {
        this.count++;
        this.$emit('increment'); // eventの発行
        }
    }
    });
    
    var app = new Vue({
    el: '#app',
    components: {
        'like-component': likeComponent
    },
    data: {
        total: 0
    },
    methods: {
        incrementTotal: function() {
        this.total++;
        }
    }
    });
})();

css

body {}

React js の練習 (javascript?)

https://reactjs.org/

とりあえず react に触れてみたかった。

ググってみると、nodejs のinstallから紹介しているサイトを多く見かけますが、 ブラウザ + エディタだけで気軽に試すことができる dotinstall.com にて写経。

以下は、その成果物のTODO管理。読めば、分かると思います

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>reactjs.org の練習 at dotinstall.com </title>
  <link rel="stylesheet" href="css/styles.css">
  <script src="https://unpkg.com/react@16/umd/react.development.js"></script>
  <script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
  <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
</head>
<body>

  <!--  #root 以下を Reactが制御/描画します -->
  <div id="root"></div>
  
  <script type="text/babel">
   (() => {
     function TodoHeader(props) {
       // filter()で未完了のTODOを抽出
       const remaining = props.todos.filter(todo => {
         return !todo.isDone;
       });
       
       return (
         <h1>
         My Todos
         <span>({remaining.length}/{props.todos.length})</span>
    
         <button onClick={props.purge}>完了TODOの一括消去</button>
    </h1>
       );
     }
     
     function TodoList(props) {
       // map() で、TODOを <TodoItem / > Component に変換
       const todos = props.todos.map(todo => {
         return (
           <TodoItem
           key={todo.id}
           todo={todo}
           checkTodo={props.checkTodo}
           deleteTodo={props.deleteTodo}
           />
         );
       });
       return (
         <ul>
         {props.todos.length ? todos : <li>対応すべきTODOはありません!</li>}
         </ul>
       );
     }


     function TodoItem(props) {
       return (
         <li key={props.todo.id}>
         <label>
         <input type="checkbox"
         checked={props.todo.isDone}
         onChange={() => props.checkTodo(props.todo)}
         />
         <span className={props.todo.isDone ? 'done' : ''}>
         {props.todo.title}
         </span>
         </label>
         <span className="cmd" onClick={() => props.deleteTodo(props.todo)}>[×]</span>
         </li>
       );
     }
     

     function TodoForm(props) {
       return (
         <form onSubmit={props.addTodo}>
         <input type="text" value={props.item} onChange={props.updateItem}/>
         <input type="submit" value="追加"/>
         </form>
       );
     }

     function getUniqueId() {
       return new Date().getTime().toString(36) + '-' + Math.random().toString(36);
     }
     
     class App extends React.Component {
       constructor() {
         super();
    // Reactの作法的に、stateは1箇所のcomponentで管理するらしい
         this.state = {
           todos: [],
           item: ''   // 新たに追加するTODOの内容
         };
    
         this.checkTodo =  this.checkTodo.bind(this);
         this.deleteTodo = this.deleteTodo.bind(this);
         this.updateItem = this.updateItem.bind(this);
         this.addTodo =    this.addTodo.bind(this);
         this.purge =      this.purge.bind(this);
       }
       
       purge() {
         if ( ! confirm('完了TODOを一括消去してよろしいですか ?')) {
           return;
         }
    // filter() で未完了TODOを集め、 setState() にて更新
         const todos = this.state.todos.filter(todo => {
           return ! todo.isDone;
         });
         this.setState({
           todos: todos
         });
       }
       
       addTodo(e) {
    // onSubmit()で呼ばれる為、画面遷移されることを防ぎます
         e.preventDefault();
    
         if (this.state.item.trim() === '') {
           return;
         }
    
         const item = {
           id: getUniqueId(),
           title: this.state.item,
           isDone: false
         };

    // slice()にて、元の配列をshallow copy
         const todos = this.state.todos.slice();
         todos.push(item);
         this.setState({
           todos: todos,
           item: ''
         });
       }

       deleteTodo(todo) {
         if (!confirm('削除してよろしいですか ?')) {
           return;
         }
    
    // slice()にて、元の配列をshallow copyし
    // indexOf()にて削除対象の位置を探索
         const todos = this.state.todos.slice();
         const pos = this.state.todos.indexOf(todo);

    // splice()にて、該当のTODOを削除
          todos.splice(pos, 1);
          this.setState({
           todos: todos
         });
       }

       checkTodo(todo) {
         const todos = this.state.todos.map(todo => {
           return {id: todo.id, title: todo.title, isDone: todo.isDone};
         });
    
         const pos = this.state.todos.map(todo => {
           return todo.id;
         }).indexOf(todo.id);

         todos[pos].isDone = !todos[pos].isDone;
         this.setState({
           todos: todos
         });
       }
       
       // TodoForm componentの onChange()から呼ばれます
       updateItem(e) {
         this.setState({
           item: e.target.value
         });
       }

       // componentDidUpdate()は、Component の props や state が
       // 更新された際に呼ばれます.
       // ここでは、TODOの内容をjsonにして、localStorage へ保存しています
       componentDidUpdate() {
         localStorage.setItem('todos', JSON.stringify(this.state.todos));
       }
       // componentDidMount()により、上記で json保存した内容を画面にloadしています
       componentDidMount() {
         this.setState({
           todos: JSON.parse(localStorage.getItem('todos')) || []
         });
       }
       
        render() {
          return (
            <div className="container">
              <TodoHeader
                todos={this.state.todos}
                purge={this.purge}
              />
              <TodoList
                todos={this.state.todos}
                checkTodo={this.checkTodo}
                deleteTodo={this.deleteTodo}
              />
              <TodoForm
                item={this.state.item}
                updateItem={this.updateItem}
                addTodo={this.addTodo}
              />
            </div>
          );
        }
      }

      ReactDOM.render(
        <App/>,
        document.getElementById('root')
      );
    })();
  </script>
</body>
</html>
body {
}

.container {
  width: 400px;
  margin: auto;
}

.container h1 {
  border-bottom: 1px solid #ddd;
  padding: 16px 0;
}

.container ul {
  padding: 0;
  list-style: none;
}

.container li {
  line-height: 2;
}

.container input[type="checkbox"] {
  margin-right: 5px;
}

.cmd {
  cursor: pointer;
  color: #08c;
  margin-left: 5px;
}

.container input[type="text"] {
  padding: 2px;
  margin-right: 5px;
}

h1 > span {
  color: #ccc;
  font-weight: normal;
  margin-left: 5px;
}


h1 > button {
  float: right;
}

.done {
  text-decoration: line-through;
  color: #ccc;
}

EVM 基礎の基礎 - PV(計画)、EV(出来高)、EV(コスト実績)

EVMのグラフを理解するだけであれば、PV(計画)、EV(出来高)、EV(コスト実績)の3個だけを理解すれば、OK.

ただし、実際のプロジェクトにおいて EVM管理を行うのであれば、 EVMグラフを作成する元となる WBSでの進捗管理や、工数管理 が必須。

ちなみに、以下の場合、「EV(出来高)は計画と比較し、遅延」更に「EV(コスト実績)は計画と比較し、超過」。

なので、

遅れを取り戻そうと、残業や休日出勤でリカバリーしようとしているが、 遅延や超過コストが、膨らんでいる最悪の状態。

と言えます。

f:id:end0tknr:20190812125027p:plain

mysqlにおける スロークエリーログ ( slow_query_log ) , 一般ログ ( general_log ) 出力設定

すっかり忘れていたので、メモ

一般ログ ( general_log )

mysqlに対する操作が全てログへ出力されます。

手順としては「show variables ~」で現在の設定内容を確認し、「set global ~」で設定するのみ

mysql> show variables like 'general%';
+------------------+----------------------------+
| Variable_name    | Value                      |
+------------------+----------------------------+
| general_log      | OFF                        |
| general_log_file | /var/mysql_data/cent76.log |
+------------------+----------------------------+

mysql> set global general_log=ON;
mysql> set global general_log_file = '/tmp/mysql-general.log';

後はファイルの内容を確認するだけ

# tail -f /tmp/mysql-general.log

スロークエリーログ ( slow_query_log )

先程の 一般ログ ( general_log )と、ほぼ同じ内容です。

mysql> show variables like 'slow%';
+---------------------+---------------------------------+
| Variable_name       | Value                           |
+---------------------+---------------------------------+
| slow_launch_time    | 2                               |
| slow_query_log      | OFF                             |
| slow_query_log_file | /var/mysql_data/cent76-slow.log |
+---------------------+---------------------------------+

mysql> set global slow_query_log=ON;
mysql> set global slow_query_log_file = '/tmp/mysql-slow.log';
# tail -f /tmp/mysql-slow.log

Win10環境のIISにおける 複数verのphp (php 5 , php7) の共存

php5 と php7 の install 先

と言っても、win版phpの場合、zipを解答するだけ、私の場合は以下に配備.

c:/PHP/php-5.6.9-nts-Win32-VC11-x64
c:/PHP/php-7.3.8-Win32-VC15-x64

また、download元は以下 https://windows.php.net/downloads/releases/archives/

テスト用 test.php の配備

<?php
phpinfo();
?>

よくある上記の内容にて test.php を作成し、これを以下のように配置。

c:/inetpub/wwwroot/php_test/
   test.php          ---1)
   php5/test.php     ---2)
   php5/php/test.php ---3)
   php7/test.php     ---4)

上記の2)は、php5で動作させ、それ以外はデフォルトとして、php7で動作させたい。

IISマネージャーでの設定

「ハンドラーマッピング」で以下のように設定します f:id:end0tknr:20190806075806p:plain f:id:end0tknr:20190806075809p:plain f:id:end0tknr:20190806075812p:plain f:id:end0tknr:20190806075821p:plain

で、完了

f:id:end0tknr:20190806075817p:plain

javascript製 多機能グラフライブラリ( echarts )の練習 - 3D 散布図

echarts.apache.org

先程のエントリの3次元版

f:id:end0tknr:20190708230441p:plain

↓こう書くと、↑こう表示 & いろいろ操作できます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ECharts sample</title>
  <!-- <script src="http://echarts.baidu.com/dist/echarts.min.js"></script> -->
  <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts/echarts.min.js"></script>
  <script type="text/javascript" src="http://echarts.baidu.com/gallery/vendors/echarts-gl/echarts-gl.min.js"></script>
</head>
<body>
  
  <div id="main_graph" style="width: 100%;height:700px;"></div>
  
  <script type="text/javascript">
   var myChart = echarts.init(document.getElementById('main_graph'));

   var data_a =[[1,26,37,27,1.163,27,13, "優"],
       [2,85,62,71,1.195,60,8,      "良"],
       [3,78,38,74,1.363,37,7,      "良"],
       [4,21,21,36,0.634,40,9,      "優"],
       [5,41,42,46,0.915,81,13, "優"],
       [6,56,52,69,1.067,92,16, "良"],
       [7,64,30,28,0.924,51,2,      "良"],
       [8,55,48,74,1.236,75,26, "良"],
       [9,76,85,113,1.237,114,27,   "良"],
       [10,91,81,104,1.041,56,40,   "良"]];
   var data_b =[[1,91,45,125,0.82,34,23, "良"],
       [2,65,27,78,0.86,45,29,      "良"],
       [3,83,60,84,1.09,73,27,      "良"],
       [4,109,81,121,1.28,68,51,    "不可"],
       [5,106,77,114,1.07,55,51,    "不可"],
       [6,109,81,121,1.28,68,51,    "不可"],
       [7,106,77,114,1.07,55,51,    "不可"],
       [8,89,65,78,0.86,51,26,      "良"],
       [9,53,33,47,0.64,50,17,      "良"],
       [10,80,55,80,1.01,75,24, "良"]];
   // 上記dataの定義
   var schema =[{index: 0, name: 'date',     text: '日'},
       {index: 1, name: 'AQIindex', text: 'AQI指数'}, //空気質指数
       {index: 2, name: 'PM25',     text: 'PM2.5'},
       {index: 3, name: 'PM10',     text: 'PM10'},
       {index: 4, name: 'CO',       text: '一酸化炭素(CO)' },
       {index: 5, name: 'NO2',      text: '二酸化窒素(NO2)'},
       {index: 6, name: 'SO2',      text: '二酸化硫黄(SO2)'}];
   // data表示のstyle (ドットの影)
   var itemStyle = {
     // normal: {
     //   opacity: 0.8,    shadowBlur: 10,
     //   shadowOffsetX: 0,shadowOffsetY: 0,
     //   shadowColor: 'rgba(0, 0, 0, 0.5)'
     // }
   };

   option = {
     title: {text: 'EChartsの練習 3D版',
        link: 'http://www.google.co.jp',
        target: 'blank', // blank or self
        x:'center',
        y:'5px',
        textStyle: { color: '#fff', fontSize: 16 }},
     backgroundColor: '#404a59',
     color:  ['#dd4444', '#fec42c'], 
     legend: {  // 凡例
             data:['本州', '九州'],
             textStyle: {color: '#fff', fontSize: 16},
               orient : 'horizontal',  // horizontal or vertical
               x:'center', y:'30px', // 表示位置
               },
     toolbox: {
       iconStyle : {borderColor: '#fff' },
       feature: {dataView : {title: 'データの表示', 
                lang: ['データの表示','閉じる','更新'],
                readOnly: false},
        restore :     {title: '更新'},
        saveAsImage : {title: '画像保存'}},
       x: 300 // 表示位置
     }, 
     tooltip: {  // カーソルを重ねた際の情報
       padding: 10,
       backgroundColor: '#222',
       borderColor: '#777',
       borderWidth: 1,
       formatter: function (obj) {
         var value = obj.value;
         return '<div style="border-bottom: 1px solid rgba(255,255,255,.3);">'
         + obj.seriesName + ' ' + value[0] + '日:'+ value[7] + '</div>'
         + schema[1].text + ':' + value[1] + '<br>'
         + schema[2].text + ':' + value[2] + '<br>'; }
     },
     xAxis3D: { // 軸の目盛設定
       type : 'value', // value or category
       name: '日',
       nameGap: 16,
       nameTextStyle: {},
       max: 31,
       splitLine: { show: true },
       axisLine:  { lineStyle: {color: '#eee'}}
     },
     yAxis3D: {
       type: 'value',
       name: 'AQI指数',
       nameLocation: 'end',
       nameGap: 20,
       nameTextStyle: {},
       splitLine: {show: true},
       axisLine: { lineStyle: {color: '#eee'}},
     },
     zAxis3D: {
       type: 'value',
       name: 'PM2.5',
       nameLocation: 'end',
       nameGap: 20,
       nameTextStyle: {},
       splitLine: {show: true},
       axisLine: { lineStyle: {color: '#eee'}},
     },
     grid3D: {
       axisLine: {
         lineStyle: {
           color: '#fff'
         }
       },
       axisPointer: {
         lineStyle: {
           color: '#ffbd67'
         }
       },
       viewControl: {
         // autoRotate: true
         // projection: 'orthographic'
       }
     },
     series: [{name: '本州',
          type: 'scatter3D',
               itemStyle: itemStyle,
               data: data_a },
              {name: '九州',
               type: 'scatter3D',
               itemStyle: itemStyle,
               data: data_b } ],
     visualMap: [
       {dimension: 2,  // 表示するdataの種類
   left: 'right', top: '10%',
        min: 0,        max: 250,
        itemWidth: 30, itemHeight: 120,
        calculable: false,
   // calculable: true,
        precision: 0.1,
        text: ['PM2.5'],
        textStyle: { color: '#fff'},
        inRange: {symbolSize: [10, 70] },
        controller: {
           inRange: { color: ['#c23531']}
         }
        },
     ],
   };
   
   myChart.setOption(option);
  </script>

</body>
</html>

javascript製 多機能グラフライブラリ( echarts )の練習 - 散布図

https://echarts.apache.org/en/index.html

f:id:end0tknr:20190708141007p:plain

↓こう書くと、↑こう表示 & いろいろ操作できます。

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ECharts sample</title>
  <script src="http://echarts.baidu.com/gallery/vendors/echarts/echarts.min.js"></script>
  <script src="http://echarts.baidu.com/gallery/vendors/echarts-gl/echarts-gl.min.js"></script>
</head>
<body>
  
  <div id="main_graph" style="width: 100%;height:700px;"></div>
  
  <script type="text/javascript">
   var myChart = echarts.init(document.getElementById('main_graph'));

   var dataBJ = [ // 北海道用data
     [1,55,9,56,0.46,18,6,  "良"],
     [2,25,11,21,0.65,34,9, "優"],
     [3,56,7,63,0.3,14,5,   "良"],
     [4,33,7,29,0.33,16,6,  "優"],
     [5,42,24,44,0.76,40,16,    "優"],
     [6,82,58,90,1.77,68,33,    "良"],
     [7,74,49,77,1.46,48,27,    "良"],
     [8,78,55,80,1.29,59,29,    "良"],
     [9,267,216,280,4.8,108,64, "不可"],
     [10,185,127,216,2.52,61,27,"可"],
   ];
   var dataGZ = [ // 本州用data
     [1,26,37,27,1.163,27,13,   "優"],
     [2,85,62,71,1.195,60,8,    "良"],
     [3,78,38,74,1.363,37,7,    "良"],
     [4,21,21,36,0.634,40,9,    "優"],
     [5,41,42,46,0.915,81,13,   "優"],
     [6,56,52,69,1.067,92,16,   "良"],
     [7,64,30,28,0.924,51,2,    "良"],
     [8,55,48,74,1.236,75,26,   "良"],
     [9,76,85,113,1.237,114,27, "良"],
     [10,91,81,104,1.041,56,40, "良"],
   ];
   var dataSH = [ // 九州用data
     [1,91,45,125,0.82,34,23,   "良"],
     [2,65,27,78,0.86,45,29,    "良"],
     [3,83,60,84,1.09,73,27,    "良"],
     [4,109,81,121,1.28,68,51,  "不可"],
     [5,106,77,114,1.07,55,51,  "不可"],
     [6,109,81,121,1.28,68,51,  "不可"],
     [7,106,77,114,1.07,55,51,  "不可"],
     [8,89,65,78,0.86,51,26,    "良"],
     [9,53,33,47,0.64,50,17,    "良"],
     [10,80,55,80,1.01,75,24,   "良"],
   ];
   // 上記dataのcolumn定義
   var schema = [
     {index: 0, name: 'date',     text: '日'},
     {index: 1, name: 'AQIindex', text: 'AQI指数'}, //空気質指数
     {index: 2, name: 'PM25',     text: 'PM2.5'},
     {index: 3, name: 'PM10',     text: 'PM10'},
     {index: 4, name: 'CO',       text: '一酸化炭素(CO)' },
     {index: 5, name: 'NO2',      text: '二酸化窒素(NO2)'},
     {index: 6, name: 'SO2',      text: '二酸化硫黄(SO2)'}
   ];
   // data表示のstyle (ドットの影)
   var itemStyle = {
     // normal: {
     //   opacity: 0.8,    shadowBlur: 10,
     //   shadowOffsetX: 0,shadowOffsetY: 0,
     //   shadowColor: 'rgba(0, 0, 0, 0.5)'
     // }
   };
   
   option = {
     title: {
       text: 'EChartsの練習',
       link: 'http://www.google.co.jp',
       target: 'blank', // blank or self
       x:'center',
       y:'5px',
       textStyle: { color: '#fff', fontSize: 16 }
     },
     backgroundColor: '#404a59',
     // data表示の色 (今回、3種の為、3色)     
     color:  ['#dd4444', '#fec42c', '#80F1BE'], 
     legend: {data: ['北海道', '本州', '九州'], // 凡例
         y: '25px',
//       y: 'top',
              textStyle: { color: '#fff', fontSize: 16 }},
     grid: { // graph本体のpadding ?
        // x: '10%', x2: 150, y: '18%', y2: '10%'
       },
     tooltip: {
       padding: 10,
       backgroundColor: '#222',
       borderColor: '#777',
       borderWidth: 1,
       formatter: function (obj) {
         var value = obj.value;
         return '<div style="border-bottom: 1px solid rgba(255,255,255,.3);">'
         + obj.seriesName + ' ' + value[0] + '日:'+ value[7] + '</div>'
         + schema[1].text + ':' + value[1] + '<br>'
         + schema[2].text + ':' + value[2] + '<br>'
         + schema[3].text + ':' + value[3] + '<br>'
         + schema[4].text + ':' + value[4] + '<br>'
         + schema[5].text + ':' + value[5] + '<br>'
         + schema[6].text + ':' + value[6].toLocaleString() + '<br>'; }
     },
     xAxis: {
       type: 'value', // = value or category
       name: '日',
       nameLocation: 'middle',
       nameGap: 16,
       nameTextStyle: {},
       max: 31,
       splitLine: { show: true },
       axisLine:  { lineStyle: {color: '#eee'}}
     },
     yAxis: {
       type: 'value',
       name: 'AQI指数',
       nameLocation: 'middle',
       nameGap: 20,
       nameTextStyle: {},
       splitLine: {show: true},
       axisLine: { lineStyle: {color: '#eee'}},
     },
     visualMap: [
       {dimension: 2,                   //表示dataのcolumn no
   left: 'right', top: '10%',
        min: 0,        max: 250,        //表示dataの値の範囲
        itemWidth: 30, itemHeight: 120, //ゲージのサイズ 
        calculable: false,
   // calculable: true,
        precision: 0.1,
        text: ['PM2.5'],
        textStyle: { color: '#fff'},
        inRange: {symbolSize: [10, 70] },
        controller: {
           inRange: { color: ['#c23531']}
         }
        },
     ],
    series: [{name: '北海道',
              type: 'scatter',
              itemStyle: itemStyle,
              data: dataBJ },
             {name: '本州',
              type: 'scatter',
              itemStyle: itemStyle,
              data: dataSH },
             {name: '九州',
              type: 'scatter',
              itemStyle: itemStyle,
              data: dataGZ } ],
     toolbox: {
       iconStyle : {borderColor: '#fff' },
       // mouse over (hover)時の色指定方法不明
       feature : {
         dataView : {title: 'データの表示', 
            lang: ['データの表示','閉じる','更新'],
            readOnly: false},
         restore :     {title: '更新'},
         saveAsImage : {title: '画像保存'}
       },
       x : 'right'  // 表示位置
     },
   };
   if (option && typeof option === "object") {
     myChart.setOption(option, true);
   }
  </script>

</body>
</html>

お名前.com による「Whois情報公開代行サービス」

DNSをお名前.com、SSL証明書GMO Global Sign で登録していますが、 SSL証明書の更新時における「メール認証」に手間取った為、メモ。

https://www.onamae.com/service/d-regist/option.html

通常、DNSを登録する場合、氏名、メールアドレス、 住所等がwhoisサービスで公開されますが、 お名前.comの「Whois情報公開代行サービス」を利用すると、 氏名、メールアドレス等の個人情報を、お名前.comのもので置き換えられ、 個人情報を隠すことができます。

更に「Whois情報公開代行サービス(メール転送付き)」のサービスでは、 お名前.com 宛のメールが、登録者のメールに転送される為、 SSL証明書の更新時における「メール認証」にも対応できるというもの

ms project 2016で、タスクのリンク設定(先行->後続)を行うと、後続タスクの開始日が自動で前倒し

「先行タスク完了日 - 後続タスク開始日」に余裕(リードタイム?)があるタスクに対し、 ms project 2016あたりから、後続タスクの開始日が自動で前倒しされる。

どうやら、ms projectのオプションで、 「リンクの編集時に手動でスケジュールされたタスクを更新する」の チェックを外すと、解消?されるみたい。

f:id:end0tknr:20190630131230p:plain

↑これらが、↓こうなってしまうので...

f:id:end0tknr:20190630131239p:plain

ms projectのオプションで、以下の設定を変更

f:id:end0tknr:20190630131227p:plain